| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  | # coding: utf-8 | 
					
						
							|  |  |  | from __future__ import unicode_literals | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  | import json | 
					
						
							|  |  |  | import random | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from .common import InfoExtractor | 
					
						
							| 
									
										
										
										
											2014-12-13 12:24:42 +01:00
										 |  |  | from ..compat import ( | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |     compat_str, | 
					
						
							| 
									
										
										
										
											2015-01-10 05:51:07 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | from ..utils import ( | 
					
						
							| 
									
										
										
										
											2014-10-15 06:46:47 +03:00
										 |  |  |     ExtractorError, | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class EightTracksIE(InfoExtractor): | 
					
						
							|  |  |  |     IE_NAME = '8tracks' | 
					
						
							| 
									
										
										
										
											2013-12-04 20:34:47 +07:00
										 |  |  |     _VALID_URL = r'https?://8tracks\.com/(?P<user>[^/]+)/(?P<id>[^/#]+)(?:#.*)?$' | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |     _TEST = { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |         "name": "EightTracks", | 
					
						
							|  |  |  |         "url": "http://8tracks.com/ytdl/youtube-dl-test-tracks-a", | 
					
						
							|  |  |  |         "info_dict": { | 
					
						
							|  |  |  |             'id': '1336550', | 
					
						
							|  |  |  |             'display_id': 'youtube-dl-test-tracks-a', | 
					
						
							|  |  |  |             "description": "test chars:  \"'/\\ä↭", | 
					
						
							|  |  |  |             "title": "youtube-dl test tracks \"'/\\ä↭<>", | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         "playlist": [ | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "96ce57f24389fc8734ce47f4c1abcc55", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885610", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "youtue-dl project<>\"' - youtube-dl test track 1 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "4ab26f05c1f7291ea460a3920be8021f", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885608", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "youtube-dl project - youtube-dl test track 2 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "d30b5b5f74217410f4689605c35d1fd7", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885679", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "youtube-dl project as well - youtube-dl test track 3 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "4eb0a669317cd725f6bbd336a29f923a", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885680", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "youtube-dl project as well - youtube-dl test track 4 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "1893e872e263a2705558d1d319ad19e8", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885682", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "PH - youtube-dl test track 5 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "b673c46f47a216ab1741ae8836af5899", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885683", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "PH - youtube-dl test track 6 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "1d74534e95df54986da7f5abf7d842b7", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885684", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "phihag - youtube-dl test track 7 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 "md5": "f081f47af8f6ae782ed131d38b9cd1c0", | 
					
						
							|  |  |  |                 "info_dict": { | 
					
						
							|  |  |  |                     "id": "11885685", | 
					
						
							|  |  |  |                     "ext": "m4a", | 
					
						
							|  |  |  |                     "title": "phihag - youtube-dl test track 8 \"'/\\\u00e4\u21ad", | 
					
						
							|  |  |  |                     "uploader_id": "ytdl" | 
					
						
							| 
									
										
										
										
											2013-06-27 20:22:00 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  |     def _real_extract(self, url): | 
					
						
							| 
									
										
										
										
											2015-03-14 15:55:21 +06:00
										 |  |  |         playlist_id = self._match_id(url) | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         webpage = self._download_webpage(url, playlist_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-14 15:54:23 +06:00
										 |  |  |         data = self._parse_json( | 
					
						
							|  |  |  |             self._search_regex( | 
					
						
							|  |  |  |                 r"(?s)PAGE\.mix\s*=\s*({.+?});\n", webpage, 'trax information'), | 
					
						
							|  |  |  |             playlist_id) | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         session = str(random.randint(0, 1000000000)) | 
					
						
							|  |  |  |         mix_id = data['id'] | 
					
						
							|  |  |  |         track_count = data['tracks_count'] | 
					
						
							| 
									
										
										
										
											2014-10-15 06:46:47 +03:00
										 |  |  |         duration = data['duration'] | 
					
						
							| 
									
										
										
										
											2015-01-10 05:51:07 +01:00
										 |  |  |         avg_song_duration = float(duration) / track_count | 
					
						
							| 
									
										
										
										
											2015-03-14 15:52:06 +06:00
										 |  |  |         # duration is sometimes negative, use predefined avg duration | 
					
						
							|  |  |  |         if avg_song_duration <= 0: | 
					
						
							|  |  |  |             avg_song_duration = 300 | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  |         first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id) | 
					
						
							|  |  |  |         next_url = first_url | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |         entries = [] | 
					
						
							| 
									
										
										
										
											2014-10-15 06:46:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[8tracks] Use track count instead of looking at at_last_track property
This fixes the error:
$ youtube-dl http://8tracks.com/vladmc/counting-stars
[8tracks] counting-stars: Downloading webpage
[8tracks] counting-stars: Downloading song information 1/4
[8tracks] counting-stars: Downloading song information 2/4
[8tracks] counting-stars: Downloading song information 3/4
[8tracks] counting-stars: Downloading song information 4/4
[8tracks] counting-stars: Downloading song information 5/4
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/phihag/projects/youtube-dl/youtube_dl/__main__.py", line 18, in <module>
    youtube_dl.main()
  File "/home/phihag/projects/youtube-dl/youtube_dl/__init__.py", line 761, in main
    _real_main(argv)
  File "/home/phihag/projects/youtube-dl/youtube_dl/__init__.py", line 714, in _real_main
    retcode = ydl.download(all_urls)
  File "/home/phihag/projects/youtube-dl/youtube_dl/YoutubeDL.py", line 701, in download
    videos = self.extract_info(url)
  File "/home/phihag/projects/youtube-dl/youtube_dl/YoutubeDL.py", line 342, in extract_info
    ie_result = ie.extract(url)
  File "/home/phihag/projects/youtube-dl/youtube_dl/extractor/common.py", line 121, in extract
    return self._real_extract(url)
  File "/home/phihag/projects/youtube-dl/youtube_dl/extractor/eighttracks.py", line 111, in _real_extract
    'id': track_data['id'],
KeyError: 'id'
											
										 
											2013-10-25 23:46:18 +02:00
										 |  |  |         for i in range(track_count): | 
					
						
							| 
									
										
										
										
											2014-10-15 06:46:47 +03:00
										 |  |  |             api_json = None | 
					
						
							|  |  |  |             download_tries = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             while api_json is None: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     api_json = self._download_webpage( | 
					
						
							|  |  |  |                         next_url, playlist_id, | 
					
						
							|  |  |  |                         note='Downloading song information %d/%d' % (i + 1, track_count), | 
					
						
							|  |  |  |                         errnote='Failed to download song information') | 
					
						
							|  |  |  |                 except ExtractorError: | 
					
						
							|  |  |  |                     if download_tries > 3: | 
					
						
							|  |  |  |                         raise | 
					
						
							|  |  |  |                     else: | 
					
						
							| 
									
										
										
										
											2014-12-06 09:20:35 +02:00
										 |  |  |                         download_tries += 1 | 
					
						
							| 
									
										
										
										
											2015-01-10 05:51:07 +01:00
										 |  |  |                         self._sleep(avg_song_duration, playlist_id) | 
					
						
							| 
									
										
										
										
											2014-10-15 06:46:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  |             api_data = json.loads(api_json) | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |             track_data = api_data['set']['track'] | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  |             info = { | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |                 'id': compat_str(track_data['id']), | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  |                 'url': track_data['track_file_stream_url'], | 
					
						
							| 
									
										
										
										
											2014-11-26 13:06:02 +01:00
										 |  |  |                 'title': track_data['performer'] + ' - ' + track_data['name'], | 
					
						
							| 
									
										
										
										
											2013-06-23 22:15:50 +02:00
										 |  |  |                 'raw_title': track_data['name'], | 
					
						
							|  |  |  |                 'uploader_id': data['user']['login'], | 
					
						
							|  |  |  |                 'ext': 'm4a', | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |             entries.append(info) | 
					
						
							| 
									
										
										
										
											2014-10-15 06:46:47 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-26 11:31:23 +02:00
										 |  |  |             next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % ( | 
					
						
							|  |  |  |                 session, mix_id, track_data['id']) | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             '_type': 'playlist', | 
					
						
							|  |  |  |             'entries': entries, | 
					
						
							|  |  |  |             'id': compat_str(mix_id), | 
					
						
							|  |  |  |             'display_id': playlist_id, | 
					
						
							|  |  |  |             'title': data.get('name'), | 
					
						
							|  |  |  |             'description': data.get('description'), | 
					
						
							|  |  |  |         } |