63 lines
1.6 KiB
Markdown
63 lines
1.6 KiB
Markdown
# `src/core/migrate.py`
|
|
|
|
One-off migration of an existing pool to the Jellyfin naming convention.
|
|
|
|
Older pools carry files like `Title.ext` / `Title (rok).ext` with **no TMDb
|
|
id**. This matches each such movie against TMDb by title + year and proposes a
|
|
`tmdbid` (and the missing year, which TMDb supplies), so the file can be renamed
|
|
to `Title (rok) [tmdbid].ext` and Jellyfin can match it deterministically.
|
|
|
|
The classification is deliberately **conservative**: only an exact
|
|
(diacritics-insensitive) title match with a matching year and a single candidate
|
|
is `auto`; everything else is `ambiguous` for the user to confirm.
|
|
|
|
Source: [`src/core/migrate.py`](../../src/core/migrate.py)
|
|
|
|
## Classes
|
|
|
|
### `MatchProposal`
|
|
|
|
*class · line 19*
|
|
|
|
```python
|
|
class MatchProposal:
|
|
```
|
|
|
|
One movie's proposed TMDb match.
|
|
|
|
## Functions
|
|
|
|
### `normalize`
|
|
|
|
*function · line 33*
|
|
|
|
```python
|
|
normalize(text: str) -> str
|
|
```
|
|
|
|
Fold a title for comparison: strip diacritics/punctuation, lowercase.
|
|
|
|
### `_year_close`
|
|
|
|
*function · line 41*
|
|
|
|
```python
|
|
_year_close(a: Optional[str], b: Optional[str]) -> bool
|
|
```
|
|
|
|
True when two year strings are both numeric and differ by at most one year (release years often disagree by one).
|
|
|
|
### `classify`
|
|
|
|
*function · line 47*
|
|
|
|
```python
|
|
classify(title: str, year: Optional[str], candidates: list) -> tuple[str, object]
|
|
```
|
|
|
|
Return `(status, chosen)` for a title/year against TMDb candidates.
|
|
|
|
`auto` requires an exact normalized-title match, a year within ±1, and that
|
|
exactly one candidate qualifies. Otherwise `ambiguous` (top hit preselected)
|
|
or `no_match` when there are no candidates.
|