Shami96 commited on
Commit
367e48b
·
verified ·
1 Parent(s): 2509c5b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -5
app.py CHANGED
@@ -4,11 +4,32 @@ from invoice import (
4
  do_parse, do_generate, load_pricing, compute_totals,
5
  today_str, new_invoice_code, logo_data_uri
6
  )
 
7
 
8
  PREVIEW_LOGO = logo_data_uri() # empty string if no asset file is present
9
 
10
 
11
  # ---------- helpers ----------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  def _unit(modules, unit_override):
13
  tiers = load_pricing()
14
  try:
@@ -221,9 +242,22 @@ def on_change(inv_type, inv_date, inv_number, modules, audit_type,
221
 
222
  def on_generate(uploaded_file, inv_date, inv_num, inv_type, modules, audit_type, s_audit_date, s_name, s_addr, s_email, s_phone, unit_override):
223
  # backend handles date, number, unit automatically
224
- meta, xlsx, pdf = do_generate(uploaded_file, inv_type, modules, audit_type, s_audit_date, s_name, s_addr, s_email, s_phone)
 
 
 
225
  preview_html = _preview(inv_type, inv_date, inv_num, modules, audit_type, s_name, s_addr, s_email, s_phone, s_audit_date, unit_override)
226
- return preview_html, xlsx, (pdf or None)
 
 
 
 
 
 
 
 
 
 
227
 
228
  def update_audit_dropdown(inv_type_value, current_audit):
229
  choices = _choices_for(inv_type_value)
@@ -439,7 +473,7 @@ with gr.Blocks(title="Professional Invoice Generator", css=custom_css) as demo:
439
  gr.HTML('<div class="controls-title">Invoice Settings</div>')
440
  with gr.Group(elem_classes=["upload-section"]):
441
  gr.HTML('<div style="text-align: center; margin-bottom: 8px; font-weight: 600; color: #374151; font-size: 11px;">Upload Report</div>')
442
- up = gr.UploadButton("Choose File (.pdf or .docx)", file_types=[".pdf", ".docx"], file_count="single", size="sm")
443
  gr.HTML('<div style="font-size: 10px; color: #6b7280; text-align: center; margin-top: 4px;">Auto-fill invoice details</div>')
444
 
445
  with gr.Group(elem_classes=["form-controls"]):
@@ -464,8 +498,9 @@ with gr.Blocks(title="Professional Invoice Generator", css=custom_css) as demo:
464
  1, "NHVR Maintenance Audit", "", "", "", "", "", "auto"
465
  ))
466
  with gr.Group(elem_classes=["download-section"]):
467
- dl_xlsx = gr.DownloadButton("Download Excel", elem_classes=["download-btn"], size="sm")
468
- dl_pdf = gr.DownloadButton("Download PDF", elem_classes=["download-btn"], size="sm")
 
469
 
470
  # Hidden states
471
  s_name = gr.State("")
 
4
  do_parse, do_generate, load_pricing, compute_totals,
5
  today_str, new_invoice_code, logo_data_uri
6
  )
7
+ import os, re, shutil, uuid
8
 
9
  PREVIEW_LOGO = logo_data_uri() # empty string if no asset file is present
10
 
11
 
12
  # ---------- helpers ----------
13
+ def _stage_for_download(path):
14
+ """
15
+ Copy `path` to /tmp with a safe filename so Hugging Face Spaces can serve it.
16
+ Returns the new path or None.
17
+ """
18
+ if not path or not os.path.isfile(path):
19
+ return None
20
+ base = os.path.basename(path)
21
+ root, ext = os.path.splitext(base)
22
+ # sanitize: keep only safe chars
23
+ safe_root = re.sub(r'[^A-Za-z0-9_.-]+', '_', root).strip('_') or f"file_{uuid.uuid4().hex[:8]}"
24
+ safe_ext = ext if ext else ""
25
+ safe = f"/tmp/{safe_root}{safe_ext}"
26
+ try:
27
+ if os.path.abspath(path) != os.path.abspath(safe):
28
+ shutil.copyfile(path, safe)
29
+ return safe
30
+ except Exception:
31
+ return None
32
+
33
  def _unit(modules, unit_override):
34
  tiers = load_pricing()
35
  try:
 
242
 
243
  def on_generate(uploaded_file, inv_date, inv_num, inv_type, modules, audit_type, s_audit_date, s_name, s_addr, s_email, s_phone, unit_override):
244
  # backend handles date, number, unit automatically
245
+ meta, xlsx, pdf = do_generate(
246
+ uploaded_file, inv_type, modules, audit_type, s_audit_date, s_name, s_addr, s_email, s_phone
247
+ )
248
+ # refresh preview
249
  preview_html = _preview(inv_type, inv_date, inv_num, modules, audit_type, s_name, s_addr, s_email, s_phone, s_audit_date, unit_override)
250
+
251
+ # IMPORTANT: stage files into /tmp with safe names so Spaces can serve them
252
+ staged_xlsx = _stage_for_download(xlsx)
253
+ staged_pdf = _stage_for_download(pdf)
254
+
255
+ return (
256
+ preview_html,
257
+ gr.DownloadButton.update(value=staged_xlsx, visible=bool(staged_xlsx)),
258
+ gr.DownloadButton.update(value=staged_pdf, visible=bool(staged_pdf))
259
+ )
260
+
261
 
262
  def update_audit_dropdown(inv_type_value, current_audit):
263
  choices = _choices_for(inv_type_value)
 
473
  gr.HTML('<div class="controls-title">Invoice Settings</div>')
474
  with gr.Group(elem_classes=["upload-section"]):
475
  gr.HTML('<div style="text-align: center; margin-bottom: 8px; font-weight: 600; color: #374151; font-size: 11px;">Upload Report</div>')
476
+ up = gr.File(label="Upload Report (.pdf or .docx)", file_types=[".pdf", ".docx"], file_count="single")
477
  gr.HTML('<div style="font-size: 10px; color: #6b7280; text-align: center; margin-top: 4px;">Auto-fill invoice details</div>')
478
 
479
  with gr.Group(elem_classes=["form-controls"]):
 
498
  1, "NHVR Maintenance Audit", "", "", "", "", "", "auto"
499
  ))
500
  with gr.Group(elem_classes=["download-section"]):
501
+ dl_xlsx = gr.DownloadButton("Download Excel", elem_classes=["download-btn"], size="sm", visible=False)
502
+ dl_pdf = gr.DownloadButton("Download PDF", elem_classes=["download-btn"], size="sm", visible=False, mime_type="application/pdf")
503
+
504
 
505
  # Hidden states
506
  s_name = gr.State("")