saitejatirunagari Claude Sonnet 4.6 commited on
Commit
53c490d
ยท
1 Parent(s): bce071b

feat(ui): merge legacy platform checkboxes into unified platform selector

Browse files

Remove the 6 separate legacy checkboxes (LinkedIn, Indeed, Glassdoor,
Remotive, WeWorkRemotely, Naukri) and combine everything into a single
"Job Platforms" grouped multiselect. Routing is preserved โ€” those 6
platforms still go through their dedicated high-quality scrapers while
all 160+ other platforms go through EverJobsScraper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (3) hide show
  1. HISTORY.md +12 -0
  2. README.md +1 -1
  3. ui.py +16 -31
HISTORY.md CHANGED
@@ -4,6 +4,18 @@ A running log of everything built, fixed, and changed. Most recent first.
4
 
5
  ---
6
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  ## 2026-06-13 โ€” Phase 1: ever-jobs Integration (160+ Platforms)
8
 
9
  ### New Features
 
4
 
5
  ---
6
 
7
+ ## 2026-06-13 โ€” Unified Platform Selector + ATS + HTML Rendering Fixes
8
+
9
+ ### Changes
10
+ - **Unified platform selector**: Merged the 6 legacy checkboxes ("๐ŸŒ Job Platforms") and the grouped ever-jobs selector ("๐ŸŒ ever-jobs Platforms") into a single "๐ŸŒ Job Platforms" section. One place to search all 170 platforms. Selecting LinkedIn/Indeed/Glassdoor/Remotive/WeWorkRemotely/Naukri still routes to their dedicated high-quality scrapers; everything else goes through EverJobsScraper.
11
+ - **ATS min_score default**: Changed slider default from 6 to 1 โ€” LLM resumes now generated for ALL jobs regardless of score.
12
+ - **HTML rendering fix**: Switched all 5 `st.markdown(..., unsafe_allow_html=True)` calls to `st.html()` โ€” fixes raw `<span>`/`<a>` tags showing as plain text in job cards (Streamlit 1.45+ regression).
13
+
14
+ ### Modified Files
15
+ - `ui.py` โ€” removed 6 legacy checkboxes, renamed section label, updated platforms_cfg, updated pipeline routing to use unified `all_platforms` key
16
+
17
+ ---
18
+
19
  ## 2026-06-13 โ€” Phase 1: ever-jobs Integration (160+ Platforms)
20
 
21
  ### New Features
README.md CHANGED
@@ -92,7 +92,7 @@ The pipeline calls `ensure_running()` automatically before any ever-jobs platfor
92
 
93
  ### Platform Selection
94
 
95
- The UI groups 160+ platforms into three categories accessible via the "ever-jobs Platforms (160+)" section:
96
 
97
  | Group | Count | Description |
98
  |-------|-------|-------------|
 
92
 
93
  ### Platform Selection
94
 
95
+ The UI has a single **"๐ŸŒ Job Platforms"** section with three groups. Selecting LinkedIn, Indeed, Glassdoor, Remotive, WeWorkRemotely, or Naukri uses their dedicated high-quality scrapers; all other platforms go through the ever-jobs REST API.
96
 
97
  | Group | Count | Description |
98
  |-------|-------|-------------|
ui.py CHANGED
@@ -489,23 +489,8 @@ with st.expander("โš™๏ธ Configure Run", expanded=not (st.session_state.running
489
 
490
  st.divider()
491
 
492
- # โ”€โ”€ Row 3: Platforms โ”€โ”€
493
  st.markdown('<p class="section-label">๐ŸŒ Job Platforms</p>', unsafe_allow_html=True)
494
- pc1, pc2, pc3, pc4, pc5, pc6 = st.columns(6)
495
- use_linkedin = pc1.checkbox("๐Ÿ”ต LinkedIn", value=True)
496
- use_indeed = pc2.checkbox("๐ŸŸ  Indeed", value=True)
497
- use_glassdoor = pc3.checkbox("๐ŸŸข Glassdoor", value=True)
498
- use_remotive = pc4.checkbox("๐ŸŒ Remotive", value=True,
499
- help="Remote/WFH PM jobs globally")
500
- use_wwr = pc5.checkbox("๐Ÿ’ป WeWorkRemotely", value=False,
501
- help="Remote jobs, worldwide")
502
- use_naukri = pc6.checkbox("๐Ÿ‡ฎ๐Ÿ‡ณ Naukri", value=False,
503
- help="Often blocked by Akamai anti-bot")
504
-
505
- st.divider()
506
-
507
- # โ”€โ”€ Row 3b: ever-jobs platform selector โ”€โ”€
508
- st.markdown('<p class="section-label">๐ŸŒ ever-jobs Platforms (160+)</p>', unsafe_allow_html=True)
509
  from src.ever_jobs_bridge.platforms import PLATFORM_GROUPS, INDIA_DEFAULT_PLATFORMS, EVER_JOBS_PLATFORMS
510
 
511
  ej_col1, ej_col2, ej_col3 = st.columns(3)
@@ -560,7 +545,7 @@ with st.expander("โš™๏ธ Configure Run", expanded=not (st.session_state.running
560
  icon="โš ๏ธ",
561
  )
562
  elif use_ever_jobs:
563
- st.caption(f"โœ“ {len(ever_jobs_platforms)} ever-jobs platform(s) selected")
564
 
565
  st.divider()
566
 
@@ -623,10 +608,7 @@ if start and not st.session_state.running:
623
  for s in PIPELINE_STEPS}
624
 
625
  platforms_cfg = {
626
- "linkedin": use_linkedin, "indeed": use_indeed,
627
- "glassdoor": use_glassdoor, "naukri": use_naukri,
628
- "remotive": use_remotive, "weworkremotely": use_wwr,
629
- "ever_jobs_platforms": ever_jobs_platforms,
630
  }
631
  job_search_cfg = {
632
  "roles": roles, "locations": locations,
@@ -741,45 +723,48 @@ if start and not st.session_state.running:
741
  seen_tc: set = set()
742
  skipped_dup: int = 0
743
 
744
- scraper_map = {}
745
- if _platforms.get("linkedin"):
 
 
 
746
  from src.scrapers.linkedin import LinkedInScraper
747
  scraper_map["linkedin"] = ("LinkedIn", LinkedInScraper())
748
  else:
749
  _step_skip("linkedin")
750
 
751
- if _platforms.get("indeed"):
752
  from src.scrapers.indeed import IndeedScraper
753
  scraper_map["indeed"] = ("Indeed", IndeedScraper())
754
  else:
755
  _step_skip("indeed")
756
 
757
- if _platforms.get("glassdoor"):
758
  from src.scrapers.glassdoor import GlassdoorScraper
759
  scraper_map["glassdoor"] = ("Glassdoor", GlassdoorScraper())
760
  else:
761
  _step_skip("glassdoor")
762
 
763
- if _platforms.get("remotive"):
764
  from src.scrapers.remotive import RemotiveScraper
765
  scraper_map["remotive"] = ("Remotive", RemotiveScraper())
766
  else:
767
  _step_skip("remotive")
768
 
769
- if _platforms.get("weworkremotely"):
770
  from src.scrapers.weworkremotely import WeWorkRemotelyScraper
771
  scraper_map["weworkremotely"] = ("WeWorkRemotely", WeWorkRemotelyScraper())
772
  else:
773
  _step_skip("weworkremotely")
774
 
775
- if _platforms.get("naukri"):
776
  from src.scrapers.naukri import NaukriScraper
777
  scraper_map["naukri"] = ("Naukri", NaukriScraper())
778
  else:
779
  _step_skip("naukri")
780
 
781
- # โ”€โ”€ ever-jobs (160+ platforms) โ”€โ”€
782
- _ej_platforms = _platforms.get("ever_jobs_platforms", [])
783
  if _ej_platforms:
784
  from src.scrapers.ever_jobs import EverJobsScraper
785
  scraper_map["ever_jobs"] = ("EverJobs", EverJobsScraper(_ej_platforms))
@@ -953,7 +938,7 @@ if start and not st.session_state.running:
953
  save_run(assessed_jobs, {
954
  "run_id": run_id,
955
  "excel_path": excel_path,
956
- "platforms": [p for p, on in _platforms.items() if on],
957
  "roles": _jscfg.get("roles", []),
958
  })
959
  _q_log("โœ… Run saved to history")
 
489
 
490
  st.divider()
491
 
492
+ # โ”€โ”€ Row 3: Unified platform selector โ”€โ”€
493
  st.markdown('<p class="section-label">๐ŸŒ Job Platforms</p>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
494
  from src.ever_jobs_bridge.platforms import PLATFORM_GROUPS, INDIA_DEFAULT_PLATFORMS, EVER_JOBS_PLATFORMS
495
 
496
  ej_col1, ej_col2, ej_col3 = st.columns(3)
 
545
  icon="โš ๏ธ",
546
  )
547
  elif use_ever_jobs:
548
+ st.caption(f"โœ“ {len(ever_jobs_platforms)} platform(s) selected")
549
 
550
  st.divider()
551
 
 
608
  for s in PIPELINE_STEPS}
609
 
610
  platforms_cfg = {
611
+ "all_platforms": ever_jobs_platforms,
 
 
 
612
  }
613
  job_search_cfg = {
614
  "roles": roles, "locations": locations,
 
723
  seen_tc: set = set()
724
  skipped_dup: int = 0
725
 
726
+ _all_plats = set(_platforms.get("all_platforms", []))
727
+ _legacy_keys = {"linkedin", "indeed", "glassdoor", "remotive", "weworkremotely", "naukri"}
728
+ scraper_map = {}
729
+
730
+ if "linkedin" in _all_plats:
731
  from src.scrapers.linkedin import LinkedInScraper
732
  scraper_map["linkedin"] = ("LinkedIn", LinkedInScraper())
733
  else:
734
  _step_skip("linkedin")
735
 
736
+ if "indeed" in _all_plats:
737
  from src.scrapers.indeed import IndeedScraper
738
  scraper_map["indeed"] = ("Indeed", IndeedScraper())
739
  else:
740
  _step_skip("indeed")
741
 
742
+ if "glassdoor" in _all_plats:
743
  from src.scrapers.glassdoor import GlassdoorScraper
744
  scraper_map["glassdoor"] = ("Glassdoor", GlassdoorScraper())
745
  else:
746
  _step_skip("glassdoor")
747
 
748
+ if "remotive" in _all_plats:
749
  from src.scrapers.remotive import RemotiveScraper
750
  scraper_map["remotive"] = ("Remotive", RemotiveScraper())
751
  else:
752
  _step_skip("remotive")
753
 
754
+ if "weworkremotely" in _all_plats:
755
  from src.scrapers.weworkremotely import WeWorkRemotelyScraper
756
  scraper_map["weworkremotely"] = ("WeWorkRemotely", WeWorkRemotelyScraper())
757
  else:
758
  _step_skip("weworkremotely")
759
 
760
+ if "naukri" in _all_plats:
761
  from src.scrapers.naukri import NaukriScraper
762
  scraper_map["naukri"] = ("Naukri", NaukriScraper())
763
  else:
764
  _step_skip("naukri")
765
 
766
+ # All non-legacy platforms (150+) โ†’ EverJobsScraper
767
+ _ej_platforms = [p for p in _all_plats if p not in _legacy_keys]
768
  if _ej_platforms:
769
  from src.scrapers.ever_jobs import EverJobsScraper
770
  scraper_map["ever_jobs"] = ("EverJobs", EverJobsScraper(_ej_platforms))
 
938
  save_run(assessed_jobs, {
939
  "run_id": run_id,
940
  "excel_path": excel_path,
941
+ "platforms": list(_platforms.get("all_platforms", [])),
942
  "roles": _jscfg.get("roles", []),
943
  })
944
  _q_log("โœ… Run saved to history")