Klnimri commited on
Commit
cca9514
·
verified ·
1 Parent(s): 0953687

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -12
app.py CHANGED
@@ -685,6 +685,7 @@ def nav_prev(ranked_dicts: List[Dict[str, Any]], idx: int):
685
  def nav_next(ranked_dicts: List[Dict[str, Any]], idx: int):
686
  return render_single_html(ranked_dicts, _safe_int(idx, 0) + 1)
687
 
 
688
  # =========================================================
689
  # Shortlist export
690
  # =========================================================
@@ -782,7 +783,9 @@ def rank_app(
782
  continue
783
 
784
  filename = os.path.basename(p)
785
- contacts_map[filename] = extract_contact_info(raw) if show_contacts_toggle else {"name": "", "email": "", "phone": ""}
 
 
786
 
787
  chunks = chunk_text_safe(raw)
788
  if not chunks:
@@ -844,7 +847,9 @@ def rank_app(
844
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
845
  with open(tmp.name, "w", newline="", encoding="utf-8") as f:
846
  w = csv.writer(f)
847
- w.writerow(["Rank", "Filename", "FinalScore(0-100)", "FitLevel", "Name", "Email", "Phone", "Summary", "LocalScore"])
 
 
848
  for ridx, c in enumerate(ranked, start=1):
849
  ci = contacts_map.get(c.filename, {"name": "", "email": "", "phone": ""})
850
  local = next((x["local_score"] for x in local_pool if x["filename"] == c.filename), "")
@@ -865,9 +870,22 @@ def rank_app(
865
  shortlist_rows = []
866
  for ridx, c in enumerate(ranked, start=1):
867
  ci = contacts_map.get(c.filename, {"name": "", "email": "", "phone": ""})
868
- shortlist_rows.append([False, ridx, c.filename, round(float(c.final_score), 2), c.fit_level, ci.get("name", ""), ci.get("email", ""), ci.get("phone", "")])
 
 
 
 
 
 
 
 
 
 
 
869
 
870
- shortlist_df = pd.DataFrame(shortlist_rows, columns=["Shortlisted", "Rank", "Filename", "Score", "Fit", "Name", "Email", "Phone"])
 
 
871
 
872
  elapsed = time.time() - t0
873
  meta = (
@@ -884,8 +902,10 @@ def rank_app(
884
 
885
  progress(1.0, desc="Done ✅")
886
  return first_html, meta, tmp.name, shortlist_df, "", "", ranked_dicts, idx0, nav
 
 
887
  # =========================================================
888
- # SGS CSS (neutral light-grey, visible borders on BOTH light/dark)
889
  # =========================================================
890
  CUSTOM_CSS = """
891
  :root{
@@ -944,8 +964,7 @@ body:before{
944
  100%{ background-position: 0% 50%; }
945
  }
946
 
947
- /* IMPORTANT:
948
- Keep text dark always so it's readable even if OS is in dark mode */
949
  .gradio-container, .gradio-container *{ color: var(--text) !important; }
950
 
951
  /* Hero */
@@ -1242,14 +1261,63 @@ button.primary:active, .gradio-container button:active{
1242
  .checkrow.partial .st{ color: rgba(150,95,10,1) !important; }
1243
  .checkrow.miss .st{ color: rgba(160,20,20,1) !important; }
1244
 
1245
- /* File uploader text color (force readable) */
 
 
 
 
 
1246
  .gradio-container .file,
1247
  .gradio-container .file-upload,
1248
  .gradio-container .upload-button,
 
 
 
 
 
 
 
 
 
1249
  .gradio-container .file *,
1250
  .gradio-container .file-upload *,
1251
- .gradio-container .upload-button *{
1252
- color: var(--text) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1253
  }
1254
 
1255
  /* Respect reduced motion */
@@ -1299,7 +1367,11 @@ with gr.Blocks(title="SGS ATS Candidate Matcher", theme=theme, css=CUSTOM_CSS) a
1299
 
1300
  with gr.Row():
1301
  jd_file = gr.File(label="Job Description file (PDF/DOCX/TXT)", file_types=[".pdf", ".docx", ".txt"])
1302
- cv_files = gr.File(label=f"Upload CVs (max {MAX_CV_UPLOADS})", file_count="multiple", file_types=[".pdf", ".docx", ".txt"])
 
 
 
 
1303
 
1304
  with gr.Accordion("Settings", open=False):
1305
  must_haves = gr.Textbox(
@@ -1345,7 +1417,17 @@ with gr.Blocks(title="SGS ATS Candidate Matcher", theme=theme, css=CUSTOM_CSS) a
1345
  run_btn.click(
1346
  fn=rank_app,
1347
  inputs=[jd_file, cv_files, must_haves, mask_pii_toggle, show_contacts_toggle],
1348
- outputs=[report_html, meta_md, export_full, shortlist_df, export_shortlist_msg, email_list, ranked_state, idx_state, nav_text],
 
 
 
 
 
 
 
 
 
 
1349
  )
1350
 
1351
  # Navigation (Executive Report): render one card at a time for smooth fullscreen
 
685
  def nav_next(ranked_dicts: List[Dict[str, Any]], idx: int):
686
  return render_single_html(ranked_dicts, _safe_int(idx, 0) + 1)
687
 
688
+
689
  # =========================================================
690
  # Shortlist export
691
  # =========================================================
 
783
  continue
784
 
785
  filename = os.path.basename(p)
786
+ contacts_map[filename] = (
787
+ extract_contact_info(raw) if show_contacts_toggle else {"name": "", "email": "", "phone": ""}
788
+ )
789
 
790
  chunks = chunk_text_safe(raw)
791
  if not chunks:
 
847
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".csv")
848
  with open(tmp.name, "w", newline="", encoding="utf-8") as f:
849
  w = csv.writer(f)
850
+ w.writerow(
851
+ ["Rank", "Filename", "FinalScore(0-100)", "FitLevel", "Name", "Email", "Phone", "Summary", "LocalScore"]
852
+ )
853
  for ridx, c in enumerate(ranked, start=1):
854
  ci = contacts_map.get(c.filename, {"name": "", "email": "", "phone": ""})
855
  local = next((x["local_score"] for x in local_pool if x["filename"] == c.filename), "")
 
870
  shortlist_rows = []
871
  for ridx, c in enumerate(ranked, start=1):
872
  ci = contacts_map.get(c.filename, {"name": "", "email": "", "phone": ""})
873
+ shortlist_rows.append(
874
+ [
875
+ False,
876
+ ridx,
877
+ c.filename,
878
+ round(float(c.final_score), 2),
879
+ c.fit_level,
880
+ ci.get("name", ""),
881
+ ci.get("email", ""),
882
+ ci.get("phone", ""),
883
+ ]
884
+ )
885
 
886
+ shortlist_df = pd.DataFrame(
887
+ shortlist_rows, columns=["Shortlisted", "Rank", "Filename", "Score", "Fit", "Name", "Email", "Phone"]
888
+ )
889
 
890
  elapsed = time.time() - t0
891
  meta = (
 
902
 
903
  progress(1.0, desc="Done ✅")
904
  return first_html, meta, tmp.name, shortlist_df, "", "", ranked_dicts, idx0, nav
905
+
906
+
907
  # =========================================================
908
+ # SGS CSS (neutral light-grey + visible borders + file uploader fixed)
909
  # =========================================================
910
  CUSTOM_CSS = """
911
  :root{
 
964
  100%{ background-position: 0% 50%; }
965
  }
966
 
967
+ /* Keep text dark always (theme-proof) */
 
968
  .gradio-container, .gradio-container *{ color: var(--text) !important; }
969
 
970
  /* Hero */
 
1261
  .checkrow.partial .st{ color: rgba(150,95,10,1) !important; }
1262
  .checkrow.miss .st{ color: rgba(160,20,20,1) !important; }
1263
 
1264
+ /* =========================================================
1265
+ File uploader: force readable label/filename ALWAYS
1266
+ (fixes the "blue header text = same color" issue)
1267
+ ========================================================= */
1268
+
1269
+ /* Make uploader surface light-grey with strong border */
1270
  .gradio-container .file,
1271
  .gradio-container .file-upload,
1272
  .gradio-container .upload-button,
1273
+ .gradio-container .file-upload > div,
1274
+ .gradio-container [data-testid="file"]{
1275
+ background: rgba(245,247,250,.92) !important;
1276
+ border: 1.4px solid rgba(17,24,39,.28) !important;
1277
+ border-radius: 16px !important;
1278
+ box-shadow: 0 12px 24px rgba(2,6,23,.10) !important;
1279
+ }
1280
+
1281
+ /* Force ALL text inside uploader to dark */
1282
  .gradio-container .file *,
1283
  .gradio-container .file-upload *,
1284
+ .gradio-container .upload-button *,
1285
+ .gradio-container [data-testid="file"] *{
1286
+ color: #111827 !important;
1287
+ }
1288
+
1289
+ /* Normalize any internal header strip that turns blue */
1290
+ .gradio-container .file-upload .file-title,
1291
+ .gradio-container .file-upload .file-label,
1292
+ .gradio-container .file-upload .label,
1293
+ .gradio-container .file-upload .wrap,
1294
+ .gradio-container .file-upload .header,
1295
+ .gradio-container [data-testid="file"] .label{
1296
+ background: rgba(245,247,250,.92) !important;
1297
+ border-bottom: 1.4px solid rgba(17,24,39,.20) !important;
1298
+ }
1299
+
1300
+ /* Filename emphasis */
1301
+ .gradio-container .file-upload .file-name,
1302
+ .gradio-container .file-upload .filename,
1303
+ .gradio-container [data-testid="file"] .file-name{
1304
+ font-weight: 900 !important;
1305
+ }
1306
+
1307
+ /* Close / clear button visible */
1308
+ .gradio-container .file-upload button,
1309
+ .gradio-container [data-testid="file"] button{
1310
+ background: rgba(255,255,255,.85) !important;
1311
+ border: 1.2px solid rgba(17,24,39,.28) !important;
1312
+ color: #111827 !important;
1313
+ }
1314
+
1315
+ /* Hover feedback */
1316
+ .gradio-container .file:hover,
1317
+ .gradio-container .file-upload:hover,
1318
+ .gradio-container [data-testid="file"]:hover{
1319
+ border-color: rgba(17,24,39,.36) !important;
1320
+ box-shadow: 0 16px 32px rgba(2,6,23,.12) !important;
1321
  }
1322
 
1323
  /* Respect reduced motion */
 
1367
 
1368
  with gr.Row():
1369
  jd_file = gr.File(label="Job Description file (PDF/DOCX/TXT)", file_types=[".pdf", ".docx", ".txt"])
1370
+ cv_files = gr.File(
1371
+ label=f"Upload CVs (max {MAX_CV_UPLOADS})",
1372
+ file_count="multiple",
1373
+ file_types=[".pdf", ".docx", ".txt"],
1374
+ )
1375
 
1376
  with gr.Accordion("Settings", open=False):
1377
  must_haves = gr.Textbox(
 
1417
  run_btn.click(
1418
  fn=rank_app,
1419
  inputs=[jd_file, cv_files, must_haves, mask_pii_toggle, show_contacts_toggle],
1420
+ outputs=[
1421
+ report_html,
1422
+ meta_md,
1423
+ export_full,
1424
+ shortlist_df,
1425
+ export_shortlist_msg,
1426
+ email_list,
1427
+ ranked_state,
1428
+ idx_state,
1429
+ nav_text,
1430
+ ],
1431
  )
1432
 
1433
  # Navigation (Executive Report): render one card at a time for smooth fullscreen