bluenevus commited on
Commit
daff1e3
·
verified ·
1 Parent(s): 1db7683

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -33
app.py CHANGED
@@ -46,6 +46,9 @@ ssl_context.verify_mode = ssl.CERT_NONE
46
  # ThreadPoolExecutor for background tasks
47
  executor = ThreadPoolExecutor(max_workers=4)
48
 
 
 
 
49
  @contextmanager
50
  def get_db_connection():
51
  if not hasattr(thread_local, "connection"):
@@ -226,7 +229,7 @@ async def process_url(url, depth, progress_callback):
226
  # App layout
227
  app.layout = dbc.Container([
228
  dcc.Store(id='pdf-store'),
229
- dcc.Store(id='progress-store'),
230
  dbc.Card(
231
  dbc.CardBody([
232
  html.H1("Website to PDF Converter", className="text-center mb-4"),
@@ -236,21 +239,22 @@ app.layout = dbc.Container([
236
  dbc.Button("Convert to PDF", id="submit-button", color="primary", className="mb-3 w-100"),
237
  dbc.Button("Download PDF", id="download-button", color="secondary", className="mb-3 w-100", disabled=True),
238
  html.Div([
239
- dbc.Spinner(html.Div(id="progress-message"), color="primary", type="grow", size="lg"),
240
- ], className="text-center mb-3"),
241
- dcc.Interval(id="progress-interval", interval=1000, n_intervals=0, disabled=True),
 
242
  dcc.Download(id="download-pdf")
243
  ]),
244
  className="mt-4"
245
  )
246
  ], fluid=True)
247
 
248
- @callback(
249
  Output("submit-button", "disabled"),
250
  Output("download-button", "disabled"),
251
- Output("progress-interval", "disabled"),
252
- Output("pdf-store", "data"),
253
  Output("progress-message", "children"),
 
254
  Input("submit-button", "n_clicks"),
255
  Input("progress-interval", "n_intervals"),
256
  State("url-input", "value"),
@@ -267,31 +271,26 @@ def update_output(n_clicks, n_intervals, url, depth, progress_data):
267
 
268
  if triggered_id == "submit-button":
269
  if not url:
270
- return False, True, True, None, "Please enter a URL"
271
 
272
  # Start the background task
273
  task_id = str(uuid.uuid4())
274
  executor.submit(background_task, url, depth, task_id)
275
 
276
- return True, True, False, None, "Processing... Please wait."
277
 
278
  elif triggered_id == "progress-interval":
279
- if progress_data is None:
280
- return True, True, False, None, "Processing... Please wait."
281
-
282
- if isinstance(progress_data, str):
283
- if progress_data.startswith("Error"):
284
- return False, True, True, None, progress_data
285
- elif progress_data == "PDF generation complete":
286
- return False, False, True, dash.no_update, "PDF ready for download!"
287
- else:
288
- return True, True, False, None, progress_data
289
-
290
- if isinstance(progress_data, bytes):
291
- encoded = base64.b64encode(progress_data).decode()
292
- return False, False, True, encoded, "PDF ready for download!"
293
 
294
- return False, True, True, None, ""
 
 
 
 
 
 
 
295
 
296
  @app.callback(
297
  Output("download-pdf", "data"),
@@ -303,25 +302,24 @@ def download_pdf(n_clicks, pdf_data):
303
  if pdf_data is None:
304
  raise PreventUpdate
305
 
306
- decoded = base64.b64decode(pdf_data)
307
- return dcc.send_bytes(decoded, f"website_content_{int(time.time())}.pdf")
308
 
309
  def background_task(url, depth, task_id):
 
 
310
  def progress_callback(message):
311
- # Update progress in the progress-store
312
- app.layout.children[1].data = message
313
 
314
  try:
315
  logger.info(f"Starting background task for URL: {url}, depth: {depth}")
316
  pdf_content = asyncio.run(process_url(url, depth, progress_callback))
317
  logger.info("Background task completed successfully")
318
- # Store the PDF content directly in the progress-store
319
- app.layout.children[1].data = pdf_content
320
- # Set a flag to indicate completion
321
- app.layout.children[1].data = "PDF generation complete"
322
  except Exception as e:
323
  logger.error(f"Error in background task: {str(e)}")
324
- app.layout.children[1].data = f"Error: {str(e)}"
325
 
326
  if __name__ == '__main__':
327
  print("Starting the Dash application...")
 
46
  # ThreadPoolExecutor for background tasks
47
  executor = ThreadPoolExecutor(max_workers=4)
48
 
49
+ # Global variable to store the generated PDF
50
+ generated_file = None
51
+
52
  @contextmanager
53
  def get_db_connection():
54
  if not hasattr(thread_local, "connection"):
 
229
  # App layout
230
  app.layout = dbc.Container([
231
  dcc.Store(id='pdf-store'),
232
+ dcc.Store(id='progress-store', data={'progress': 0, 'message': ''}),
233
  dbc.Card(
234
  dbc.CardBody([
235
  html.H1("Website to PDF Converter", className="text-center mb-4"),
 
239
  dbc.Button("Convert to PDF", id="submit-button", color="primary", className="mb-3 w-100"),
240
  dbc.Button("Download PDF", id="download-button", color="secondary", className="mb-3 w-100", disabled=True),
241
  html.Div([
242
+ dbc.Progress(id="progress-bar", value=0, className="mb-3"),
243
+ html.Div(id="progress-message", className="text-center"),
244
+ ], className="mb-3"),
245
+ dcc.Interval(id="progress-interval", interval=1000, n_intervals=0),
246
  dcc.Download(id="download-pdf")
247
  ]),
248
  className="mt-4"
249
  )
250
  ], fluid=True)
251
 
252
+ @app.callback(
253
  Output("submit-button", "disabled"),
254
  Output("download-button", "disabled"),
255
+ Output("progress-bar", "value"),
 
256
  Output("progress-message", "children"),
257
+ Output("pdf-store", "data"),
258
  Input("submit-button", "n_clicks"),
259
  Input("progress-interval", "n_intervals"),
260
  State("url-input", "value"),
 
271
 
272
  if triggered_id == "submit-button":
273
  if not url:
274
+ return False, True, 0, "Please enter a URL", None
275
 
276
  # Start the background task
277
  task_id = str(uuid.uuid4())
278
  executor.submit(background_task, url, depth, task_id)
279
 
280
+ return True, True, 0, "Processing... Please wait.", None
281
 
282
  elif triggered_id == "progress-interval":
283
+ progress = progress_data['progress']
284
+ message = progress_data['message']
 
 
 
 
 
 
 
 
 
 
 
 
285
 
286
+ if isinstance(message, str) and message.startswith("Error"):
287
+ return False, True, 100, message, None
288
+ elif progress == 100 and generated_file:
289
+ return False, False, 100, "PDF ready for download!", generated_file
290
+ else:
291
+ return True, True, progress, message, None
292
+
293
+ return False, True, 0, "", None
294
 
295
  @app.callback(
296
  Output("download-pdf", "data"),
 
302
  if pdf_data is None:
303
  raise PreventUpdate
304
 
305
+ return dcc.send_bytes(pdf_data, f"website_content_{int(time.time())}.pdf")
 
306
 
307
  def background_task(url, depth, task_id):
308
+ global generated_file
309
+
310
  def progress_callback(message):
311
+ progress = int(float(message.split()[-1].strip('%')))
312
+ app.layout.children[1].data = {'progress': progress, 'message': message}
313
 
314
  try:
315
  logger.info(f"Starting background task for URL: {url}, depth: {depth}")
316
  pdf_content = asyncio.run(process_url(url, depth, progress_callback))
317
  logger.info("Background task completed successfully")
318
+ generated_file = pdf_content
319
+ app.layout.children[1].data = {'progress': 100, 'message': "PDF generation complete"}
 
 
320
  except Exception as e:
321
  logger.error(f"Error in background task: {str(e)}")
322
+ app.layout.children[1].data = {'progress': 100, 'message': f"Error: {str(e)}"}
323
 
324
  if __name__ == '__main__':
325
  print("Starting the Dash application...")