shukdevdatta123 commited on
Commit
4f49a0e
·
verified ·
1 Parent(s): 896a7ad

Create v4.txt

Browse files
Files changed (1) hide show
  1. v4.txt +608 -0
v4.txt ADDED
@@ -0,0 +1,608 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import openai
3
+ import fitz # PyMuPDF for PDF processing
4
+ import os
5
+ import tempfile
6
+ import base64
7
+ from datetime import datetime
8
+ import re
9
+
10
+ # Variable to store API key
11
+ api_key = ""
12
+
13
+ # Function to update API key
14
+ def set_api_key(key):
15
+ global api_key
16
+ api_key = key
17
+ return "API Key Set Successfully!"
18
+
19
+ # Function to extract text from PDF
20
+ def extract_text_from_pdf(pdf_path):
21
+ try:
22
+ doc = fitz.open(pdf_path)
23
+ text = "\n".join([page.get_text("text") for page in doc])
24
+ return text
25
+ except Exception as e:
26
+ return f"Error extracting text from PDF: {str(e)}"
27
+
28
+ # Function to interact with OpenAI API for systematic review
29
+ def generate_systematic_review(pdf_files, review_question, include_tables=True, include_figures=True):
30
+ if not api_key:
31
+ return "Please enter your OpenAI API key first."
32
+
33
+ if not pdf_files:
34
+ return "Please upload at least one PDF file."
35
+
36
+ if not review_question:
37
+ return "Please enter a review question."
38
+
39
+ try:
40
+ openai.api_key = api_key
41
+
42
+ # Create the system message with systematic review guidelines
43
+ system_prompt = """You are an expert academic assistant. Create a systematic review using academic research paper formatting. The Systematic Review must be in great details. Structure it using these steps:
44
+
45
+ Step 1: Identify a Research Field
46
+ The first step in writing a systematic review paper is to identify a research field. This involves selecting a specific area of study that you are interested in and want to explore further.
47
+
48
+ Step 2: Generate a Research Question
49
+ Once you have identified your research field, the next step is to generate a research question. This question should be specific, measurable, achievable, relevant, and time-bound (SMART). Consider using the PICO framework (Population, Intervention, Comparison, Outcome) to structure clinical questions.
50
+
51
+ Step 3: Create a Protocol
52
+ After generating your research question, create a detailed protocol. This is a comprehensive plan outlining your research methodology, including search strategies, databases to be used, and analysis techniques. The protocol should be registered in appropriate databases (e.g., PROSPERO) when applicable and follow PRISMA guidelines.
53
+
54
+ Step 4: Define Inclusion and Exclusion Criteria
55
+ Clearly articulate the criteria for including or excluding studies in your review. These criteria should be directly tied to your research question and may include: publication date range, study types, population characteristics, intervention specifications, outcome measures, and language restrictions.
56
+
57
+ Step 5: Evaluate Relevant Literature
58
+ Conduct a comprehensive literature search using multiple databases (e.g., PubMed, Scopus, Web of Science, CINAHL) with clearly defined search terms and Boolean operators. Document your search strategy in detail to ensure reproducibility. Consider both published and unpublished (gray) literature to minimize publication bias.
59
+
60
+ Step 6: Quality Assessment of Studies
61
+ Apply established quality assessment tools appropriate for your included study designs (e.g., Cochrane Risk of Bias Tool for randomized trials, ROBINS-I for non-randomized studies, CASP checklists). Document quality assessments for all included studies.
62
+
63
+ Step 7: Data Extraction
64
+ Create and use a standardized data extraction form to systematically collect relevant information from each study. This should include: study characteristics, participant demographics, intervention details, comparison groups, outcome measures, and results. Have multiple reviewers extract data independently when possible.
65
+
66
+ Step 8: Data Synthesis and Analysis
67
+ Synthesize the extracted data using appropriate methods. If statistical pooling is appropriate, conduct meta-analysis with suitable models (fixed or random effects). If heterogeneity precludes meta-analysis, provide a narrative synthesis with clear explanations.
68
+
69
+ Step 9: Critical Analysis of Results
70
+ Analyze your findings critically, examining patterns, inconsistencies, and relationships across studies. Address heterogeneity, publication bias (using funnel plots when applicable), and methodological limitations. Consider using the GRADE approach to evaluate certainty of evidence.
71
+
72
+ Step 10: Interpreting Findings
73
+ Interpret your findings in the context of the original research question. Discuss implications for practice, policy, and future research. Address limitations of your systematic review process and any potential biases.
74
+
75
+ Step 11: Concluding Statements
76
+ Provide clear, substantiated conclusions based on your review findings. Ensure conclusions are proportionate to the evidence presented and acknowledge uncertainty where appropriate. Offer specific recommendations for future research.
77
+
78
+ Step 12: References and Documentation
79
+ Include a comprehensive reference list following a specific citation style (APA, Vancouver, etc.). Provide links to source papers when available.
80
+
81
+ Your response should be formatted in HTML (but avoid showing these tags ```html ```) but generate the content to look like a professional academic paper. Include proper section headers, abstracts, methodology sections, etc. Number all sections like an academic paper. Follow academic journal standards with double spacing, appropriate margins, and consistent formatting throughout.
82
+ """
83
+
84
+ # Extract text from each PDF
85
+ pdf_texts = []
86
+ pdf_names = []
87
+
88
+ for pdf_file in pdf_files:
89
+ if isinstance(pdf_file, str): # If it's already a path
90
+ pdf_path = pdf_file
91
+ else: # If it's a file object
92
+ pdf_path = pdf_file.name
93
+
94
+ pdf_name = os.path.basename(pdf_path)
95
+ pdf_text = extract_text_from_pdf(pdf_path)
96
+
97
+ pdf_texts.append(pdf_text)
98
+ pdf_names.append(pdf_name)
99
+
100
+ # Prepare the user prompt with the review question and instructions
101
+ visual_instruction = ""
102
+ if include_tables and include_figures:
103
+ visual_instruction = " Please include important new generated tables and create essential figures (using SVG format) to illustrate key findings, trends, or conceptual frameworks in your review. Create at least 2-3 figures that help visualize the most important insights."
104
+ elif include_tables:
105
+ visual_instruction = " Please include important new generated tables in your review."
106
+ elif include_figures:
107
+ visual_instruction = " Please create essential figures (using SVG format) to illustrate key findings, trends, or conceptual frameworks in your review. Create at least 2-3 figures that help visualize the most important insights."
108
+
109
+ user_prompt = f"Please generate a systematic review of the following {len(pdf_files)} papers: {', '.join(pdf_names)}.{visual_instruction}\n\nReview Question: {review_question}"
110
+
111
+ # Create the messages for the API call
112
+ messages = [
113
+ {"role": "system", "content": system_prompt},
114
+ {"role": "user", "content": user_prompt + "\n\n" + "\n\n".join([f"Paper {i+1} - {pdf_names[i]}:\n{pdf_texts[i]}" for i in range(len(pdf_texts))])}
115
+ ]
116
+
117
+ # Call the API with temperature=0.7 and top_p=1
118
+ response = openai.ChatCompletion.create(
119
+ model="gpt-4.1",
120
+ messages=messages,
121
+ temperature=0.7,
122
+ top_p=1,
123
+ max_tokens=16384
124
+ )
125
+
126
+ # Get the AI response
127
+ review_content = response["choices"][0]["message"]["content"]
128
+
129
+ # Process and replace any SVG content with properly formatted SVG
130
+ review_content = process_svg_content(review_content)
131
+
132
+ # Apply professional academic paper styling
133
+ styled_html = f"""
134
+ <!DOCTYPE html>
135
+ <html lang="en">
136
+ <head>
137
+ <meta charset="UTF-8">
138
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
139
+ <title>Systematic Review</title>
140
+ <style>
141
+ /* Academic Paper Styling */
142
+ body {{
143
+ font-family: 'Times New Roman', Times, serif;
144
+ line-height: 1.6;
145
+ color: #333;
146
+ margin: 0;
147
+ padding: 0;
148
+ background-color: #f9f9f9;
149
+ }}
150
+ .paper-container {{
151
+ max-width: 800px;
152
+ margin: 0 auto;
153
+ padding: 40px;
154
+ background-color: white;
155
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
156
+ }}
157
+ header {{
158
+ text-align: center;
159
+ margin-bottom: 30px;
160
+ border-bottom: 1px solid #ddd;
161
+ padding-bottom: 20px;
162
+ }}
163
+ h1 {{
164
+ font-size: 24px;
165
+ margin: 0 0 15px;
166
+ font-weight: bold;
167
+ }}
168
+ .author-info {{
169
+ font-size: 14px;
170
+ margin-bottom: 15px;
171
+ }}
172
+ .abstract {{
173
+ font-style: italic;
174
+ margin: 20px 0;
175
+ padding: 15px;
176
+ background-color: #f8f8f8;
177
+ border-left: 3px solid #ccc;
178
+ }}
179
+ h2 {{
180
+ font-size: 18px;
181
+ margin: 30px 0 15px;
182
+ border-bottom: 1px solid #eee;
183
+ padding-bottom: 5px;
184
+ }}
185
+ h3 {{
186
+ font-size: 16px;
187
+ margin: 25px 0 10px;
188
+ }}
189
+ p {{
190
+ margin: 0 0 15px;
191
+ text-align: justify;
192
+ }}
193
+ .section {{
194
+ margin-bottom: 30px;
195
+ }}
196
+ table {{
197
+ width: 100%;
198
+ border-collapse: collapse;
199
+ margin: 20px 0;
200
+ font-size: 14px;
201
+ }}
202
+ table, th, td {{
203
+ border: 1px solid #ddd;
204
+ }}
205
+ th, td {{
206
+ padding: 10px;
207
+ text-align: left;
208
+ }}
209
+ th {{
210
+ background-color: #f2f2f2;
211
+ }}
212
+ tr:nth-child(even) {{
213
+ background-color: #f9f9f9;
214
+ }}
215
+ .citation {{
216
+ font-size: 14px;
217
+ color: #555;
218
+ }}
219
+ .reference-list {{
220
+ margin-top: 40px;
221
+ border-top: 1px solid #ddd;
222
+ padding-top: 20px;
223
+ }}
224
+ .reference-list h2 {{
225
+ margin-top: 0;
226
+ }}
227
+ .reference-item {{
228
+ margin-bottom: 10px;
229
+ padding-left: 25px;
230
+ text-indent: -25px;
231
+ }}
232
+ ul, ol {{
233
+ margin: 15px 0;
234
+ padding-left: 25px;
235
+ }}
236
+ li {{
237
+ margin-bottom: 5px;
238
+ }}
239
+ .figure {{
240
+ margin: 25px 0;
241
+ text-align: center;
242
+ }}
243
+ .figure svg {{
244
+ max-width: 100%;
245
+ height: auto;
246
+ }}
247
+ .figure-caption {{
248
+ font-size: 14px;
249
+ color: #666;
250
+ margin-top: 10px;
251
+ text-align: center;
252
+ }}
253
+ .footnote {{
254
+ font-size: 12px;
255
+ color: #777;
256
+ }}
257
+ svg {{
258
+ display: block;
259
+ margin: 0 auto;
260
+ max-width: 100%;
261
+ height: auto;
262
+ }}
263
+ @media print {{
264
+ body {{
265
+ background-color: white;
266
+ }}
267
+ .paper-container {{
268
+ box-shadow: none;
269
+ padding: 0;
270
+ }}
271
+ }}
272
+ </style>
273
+ </head>
274
+ <body>
275
+ <div class="paper-container">
276
+ {review_content}
277
+ </div>
278
+ </body>
279
+ </html>
280
+ """
281
+
282
+ return styled_html
283
+
284
+ except Exception as e:
285
+ return f"""
286
+ <div style="color: red; padding: 20px; border: 1px solid red; border-radius: 5px; background-color: #ffecec;">
287
+ <h3>Error Generating Systematic Review</h3>
288
+ <p>{str(e)}</p>
289
+ </div>
290
+ """
291
+
292
+ # Function to clean up and format SVG content
293
+ def process_svg_content(content):
294
+ # Find SVG blocks
295
+ svg_pattern = r'```svg\s*([\s\S]*?)\s*```'
296
+
297
+ def replace_svg(match):
298
+ svg_content = match.group(1).strip()
299
+ # Ensure proper SVG structure
300
+ if not svg_content.startswith('<svg'):
301
+ svg_content = f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500">{svg_content}</svg>'
302
+
303
+ # Wrap in figure div with caption if not already
304
+ if '<div class="figure">' not in svg_content:
305
+ figure_number = len(re.findall(r'<div class="figure">', content[:match.start()])) + 1
306
+ return f"""
307
+ <div class="figure">
308
+ {svg_content}
309
+ <div class="figure-caption">Figure {figure_number}: Generated visualization of key findings.</div>
310
+ </div>
311
+ """
312
+ return svg_content
313
+
314
+ # Replace SVG code blocks with properly formatted SVG elements
315
+ processed_content = re.sub(svg_pattern, replace_svg, content)
316
+
317
+ return processed_content
318
+
319
+ # Function to save uploaded files
320
+ def save_uploaded_files(files):
321
+ if not files:
322
+ return []
323
+
324
+ saved_paths = []
325
+ for file in files:
326
+ if file is not None:
327
+ # Create a temporary file
328
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
329
+ tmp_file.write(file)
330
+ saved_paths.append(tmp_file.name)
331
+
332
+ return saved_paths
333
+
334
+ # Function to create a downloadable HTML file
335
+ def create_html_download_link(html_content):
336
+ if not html_content or "<div style=\"color: red; padding: 20px;" in html_content or "Please upload at least one PDF file" in html_content:
337
+ return None
338
+
339
+ # Create timestamp for the filename
340
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
341
+ filename = f"systematic_review_{timestamp}.html"
342
+
343
+ # Encode the HTML content for download
344
+ b64_html = base64.b64encode(html_content.encode()).decode()
345
+ download_link = f'<a href="data:text/html;base64,{b64_html}" download="{filename}" class="download-button">Download HTML</a>'
346
+
347
+ return download_link
348
+
349
+ # Add CSS styling for the Gradio interface
350
+ custom_css = """
351
+ <style>
352
+ /* Main UI */
353
+ .gradio-container {
354
+ font-family: 'Arial', sans-serif;
355
+ background-color: #f9f9f9;
356
+ }
357
+
358
+ /* Header */
359
+ h1 {
360
+ font-size: 28px;
361
+ color: #333;
362
+ margin-bottom: 20px;
363
+ text-align: center;
364
+ padding-bottom: 10px;
365
+ border-bottom: 2px solid #4a00e0;
366
+ }
367
+
368
+ /* Primary Button */
369
+ #generate_button {
370
+ background: linear-gradient(135deg, #4a00e0 0%, #8e2de2 100%);
371
+ color: white;
372
+ font-weight: bold;
373
+ padding: 10px 20px;
374
+ border-radius: 5px;
375
+ transition: all 0.3s ease;
376
+ }
377
+ #generate_button:hover {
378
+ background: linear-gradient(135deg, #5b10f1 0%, #9f3ef3 100%);
379
+ transform: translateY(-2px);
380
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
381
+ }
382
+
383
+ /* API Key Button */
384
+ #api_key_button {
385
+ background: linear-gradient(135deg, #68d391 0%, #48bb78 100%);
386
+ color: white;
387
+ font-weight: bold;
388
+ margin-top: 27px;
389
+ padding: 10px 20px;
390
+ border-radius: 5px;
391
+ transition: all 0.3s ease;
392
+ }
393
+ #api_key_button:hover {
394
+ background: linear-gradient(135deg, #38a169 0%, #68d391 100%);
395
+ transform: translateY(-2px);
396
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
397
+ }
398
+
399
+ /* Form Elements */
400
+ .input-container {
401
+ background-color: white;
402
+ padding: 20px;
403
+ border-radius: 8px;
404
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
405
+ margin-bottom: 20px;
406
+ }
407
+
408
+ /* Labels */
409
+ label {
410
+ font-weight: 600;
411
+ color: #555;
412
+ margin-bottom: 8px;
413
+ }
414
+
415
+ /* Instructions Accordion */
416
+ .accordion {
417
+ background-color: white;
418
+ border: 1px solid #e0e0e0;
419
+ border-radius: 8px;
420
+ margin-bottom: 20px;
421
+ }
422
+
423
+ /* Output Container */
424
+ .output-container {
425
+ background-color: white;
426
+ padding: 15px;
427
+ border-radius: 8px;
428
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
429
+ }
430
+
431
+ /* File Upload Area */
432
+ .file-upload {
433
+ border: 2px dashed #ccc;
434
+ border-radius: 5px;
435
+ padding: 20px;
436
+ text-align: center;
437
+ margin-bottom: 20px;
438
+ }
439
+
440
+ /* Download Button */
441
+ .download-button {
442
+ display: inline-block;
443
+ background: linear-gradient(135deg, #4a00e0 0%, #8e2de2 100%);
444
+ color: white;
445
+ font-weight: bold;
446
+ padding: 8px 16px;
447
+ border-radius: 4px;
448
+ text-decoration: none;
449
+ margin-bottom: 10px;
450
+ transition: all 0.3s ease;
451
+ }
452
+ .download-button:hover {
453
+ background: linear-gradient(135deg, #5b10f1 0%, #9f3ef3 100%);
454
+ transform: translateY(-2px);
455
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
456
+ }
457
+
458
+ /* Download Container */
459
+ #download-container {
460
+ display: flex;
461
+ justify-content: center;
462
+ margin: 20px 0;
463
+ padding: 15px;
464
+ background-color: #f5f5f5;
465
+ border-radius: 8px;
466
+ }
467
+
468
+ /* Checkbox Group */
469
+ .checkbox-group {
470
+ display: flex;
471
+ gap: 20px;
472
+ margin: 15px 0;
473
+ }
474
+
475
+ /* Responsive adjustments */
476
+ @media screen and (max-width: 768px) {
477
+ .gradio-container {
478
+ padding: 10px;
479
+ }
480
+ }
481
+ </style>
482
+ """
483
+
484
+ # Gradio UI Layout with improved styling
485
+ with gr.Blocks(css=custom_css) as demo:
486
+ gr.Markdown("# Systematic Review Generator for Research Papers")
487
+
488
+ with gr.Accordion("How to Use This App", open=False):
489
+ gr.Markdown("""
490
+ ### Getting Started:
491
+ 1. Enter your OpenAI API key in the field below and click "Set API Key"
492
+ 2. Upload multiple PDF research papers (2 or more recommended)
493
+ 3. Enter your review question or topic
494
+ 4. Choose visual elements to include (tables and/or figures)
495
+ 5. Click "Generate Systematic Review" to start the process
496
+ 6. After generation, you can download the review as HTML
497
+
498
+ ### Tips for Best Results:
499
+ - Upload papers that are related to the same research topic or field
500
+ - Be specific in your review question to get more focused results
501
+ - The generated review will follow a systematic structure including research field identification, data extraction, analysis, and conclusions
502
+ - The more papers you upload, the more comprehensive the review will be
503
+ - Tables help organize and compare findings across studies
504
+ - Figures help visualize key trends, frameworks, or relationships identified in the review
505
+ - The review will be formatted as a professional academic paper with proper sections and citations
506
+ """)
507
+
508
+ # API Key Input in a styled container
509
+ with gr.Row(elem_classes="input-container"):
510
+ with gr.Column(scale=3):
511
+ api_key_input = gr.Textbox(label="Enter OpenAI API Key", type="password", placeholder="sk-...")
512
+ with gr.Column(scale=1):
513
+ api_key_button = gr.Button("Set API Key", elem_id="api_key_button")
514
+ api_key_output = gr.Textbox(label="API Key Status", interactive=False)
515
+
516
+ # PDF Upload and Review Settings
517
+ with gr.Row(elem_classes="input-container"):
518
+ with gr.Column():
519
+ gr.Markdown("### Upload Research Papers")
520
+ pdf_files = gr.File(label="Upload PDF Research Papers", file_count="multiple", type="binary", elem_classes="file-upload")
521
+ review_question = gr.Textbox(
522
+ label="Review Question or Topic",
523
+ value="Please generate a systematic review of the following papers.",
524
+ placeholder="e.g., What are the effects of mindfulness meditation on stress reduction?"
525
+ )
526
+
527
+ with gr.Row(elem_classes="checkbox-group"):
528
+ include_tables = gr.Checkbox(label="Include Comparison Tables", value=True)
529
+ include_figures = gr.Checkbox(label="Include Visual Figures", value=True)
530
+
531
+ generate_button = gr.Button("Generate Systematic Review", elem_id="generate_button", size="large")
532
+
533
+ # Download link container
534
+ download_html_output = gr.HTML(label="Download Options")
535
+
536
+ # Output with improved styling
537
+ with gr.Row(elem_classes="output-container"):
538
+ review_output = gr.HTML(label="Systematic Review")
539
+
540
+ # Button actions
541
+ api_key_button.click(set_api_key, inputs=[api_key_input], outputs=[api_key_output])
542
+
543
+ # Generate systematic review
544
+ def process_files_and_generate_review(files, question, include_tables, include_figures):
545
+ if not files:
546
+ return ("""
547
+ <div style="padding: 20px; border: 1px solid #e0e0e0; border-radius: 5px; background-color: #f9f9f9;">
548
+ <h3 style="color: #666;">Please upload at least one PDF file.</h3>
549
+ <p>To generate a systematic review, upload one or more research papers in PDF format.</p>
550
+ </div>
551
+ """, "")
552
+
553
+ # Save uploaded files
554
+ saved_paths = save_uploaded_files(files)
555
+
556
+ # Show loading message
557
+ loading_message = """
558
+ <div style="padding: 20px; text-align: center;">
559
+ <h3>Generating Systematic Review...</h3>
560
+ <p>This may take a few minutes depending on the number and size of papers.</p>
561
+ <div style="width: 100%; height: 4px; background-color: #f0f0f0; margin: 20px 0; border-radius: 2px; overflow: hidden;">
562
+ <div style="width: 30%; height: 100%; background: linear-gradient(90deg, #4a00e0, #8e2de2); animation: progress 2s infinite linear;"></div>
563
+ </div>
564
+ <style>
565
+ @keyframes progress {
566
+ 0% { margin-left: -30%; }
567
+ 100% { margin-left: 100%; }
568
+ }
569
+ </style>
570
+ </div>
571
+ """
572
+
573
+ yield loading_message, ""
574
+
575
+ # Generate review
576
+ review = generate_systematic_review(saved_paths, question, include_tables, include_figures)
577
+
578
+ # Create HTML download link
579
+ html_link = create_html_download_link(review)
580
+
581
+ # Create download link HTML
582
+ download_link = f"""
583
+ <div id="download-container">
584
+ <div>
585
+ <h3>Download Option:</h3>
586
+ {html_link or ""}
587
+ </div>
588
+ </div>
589
+ """
590
+
591
+ # Clean up temporary files
592
+ for path in saved_paths:
593
+ try:
594
+ os.remove(path)
595
+ except:
596
+ pass
597
+
598
+ yield review, download_link
599
+
600
+ generate_button.click(
601
+ process_files_and_generate_review,
602
+ inputs=[pdf_files, review_question, include_tables, include_figures],
603
+ outputs=[review_output, download_html_output]
604
+ )
605
+
606
+ # Launch the app
607
+ if __name__ == "__main__":
608
+ demo.launch(share=True)