This commit is contained in:
@@ -169,16 +169,20 @@ class _AtsAdapter(ABC):
|
||||
def _extract_location(self, record: dict[str, object]) -> tuple[str, str, str, str]:
|
||||
location_raw = _first_text(
|
||||
record,
|
||||
"location",
|
||||
"location.city",
|
||||
"location.name",
|
||||
"location.address",
|
||||
"location.raw",
|
||||
"categories.location",
|
||||
"city",
|
||||
"cityName",
|
||||
"place",
|
||||
"office",
|
||||
"location.address",
|
||||
"address",
|
||||
"data.location",
|
||||
"officeLocation",
|
||||
"locationName",
|
||||
"location",
|
||||
)
|
||||
if not location_raw:
|
||||
location_raw = _first_text(record, "data.city", "data.location")
|
||||
@@ -223,6 +227,13 @@ class _AtsAdapter(ABC):
|
||||
"remote_type",
|
||||
"job_type",
|
||||
).lower()
|
||||
if not workplace_raw:
|
||||
if record.get("hybrid") is True:
|
||||
return "hybrid"
|
||||
if record.get("remote") is True:
|
||||
return "remote"
|
||||
if record.get("on_site") is True:
|
||||
return "on_site"
|
||||
if "remote" in workplace_raw:
|
||||
return "remote" if "hybrid" not in workplace_raw else "hybrid"
|
||||
if "hybrid" in workplace_raw:
|
||||
@@ -256,18 +267,21 @@ class _AtsAdapter(ABC):
|
||||
"url",
|
||||
"jobUrl",
|
||||
"job_url",
|
||||
"hostedUrl",
|
||||
"applyUrl",
|
||||
"link",
|
||||
"absoluteUrl",
|
||||
"careers_url",
|
||||
"data.url",
|
||||
)
|
||||
employer_name = _first_text(
|
||||
record,
|
||||
"company_name",
|
||||
"company.name",
|
||||
"company",
|
||||
"employer",
|
||||
"organization",
|
||||
"organizationName",
|
||||
"company.name",
|
||||
"department",
|
||||
"hiringOrganization",
|
||||
)
|
||||
@@ -290,6 +304,7 @@ class _AtsAdapter(ABC):
|
||||
"published_at",
|
||||
"created_at",
|
||||
"jobCreated",
|
||||
"releasedDate",
|
||||
)
|
||||
valid_through = _first_text(
|
||||
record,
|
||||
@@ -308,6 +323,9 @@ class _AtsAdapter(ABC):
|
||||
"jobType",
|
||||
"type",
|
||||
"data.employmentType",
|
||||
"employment_type_code",
|
||||
"categories.commitment",
|
||||
"typeOfEmployment.label",
|
||||
)
|
||||
)
|
||||
workplace_type = self._extract_workplace(record)
|
||||
@@ -428,13 +446,20 @@ class GreenhouseAdapter(_AtsAdapter):
|
||||
|
||||
class LeverAdapter(_AtsAdapter):
|
||||
parser_key = "ats-lever"
|
||||
source_hosts = ("jobs.lever.co",)
|
||||
source_hosts = (
|
||||
"jobs.lever.co",
|
||||
"jobs.eu.lever.co",
|
||||
"api.lever.co",
|
||||
"api.eu.lever.co",
|
||||
)
|
||||
support_markers = ("lever", "requisition", "posting")
|
||||
listing_paths = (("data",), ("jobs",), ("results",))
|
||||
detail_paths = (("data",), ("job",), ("position",), ("result",))
|
||||
closed_statuses = CLOSED_STATUSES | {"archived", "deleted"}
|
||||
|
||||
def _extract_records(self, payload):
|
||||
if isinstance(payload, list):
|
||||
return [item for item in payload if isinstance(item, dict)]
|
||||
for path in self.listing_paths:
|
||||
value = payload
|
||||
for key in path:
|
||||
@@ -466,7 +491,7 @@ class RecruiteeAdapter(_AtsAdapter):
|
||||
parser_key = "ats-recruitee"
|
||||
source_hosts = ("recruitee.com",)
|
||||
support_markers = ("recruitee", "career", "vacancy")
|
||||
listing_paths = (("jobs",), ("data", "jobs"), ("vacancies",))
|
||||
listing_paths = (("jobs",), ("offers",), ("data", "jobs"), ("vacancies",))
|
||||
detail_paths = (("job",), ("data", "job"), ("vacancy",), ("result",))
|
||||
closed_statuses = CLOSED_STATUSES | {"hidden", "paused"}
|
||||
|
||||
@@ -494,12 +519,26 @@ class RecruiteeAdapter(_AtsAdapter):
|
||||
|
||||
class SmartRecruitersAdapter(_AtsAdapter):
|
||||
parser_key = "ats-smartrecruiters"
|
||||
parser_version = "1.1.0"
|
||||
source_hosts = ("smartrecruiters.com",)
|
||||
support_markers = ("smartrecruiters", "smart recruiter")
|
||||
listing_paths = (("jobs",), ("data", "jobs"), ("results",))
|
||||
listing_paths = (("jobs",), ("data", "jobs"), ("results",), ("content",))
|
||||
detail_paths = (("job",), ("data", "job"), ("posting",), ("result",))
|
||||
closed_statuses = CLOSED_STATUSES | {"unpublished", "expired"}
|
||||
|
||||
def _to_job(self, record: dict[str, object], base_url: str) -> ExtractedJob:
|
||||
prepared = dict(record)
|
||||
if not _first_text(prepared, "url", "jobUrl", "hostedUrl", "applyUrl", "link"):
|
||||
company_identifier = _first_text(prepared, "company.identifier")
|
||||
posting_id = _first_text(prepared, "id", "uuid")
|
||||
if company_identifier and posting_id:
|
||||
prepared["url"] = (
|
||||
f"https://jobs.smartrecruiters.com/{company_identifier}/{posting_id}"
|
||||
)
|
||||
if _find_nested(prepared, "location.remote") is True:
|
||||
prepared["remote"] = True
|
||||
return super()._to_job(prepared, base_url)
|
||||
|
||||
def _extract_records(self, payload):
|
||||
for path in self.listing_paths:
|
||||
value = payload
|
||||
|
||||
Reference in New Issue
Block a user