JAA-ATS-Tool / src /geo_filter.py
saitejatirunagari's picture
Fix location/freshness filters and make ever-jobs URL configurable
39623f2
Raw
History Blame
4.75 kB
"""
Location filtering — drop jobs that are clearly outside the user's selected
geography (fixes "international jobs leaking in").
The pipeline searches role x location, but several boards (LinkedIn "Remote",
Remotive, WeWorkRemotely, ever-jobs aggregators) return jobs from anywhere
regardless of the requested location. This module decides, per job, whether its
location is acceptable given what the user selected.
Design goals:
- Be permissive about INDIA jobs (LinkedIn usually appends ", India" or the
state, but some only show the city), so keep a broad Indian-city list.
- Only drop a job when it is clearly foreign (names a non-India country/city)
or, in India-only mode, when it is neither India nor an allowed remote role.
- If the user selected "Worldwide"/"Anywhere", do not filter at all.
"""
from __future__ import annotations
INDIA_TOKENS = {
"india", "bharat", "bengaluru", "bangalore", "mumbai", "delhi", "new delhi",
"delhi ncr", "ncr", "gurugram", "gurgaon", "noida", "hyderabad", "pune",
"chennai", "kolkata", "ahmedabad", "jaipur", "surat", "lucknow", "kochi",
"cochin", "coimbatore", "indore", "nagpur", "chandigarh", "bhubaneswar",
"visakhapatnam", "vizag", "thiruvananthapuram", "trivandrum", "mysuru",
"mysore", "mohali", "vadodara", "nashik", "kanpur", "patna", "guwahati",
"raipur", "bhopal", "goa", "mangaluru", "mangalore",
# states / UTs commonly shown in LinkedIn location strings
"karnataka", "maharashtra", "telangana", "tamil nadu", "kerala",
"uttar pradesh", "west bengal", "gujarat", "haryana", "rajasthan",
"andhra pradesh", "madhya pradesh", "punjab", "odisha", "bihar",
}
# Clear non-India signals — if present (and India is not), the job is foreign.
FOREIGN_TOKENS = {
"united states", "usa", "u.s.", " us)", "u.s", "america",
"united kingdom", " uk", "u.k", "england", "london", "scotland",
"canada", "toronto", "vancouver",
"germany", "berlin", "munich", "deutschland",
"france", "paris", "spain", "madrid", "italy", "netherlands", "amsterdam",
"ireland", "dublin", "poland", "portugal", "sweden", "switzerland",
"singapore", "malaysia", "kuala lumpur", "indonesia", "jakarta",
"philippines", "manila", "thailand", "bangkok", "vietnam", "hong kong",
"china", "japan", "tokyo", "korea", "seoul",
"australia", "sydney", "melbourne", "new zealand",
"dubai", "abu dhabi", "uae", "saudi", "qatar", "doha", "bahrain", "kuwait",
"egypt", "nigeria", "kenya", "south africa", "brazil", "mexico", "argentina",
"bangladesh", "dhaka", "pakistan", "sri lanka", "nepal",
# US state abbreviations frequently seen as "City, CA" / "City, NY"
" ca", " ny", " tx", " wa", " ma", " il", " ga", " fl", " co", " va",
}
REMOTE_TOKENS = {"remote", "anywhere", "work from home", "wfh"}
GLOBAL_TOKENS = {"worldwide", "anywhere", "global"}
def _norm(s: str) -> str:
return (s or "").strip().lower()
def wants_india(selected_locations) -> bool:
sl = " ".join(_norm(x) for x in (selected_locations or []))
return any(tok in sl for tok in ("india", "bangalore", "bengaluru", "mumbai",
"delhi", "hyderabad", "pune", "chennai",
"noida", "gurgaon", "kolkata"))
def allows_remote(selected_locations) -> bool:
sl = [_norm(x) for x in (selected_locations or [])]
return any(any(t in s for t in REMOTE_TOKENS | GLOBAL_TOKENS) for s in sl)
def no_geo_restriction(selected_locations) -> bool:
sl = [_norm(x) for x in (selected_locations or [])]
return any(any(t in s for t in GLOBAL_TOKENS) for s in sl)
def _has(tokens, text) -> bool:
return any(t in text for t in tokens)
def location_allowed(job_location: str, selected_locations) -> bool:
"""True if `job_location` is acceptable for the user's selected locations."""
if no_geo_restriction(selected_locations):
return True
jl = _norm(job_location)
if not jl:
return True # unknown location — don't drop (LinkedIn often omits it)
india_mode = wants_india(selected_locations)
is_india = _has(INDIA_TOKENS, jl)
is_remote = _has(REMOTE_TOKENS, jl)
is_foreign = _has(FOREIGN_TOKENS, jl) and not is_india
if india_mode:
if is_india:
return True
# Allow a remote role only if the user opted into remote AND it isn't
# explicitly a foreign-remote posting (e.g. "Remote, US").
if is_remote and allows_remote(selected_locations) and not is_foreign:
return True
return False
# Non-India searches: only drop the obviously-foreign-to-selection case is
# hard to generalize, so keep everything (user didn't pick India).
return True