ymcmy/physics_pdf
1
1import gradio as gr2from bs4 import BeautifulSoup3import requests4from jinja2 import Template5from urllib.parse import urljoin6import os7import warnings8import logging9 10warnings.filterwarnings("ignore")11 12# Set up logging13logging.basicConfig(level=logging.DEBUG, filename='app.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')14 15books = {16 "College Physics AP": {17 "conceptual_link": "https://openstax.org/books/college-physics-ap-courses-2e/pages/{}-conceptual-questions",18 "problem_link": "https://openstax.org/books/college-physics-ap-courses-2e/pages/{}-problems-exercises",19 "href_base_url": "https://openstax.org/books/college-physics-ap-courses-2e/pages/"20 },21 "University Physics Vol. 1": {22 "conceptual_link": "https://openstax.org/books/university-physics-volume-1/pages/{}-conceptual-questions",23 "problem_link": "https://openstax.org/books/university-physics-volume-1/pages/{}-problems",24 "href_base_url": "https://openstax.org/books/university-physics-volume-1/pages/"25 },26 "University Physics Vol. 2": {27 "conceptual_link": "https://openstax.org/books/university-physics-volume-2/pages/{}-conceptual-questions",28 "problem_link": "https://openstax.org/books/university-physics-volume-2/pages/{}-problems",29 "href_base_url": "https://openstax.org/books/university-physics-volume-2/pages/"30 }31}32 33img_base_url = 'https://openstax.org'34 35def get_html(url):36 headers = {37 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"38 }39 try:40 response = requests.get(url, headers=headers)41 response.encoding = 'utf-8'42 response.raise_for_status() # Raise an HTTPError for bad responses43 soup = BeautifulSoup(response.text, 'html.parser')44 return soup45 except requests.RequestException as e:46 logging.error(f"An error occurred when getting HTML: {e}")47 return None48 49def get_question(exercises, question_index, img_base_url, href_base_url):50 question_index = question_index - 151 52 if question_index >= len(exercises):53 return "Question index out of range."54 55 exercise_div = exercises[question_index]56 logging.debug(f"Processing exercise: {exercise_div}")57 58 for img_tag in exercise_div.find_all('img'):59 img_tag['src'] = urljoin(img_base_url, img_tag['data-lazy-src'])60 61 for a_tag in exercise_div.find_all('a'):62 a_tag['href'] = urljoin(href_base_url, a_tag['href'])63 64 return str(exercise_div)65 66def get_all_questions(book_key, unit_num, conceptual_list, problem_list):67 book = books[book_key]68 conceptual_url = book["conceptual_link"].format(int(unit_num))69 problem_url = book["problem_link"].format(int(unit_num))70 71 conceptual_html = get_html(conceptual_url)72 if conceptual_html is None:73 return []74 problem_html = get_html(problem_url)75 if problem_html is None:76 return []77 78 conceptual_exercises = conceptual_html.find_all('div', {'data-type': 'exercise'})79 problem_exercises = problem_html.find_all('div', {'data-type': 'exercise'})80 questions = []81 82 for i in conceptual_list:83 questions.append(get_question(conceptual_exercises, i, img_base_url, book["href_base_url"]))84 85 for i in problem_list:86 questions.append(get_question(problem_exercises, i, img_base_url, book["href_base_url"]))87 88 return questions89 90def generate_html(book_key, chapter_num, conceptual_input, problem_input, path):91 conceptual_list = list(map(int, conceptual_input.split(",")) if conceptual_input else [])92 problem_list = list(map(int, problem_input.split(",")) if problem_input else [])93 94 questions = get_all_questions(book_key, int(chapter_num), conceptual_list, problem_list)95 template_str = '''96 <!DOCTYPE html>97 <html>98 <head>99 <title>Chapter {{ chapter_number }} Questions</title>100 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css">101 <script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.js"></script>102 <script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/contrib/auto-render.min.js"103 onload="renderMathInElement(document.body);"></script>104 <style>105 body {106 font-family: 'Calibri', sans-serif;107 font-size: 20px;108 }109 .page-break {110 page-break-after: always;111 }112 .mathjax {113 display: inline-block;114 }115 </style>116 </head>117 <body>118 <div>119 <h2>Chapter: {{ chapter_number }}</h2>120 {% if conceptual_problem_list %}121 <h2>Conceptual Problems: {{ conceptual_problem_list|join(", ") }}</h2>122 {% endif %}123 {% if problems_and_exercise_list %}124 <h2>Problems and Exercises: {{ problems_and_exercise_list|join(", ") }}</h2>125 {% endif %}126 </div>127 <div class="page-break"></div>128 129 {% for question in questions %}130 <div class="mathjax">{{ question|safe }}</div>131 <div class="page-break"></div>132 {% endfor %}133 </body>134 </html>135 '''136 template = Template(template_str)137 138 rendered_html = template.render(chapter_number=int(chapter_num),139 conceptual_problem_list=conceptual_list,140 problems_and_exercise_list=problem_list,141 questions=questions)142 143 with open(path, 'w', encoding='utf-8') as f:144 f.write(rendered_html)145 146def main_function(book_key, unit_num, conceptual_input, problem_input):147 try:148 if not conceptual_input and not problem_input:149 return "Both lists cannot be empty. Please provide at least one."150 151 # Ensure the directory exists152 abs_path = "D:\\projects\\phy_pdf"153 if not os.path.exists(abs_path):154 os.makedirs(abs_path)155 156 # Delete all existing HTML files in the directory157 for file_name in os.listdir(abs_path):158 if file_name.endswith(".html"):159 os.remove(os.path.join(abs_path, file_name))160 161 file_name = "questions_" + str(int(unit_num))162 html_path = os.path.join(abs_path, file_name + ".html")163 164 generate_html(book_key, unit_num, conceptual_input, problem_input, html_path)165 166 logging.info("HTML generated successfully")167 return html_path168 except Exception as e:169 logging.error(f"An error occurred in main_function: {e}")170 return "An error occurred. Please check the logs for more details."171 172iface = gr.Interface(173 fn=main_function,174 inputs=[175 gr.Dropdown(label="Select Book", choices=list(books.keys())),176 gr.Number(label="Chapter Number"),177 gr.Textbox(label="Conceptual Problems List (comma-separated)"),178 gr.Textbox(label="Problems & Exercises List (comma-separated)")179 ],180 outputs=gr.File(label="Generated HTML"),181 live=False182)183 184iface.launch()185 