228 lines
5.7 KiB
Markdown
228 lines
5.7 KiB
Markdown
# `src/core/file.py`
|
|
|
|
The `File` class: one playable movie file as the UI sees it. A `File` is a *view* onto one media entry of a movie record in the pool index — metadata (title, tags, ČSFD link, attributes, date) lives on the shared record, so every version of a film reads the same values. See `docs/architecture.md`.
|
|
|
|
Source: [`src/core/file.py`](../../src/core/file.py)
|
|
|
|
## Classes
|
|
|
|
### `File`
|
|
|
|
*class · line 5*
|
|
|
|
```python
|
|
class File:
|
|
```
|
|
|
|
One movie file in the pool, as the UI sees it. Holds the path, the list of tags and the metadata accessors; metadata itself is stored on the movie record in the pool index and the `File` reads it through it.
|
|
|
|
#### `File.__init__`
|
|
|
|
*method · line 6*
|
|
|
|
```python
|
|
__init__(file_path: Path, tagmanager=None, index=None) -> None
|
|
```
|
|
|
|
Create a file object for `file_path`. Metadata is loaded from the pool index when `index` is given; without an index the object is in-memory only.
|
|
|
|
#### `File._identity_from_path`
|
|
|
|
*method · line 41*
|
|
|
|
```python
|
|
_identity_from_path() -> tuple[str, str, str | None, int | None, str]
|
|
```
|
|
|
|
`(key, title, year, tmdb_id, label)` implied by this file's location.
|
|
|
|
A file inside its own `Title (rok) [tmdbid]` folder is one version of
|
|
that movie — identity comes from the **folder**, and the rest of its own
|
|
stem is the version label. A flat file carries both in its own name.
|
|
|
|
#### `File.get_metadata`
|
|
|
|
*method · line 67*
|
|
|
|
```python
|
|
get_metadata() -> None
|
|
```
|
|
|
|
Load this file's metadata from the movie record that owns it.
|
|
|
|
Since the pool index became identity-keyed (see `src.core.movie`),
|
|
a File is a *view* on one media entry of a movie record — every version
|
|
of the same film therefore reads the same title/tags/ČSFD/… A file the
|
|
index doesn't know yet joins the movie of the same identity when there
|
|
is one (that's how a newly added version inherits the shared metadata
|
|
instead of blanking it), otherwise it starts a new record.
|
|
|
|
#### `File._init_new_metadata`
|
|
|
|
*method · line 95*
|
|
|
|
```python
|
|
_init_new_metadata() -> None
|
|
```
|
|
|
|
Reset all metadata fields to their defaults for a file the index doesn't know yet.
|
|
|
|
#### `File._build_record`
|
|
|
|
*method · line 107*
|
|
|
|
```python
|
|
_build_record() -> dict
|
|
```
|
|
|
|
Serialise this file's metadata into the dictionary stored in the pool index (tags as full paths, auto-derived tags, date, title, ČSFD link, …).
|
|
|
|
#### `File._apply_record`
|
|
|
|
*method · line 126*
|
|
|
|
```python
|
|
_apply_record(data: dict) -> None
|
|
```
|
|
|
|
Load metadata from an index record dictionary into this object's fields (the inverse of `_build_record`). Missing keys fall back to defaults.
|
|
|
|
#### `File.save_metadata`
|
|
|
|
*method · line 152*
|
|
|
|
```python
|
|
save_metadata()
|
|
```
|
|
|
|
Persist metadata into this file's movie record (no-op without index).
|
|
|
|
Writes the shared fields onto the movie record and makes sure the
|
|
record lists this file among its media. A file the index has never seen
|
|
starts a new record under its own identity key.
|
|
|
|
#### `File._library_name`
|
|
|
|
*method · line 182*
|
|
|
|
```python
|
|
_library_name() -> str
|
|
```
|
|
|
|
Top-level pool folder this file sits in (its library), or `""`.
|
|
|
|
#### `File.added_timestamp`
|
|
|
|
*method · line 190*
|
|
|
|
```python
|
|
added_timestamp() -> float
|
|
```
|
|
|
|
Epoch seconds for 'date added' — the stored `added` or the file mtime.
|
|
|
|
Used to order the "recently added" folder (newer = larger). The fallback
|
|
is **mtime**, not ctime: creating the Filmotéka hardlinks bumps the source
|
|
inode's ctime, which would make ctime-based ordering meaningless, whereas
|
|
mtime (preserved from the source on import) stays stable.
|
|
|
|
#### `File.name_context`
|
|
|
|
*method · line 209*
|
|
|
|
```python
|
|
name_context() -> dict
|
|
```
|
|
|
|
Fields for a miniDLNA filename template (see config tag schema).
|
|
|
|
Provides title / year / rating / ext / stem / filename from the movie's
|
|
metadata (year & rating come from the NFO cache, year falling back to a
|
|
`Rok` tag, then the canonical filename). Missing values render empty.
|
|
|
|
#### `File.set_attribute`
|
|
|
|
*method · line 242*
|
|
|
|
```python
|
|
set_attribute(key: str, value: str | None) -> None
|
|
```
|
|
|
|
Set a free-form attribute (e.g. 'collection_sort'); None/'' removes it.
|
|
|
|
#### `File.delete_metadata`
|
|
|
|
*method · line 253*
|
|
|
|
```python
|
|
delete_metadata() -> None
|
|
```
|
|
|
|
Drop this file from its movie record; the last one takes the record.
|
|
|
|
Removing one version of a multi-version movie leaves the movie (and its
|
|
metadata) in place — only when its last media entry goes does the whole
|
|
record go with it.
|
|
|
|
#### `File.relocate`
|
|
|
|
*method · line 273*
|
|
|
|
```python
|
|
relocate(new_path: Path) -> None
|
|
```
|
|
|
|
Point this File at a new path, moving its media entry along.
|
|
|
|
The physical file must already have been moved/renamed by the caller;
|
|
this only repoints the movie record's media entry (and the File), so a
|
|
rename never detaches a file from its movie.
|
|
|
|
#### `File.set_date`
|
|
|
|
*method · line 294*
|
|
|
|
```python
|
|
set_date(date_str: str | None)
|
|
```
|
|
|
|
Set the date the movie was added (`YYYY-MM-DD`) or clear it with `None` / an empty string, then save the metadata.
|
|
|
|
#### `File.apply_nfo`
|
|
|
|
*method · line 303*
|
|
|
|
```python
|
|
apply_nfo(nfo, schema: list[dict] | None=None) -> dict
|
|
```
|
|
|
|
Regenerate the auto (NFO-derived) tags from the movie's NFO.
|
|
|
|
Reads genres/year/countries/rating from `nfo` (`nfo.NfoData`) per the
|
|
tag schema's source fields and (re)creates those tags; user-added tags are
|
|
kept. Also caches year/rating (for folder grouping) and fills the title
|
|
when missing. `nfo` of `None` (no NFO yet) is a no-op.
|
|
|
|
Returns:
|
|
dict with 'success' and 'tags_added'.
|
|
|
|
#### `File.add_tag`
|
|
|
|
*method · line 347*
|
|
|
|
```python
|
|
add_tag(tag)
|
|
```
|
|
|
|
Attach a tag to this file. Accepts a `Tag` or a `category/name` string; a string without a category goes to the `default` category. Saves on change.
|
|
|
|
#### `File.remove_tag`
|
|
|
|
*method · line 364*
|
|
|
|
```python
|
|
remove_tag(tag)
|
|
```
|
|
|
|
Detach a tag, given as a `Tag` or a `category/name` string. Saves on change.
|