[refactor] Single quotes consistency
[youtube-dl] / youtube_dl / extractor / thesixtyone.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4 from .common import InfoExtractor
5 from ..utils import unified_strdate
6
7
8 class TheSixtyOneIE(InfoExtractor):
9     _VALID_URL = r'''(?x)https?://(?:www\.)?thesixtyone\.com/
10         (?:.*?/)*
11         (?:
12             s|
13             song/comments/list|
14             song
15         )/(?P<id>[A-Za-z0-9]+)/?$'''
16     _SONG_URL_TEMPLATE = 'http://thesixtyone.com/s/{0:}'
17     _SONG_FILE_URL_TEMPLATE = 'http://{audio_server:}/thesixtyone_production/audio/{0:}_stream'
18     _THUMBNAIL_URL_TEMPLATE = '{photo_base_url:}_desktop'
19     _TESTS = [
20         {
21             'url': 'http://www.thesixtyone.com/s/SrE3zD7s1jt/',
22             'md5': '821cc43b0530d3222e3e2b70bb4622ea',
23             'info_dict': {
24                 'id': 'SrE3zD7s1jt',
25                 'ext': 'mp3',
26                 'title': 'CASIO - Unicorn War Mixtape',
27                 'thumbnail': 're:^https?://.*_desktop$',
28                 'upload_date': '20071217',
29                 'duration': 3208,
30             }
31         },
32         {
33             'url': 'http://www.thesixtyone.com/song/comments/list/SrE3zD7s1jt',
34             'only_matching': True,
35         },
36         {
37             'url': 'http://www.thesixtyone.com/s/ULoiyjuJWli#/s/SrE3zD7s1jt/',
38             'only_matching': True,
39         },
40         {
41             'url': 'http://www.thesixtyone.com/#/s/SrE3zD7s1jt/',
42             'only_matching': True,
43         },
44         {
45             'url': 'http://www.thesixtyone.com/song/SrE3zD7s1jt/',
46             'only_matching': True,
47         },
48     ]
49
50     _DECODE_MAP = {
51         'x': 'a',
52         'm': 'b',
53         'w': 'c',
54         'q': 'd',
55         'n': 'e',
56         'p': 'f',
57         'a': '0',
58         'h': '1',
59         'e': '2',
60         'u': '3',
61         's': '4',
62         'i': '5',
63         'o': '6',
64         'y': '7',
65         'r': '8',
66         'c': '9'
67     }
68
69     def _real_extract(self, url):
70         song_id = self._match_id(url)
71
72         webpage = self._download_webpage(
73             self._SONG_URL_TEMPLATE.format(song_id), song_id)
74
75         song_data = self._parse_json(self._search_regex(
76             r'"%s":\s(\{.*?\})' % song_id, webpage, 'song_data'), song_id)
77
78         if self._search_regex(r'(t61\.s3_audio_load\s*=\s*1\.0;)', webpage, 's3_audio_load marker', default=None):
79             song_data['audio_server'] = 's3.amazonaws.com'
80         else:
81             song_data['audio_server'] = song_data['audio_server'] + '.thesixtyone.com'
82
83         keys = [self._DECODE_MAP.get(s, s) for s in song_data['key']]
84         url = self._SONG_FILE_URL_TEMPLATE.format(
85             "".join(reversed(keys)), **song_data)
86
87         formats = [{
88             'format_id': 'sd',
89             'url': url,
90             'ext': 'mp3',
91         }]
92
93         return {
94             'id': song_id,
95             'title': '{artist:} - {name:}'.format(**song_data),
96             'formats': formats,
97             'comment_count': song_data.get('comments_count'),
98             'duration': song_data.get('play_time'),
99             'like_count': song_data.get('score'),
100             'thumbnail': self._THUMBNAIL_URL_TEMPLATE.format(**song_data),
101             'upload_date': unified_strdate(song_data.get('publish_date')),
102         }