mirror of
https://github.com/oskvr37/tiddl.git
synced 2026-06-13 04:05:08 +03:00
✨ New metadata.album_review config setting (#216)
* add `get_album_review` endpoint * add `metadata.album_review` config option * add comment to `add_track_metadata` * move `AlbumReview` model to its own file and clean up imports * fix API endpoint for fetching album reviews * add normalized_text method to AlbumReview model for text processing * add unit test for `normalize_review_text` function and refactor `AlbumReview` model * add `album_review` to metadata * update comment * add comment
This commit is contained in:
@@ -91,6 +91,10 @@ embed_lyrics = false
|
||||
# embed track cover in the track file
|
||||
cover = false
|
||||
|
||||
# embed album review text to track COMMENT metadata field.
|
||||
# only works when downloading album
|
||||
album_review = false
|
||||
|
||||
|
||||
[cover]
|
||||
# please don't confuse the cover from metadata with cover as a distinct file.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from tiddl.core.api.models.review import normalize_review_text
|
||||
|
||||
|
||||
def test_normalize_review_text():
|
||||
text_before = 'Dropping on Halloween of 2017 with only a single day\'s advance notice, [wimpLink albumId="80611906"]Without Warning[/wimpLink] is a collaborative full-length between [wimpLink artistId="7279286"]21 Savage[/wimpLink], [wimpLink artistId="3958646"]Offset[/wimpLink] (of [wimpLink artistId="5024748"]Migos[/wimpLink]), and producer [wimpLink artistId="5012586"]Metro Boomin[/wimpLink], three of the most successful rap artists of the year. The release plays up its Halloween theme, with [wimpLink artistId="5012586"]Metro Boomin[/wimpLink] filling the tracks with scary sound effects and ominous beats, and the MCs delivering ghastly, violent lyrics. [wimpLink artistId="5198891"]Travis Scott[/wimpLink] and [wimpLink artistId="5906497"]Quavo[/wimpLink] contribute guest verses, and additional producers include Dre Moon, [wimpLink artistId="25917"]Southside[/wimpLink], and Cubeatz. [wimpLink albumId="80611906"]Without Warning[/wimpLink] was an immediate success, hitting the Top Five of the Billboard 200 albums chart following its release.'
|
||||
text_after = "Dropping on Halloween of 2017 with only a single day's advance notice, Without Warning is a collaborative full-length between 21 Savage, Offset (of Migos), and producer Metro Boomin, three of the most successful rap artists of the year. The release plays up its Halloween theme, with Metro Boomin filling the tracks with scary sound effects and ominous beats, and the MCs delivering ghastly, violent lyrics. Travis Scott and Quavo contribute guest verses, and additional producers include Dre Moon, Southside, and Cubeatz. Without Warning was an immediate success, hitting the Top Five of the Billboard 200 albums chart following its release."
|
||||
|
||||
assert normalize_review_text(text=text_before) == text_after
|
||||
@@ -172,11 +172,13 @@ def download_callback(
|
||||
artist: str = "",
|
||||
credits: list[AlbumItemsCredits.ItemWithCredits.CreditsEntry] = [],
|
||||
cover_data: bytes | None = None,
|
||||
album_review: str = "",
|
||||
) -> None:
|
||||
self.date = date
|
||||
self.artist = artist
|
||||
self.credits = credits
|
||||
self.cover_data = cover_data
|
||||
self.album_review = album_review
|
||||
|
||||
async def handle_resource(resource: TidalResource):
|
||||
async def handle_item(
|
||||
@@ -222,6 +224,7 @@ def download_callback(
|
||||
cover_data=cover_data,
|
||||
date=track_metadata.date,
|
||||
credits=track_metadata.credits,
|
||||
comment=track_metadata.album_review,
|
||||
)
|
||||
|
||||
elif isinstance(item, Video):
|
||||
@@ -245,6 +248,16 @@ def download_callback(
|
||||
if album.cover and (CONFIG.metadata.cover or save_cover):
|
||||
cover = Cover(album.cover, size=CONFIG.cover.size)
|
||||
|
||||
album_review = ""
|
||||
|
||||
if CONFIG.metadata.album_review:
|
||||
try:
|
||||
album_review = ctx.obj.api.get_album_review(
|
||||
album_id=resource.id
|
||||
).normalized_text()
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
|
||||
while True:
|
||||
album_items = ctx.obj.api.get_album_items_credits(
|
||||
album_id=album.id, offset=offset
|
||||
@@ -264,6 +277,7 @@ def download_callback(
|
||||
date=str(album.releaseDate),
|
||||
artist=album.artist.name if album.artist else "",
|
||||
credits=album_item.credits,
|
||||
album_review=album_review,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -27,6 +27,7 @@ class Config(BaseModel):
|
||||
enable: bool = True
|
||||
lyrics: bool = False
|
||||
cover: bool = False
|
||||
album_review: bool = False
|
||||
|
||||
metadata: MetadataConfig = MetadataConfig()
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from .models.base import (
|
||||
TrackStream,
|
||||
VideoStream,
|
||||
)
|
||||
from .models.review import AlbumReview
|
||||
|
||||
|
||||
ID: TypeAlias = str | int
|
||||
@@ -96,6 +97,14 @@ class TidalAPI:
|
||||
expire_after=3600,
|
||||
)
|
||||
|
||||
def get_album_review(self, album_id: ID):
|
||||
return self.client.fetch(
|
||||
AlbumReview,
|
||||
f"albums/{album_id}/review",
|
||||
{"countryCode": self.country_code},
|
||||
expire_after=3600,
|
||||
)
|
||||
|
||||
def get_artist(self, artist_id: ID):
|
||||
return self.client.fetch(
|
||||
Artist,
|
||||
|
||||
@@ -28,9 +28,11 @@ class Items(BaseModel):
|
||||
class ArtistAlbumsItems(Items):
|
||||
items: List[Album]
|
||||
|
||||
|
||||
class ArtistVideosItems(Items):
|
||||
items: List[Video]
|
||||
|
||||
|
||||
ItemType = Literal["track", "video"]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import re
|
||||
|
||||
from datetime import datetime
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
def normalize_review_text(text: str | None = None) -> str:
|
||||
if not text:
|
||||
return ""
|
||||
|
||||
text = re.sub(
|
||||
r"\[wimpLink\b[^\]]*\](.*?)\[/wimpLink\]",
|
||||
r"\1",
|
||||
text,
|
||||
flags=re.DOTALL | re.IGNORECASE,
|
||||
)
|
||||
|
||||
text = re.sub(r"\[/?wimpLink\b[^\]]*\]", "", text, flags=re.IGNORECASE)
|
||||
|
||||
return text.strip()
|
||||
|
||||
|
||||
class AlbumReview(BaseModel):
|
||||
source: str
|
||||
lastUpdated: datetime
|
||||
text: str
|
||||
summary: str
|
||||
|
||||
def normalized_text(self) -> str:
|
||||
return normalize_review_text(self.text)
|
||||
@@ -26,6 +26,7 @@ class Metadata:
|
||||
default_factory=list
|
||||
)
|
||||
cover_data: bytes | None = None
|
||||
comment: str = ""
|
||||
|
||||
|
||||
def add_flac_metadata(track_path: Path, metadata: Metadata) -> None:
|
||||
@@ -55,6 +56,7 @@ def add_flac_metadata(track_path: Path, metadata: Metadata) -> None:
|
||||
"YEAR": (str(date.year) if date else ""),
|
||||
"COPYRIGHT": metadata.copyright or "",
|
||||
"ISRC": metadata.isrc,
|
||||
"COMMENT": metadata.comment,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -94,6 +96,7 @@ def add_m4a_metadata(track_path: Path, metadata: Metadata) -> None:
|
||||
"artist": metadata.artists,
|
||||
"date": metadata.date,
|
||||
"copyright": metadata.copyright or "",
|
||||
"comment": metadata.comment,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -111,6 +114,7 @@ def add_track_metadata(
|
||||
lyrics: str = "",
|
||||
cover_data: bytes | None = None,
|
||||
credits: list[AlbumItemsCredits.ItemWithCredits.CreditsEntry] | None = None,
|
||||
comment: str = "",
|
||||
) -> None:
|
||||
"""Add FLAC or M4A metadata based on file extension."""
|
||||
|
||||
@@ -128,6 +132,7 @@ def add_track_metadata(
|
||||
lyrics=lyrics or None,
|
||||
cover_data=cover_data,
|
||||
credits=credits or [],
|
||||
comment=comment,
|
||||
)
|
||||
|
||||
ext = path.suffix.lower()
|
||||
|
||||
@@ -63,6 +63,8 @@ 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
|
||||
quality = item.audioQuality or ""
|
||||
else: # Video
|
||||
version = ""
|
||||
|
||||
Reference in New Issue
Block a user