""" 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