diff --git a/docs/templating.md b/docs/templating.md index ce64156..0751353 100644 --- a/docs/templating.md +++ b/docs/templating.md @@ -44,18 +44,21 @@ Each object type exposes fields you can use inside templates. | `item.artists` | All main artists | `Daft Punk, Pharrell Williams` | | `item.features` | Featured artists | `Pharrell Williams` | | `item.artists_with_features` | Main + featured artists | `Daft Punk, Pharrell Williams` | +| `item.explicit` | Explicit content | `E` | +| `item.dolby:(Dolby Atmos)` | Dolby Atmos (track only) | `(Dolby Atmos)` | --- ### `album` -| Field | Description | Example | -| --------------- | ------------------------- | ------------ | -| `album.id` | Album ID | `98765` | -| `album.title` | Album title | `Discovery` | -| `album.artist` | Primary artist | `Daft Punk` | -| `album.artists` | All main artists | `Daft Punk` | -| `album.date` | Release date (`datetime`) | `2001-03-13` | +| Field | Description | Example | +| ---------------- | ------------------------- | ------------ | +| `album.id` | Album ID | `98765` | +| `album.title` | Album title | `Discovery` | +| `album.artist` | Primary artist | `Daft Punk` | +| `album.artists` | All main artists | `Daft Punk` | +| `album.date` | Release date (`datetime`) | `2001-03-13` | +| `album.explicit` | Explicit content | `clean` | --- @@ -71,6 +74,24 @@ Each object type exposes fields you can use inside templates. --- +### Explicit + +| Format | True Value | False Value | +| ---------------- | ---------- | ----------- | +| `.explicit` | E | | +| `.explicit:long` | explicit | | +| `.explicit:full` | explicit | clean | + +### Dolby Atmos + +Dolby Atmos is only available in tracks. Format it like this: `item.dolby:`. + +| Format | True Value | False Value | +| ------------------ | ---------- | ----------- | +| `item.dolby:D` | D | | +| `item.dolby:DOLBY` | DOLBY | | +| `item.dolby:dolby` | dolby | | + ### `extra` and `custom` fields You can also use: diff --git a/examples/track_templating.py b/examples/track_templating.py index 9f9fb2e..ece4ab6 100644 --- a/examples/track_templating.py +++ b/examples/track_templating.py @@ -10,7 +10,7 @@ if __name__ == "__main__": album = api.get_album(ALBUM_ID) album_items = api.get_album_items(ALBUM_ID) - TEMPLATE = "{album.artists}/{album.title}, {album.date:%Y}/{item.number:02d}. {item.artists} - {item.title} ({custom_field})" + TEMPLATE = "{album.artists}/{album.title}, {album.date:%Y}, {album.explicit}/{item.number:02d}. {item.artists} - {item.title} ({custom_field}) {item.explicit:full}" for album_item in album_items.items: track = album_item.item diff --git a/tiddl/core/utils/format.py b/tiddl/core/utils/format.py index fa1847d..6ee08eb 100644 --- a/tiddl/core/utils/format.py +++ b/tiddl/core/utils/format.py @@ -5,6 +5,44 @@ from tiddl.core.api.models import Track, Video, Album, Playlist from tiddl.core.utils.sanitize import sanitize_string +class Explicit: + def __init__(self, value: bool | None): + self.value = value + + def __format__(self, format_spec: str): + if self.value is None: + return "" + + features = format_spec.split(",") + + def get_base(): + for feature in features: + match feature: + case "long": + return "explicit" if self.value else "" + case "full": + return "explicit" if self.value else "clean" + + return "E" if self.value else "" + + base = get_base() + + for feature in features: + match feature: + case "upper": + return base.upper() + + return base + + +class DolbyAtmos: + def __init__(self, value: bool) -> None: + self.value = value + + def __format__(self, format_spec: str) -> str: + return format_spec if self.value is True else "" + + @dataclass(slots=True) class AlbumTemplate: id: int @@ -12,6 +50,7 @@ class AlbumTemplate: artist: str artists: str date: datetime + explicit: Explicit @dataclass(slots=True) @@ -30,6 +69,8 @@ class ItemTemplate: artists: str features: str artists_with_features: str + explicit: Explicit + dolby: DolbyAtmos @dataclass(slots=True) @@ -64,13 +105,13 @@ def generate_template_data( copyright_ = item.copyright or "" bpm = item.bpm or 0 isrc = item.isrc or "" - # FIX audio quality should be returned from `get_existing_track_filename`. - # `item.audioQuality` tells highest quality of track - not quality we downloaded + dolby = DolbyAtmos("DOLBY_ATMOS" in item.mediaMetadata.tags) else: # Video version = "" copyright_ = "" bpm = 0 isrc = "" + dolby = DolbyAtmos(False) item_template = ItemTemplate( id=item.id, @@ -87,6 +128,8 @@ def generate_template_data( artists=", ".join(main_artists), features=", ".join(featured_artists), artists_with_features=", ".join(main_artists + featured_artists), + explicit=Explicit(getattr(item, "explicit", None)), + dolby=dolby, ) album_template = None @@ -99,6 +142,7 @@ def generate_template_data( a.name for a in (album.artists or []) if a.type == "MAIN" ), date=album.releaseDate, + explicit=Explicit(getattr(album, "explicit", None)), ) playlist_template = None @@ -145,7 +189,10 @@ def format_template( ) path: str = "/".join( - [sanitize_string(segment.format(**data)) for segment in template.split("/")] + [ + sanitize_string(segment.format(**data)).strip() + for segment in template.split("/") + ] ) if with_asterisk_ext: