From 1cea3a7d1d88068d87701214dc34b97e621e4148 Mon Sep 17 00:00:00 2001 From: aerworker Date: Sun, 16 Jun 2019 23:38:10 +0300 Subject: [PATCH 1/6] [yandexmusic] extract tracks from all volumes of an album (closes #21420) --- youtube_dl/extractor/yandexmusic.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/youtube_dl/extractor/yandexmusic.py b/youtube_dl/extractor/yandexmusic.py index 1dfee59e9..995c701dd 100644 --- a/youtube_dl/extractor/yandexmusic.py +++ b/youtube_dl/extractor/yandexmusic.py @@ -152,7 +152,7 @@ class YandexMusicAlbumIE(YandexMusicPlaylistBaseIE): IE_DESC = 'Яндекс.Музыка - Альбом' _VALID_URL = r'https?://music\.yandex\.(?:ru|kz|ua|by)/album/(?P\d+)/?(\?|$)' - _TEST = { + _TESTS = [{ 'url': 'http://music.yandex.ru/album/540508', 'info_dict': { 'id': '540508', @@ -160,7 +160,15 @@ class YandexMusicAlbumIE(YandexMusicPlaylistBaseIE): }, 'playlist_count': 50, 'skip': 'Travis CI servers blocked by YandexMusic', - } + }, { + 'url': 'https://music.yandex.ru/album/3840501', + 'info_dict': { + 'id': '3840501', + 'title': 'Hooverphonic - The Best of Hooverphonic (2016)', + }, + 'playlist_count': 33, + 'skip': 'Travis CI servers blocked by YandexMusic', + }] def _real_extract(self, url): album_id = self._match_id(url) @@ -169,7 +177,7 @@ class YandexMusicAlbumIE(YandexMusicPlaylistBaseIE): 'http://music.yandex.ru/handlers/album.jsx?album=%s' % album_id, album_id, 'Downloading album JSON') - entries = self._build_playlist(album['volumes'][0]) + entries = self._build_playlist([track for volume in album['volumes'] for track in volume]) title = '%s - %s' % (album['artists'][0]['name'], album['title']) year = album.get('year') From 6192e3403310b49c750cb86a698eef16983947a4 Mon Sep 17 00:00:00 2001 From: aerworker Date: Wed, 19 Jun 2019 22:35:37 +0300 Subject: [PATCH 2/6] [yandexmusic] extract genre, disk_number and track_number --- youtube_dl/extractor/yandexmusic.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/yandexmusic.py b/youtube_dl/extractor/yandexmusic.py index 995c701dd..65dd134b6 100644 --- a/youtube_dl/extractor/yandexmusic.py +++ b/youtube_dl/extractor/yandexmusic.py @@ -51,7 +51,7 @@ class YandexMusicTrackIE(YandexMusicBaseIE): IE_DESC = 'Яндекс.Музыка - Трек' _VALID_URL = r'https?://music\.yandex\.(?:ru|kz|ua|by)/album/(?P\d+)/track/(?P\d+)' - _TEST = { + _TESTS = [{ 'url': 'http://music.yandex.ru/album/540508/track/4878838', 'md5': 'f496818aa2f60b6c0062980d2e00dc20', 'info_dict': { @@ -67,7 +67,26 @@ class YandexMusicTrackIE(YandexMusicBaseIE): 'release_year': 2009, }, 'skip': 'Travis CI servers blocked by YandexMusic', - } + }, { + 'url': 'http://music.yandex.ru/album/3840501/track/705105', + 'md5': 'ebe7b4e2ac7ac03fe11c19727ca6153e', + 'info_dict': { + 'id': '705105', + 'ext': 'mp3', + 'title': 'Hooverphonic - Sometimes', + 'filesize': 5743386, + 'duration': 239.27, + 'track': 'Sometimes', + 'album': 'The Best of Hooverphonic', + 'album_artist': 'Hooverphonic', + 'artist': 'Hooverphonic', + 'release_year': 2016, + 'genre': 'pop', + 'disc_number': 2, + 'track_number': 9, + }, + 'skip': 'Travis CI servers blocked by YandexMusic', + }] def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) @@ -121,10 +140,16 @@ class YandexMusicTrackIE(YandexMusicBaseIE): album = albums[0] if isinstance(album, dict): year = album.get('year') + track_position = album.get('trackPosition') or {} + disc_number = track_position.get('volume') + track_number = track_position.get('index') track_info.update({ 'album': album.get('title'), 'album_artist': extract_artist(album.get('artists')), 'release_year': int_or_none(year), + 'genre': album.get('genre'), + 'disc_number': int_or_none(disc_number), + 'track_number': int_or_none(track_number), }) track_artist = extract_artist(track.get('artists')) From 69d2fd73dee44b2f8ad6511729d0037a2abe0dc8 Mon Sep 17 00:00:00 2001 From: aerworker Date: Wed, 19 Jun 2019 23:00:47 +0300 Subject: [PATCH 3/6] [yandexmusic] extract decomposed artist names --- youtube_dl/extractor/yandexmusic.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/yandexmusic.py b/youtube_dl/extractor/yandexmusic.py index 65dd134b6..b03fb6a3e 100644 --- a/youtube_dl/extractor/yandexmusic.py +++ b/youtube_dl/extractor/yandexmusic.py @@ -5,7 +5,10 @@ import re import hashlib from .common import InfoExtractor -from ..compat import compat_str +from ..compat import ( + compat_str, + compat_basestring, +) from ..utils import ( ExtractorError, int_or_none, @@ -57,13 +60,13 @@ class YandexMusicTrackIE(YandexMusicBaseIE): 'info_dict': { 'id': '4878838', 'ext': 'mp3', - 'title': 'Carlo Ambrosio, Carlo Ambrosio & Fabio Di Bari - Gypsy Eyes 1', + 'title': 'Carlo Ambrosio & Fabio Di Bari - Gypsy Eyes 1', 'filesize': 4628061, 'duration': 193.04, 'track': 'Gypsy Eyes 1', 'album': 'Gypsy Soul', 'album_artist': 'Carlo Ambrosio', - 'artist': 'Carlo Ambrosio, Carlo Ambrosio & Fabio Di Bari', + 'artist': 'Carlo Ambrosio & Fabio Di Bari', 'release_year': 2009, }, 'skip': 'Travis CI servers blocked by YandexMusic', @@ -129,9 +132,21 @@ class YandexMusicTrackIE(YandexMusicBaseIE): 'abr': int_or_none(download_data.get('bitrate')), } + def extract_artist_name(artist): + decomposed = artist.get('decomposed') + if not isinstance(decomposed, list): + return artist['name'] + parts = [artist['name']] + for element in decomposed: + if isinstance(element, dict) and element.get('name'): + parts.append(element['name']) + elif isinstance(element, compat_basestring): + parts.append(element) + return ''.join(parts) + def extract_artist(artist_list): if artist_list and isinstance(artist_list, list): - artists_names = [a['name'] for a in artist_list if a.get('name')] + artists_names = [extract_artist_name(a) for a in artist_list if a.get('name')] if artists_names: return ', '.join(artists_names) From e8a7f124d9ff8cb108ab068b99efa031783f3d35 Mon Sep 17 00:00:00 2001 From: Sergey M Date: Sun, 14 Jul 2019 02:32:05 +0700 Subject: [PATCH 4/6] Update yandexmusic.py --- youtube_dl/extractor/yandexmusic.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/youtube_dl/extractor/yandexmusic.py b/youtube_dl/extractor/yandexmusic.py index b03fb6a3e..3b2a55b32 100644 --- a/youtube_dl/extractor/yandexmusic.py +++ b/youtube_dl/extractor/yandexmusic.py @@ -5,10 +5,7 @@ import re import hashlib from .common import InfoExtractor -from ..compat import ( - compat_str, - compat_basestring, -) +from ..compat import compat_str from ..utils import ( ExtractorError, int_or_none, @@ -140,7 +137,7 @@ class YandexMusicTrackIE(YandexMusicBaseIE): for element in decomposed: if isinstance(element, dict) and element.get('name'): parts.append(element['name']) - elif isinstance(element, compat_basestring): + elif isinstance(element, compat_str): parts.append(element) return ''.join(parts) From 920ce0af79ebe7eff523fbdf1c2ed95b3ee8b604 Mon Sep 17 00:00:00 2001 From: Sergey M Date: Sun, 14 Jul 2019 02:32:53 +0700 Subject: [PATCH 5/6] Update yandexmusic.py --- youtube_dl/extractor/yandexmusic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/youtube_dl/extractor/yandexmusic.py b/youtube_dl/extractor/yandexmusic.py index 3b2a55b32..c8c5ba222 100644 --- a/youtube_dl/extractor/yandexmusic.py +++ b/youtube_dl/extractor/yandexmusic.py @@ -68,6 +68,7 @@ class YandexMusicTrackIE(YandexMusicBaseIE): }, 'skip': 'Travis CI servers blocked by YandexMusic', }, { + # multiple disks 'url': 'http://music.yandex.ru/album/3840501/track/705105', 'md5': 'ebe7b4e2ac7ac03fe11c19727ca6153e', 'info_dict': { From 318ed50faeda86ddc455f29aeb0f19ddd01748a5 Mon Sep 17 00:00:00 2001 From: Sergey M Date: Sun, 14 Jul 2019 02:36:08 +0700 Subject: [PATCH 6/6] Update yandexmusic.py --- youtube_dl/extractor/yandexmusic.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/youtube_dl/extractor/yandexmusic.py b/youtube_dl/extractor/yandexmusic.py index c8c5ba222..fea817419 100644 --- a/youtube_dl/extractor/yandexmusic.py +++ b/youtube_dl/extractor/yandexmusic.py @@ -153,16 +153,17 @@ class YandexMusicTrackIE(YandexMusicBaseIE): album = albums[0] if isinstance(album, dict): year = album.get('year') - track_position = album.get('trackPosition') or {} - disc_number = track_position.get('volume') - track_number = track_position.get('index') + disc_number = int_or_none(try_get( + album, lambda x: x['trackPosition']['volume'])) + track_number = int_or_none(try_get( + album, lambda x: x['trackPosition']['index'])) track_info.update({ 'album': album.get('title'), 'album_artist': extract_artist(album.get('artists')), 'release_year': int_or_none(year), 'genre': album.get('genre'), - 'disc_number': int_or_none(disc_number), - 'track_number': int_or_none(track_number), + 'disc_number': disc_number, + 'track_number': track_number, }) track_artist = extract_artist(track.get('artists'))