aboalaa1472 commited on
Commit
a014e82
Β·
verified Β·
1 Parent(s): b1f049f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -88
app.py CHANGED
@@ -7,7 +7,7 @@ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
7
  from reportlab.lib.units import inch
8
  from reportlab.lib import colors
9
  from reportlab.lib.enums import TA_CENTER, TA_LEFT
10
- import io
11
  import os
12
  from PIL import Image as PILImage
13
 
@@ -95,15 +95,17 @@ def generate_schedule(start_date, end_date, off_days, num_lessons, logo_file=Non
95
 
96
  def create_pdf(schedule_data, start_date, end_date, off_days, num_lessons, logo_file=None):
97
  """
98
- Create PDF from schedule data
99
  """
100
  try:
101
- # Create a bytes buffer for the PDF
102
- buffer = io.BytesIO()
 
 
103
 
104
  # Create PDF document
105
- doc = SimpleDocTemplate(buffer, pagesize=A4, rightMargin=72, leftMargin=72,
106
- topMargin=72, bottomMargin=18)
107
 
108
  # Container for the 'Flowable' objects
109
  elements = []
@@ -131,20 +133,21 @@ def create_pdf(schedule_data, start_date, end_date, off_days, num_lessons, logo_
131
  # Add logo if provided
132
  if logo_file is not None:
133
  try:
134
- # Save uploaded file temporarily
135
- logo_path = "temp_logo.png"
136
- with open(logo_path, "wb") as f:
137
- f.write(logo_file)
138
 
139
  # Add logo to PDF
140
- logo = Image(logo_path, width=2*inch, height=1*inch)
141
  logo.hAlign = 'CENTER'
142
  elements.append(logo)
143
  elements.append(Spacer(1, 20))
144
 
145
- # Clean up temp file
146
- os.remove(logo_path)
147
- except:
 
148
  pass # Skip logo if there's an error
149
 
150
  # Add title
@@ -194,63 +197,43 @@ def create_pdf(schedule_data, start_date, end_date, off_days, num_lessons, logo_
194
 
195
  elements.append(table)
196
 
 
 
 
 
 
 
197
  # Build PDF
198
  doc.build(elements)
199
 
200
- # Get the value of the BytesIO buffer
201
- pdf_data = buffer.getvalue()
202
- buffer.close()
203
-
204
- return pdf_data
205
 
206
  except Exception as e:
207
  print(f"PDF creation error: {str(e)}")
208
  return None
209
 
210
- def create_csv(schedule_data):
211
- """
212
- Create CSV from schedule data
213
- """
214
- try:
215
- df = pd.DataFrame(schedule_data)
216
- csv_buffer = io.StringIO()
217
- df.to_csv(csv_buffer, index=False)
218
- return csv_buffer.getvalue()
219
- except Exception as e:
220
- print(f"CSV creation error: {str(e)}")
221
- return None
222
-
223
  def process_schedule(start_date, end_date, off_days, num_lessons, logo_file):
224
  """
225
  Main processing function for Gradio interface
226
  """
227
- # Generate schedule
228
- summary, df, schedule_data = generate_schedule(start_date, end_date, off_days, num_lessons, logo_file)
229
-
230
- if schedule_data is None:
231
- return summary, None, None, None
232
-
233
- # Create PDF
234
- pdf_data = create_pdf(schedule_data, start_date, end_date, off_days, num_lessons, logo_file)
235
-
236
- # Create CSV
237
- csv_data = create_csv(schedule_data)
238
-
239
- # Save files temporarily for download
240
- pdf_path = None
241
- csv_path = None
242
-
243
- if pdf_data:
244
- pdf_path = "study_schedule.pdf"
245
- with open(pdf_path, "wb") as f:
246
- f.write(pdf_data)
247
-
248
- if csv_data:
249
- csv_path = "study_schedule.csv"
250
- with open(csv_path, "w") as f:
251
- f.write(csv_data)
252
-
253
- return summary, df, pdf_path, csv_path
254
 
255
  # Create Gradio interface
256
  def create_interface():
@@ -270,6 +253,15 @@ def create_interface():
270
  border-left: 4px solid #2E86AB;
271
  margin: 1rem 0;
272
  }
 
 
 
 
 
 
 
 
 
273
  """
274
  ) as demo:
275
 
@@ -283,7 +275,7 @@ def create_interface():
283
  2. Choose your off-days (days you don't want to study)<br>
284
  3. Set the number of lessons to schedule<br>
285
  4. Optionally upload a logo for your PDF<br>
286
- 5. Generate your personalized study schedule!
287
  </div>
288
  """,
289
  elem_classes=["main-header"]
@@ -294,15 +286,17 @@ def create_interface():
294
  gr.Markdown("### πŸ“… Schedule Settings")
295
 
296
  start_date = gr.Textbox(
297
- label="Start Date",
298
  placeholder="YYYY-MM-DD (e.g., 2025-07-01)",
299
- value="2025-07-01"
 
300
  )
301
 
302
  end_date = gr.Textbox(
303
- label="End Date",
304
  placeholder="YYYY-MM-DD (e.g., 2025-08-30)",
305
- value="2025-08-30"
 
306
  )
307
 
308
  num_lessons = gr.Slider(
@@ -310,61 +304,96 @@ def create_interface():
310
  maximum=200,
311
  value=90,
312
  step=1,
313
- label="Number of Lessons"
 
314
  )
315
 
316
  off_days = gr.CheckboxGroup(
317
  choices=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
318
- label="Off Days (Days you don't want to study)",
319
- value=["Sunday"]
 
320
  )
321
 
322
  logo_file = gr.File(
323
- label="Upload Logo (Optional)",
324
  file_types=["image"],
325
- type="binary"
 
326
  )
327
 
328
- generate_btn = gr.Button("πŸš€ Generate Schedule", variant="primary", size="lg")
 
 
 
 
 
329
 
330
  with gr.Row():
331
  with gr.Column():
332
  gr.Markdown("### πŸ“Š Results")
333
 
334
  summary_output = gr.Markdown()
 
335
  schedule_table = gr.Dataframe(
336
  headers=["Date", "Day", "Session"],
337
- interactive=False
 
338
  )
339
 
340
- with gr.Row():
341
- pdf_download = gr.File(label="πŸ“„ Download PDF", visible=False)
342
- csv_download = gr.File(label="πŸ“Š Download CSV", visible=False)
 
 
343
 
344
  # Event handler
345
  generate_btn.click(
346
  fn=process_schedule,
347
  inputs=[start_date, end_date, off_days, num_lessons, logo_file],
348
- outputs=[summary_output, schedule_table, pdf_download, csv_download]
349
- ).then(
350
- lambda: [gr.update(visible=True), gr.update(visible=True)],
351
- outputs=[pdf_download, csv_download]
352
  )
353
 
354
  # Example section
355
  gr.Markdown(
356
  """
357
- ### πŸ’‘ Tips:
358
- - **Date Format**: Use YYYY-MM-DD format (e.g., 2025-07-01)
359
- - **Off Days**: Select days you want to skip (weekends, holidays, etc.)
360
- - **Lessons**: Adjust the number based on your course requirements
361
- - **Logo**: Upload PNG, JPG, or other image formats for PDF branding
 
 
 
 
 
 
 
 
362
 
363
- ### 🎯 Example:
364
- - Start: 2025-07-01, End: 2025-08-30
365
- - Off Days: Friday, Sunday
 
 
 
 
 
 
 
 
 
 
 
 
366
  - Lessons: 90
367
- - This creates a schedule with 1-2 lessons per available day
 
 
 
 
 
 
368
  """
369
  )
370
 
@@ -377,5 +406,5 @@ if __name__ == "__main__":
377
  server_name="0.0.0.0",
378
  server_port=7860,
379
  share=False,
380
- debug=False
381
  )
 
7
  from reportlab.lib.units import inch
8
  from reportlab.lib import colors
9
  from reportlab.lib.enums import TA_CENTER, TA_LEFT
10
+ import tempfile
11
  import os
12
  from PIL import Image as PILImage
13
 
 
95
 
96
  def create_pdf(schedule_data, start_date, end_date, off_days, num_lessons, logo_file=None):
97
  """
98
+ Create PDF from schedule data and return file path
99
  """
100
  try:
101
+ # Create a temporary file for the PDF
102
+ pdf_file = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf', prefix='study_schedule_')
103
+ pdf_path = pdf_file.name
104
+ pdf_file.close()
105
 
106
  # Create PDF document
107
+ doc = SimpleDocTemplate(pdf_path, pagesize=A4, rightMargin=72, leftMargin=72,
108
+ topMargin=72, bottomMargin=72)
109
 
110
  # Container for the 'Flowable' objects
111
  elements = []
 
133
  # Add logo if provided
134
  if logo_file is not None:
135
  try:
136
+ # Create temporary file for logo
137
+ logo_temp = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
138
+ logo_temp.write(logo_file)
139
+ logo_temp.close()
140
 
141
  # Add logo to PDF
142
+ logo = Image(logo_temp.name, width=2*inch, height=1*inch)
143
  logo.hAlign = 'CENTER'
144
  elements.append(logo)
145
  elements.append(Spacer(1, 20))
146
 
147
+ # Clean up temp logo file
148
+ os.unlink(logo_temp.name)
149
+ except Exception as e:
150
+ print(f"Logo processing error: {e}")
151
  pass # Skip logo if there's an error
152
 
153
  # Add title
 
197
 
198
  elements.append(table)
199
 
200
+ # Add footer
201
+ elements.append(Spacer(1, 30))
202
+ footer = Paragraph(f"Generated on {datetime.now().strftime('%Y-%m-%d %H:%M')}",
203
+ styles['Normal'])
204
+ elements.append(footer)
205
+
206
  # Build PDF
207
  doc.build(elements)
208
 
209
+ return pdf_path
 
 
 
 
210
 
211
  except Exception as e:
212
  print(f"PDF creation error: {str(e)}")
213
  return None
214
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  def process_schedule(start_date, end_date, off_days, num_lessons, logo_file):
216
  """
217
  Main processing function for Gradio interface
218
  """
219
+ try:
220
+ # Generate schedule
221
+ summary, df, schedule_data = generate_schedule(start_date, end_date, off_days, num_lessons, logo_file)
222
+
223
+ if schedule_data is None:
224
+ return summary, None, None, gr.update(visible=False)
225
+
226
+ # Create PDF
227
+ pdf_path = create_pdf(schedule_data, start_date, end_date, off_days, num_lessons, logo_file)
228
+
229
+ if pdf_path is None:
230
+ return summary, df, None, gr.update(visible=False)
231
+
232
+ return summary, df, pdf_path, gr.update(visible=True)
233
+
234
+ except Exception as e:
235
+ error_msg = f"❌ Error processing schedule: {str(e)}"
236
+ return error_msg, None, None, gr.update(visible=False)
 
 
 
 
 
 
 
 
 
237
 
238
  # Create Gradio interface
239
  def create_interface():
 
253
  border-left: 4px solid #2E86AB;
254
  margin: 1rem 0;
255
  }
256
+ .generate-btn {
257
+ background: linear-gradient(45deg, #2E86AB, #A23B72) !important;
258
+ border: none !important;
259
+ color: white !important;
260
+ font-weight: bold !important;
261
+ font-size: 16px !important;
262
+ padding: 12px 24px !important;
263
+ border-radius: 8px !important;
264
+ }
265
  """
266
  ) as demo:
267
 
 
275
  2. Choose your off-days (days you don't want to study)<br>
276
  3. Set the number of lessons to schedule<br>
277
  4. Optionally upload a logo for your PDF<br>
278
+ 5. Generate and download your personalized study schedule as PDF!
279
  </div>
280
  """,
281
  elem_classes=["main-header"]
 
286
  gr.Markdown("### πŸ“… Schedule Settings")
287
 
288
  start_date = gr.Textbox(
289
+ label="πŸ“… Start Date",
290
  placeholder="YYYY-MM-DD (e.g., 2025-07-01)",
291
+ value="2025-07-01",
292
+ info="Enter start date in YYYY-MM-DD format"
293
  )
294
 
295
  end_date = gr.Textbox(
296
+ label="πŸ“… End Date",
297
  placeholder="YYYY-MM-DD (e.g., 2025-08-30)",
298
+ value="2025-08-30",
299
+ info="Enter end date in YYYY-MM-DD format"
300
  )
301
 
302
  num_lessons = gr.Slider(
 
304
  maximum=200,
305
  value=90,
306
  step=1,
307
+ label="πŸ“š Number of Lessons",
308
+ info="Total lessons to schedule"
309
  )
310
 
311
  off_days = gr.CheckboxGroup(
312
  choices=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
313
+ label="🚫 Off Days (Days you don't want to study)",
314
+ value=["Sunday"],
315
+ info="Select days to skip"
316
  )
317
 
318
  logo_file = gr.File(
319
+ label="πŸ–ΌοΈ Upload Logo (Optional)",
320
  file_types=["image"],
321
+ type="binary",
322
+ info="Upload PNG, JPG, or other image for PDF header"
323
  )
324
 
325
+ generate_btn = gr.Button(
326
+ "πŸš€ Generate Schedule",
327
+ variant="primary",
328
+ size="lg",
329
+ elem_classes=["generate-btn"]
330
+ )
331
 
332
  with gr.Row():
333
  with gr.Column():
334
  gr.Markdown("### πŸ“Š Results")
335
 
336
  summary_output = gr.Markdown()
337
+
338
  schedule_table = gr.Dataframe(
339
  headers=["Date", "Day", "Session"],
340
+ interactive=False,
341
+ wrap=True
342
  )
343
 
344
+ pdf_download = gr.File(
345
+ label="πŸ“„ Download PDF Schedule",
346
+ visible=False,
347
+ interactive=True
348
+ )
349
 
350
  # Event handler
351
  generate_btn.click(
352
  fn=process_schedule,
353
  inputs=[start_date, end_date, off_days, num_lessons, logo_file],
354
+ outputs=[summary_output, schedule_table, pdf_download, pdf_download]
 
 
 
355
  )
356
 
357
  # Example section
358
  gr.Markdown(
359
  """
360
+ ### πŸ’‘ Usage Tips:
361
+
362
+ **πŸ“… Date Format**: Always use YYYY-MM-DD format
363
+ - βœ… Correct: `2025-07-01`
364
+ - ❌ Wrong: `07/01/2025` or `1 July 2025`
365
+
366
+ **🚫 Off Days**: Select any days you want to skip
367
+ - Example: Skip weekends β†’ Select "Saturday" and "Sunday"
368
+ - Example: Skip Friday prayers β†’ Select "Friday"
369
+
370
+ **πŸ“š Lessons**: Adjust based on your course
371
+ - Online course with 90 videos β†’ Set to 90
372
+ - Textbook with 20 chapters β†’ Set to 20
373
 
374
+ **πŸ–ΌοΈ Logo**: Upload any image to brand your PDF
375
+ - Supported: PNG, JPG, JPEG, GIF
376
+ - Recommended size: 200x100 pixels or similar ratio
377
+
378
+ ### 🎯 Example Scenarios:
379
+
380
+ **Scenario 1: Weekend Study**
381
+ - Start: 2025-07-01, End: 2025-12-31
382
+ - Off Days: Monday, Tuesday, Wednesday, Thursday, Friday
383
+ - Lessons: 50
384
+ - Result: Weekend-only schedule
385
+
386
+ **Scenario 2: Intensive Course**
387
+ - Start: 2025-07-01, End: 2025-07-31
388
+ - Off Days: Sunday
389
  - Lessons: 90
390
+ - Result: ~3-4 lessons per day
391
+
392
+ **Scenario 3: Relaxed Learning**
393
+ - Start: 2025-07-01, End: 2025-12-31
394
+ - Off Days: Friday, Saturday, Sunday
395
+ - Lessons: 100
396
+ - Result: ~1 lesson per weekday
397
  """
398
  )
399
 
 
406
  server_name="0.0.0.0",
407
  server_port=7860,
408
  share=False,
409
+ debug=True
410
  )