Различные улучшения
- Исполнители разделяются нулевым байтом, согласно спецификации ID3v2.4 (4.2 Text information frames) - Улучшено распознавание нескольких исполнителей в треке (main.py:42) - Информация о исполнителе/альбоме выводится через logging
This commit is contained in:
parent
99cc98b10f
commit
95bb1c2b32
1 changed files with 31 additions and 19 deletions
50
main.py
50
main.py
|
|
@ -39,6 +39,24 @@ class PlaylistId:
|
||||||
kind: int
|
kind: int
|
||||||
|
|
||||||
|
|
||||||
|
def parse_artists(artists: list) -> list[str]:
|
||||||
|
artists_names = []
|
||||||
|
for artist in artists:
|
||||||
|
artists_names.append(artist['name'])
|
||||||
|
if decomposed := artist.get('decomposed'):
|
||||||
|
for d_artist in decomposed:
|
||||||
|
if isinstance(d_artist, dict):
|
||||||
|
artists_names.append(d_artist['name'])
|
||||||
|
return artists_names
|
||||||
|
|
||||||
|
|
||||||
|
def parse_title(json: dict) -> str:
|
||||||
|
title = json['title']
|
||||||
|
if version := json.get('version'):
|
||||||
|
title = TITLE_FMT % {'title': title, 'version': version}
|
||||||
|
return title
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class BasicAlbumInfo:
|
class BasicAlbumInfo:
|
||||||
id: str
|
id: str
|
||||||
|
|
@ -52,14 +70,11 @@ class BasicAlbumInfo:
|
||||||
if json['metaType'] != 'music':
|
if json['metaType'] != 'music':
|
||||||
logging.info('"%s" пропущен т.к. не является музыкальным альбомом', json['title'])
|
logging.info('"%s" пропущен т.к. не является музыкальным альбомом', json['title'])
|
||||||
return None
|
return None
|
||||||
artists = [a['name'] for a in json['artists']]
|
artists = parse_artists(json['artists'])
|
||||||
title = json['title']
|
title = parse_title(json)
|
||||||
version = json.get('version', None)
|
release_date = json.get('releaseDate')
|
||||||
release_date = json.get('releaseDate', None)
|
|
||||||
if release_date is not None:
|
if release_date is not None:
|
||||||
release_date = dt.datetime.fromisoformat(release_date)
|
release_date = dt.datetime.fromisoformat(release_date)
|
||||||
if version is not None:
|
|
||||||
title = TITLE_FMT % {'title': title, 'version': version}
|
|
||||||
return BasicAlbumInfo(id=json['id'], title=title, year=json['year'],
|
return BasicAlbumInfo(id=json['id'], title=title, year=json['year'],
|
||||||
artists=artists, release_date=release_date)
|
artists=artists, release_date=release_date)
|
||||||
|
|
||||||
|
|
@ -81,21 +96,17 @@ class BasicTrackInfo:
|
||||||
if not json['available']:
|
if not json['available']:
|
||||||
return None
|
return None
|
||||||
album_json = json['albums'][0]
|
album_json = json['albums'][0]
|
||||||
artists_names = [a['name'] for a in json['artists']]
|
artists = parse_artists(json['artists'])
|
||||||
track_position = album_json['trackPosition']
|
track_position = album_json['trackPosition']
|
||||||
album = BasicAlbumInfo.from_json(album_json)
|
album = BasicAlbumInfo.from_json(album_json)
|
||||||
if album is None:
|
if album is None:
|
||||||
raise RuntimeError
|
raise ValueError
|
||||||
url_template = 'https://' + json['ogImage']
|
url_template = 'https://' + json['ogImage']
|
||||||
has_lyrics = json['lyricsInfo']['hasAvailableTextLyrics']
|
has_lyrics = json['lyricsInfo']['hasAvailableTextLyrics']
|
||||||
|
title = parse_title(json)
|
||||||
title = json['title']
|
|
||||||
version = json.get('version', None)
|
|
||||||
if version is not None:
|
|
||||||
title = TITLE_FMT % {'title': title, 'version': version}
|
|
||||||
return BasicTrackInfo(title=title, id=str(json['id']), real_id=json['realId'],
|
return BasicTrackInfo(title=title, id=str(json['id']), real_id=json['realId'],
|
||||||
number=track_position['index'], disc_number=track_position['volume'],
|
number=track_position['index'], disc_number=track_position['volume'],
|
||||||
artists=artists_names, album=album, url_template=url_template,
|
artists=artists, album=album, url_template=url_template,
|
||||||
has_lyrics=has_lyrics)
|
has_lyrics=has_lyrics)
|
||||||
|
|
||||||
def pic_url(self, resolution: int) -> str:
|
def pic_url(self, resolution: int) -> str:
|
||||||
|
|
@ -245,7 +256,7 @@ def set_id3_tags(path: Path, track: BasicTrackInfo, lyrics: Optional[str],
|
||||||
release_date = track.album.year
|
release_date = track.album.year
|
||||||
audiofile = eyed3.load(path)
|
audiofile = eyed3.load(path)
|
||||||
audiofile.tag = tag = eyed3.id3.tag.Tag()
|
audiofile.tag = tag = eyed3.id3.tag.Tag()
|
||||||
tag.artist = '; '.join(track.artists)
|
tag.artist = chr(0).join(track.artists)
|
||||||
tag.album_artist = track.album.artists[0]
|
tag.album_artist = track.album.artists[0]
|
||||||
tag.album = track.album.title
|
tag.album = track.album.title
|
||||||
tag.title = track.title
|
tag.title = track.title
|
||||||
|
|
@ -362,17 +373,18 @@ if __name__ == '__main__':
|
||||||
full_album = get_full_album_info(session, album.id)
|
full_album = get_full_album_info(session, album.id)
|
||||||
result_tracks.extend(full_album.tracks)
|
result_tracks.extend(full_album.tracks)
|
||||||
albums_count += 1
|
albums_count += 1
|
||||||
print(f'{artist_info.name}')
|
logging.info(artist_info.name)
|
||||||
print(f'Альбомов: {albums_count}')
|
logging.info('Альбомов: %d', albums_count)
|
||||||
elif args.album_id is not None:
|
elif args.album_id is not None:
|
||||||
album = get_full_album_info(session, args.album_id)
|
album = get_full_album_info(session, args.album_id)
|
||||||
|
logging.info(album.title)
|
||||||
result_tracks = album.tracks
|
result_tracks = album.tracks
|
||||||
elif args.track_id is not None:
|
elif args.track_id is not None:
|
||||||
result_tracks = [get_full_track_info(session, args.track_id)]
|
result_tracks = [get_full_track_info(session, args.track_id)]
|
||||||
elif args.playlist_id is not None:
|
elif args.playlist_id is not None:
|
||||||
result_tracks = get_playlist(session, args.playlist_id)
|
result_tracks = get_playlist(session, args.playlist_id)
|
||||||
|
|
||||||
print(f'Треков: {len(result_tracks)}')
|
logging.info('Треков: %d', len(result_tracks))
|
||||||
covers: dict[str, bytes] = {}
|
covers: dict[str, bytes] = {}
|
||||||
|
|
||||||
for track in result_tracks:
|
for track in result_tracks:
|
||||||
|
|
@ -399,7 +411,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
cover = None
|
cover = None
|
||||||
if args.embed_cover:
|
if args.embed_cover:
|
||||||
if cached_cover := covers.get(album.id, None):
|
if cached_cover := covers.get(album.id):
|
||||||
cover = cached_cover
|
cover = cached_cover
|
||||||
else:
|
else:
|
||||||
cover = covers[album.id] = download_bytes(session,
|
cover = covers[album.id] = download_bytes(session,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue