# `src/core/csfd.py` ČSFD.cz scraper — a *title bridge* to TMDb. Curator identifies movies by **TMDb id**. A direct TMDb search on a Czech distribution title is unreliable (remakes, localized names, "weird" hits). ČSFD, on the other hand, indexes Czech release names well **and** lists a film's *original* title. So the bridge is:: filename → ČSFD search → ČSFD film page → original title + year → TMDb search → tmdbid This module only scrapes ČSFD; the TMDb half lives in `src.core.file_manager` (`FileManager.resolve_via_csfd`). Nothing here feeds tags/genres — those still come from TMDb via Jellyfin/NFO. ČSFD serves an **Anubis** proof-of-work wall in front of every page: a plain request gets a 200 with a JS challenge instead of the movie. We detect it, solve the SHA-256 PoW the way the bundled worker JS does, and replay the request through a shared `requests.Session` (so a batch pays the PoW cost only once). Source: [`src/core/csfd.py`](../../src/core/csfd.py) ## Classes ### `CsfdError` *class · line 62* ```python class CsfdError(RuntimeError): ``` A ČSFD lookup could not be completed (deps missing, network, anti-bot). ### `CsfdFilm` *class · line 67* ```python class CsfdFilm: ``` The slice of a ČSFD film page Curator needs to reach a TMDb id. #### `CsfdFilm.tmdb_query` *property · line 77* ```python tmdb_query -> tuple[str, Optional[str]] ``` `(title, year)` best suited for a TMDb search — original title first. ## Functions ### `dependencies_available` *function · line 82* ```python dependencies_available() -> bool ``` True when `requests` + `beautifulsoup4` are importable. ### `_check_dependencies` *function · line 87* ```python _check_dependencies() -> None ``` Raise `CsfdError` when the optional `requests` / `beautifulsoup4` packages are missing (they are needed only for ČSFD scraping). ### `_extract_csfd_id` *function · line 95* ```python _extract_csfd_id(url: str) -> Optional[int] ``` Pull the numeric film id out of a ČSFD URL, or `None`. ### `_extract_json_blob` *function · line 105* ```python _extract_json_blob(html: str, element_id: str) ``` Return the parsed JSON from an Anubis `