bluenevus commited on
Commit
5c05510
·
1 Parent(s): 252bbff

Update app.py via AI Editor

Browse files
Files changed (1) hide show
  1. app.py +54 -62
app.py CHANGED
@@ -60,6 +60,7 @@ app.layout = html.Div([
60
  dcc.Store(id='session-id', storage_type='local'),
61
  dcc.Store(id='current-slide-index', storage_type='session'),
62
  dcc.Store(id='files-box-store', storage_type='session'),
 
63
  html.Script('''
64
  (function() {
65
  function uuidv4() {
@@ -112,18 +113,7 @@ app.layout = html.Div([
112
  dbc.CardHeader("All Uploaded/Generated Files", className="bg-light"),
113
  dbc.CardBody(id="files-box", className="mb-2"),
114
  ], className="mb-3 shadow-sm"),
115
- dbc.Button("Generate Slides", id='generate-button', color="primary", className="w-100 mt-2", size="lg"),
116
- html.Div([
117
- dbc.Label("Generated Slide Sets", className="fw-bold"),
118
- dcc.Dropdown(
119
- id='slide-generation-list',
120
- options=[],
121
- value=None,
122
- placeholder="No slides generated yet",
123
- clearable=False,
124
- style={'marginBottom': '10px'}
125
- )
126
- ], className="mt-3"),
127
  html.Div([
128
  html.Div("Status / Log:", className="fw-bold mb-1"),
129
  html.Div(id='log-output', style={'whiteSpace': 'pre-line', 'height': '150px', 'overflowY': 'scroll', 'border': '1px solid #ddd', 'padding': '10px'})
@@ -141,13 +131,16 @@ app.layout = html.Div([
141
  style={'height': '400px', 'resize': 'vertical'},
142
  className="mb-3"
143
  ),
144
- dcc.Loading(
145
- id="loading-ppt",
146
- type="default",
147
- children=[
148
- dbc.Button("Generate PowerPoint", id='generate-ppt-button', color="primary", className="w-100 mt-3", size="lg")
149
- ],
150
- style={'width': '100%'}
 
 
 
151
  ),
152
  ])
153
  ], className="mb-4 shadow-sm")
@@ -290,14 +283,12 @@ def store_session_id(n_intervals):
290
  Output('files-box', 'children'),
291
  Output('slides-content', 'value'),
292
  Output('log-output', 'children'),
293
- Output('slide-generation-list', 'options'),
294
- Output('slide-generation-list', 'value'),
295
  Output('current-slide-index', 'data'),
296
  Output("download-dynamic", "data"),
 
297
  Input('upload-file', 'contents'),
298
- Input('generate-button', 'n_clicks'),
299
  Input('generate-ppt-button', 'n_clicks'),
300
- Input('slide-generation-list', 'value'),
301
  Input({'type': 'file-download', 'index': dash.ALL}, 'n_clicks'),
302
  Input({'type': 'file-delete', 'index': dash.ALL}, 'n_clicks'),
303
  State('upload-file', 'filename'),
@@ -307,12 +298,13 @@ def store_session_id(n_intervals):
307
  State('current-slide-index', 'data'),
308
  State({'type': 'file-download', 'index': dash.ALL}, 'id'),
309
  State({'type': 'file-delete', 'index': dash.ALL}, 'id'),
 
310
  prevent_initial_call=True
311
  )
312
  def unified_callback(
313
- upload_contents, gen_btn, gen_ppt_btn, selected_slide_idx, file_downloads, file_deletes,
314
  upload_filename, document_text, slides_content, session_id, current_slide_idx,
315
- download_ids, delete_ids
316
  ):
317
  ctx = callback_context
318
  if not ctx.triggered or not session_id:
@@ -321,10 +313,10 @@ def unified_callback(
321
  session = get_or_create_session_data(session_id)
322
  slides_md = slides_content
323
  log_str = ""
324
- slide_list = session.get('slide_markdown_names', [])
325
  slide_md_list = session.get('slide_markdowns', [])
326
  slide_idx = current_slide_idx if current_slide_idx is not None else None
327
  download_data = None
 
328
 
329
  with session['lock']:
330
  if 'files_box' not in session:
@@ -372,16 +364,11 @@ def unified_callback(
372
  return html.Div("No files uploaded or generated yet.", className="text-muted")
373
  return files_box
374
 
375
- dropdown_options = [
376
- {'label': slide_name, 'value': idx}
377
- for idx, slide_name in enumerate(slide_list)
378
- ]
379
- dropdown_value = slide_idx if (slide_idx is not None and slide_idx < len(slide_list)) else (len(slide_list) - 1 if slide_list else None)
380
-
381
  with session['lock']:
382
  log_str = '\n'.join(session['log_messages'][:100])
383
 
384
  if button_id == 'upload-file':
 
385
  if upload_contents and upload_filename:
386
  try:
387
  header, content_string = upload_contents.split(',')
@@ -394,9 +381,11 @@ def unified_callback(
394
  with session['lock']:
395
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - Error uploading file: {str(e)}")
396
  log_str = '\n'.join(session['log_messages'][:100])
397
- return rebuild_files_box(session), slides_content, log_str, dropdown_options, dropdown_value, slide_idx, None
 
398
 
399
- elif button_id == 'generate-button':
 
400
  decoded_file_text = None
401
  uploaded_files = [f for f in session['files_box'] if f['type'] == 'uploaded']
402
  if uploaded_files:
@@ -409,7 +398,8 @@ def unified_callback(
409
  with session['lock']:
410
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - Could not decode uploaded file as text. Please upload a UTF-8 or Latin-1 encoded text file.")
411
  log_str = '\n'.join(session['log_messages'][:100])
412
- return rebuild_files_box(session), "Could not decode uploaded file as text. Please upload a UTF-8 or Latin-1 encoded text file.", log_str, dropdown_options, dropdown_value, slide_idx, None
 
413
  combined_text = ""
414
  if decoded_file_text and document_text:
415
  combined_text = decoded_file_text.strip() + "\n\n" + document_text.strip()
@@ -421,7 +411,8 @@ def unified_callback(
421
  with session['lock']:
422
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - Please upload a file or enter text.")
423
  log_str = '\n'.join(session['log_messages'][:100])
424
- return rebuild_files_box(session), "Please upload a file or enter text.", log_str, dropdown_options, dropdown_value, slide_idx, None
 
425
  try:
426
  add_log("Starting slide generation...", session_id)
427
  slides_markdown = process_document(combined_text, session_id)
@@ -434,20 +425,19 @@ def unified_callback(
434
  session['current_slide_md'] = slides_markdown
435
  slide_idx = len(session['slide_markdowns']) - 1
436
  log_str = '\n'.join(session['log_messages'][:100])
437
- dropdown_options = [
438
- {'label': name, 'value': idx}
439
- for idx, name in enumerate(session['slide_markdown_names'])
440
- ]
441
- dropdown_value = slide_idx
442
  except Exception as e:
443
  add_log(f"An error occurred during slide generation: {str(e)}", session_id)
444
  with session['lock']:
445
  log_str = '\n'.join(session['log_messages'][:100])
446
- return rebuild_files_box(session), f"An error occurred: {str(e)}", log_str, dropdown_options, dropdown_value, slide_idx, None
447
- return rebuild_files_box(session), slides_md, log_str, dropdown_options, dropdown_value, slide_idx, None
 
 
448
 
449
  elif button_id == 'generate-ppt-button':
 
450
  if not slides_content or not session_id:
 
451
  raise PreventUpdate
452
  try:
453
  add_log("Starting PowerPoint generation...", session_id)
@@ -461,23 +451,10 @@ def unified_callback(
461
  add_log(f"An error occurred during PowerPoint generation: {str(e)}", session_id)
462
  with session['lock']:
463
  log_str = '\n'.join(session['log_messages'][:100])
464
- return rebuild_files_box(session), slides_content, log_str, dropdown_options, dropdown_value, slide_idx, None
465
- return rebuild_files_box(session), slides_content, log_str, dropdown_options, dropdown_value, slide_idx, None
466
-
467
- elif button_id == 'slide-generation-list':
468
- try:
469
- if selected_slide_idx is not None and 0 <= selected_slide_idx < len(slide_md_list):
470
- slides_md = slide_md_list[selected_slide_idx]
471
- slide_idx = selected_slide_idx
472
- dropdown_value = slide_idx
473
- else:
474
- slides_md = ""
475
- except Exception as e:
476
- add_log(f"An error occurred while loading slide set: {str(e)}", session_id)
477
- with session['lock']:
478
- log_str = '\n'.join(session['log_messages'][:100])
479
- return rebuild_files_box(session), slides_content, log_str, dropdown_options, dropdown_value, slide_idx, None
480
- return rebuild_files_box(session), slides_md, log_str, dropdown_options, dropdown_value, slide_idx, None
481
 
482
  elif button_id.startswith("{"):
483
  triggered_id = eval(button_id)
@@ -487,7 +464,8 @@ def unified_callback(
487
  if 0 <= idx < len(session['files_box']):
488
  file_bytes = session['files_box'][idx]['content']
489
  file_name = session['files_box'][idx]['name']
490
- return rebuild_files_box(session), slides_content, log_str, dropdown_options, dropdown_value, slide_idx, dcc.send_bytes(file_bytes, file_name)
 
491
  elif triggered_id['type'] == 'file-delete':
492
  idx = triggered_id['index']
493
  with session['lock']:
@@ -496,13 +474,27 @@ def unified_callback(
496
  del session['files_box'][idx]
497
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - File '{deleted_name}' deleted.")
498
  log_str = '\n'.join(session['log_messages'][:100])
499
- return rebuild_files_box(session), slides_content, log_str, dropdown_options, dropdown_value, slide_idx, None
 
500
  else:
 
501
  raise PreventUpdate
502
 
503
  else:
 
504
  raise PreventUpdate
505
 
 
 
 
 
 
 
 
 
 
 
 
506
  if __name__ == '__main__':
507
  print("Starting the Dash application...")
508
  app.run(debug=True, host='0.0.0.0', port=7860, threaded=True)
 
60
  dcc.Store(id='session-id', storage_type='local'),
61
  dcc.Store(id='current-slide-index', storage_type='session'),
62
  dcc.Store(id='files-box-store', storage_type='session'),
63
+ dcc.Store(id='loading-active', storage_type='session', data=False),
64
  html.Script('''
65
  (function() {
66
  function uuidv4() {
 
113
  dbc.CardHeader("All Uploaded/Generated Files", className="bg-light"),
114
  dbc.CardBody(id="files-box", className="mb-2"),
115
  ], className="mb-3 shadow-sm"),
116
+ dbc.Button("Generate Content", id='generate-content-button', color="primary", className="w-100 mt-2", size="lg"),
 
 
 
 
 
 
 
 
 
 
 
117
  html.Div([
118
  html.Div("Status / Log:", className="fw-bold mb-1"),
119
  html.Div(id='log-output', style={'whiteSpace': 'pre-line', 'height': '150px', 'overflowY': 'scroll', 'border': '1px solid #ddd', 'padding': '10px'})
 
131
  style={'height': '400px', 'resize': 'vertical'},
132
  className="mb-3"
133
  ),
134
+ dbc.Button("Generate PowerPoint", id='generate-ppt-button', color="primary", className="w-100 mt-3", size="lg"),
135
+ html.Div(
136
+ dcc.Loading(
137
+ id="loading-box",
138
+ type="default",
139
+ fullscreen=False,
140
+ children=html.Div(id="loading-placeholder", style={'height': '100px'})
141
+ ),
142
+ id="loading-box-container",
143
+ style={'marginTop': '2rem', 'marginBottom': '1rem', 'minHeight': '120px', 'display': 'flex', 'justifyContent': 'center', 'alignItems': 'center'}
144
  ),
145
  ])
146
  ], className="mb-4 shadow-sm")
 
283
  Output('files-box', 'children'),
284
  Output('slides-content', 'value'),
285
  Output('log-output', 'children'),
 
 
286
  Output('current-slide-index', 'data'),
287
  Output("download-dynamic", "data"),
288
+ Output('loading-active', 'data'),
289
  Input('upload-file', 'contents'),
290
+ Input('generate-content-button', 'n_clicks'),
291
  Input('generate-ppt-button', 'n_clicks'),
 
292
  Input({'type': 'file-download', 'index': dash.ALL}, 'n_clicks'),
293
  Input({'type': 'file-delete', 'index': dash.ALL}, 'n_clicks'),
294
  State('upload-file', 'filename'),
 
298
  State('current-slide-index', 'data'),
299
  State({'type': 'file-download', 'index': dash.ALL}, 'id'),
300
  State({'type': 'file-delete', 'index': dash.ALL}, 'id'),
301
+ State('loading-active', 'data'),
302
  prevent_initial_call=True
303
  )
304
  def unified_callback(
305
+ upload_contents, gen_content_btn, gen_ppt_btn, file_downloads, file_deletes,
306
  upload_filename, document_text, slides_content, session_id, current_slide_idx,
307
+ download_ids, delete_ids, loading_prev
308
  ):
309
  ctx = callback_context
310
  if not ctx.triggered or not session_id:
 
313
  session = get_or_create_session_data(session_id)
314
  slides_md = slides_content
315
  log_str = ""
 
316
  slide_md_list = session.get('slide_markdowns', [])
317
  slide_idx = current_slide_idx if current_slide_idx is not None else None
318
  download_data = None
319
+ loading_on = False
320
 
321
  with session['lock']:
322
  if 'files_box' not in session:
 
364
  return html.Div("No files uploaded or generated yet.", className="text-muted")
365
  return files_box
366
 
 
 
 
 
 
 
367
  with session['lock']:
368
  log_str = '\n'.join(session['log_messages'][:100])
369
 
370
  if button_id == 'upload-file':
371
+ loading_on = True
372
  if upload_contents and upload_filename:
373
  try:
374
  header, content_string = upload_contents.split(',')
 
381
  with session['lock']:
382
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - Error uploading file: {str(e)}")
383
  log_str = '\n'.join(session['log_messages'][:100])
384
+ loading_on = False
385
+ return rebuild_files_box(session), slides_content, log_str, slide_idx, None, loading_on
386
 
387
+ elif button_id == 'generate-content-button':
388
+ loading_on = True
389
  decoded_file_text = None
390
  uploaded_files = [f for f in session['files_box'] if f['type'] == 'uploaded']
391
  if uploaded_files:
 
398
  with session['lock']:
399
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - Could not decode uploaded file as text. Please upload a UTF-8 or Latin-1 encoded text file.")
400
  log_str = '\n'.join(session['log_messages'][:100])
401
+ loading_on = False
402
+ return rebuild_files_box(session), "Could not decode uploaded file as text. Please upload a UTF-8 or Latin-1 encoded text file.", log_str, slide_idx, None, loading_on
403
  combined_text = ""
404
  if decoded_file_text and document_text:
405
  combined_text = decoded_file_text.strip() + "\n\n" + document_text.strip()
 
411
  with session['lock']:
412
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - Please upload a file or enter text.")
413
  log_str = '\n'.join(session['log_messages'][:100])
414
+ loading_on = False
415
+ return rebuild_files_box(session), "Please upload a file or enter text.", log_str, slide_idx, None, loading_on
416
  try:
417
  add_log("Starting slide generation...", session_id)
418
  slides_markdown = process_document(combined_text, session_id)
 
425
  session['current_slide_md'] = slides_markdown
426
  slide_idx = len(session['slide_markdowns']) - 1
427
  log_str = '\n'.join(session['log_messages'][:100])
 
 
 
 
 
428
  except Exception as e:
429
  add_log(f"An error occurred during slide generation: {str(e)}", session_id)
430
  with session['lock']:
431
  log_str = '\n'.join(session['log_messages'][:100])
432
+ loading_on = False
433
+ return rebuild_files_box(session), f"An error occurred: {str(e)}", log_str, slide_idx, None, loading_on
434
+ loading_on = False
435
+ return rebuild_files_box(session), slides_md, log_str, slide_idx, None, loading_on
436
 
437
  elif button_id == 'generate-ppt-button':
438
+ loading_on = True
439
  if not slides_content or not session_id:
440
+ loading_on = False
441
  raise PreventUpdate
442
  try:
443
  add_log("Starting PowerPoint generation...", session_id)
 
451
  add_log(f"An error occurred during PowerPoint generation: {str(e)}", session_id)
452
  with session['lock']:
453
  log_str = '\n'.join(session['log_messages'][:100])
454
+ loading_on = False
455
+ return rebuild_files_box(session), slides_content, log_str, slide_idx, None, loading_on
456
+ loading_on = False
457
+ return rebuild_files_box(session), slides_content, log_str, slide_idx, None, loading_on
 
 
 
 
 
 
 
 
 
 
 
 
 
458
 
459
  elif button_id.startswith("{"):
460
  triggered_id = eval(button_id)
 
464
  if 0 <= idx < len(session['files_box']):
465
  file_bytes = session['files_box'][idx]['content']
466
  file_name = session['files_box'][idx]['name']
467
+ loading_on = False
468
+ return rebuild_files_box(session), slides_content, log_str, slide_idx, dcc.send_bytes(file_bytes, file_name), loading_on
469
  elif triggered_id['type'] == 'file-delete':
470
  idx = triggered_id['index']
471
  with session['lock']:
 
474
  del session['files_box'][idx]
475
  session['log_messages'].insert(0, f"{time.strftime('%H:%M:%S')} - File '{deleted_name}' deleted.")
476
  log_str = '\n'.join(session['log_messages'][:100])
477
+ loading_on = False
478
+ return rebuild_files_box(session), slides_content, log_str, slide_idx, None, loading_on
479
  else:
480
+ loading_on = False
481
  raise PreventUpdate
482
 
483
  else:
484
+ loading_on = False
485
  raise PreventUpdate
486
 
487
+ # Loading indicator logic
488
+ @app.callback(
489
+ Output("loading-box", "children"),
490
+ Input('loading-active', 'data')
491
+ )
492
+ def update_loading_box(loading_active):
493
+ if loading_active:
494
+ return dcc.Loading(type="default", fullscreen=False, children=html.Div(style={'height': '100px'}))
495
+ else:
496
+ return html.Div(style={'height': '100px'})
497
+
498
  if __name__ == '__main__':
499
  print("Starting the Dash application...")
500
  app.run(debug=True, host='0.0.0.0', port=7860, threaded=True)