Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -227,24 +227,6 @@ async def process_url(url, depth, progress_callback):
|
|
227 |
app.layout = dbc.Container([
|
228 |
dcc.Store(id='pdf-store'),
|
229 |
dcc.Store(id='progress-store'),
|
230 |
-
dbc.Navbar(
|
231 |
-
dbc.Container([
|
232 |
-
html.A(
|
233 |
-
dbc.Row([
|
234 |
-
dbc.Col(html.Img(src="/assets/logo.png", height="30px")),
|
235 |
-
dbc.Col(dbc.NavbarBrand("Website to PDF Converter", className="ms-2")),
|
236 |
-
],
|
237 |
-
align="center",
|
238 |
-
className="g-0",
|
239 |
-
),
|
240 |
-
href="/",
|
241 |
-
style={"textDecoration": "none"},
|
242 |
-
)
|
243 |
-
]),
|
244 |
-
color="#116F70",
|
245 |
-
dark=True,
|
246 |
-
),
|
247 |
-
|
248 |
dbc.Card(
|
249 |
dbc.CardBody([
|
250 |
html.H1("Website to PDF Converter", className="text-center mb-4"),
|
@@ -252,18 +234,20 @@ app.layout = dbc.Container([
|
|
252 |
dbc.Input(id="url-input", type="text", placeholder="Enter website URL (e.g., https://www.gradio.app/docs)", className="mb-3"),
|
253 |
dcc.Slider(id="depth-slider", min=1, max=10, step=1, value=3, marks={i: str(i) for i in range(1, 11)}, className="mb-3"),
|
254 |
dbc.Button("Convert to PDF", id="submit-button", color="primary", className="mb-3 w-100"),
|
255 |
-
dbc.
|
256 |
dbc.Spinner(html.Div(id="output-area"), color="primary", type="grow"),
|
257 |
dcc.Interval(id="progress-interval", interval=1000, n_intervals=0, disabled=True),
|
|
|
258 |
]),
|
259 |
className="mt-4"
|
260 |
)
|
261 |
], fluid=True)
|
262 |
|
263 |
@app.callback(
|
264 |
-
Output("
|
|
|
265 |
Output("progress-interval", "disabled"),
|
266 |
-
Output("
|
267 |
Input("submit-button", "n_clicks"),
|
268 |
Input("progress-interval", "n_intervals"),
|
269 |
Input("progress-store", "data"),
|
@@ -280,45 +264,39 @@ def update_output(n_clicks, n_intervals, progress_data, url, depth):
|
|
280 |
|
281 |
if triggered_id == "submit-button":
|
282 |
if not url:
|
283 |
-
return
|
284 |
|
285 |
# Start the background task
|
286 |
task_id = str(uuid.uuid4())
|
287 |
executor.submit(background_task, url, depth, task_id)
|
288 |
|
289 |
-
return
|
290 |
|
291 |
elif triggered_id == "progress-interval" or triggered_id == "progress-store":
|
292 |
-
# Check progress
|
293 |
if progress_data is None:
|
294 |
-
return
|
295 |
|
296 |
if isinstance(progress_data, str) and progress_data.startswith("Error"):
|
297 |
-
return
|
298 |
-
|
299 |
-
if isinstance(progress_data, str) and progress_data.startswith("Processing"):
|
300 |
-
return progress_data, False, {"visibility": "visible"}
|
301 |
|
302 |
-
# PDF generation complete
|
303 |
if isinstance(progress_data, bytes):
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
html.H4("PDF Generated Successfully"),
|
309 |
-
html.P("Click the link below to download your PDF:"),
|
310 |
-
html.A(
|
311 |
-
filename,
|
312 |
-
href=f"data:application/pdf;base64,{encoded}",
|
313 |
-
download=filename,
|
314 |
-
className="btn btn-success mt-2"
|
315 |
-
)
|
316 |
-
]), True, {"visibility": "hidden"}
|
317 |
-
except Exception as e:
|
318 |
-
logger.error(f"Error creating download link: {str(e)}")
|
319 |
-
return f"An error occurred while creating the download link: {str(e)}", True, {"visibility": "hidden"}
|
320 |
|
321 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
|
323 |
def background_task(url, depth, task_id):
|
324 |
def progress_callback(message):
|
|
|
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"),
|
|
|
234 |
dbc.Input(id="url-input", type="text", placeholder="Enter website URL (e.g., https://www.gradio.app/docs)", className="mb-3"),
|
235 |
dcc.Slider(id="depth-slider", min=1, max=10, step=1, value=3, marks={i: str(i) for i in range(1, 11)}, className="mb-3"),
|
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 |
dbc.Spinner(html.Div(id="output-area"), color="primary", type="grow"),
|
239 |
dcc.Interval(id="progress-interval", interval=1000, n_intervals=0, disabled=True),
|
240 |
+
dcc.Download(id="download-pdf")
|
241 |
]),
|
242 |
className="mt-4"
|
243 |
)
|
244 |
], fluid=True)
|
245 |
|
246 |
@app.callback(
|
247 |
+
Output("download-button", "disabled"),
|
248 |
+
Output("download-button", "color"),
|
249 |
Output("progress-interval", "disabled"),
|
250 |
+
Output("pdf-store", "data"),
|
251 |
Input("submit-button", "n_clicks"),
|
252 |
Input("progress-interval", "n_intervals"),
|
253 |
Input("progress-store", "data"),
|
|
|
264 |
|
265 |
if triggered_id == "submit-button":
|
266 |
if not url:
|
267 |
+
return True, "secondary", True, None
|
268 |
|
269 |
# Start the background task
|
270 |
task_id = str(uuid.uuid4())
|
271 |
executor.submit(background_task, url, depth, task_id)
|
272 |
|
273 |
+
return True, "secondary", False, None
|
274 |
|
275 |
elif triggered_id == "progress-interval" or triggered_id == "progress-store":
|
|
|
276 |
if progress_data is None:
|
277 |
+
return True, "secondary", False, None
|
278 |
|
279 |
if isinstance(progress_data, str) and progress_data.startswith("Error"):
|
280 |
+
return True, "secondary", True, None
|
|
|
|
|
|
|
281 |
|
|
|
282 |
if isinstance(progress_data, bytes):
|
283 |
+
encoded = base64.b64encode(progress_data).decode()
|
284 |
+
return False, "primary", True, encoded
|
285 |
+
|
286 |
+
return True, "secondary", False, None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
|
288 |
+
@app.callback(
|
289 |
+
Output("download-pdf", "data"),
|
290 |
+
Input("download-button", "n_clicks"),
|
291 |
+
State("pdf-store", "data"),
|
292 |
+
prevent_initial_call=True
|
293 |
+
)
|
294 |
+
def download_pdf(n_clicks, pdf_data):
|
295 |
+
if pdf_data is None:
|
296 |
+
raise PreventUpdate
|
297 |
+
|
298 |
+
decoded = base64.b64decode(pdf_data)
|
299 |
+
return dcc.send_bytes(decoded, f"website_content_{int(time.time())}.pdf")
|
300 |
|
301 |
def background_task(url, depth, task_id):
|
302 |
def progress_callback(message):
|