fix album, artist, and show parsing

This commit is contained in:
zotify 2023-04-08 22:31:29 +12:00
parent dbf05e3b50
commit 8d8d173a78
8 changed files with 48 additions and 64 deletions

View File

@ -1,4 +1,4 @@
# STILL IN DEVELOPMENT, SOME CHANGES AREN'T IMPLEMENTED AND SOME AREN'T FINAL!
# STILL IN DEVELOPMENT, EVERYTHING HERE IS SUBJECT TO CHANGE!
## v1.0.0
An unexpected reboot
@ -41,6 +41,7 @@ An unexpected reboot
- `{album_artists}`
- !!`{duration}` - In milliseconds
- `{explicit}`
- `{explicit_symbol}` - For output format, will be \[E] if track is explicit.
- `{isrc}`
- `{licensor}`
- !!`{popularity}`

View File

@ -1,6 +1,6 @@
[metadata]
name = zotify
version = 0.9.0
version = 0.9.1
author = Zotify Contributors
description = A highly customizable music and podcast downloader
long_description = file: README.md

View File

@ -7,7 +7,7 @@ from zotify.app import client
from zotify.config import CONFIG_PATHS, CONFIG_VALUES
from zotify.utils import OptionalOrFalse
VERSION = "0.9.0"
VERSION = "0.9.1"
def main():

View File

@ -170,7 +170,7 @@ class App:
self.__playable_list.append(
PlayableData(
PlayableType.TRACK,
bytes_to_hex(track.gid),
TrackId.from_hex(bytes_to_hex(track.gid)),
self.__config.music_library,
self.__config.output_album,
)
@ -187,7 +187,7 @@ class App:
self.__playable_list.append(
PlayableData(
PlayableType.TRACK,
bytes_to_hex(track.gid),
TrackId.from_hex(bytes_to_hex(track.gid)),
self.__config.music_library,
self.__config.output_album,
)
@ -215,7 +215,7 @@ class App:
self.__playable_list.append(
PlayableData(
PlayableType.EPISODE,
bytes_to_hex(episode.gid),
EpisodeId.from_hex(bytes_to_hex(episode.gid)),
self.__config.podcast_library,
self.__config.output_podcast,
)

View File

@ -138,7 +138,7 @@ CONFIG_VALUES = {
AUDIO_FORMAT: {
"default": "vorbis",
"type": AudioFormat,
"choices": [n.value for n in AudioFormat],
"choices": [n.value.name for n in AudioFormat],
"arg": "--audio-format",
"help": "Audio format of final track output",
},
@ -335,7 +335,7 @@ class Config:
elif config_type == Path:
return Path(value).expanduser()
elif config_type == AudioFormat:
return AudioFormat(value)
return AudioFormat[value.upper()]
elif config_type == ImageSize.from_string:
return ImageSize.from_string(value)
elif config_type == Quality.from_string:

View File

@ -6,7 +6,7 @@ from typing import Any
from music_tag import load_file
from mutagen.oggvorbis import OggVorbisHeaderError
from zotify.utils import AudioFormat, ExtMap
from zotify.utils import AudioFormat
# fmt: off
@ -18,18 +18,16 @@ class FFmpegExecutionError(OSError, TranscodingError): ...
class LocalFile:
audio_format: AudioFormat
def __init__(
self,
path: Path,
audio_format: AudioFormat | None = None,
bitrate: int | None = None,
):
self.path = path
self.bitrate = bitrate
self.__path = path
self.__bitrate = bitrate
if audio_format:
self.audio_format = audio_format
self.__audio_format = audio_format
def transcode(
self,
@ -48,10 +46,10 @@ class LocalFile:
ffmpeg: Location of FFmpeg binary
opt_args: Additional arguments to pass to ffmpeg
"""
if audio_format:
new_ext = ExtMap[audio_format.value]
if audio_format is not None:
new_ext = audio_format.value.ext
else:
new_ext = ExtMap[self.audio_format.value]
new_ext = self.__audio_format.value.ext
cmd = [
ffmpeg,
"-y",
@ -59,18 +57,18 @@ class LocalFile:
"-loglevel",
"error",
"-i",
str(self.path),
str(self.__path),
]
newpath = self.path.parent.joinpath(
self.path.name.rsplit(".", 1)[0] + new_ext.value
newpath = self.__path.parent.joinpath(
self.__path.name.rsplit(".", 1)[0] + new_ext
)
if self.path == newpath:
if self.__path == newpath:
raise TargetExistsError(
f"Transcoding Error: Cannot overwrite source, target file is already a {self.audio_format} file."
f"Transcoding Error: Cannot overwrite source, target file is already a {self.__audio_format} file."
)
cmd.extend(["-b:a", str(bitrate) + "k"]) if bitrate else None
cmd.extend(["-c:a", audio_format.value]) if audio_format else None
cmd.extend(["-c:a", audio_format.value.name]) if audio_format else None
cmd.extend(opt_args)
cmd.append(str(newpath))
@ -88,11 +86,11 @@ class LocalFile:
)
if replace:
Path(self.path).unlink()
self.path = newpath
self.bitrate = bitrate
self.__path.unlink()
self.__path = newpath
self.__bitrate = bitrate
if audio_format:
self.audio_format = audio_format
self.__audio_format = audio_format
def write_metadata(self, metadata: dict[str, Any]) -> None:
"""
@ -100,7 +98,7 @@ class LocalFile:
Args:
metadata: key-value metadata dictionary
"""
f = load_file(self.path)
f = load_file(self.__path)
f.save()
for k, v in metadata.items():
try:
@ -118,7 +116,7 @@ class LocalFile:
Args:
image: raw image data
"""
f = load_file(self.path)
f = load_file(self.__path)
f["artwork"] = image
try:
f.save()

View File

@ -3,7 +3,6 @@ from pathlib import Path
from typing import Any
from librespot.core import PlayableContentFeeder
from librespot.metadata import AlbumId
from librespot.util import bytes_to_hex
from librespot.structure import GeneralAudioStream
from requests import get
@ -132,12 +131,6 @@ class Track(PlayableContentFeeder.LoadedStream, Playable):
track.metrics,
)
self.__api = api
try:
isinstance(self.track.album.genre, str)
except AttributeError:
self.album = self.__api.get_metadata_4_album(
AlbumId.from_hex(bytes_to_hex(self.track.album.gid))
)
self.cover_images = self.album.cover_group.image
self.metadata = self.__default_metadata()
@ -155,22 +148,19 @@ class Track(PlayableContentFeeder.LoadedStream, Playable):
"artist": self.artist[0].name,
"artists": "\0".join([a.name for a in self.artist]),
"date": f"{date.year}-{date.month}-{date.day}",
"release_date": f"{date.year}-{date.month}-{date.day}",
"disc_number": self.disc_number,
"duration": self.duration,
"explicit": self.explicit,
"genre": self.album.genre,
"explicit_symbol": "[E]" if self.explicit else "",
"isrc": self.external_id[0].id,
"licensor": self.licensor,
"popularity": self.popularity,
"track_number": self.number,
"popularity": (self.popularity * 255) / 100,
"track_number": str(self.number).zfill(2),
# "year": self.album.date.year,
"title": self.name,
"replaygain_track_gain": self.normalization_data.track_gain_db,
"replaygain_track_peak": self.normalization_data.track_peak,
"replaygain_album_gain": self.normalization_data.album_gain_db,
"replaygain_album_prak": self.normalization_data.album_peak,
"title": self.name,
"track_title": self.name,
# "year": self.album.date.year,
"replaygain_album_peak": self.normalization_data.album_peak,
}
def get_lyrics(self) -> Lyrics:

View File

@ -2,6 +2,7 @@ from argparse import Action, ArgumentError
from enum import Enum, IntEnum
from re import IGNORECASE, sub
from sys import platform as PLATFORM
from typing import NamedTuple
from librespot.audio.decoders import AudioQuality
from librespot.util import Base62, bytes_to_hex
@ -13,26 +14,20 @@ LYRICS_URL = "https://sp" + "client.wg.sp" + "otify.com/color-lyrics/v2/track/"
BASE62 = Base62.create_instance_with_inverted_character_set()
class AudioCodec(NamedTuple):
ext: str
name: str
class AudioFormat(Enum):
AAC = "aac"
FDK_AAC = "fdk_aac"
FLAC = "flac"
MP3 = "mp3"
OPUS = "opus"
VORBIS = "vorbis"
WAV = "wav"
WV = "wavpack"
class ExtMap(Enum):
AAC = "m4a"
FDK_AAC = "m4a"
FLAC = "flac"
MP3 = "mp3"
OPUS = "ogg"
VORBIS = "ogg"
WAV = "wav"
WAVPACK = "wv"
AAC = AudioCodec("aac", "m4a")
FDK_AAC = AudioCodec("fdk_aac", "m4a")
FLAC = AudioCodec("flac", "flac")
MP3 = AudioCodec("mp3", "mp3")
OPUS = AudioCodec("opus", "ogg")
VORBIS = AudioCodec("vorbis", "ogg")
WAV = AudioCodec("wav", "wav")
WV = AudioCodec("wavpack", "wv")
class Quality(Enum):