add formatTrack

This commit is contained in:
oskvr37
2025-01-20 14:18:56 +01:00
parent 0734789aea
commit aec889c57d
2 changed files with 148 additions and 1 deletions
+98 -1
View File
@@ -1,6 +1,8 @@
import unittest
import json
from tiddl.utils import TidalResource
from tiddl.models import Track
from tiddl.utils import TidalResource, formatTrack
class TestTidalResource(unittest.TestCase):
@@ -42,5 +44,100 @@ class TestTidalResource(unittest.TestCase):
TidalResource(resource)
class TestFormatTrack(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.track = Track(
**{
"id": 66421438,
"title": "Shutdown",
"duration": 189,
"replayGain": -9.95,
"peak": 0.966051,
"allowStreaming": True,
"streamReady": True,
"adSupportedStreamReady": True,
"djReady": True,
"stemReady": False,
"streamStartDate": "2016-11-15T00:00:00.000+0000",
"premiumStreamingOnly": False,
"trackNumber": 9,
"volumeNumber": 1,
"version": None,
"popularity": 24,
"copyright": "(P) 2016 Boy Better Know",
"bpm": 69,
"url": "http://www.tidal.com/track/66421438",
"isrc": "GB7QY1500024",
"editable": False,
"explicit": True,
"audioQuality": "LOSSLESS",
"audioModes": ["STEREO"],
"mediaMetadata": {"tags": ["LOSSLESS", "HIRES_LOSSLESS"]},
"artist": {
"id": 3566984,
"name": "Skepta",
"type": "MAIN",
"picture": "747af850-fa9c-4178-a3e6-49259b67df86",
},
"artists": [
{
"id": 3566984,
"name": "Skepta",
"type": "MAIN",
"picture": "747af850-fa9c-4178-a3e6-49259b67df86",
}
],
"album": {
"id": 66421429,
"title": "Konnichiwa",
"cover": "e0c2f05e-e21f-47c5-9c37-2993437df27d",
"vibrantColor": "#ae3b31",
"videoCover": None,
},
"mixes": {"TRACK_MIX": "001aa4abeb471e8f55f5784772b478"},
"playlistNumber": None,
}
)
def test_templating(self):
test_cases = [
("{id}", "66421438"),
("{title}", "Shutdown"),
("{version}", ""),
("{artist}", "Skepta"),
("{artists}", "Skepta"),
("{album}", "Konnichiwa"),
("{number}", "9"),
("{disc}", "1"),
("{date}", "11-15-16"),
("{year}", "2016"),
("{playlist_number}", ""),
("{bpm}", "69"),
("{quality}", "high"),
("{artist}/{album}/{title}", "Skepta/Konnichiwa/Shutdown"),
]
for template, expected_result in test_cases:
result = formatTrack(template, self.track)
self.assertEqual(result, expected_result)
def test_invalid_characters(self):
test_cases = [
"\\",
":",
'"',
"?",
"<",
">",
"|",
]
for template in test_cases:
with self.subTest(template=template):
with self.assertRaises(ValueError):
formatTrack(template, self.track)
if __name__ == "__main__":
unittest.main()
+50
View File
@@ -1,6 +1,8 @@
import re
from urllib.parse import urlparse
from typing import Literal, get_args
from tiddl.models import Track, QUALITY_TO_ARG
ResourceTypeLiteral = Literal["track", "album", "playlist", "artist"]
@@ -39,3 +41,51 @@ class TidalResource:
def __str__(self) -> str:
return f"{self.resource_type}/{self.resource_id}"
def sanitizeString(string: str) -> str:
pattern = r'[\\/:"*?<>|]+'
return re.sub(pattern, "", string)
def formatTrack(template: str, track: Track, date_format="%x") -> str:
disallowed_chars = r'[\\:"*?<>|]+'
invalid_chars = re.findall(disallowed_chars, template)
if invalid_chars:
raise ValueError(
f"Template '{template}' contains disallowed characters: {' '.join(sorted(set(invalid_chars)))}"
)
artist = track.artist.name if track.artist else ""
features = [
track_artist.name
for track_artist in track.artists
if track_artist.name != artist
]
track_dict: dict[str, str] = {
"id": str(track.id),
"title": track.title,
"version": track.version or "",
"artist": artist,
"artists": ", ".join(features + [artist]),
"features": ", ".join(features),
"album": track.album.title,
"number": str(track.trackNumber),
"disc": str(track.volumeNumber),
"date": (
track.streamStartDate.strftime(date_format).replace("/", "-")
if track.streamStartDate
else ""
),
"year": track.streamStartDate.strftime("%Y") if track.streamStartDate else "",
"playlist_number": str(track.playlistNumber or ""),
"bpm": str(track.bpm or ""),
"quality": QUALITY_TO_ARG[track.audioQuality],
}
for key, value in track_dict.items():
track_dict[key] = sanitizeString(value)
return template.format(**track_dict)