|
@ -109,7 +109,7 @@ class BandcampIE(InfoExtractor): |
|
|
|
|
|
|
|
|
class BandcampAlbumIE(InfoExtractor): |
|
|
class BandcampAlbumIE(InfoExtractor): |
|
|
IE_NAME = 'Bandcamp:album' |
|
|
IE_NAME = 'Bandcamp:album' |
|
|
_VALID_URL = r'https?://(?:(?P<subdomain>[^.]+)\.)?bandcamp\.com(?:/album/(?P<title>[^?#]+)|/?(?:$|[?#]))' |
|
|
_VALID_URL = r'https?://(?:(?P<subdomain>[^.]+)\.)?bandcamp\.com(?:/album/(?P<album_id>[^?#]+)|/?(?:$|[?#]))' |
|
|
|
|
|
|
|
|
_TESTS = [{ |
|
|
_TESTS = [{ |
|
|
'url': 'http://blazo.bandcamp.com/album/jazz-format-mixtape-vol-1', |
|
|
'url': 'http://blazo.bandcamp.com/album/jazz-format-mixtape-vol-1', |
|
@ -133,31 +133,37 @@ class BandcampAlbumIE(InfoExtractor): |
|
|
], |
|
|
], |
|
|
'info_dict': { |
|
|
'info_dict': { |
|
|
'title': 'Jazz Format Mixtape vol.1', |
|
|
'title': 'Jazz Format Mixtape vol.1', |
|
|
|
|
|
'id': 'jazz-format-mixtape-vol-1', |
|
|
|
|
|
'uploader_id': 'blazo', |
|
|
}, |
|
|
}, |
|
|
'params': { |
|
|
'params': { |
|
|
'playlistend': 2 |
|
|
'playlistend': 2 |
|
|
}, |
|
|
}, |
|
|
'skip': 'Bandcamp imposes download limits. See test_playlists:test_bandcamp_album for the playlist test' |
|
|
'skip': 'Bandcamp imposes download limits.' |
|
|
}, { |
|
|
}, { |
|
|
'url': 'http://nightbringer.bandcamp.com/album/hierophany-of-the-open-grave', |
|
|
'url': 'http://nightbringer.bandcamp.com/album/hierophany-of-the-open-grave', |
|
|
'info_dict': { |
|
|
'info_dict': { |
|
|
'title': 'Hierophany of the Open Grave', |
|
|
'title': 'Hierophany of the Open Grave', |
|
|
|
|
|
'uploader_id': 'nightbringer', |
|
|
|
|
|
'id': 'hierophany-of-the-open-grave', |
|
|
}, |
|
|
}, |
|
|
'playlist_mincount': 9, |
|
|
'playlist_mincount': 9, |
|
|
}, { |
|
|
}, { |
|
|
'url': 'http://dotscale.bandcamp.com', |
|
|
'url': 'http://dotscale.bandcamp.com', |
|
|
'info_dict': { |
|
|
'info_dict': { |
|
|
'title': 'Loom', |
|
|
'title': 'Loom', |
|
|
|
|
|
'id': 'dotscale', |
|
|
|
|
|
'uploader_id': 'dotscale', |
|
|
}, |
|
|
}, |
|
|
'playlist_mincount': 7, |
|
|
'playlist_mincount': 7, |
|
|
}] |
|
|
}] |
|
|
|
|
|
|
|
|
def _real_extract(self, url): |
|
|
def _real_extract(self, url): |
|
|
mobj = re.match(self._VALID_URL, url) |
|
|
mobj = re.match(self._VALID_URL, url) |
|
|
playlist_id = mobj.group('subdomain') |
|
|
uploader_id = mobj.group('subdomain') |
|
|
title = mobj.group('title') |
|
|
album_id = mobj.group('album_id') |
|
|
display_id = title or playlist_id |
|
|
playlist_id = album_id or uploader_id |
|
|
webpage = self._download_webpage(url, display_id) |
|
|
webpage = self._download_webpage(url, playlist_id) |
|
|
tracks_paths = re.findall(r'<a href="(.*?)" itemprop="url">', webpage) |
|
|
tracks_paths = re.findall(r'<a href="(.*?)" itemprop="url">', webpage) |
|
|
if not tracks_paths: |
|
|
if not tracks_paths: |
|
|
raise ExtractorError('The page doesn\'t contain any tracks') |
|
|
raise ExtractorError('The page doesn\'t contain any tracks') |
|
@ -168,8 +174,8 @@ class BandcampAlbumIE(InfoExtractor): |
|
|
r'album_title\s*:\s*"(.*?)"', webpage, 'title', fatal=False) |
|
|
r'album_title\s*:\s*"(.*?)"', webpage, 'title', fatal=False) |
|
|
return { |
|
|
return { |
|
|
'_type': 'playlist', |
|
|
'_type': 'playlist', |
|
|
|
|
|
'uploader_id': uploader_id, |
|
|
'id': playlist_id, |
|
|
'id': playlist_id, |
|
|
'display_id': display_id, |
|
|
|
|
|
'title': title, |
|
|
'title': title, |
|
|
'entries': entries, |
|
|
'entries': entries, |
|
|
} |
|
|
} |
xxxxxxxxxx