]>
Commit | Line | Data |
---|---|---|
1cdedfee | 1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
81028ff9 PH |
4 | import re |
5 | ||
1cdedfee | 6 | from .common import InfoExtractor |
be64b5b0 PH |
7 | from ..compat import ( |
8 | compat_chr, | |
9 | compat_ord, | |
10 | ) | |
11 | from ..utils import ( | |
12 | int_or_none, | |
13 | parse_filesize, | |
14 | ) | |
1cdedfee | 15 | |
16 | ||
17 | class XMinusIE(InfoExtractor): | |
18 | _VALID_URL = r'https?://(?:www\.)?x-minus\.org/track/(?P<id>[0-9]+)' | |
19 | _TEST = { | |
20 | 'url': 'http://x-minus.org/track/4542/%D0%BF%D0%B5%D1%81%D0%B5%D0%BD%D0%BA%D0%B0-%D1%88%D0%BE%D1%84%D0%B5%D1%80%D0%B0.html', | |
21 | 'md5': '401a15f2d2dcf6d592cb95528d72a2a8', | |
22 | 'info_dict': { | |
23 | 'id': '4542', | |
24 | 'ext': 'mp3', | |
25 | 'title': 'Леонид Агутин-Песенка шофера', | |
26 | 'duration': 156, | |
be64b5b0 PH |
27 | 'tbr': 320, |
28 | 'filesize_approx': 5900000, | |
29 | 'view_count': int, | |
81028ff9 | 30 | 'description': 'md5:03238c5b663810bc79cf42ef3c03e371', |
1cdedfee | 31 | } |
32 | } | |
33 | ||
34 | def _real_extract(self, url): | |
35 | video_id = self._match_id(url) | |
1cdedfee | 36 | webpage = self._download_webpage(url, video_id) |
be64b5b0 | 37 | |
1cdedfee | 38 | artist = self._html_search_regex( |
be64b5b0 | 39 | r'minus_track\.artist="(.+?)"', webpage, 'artist') |
1cdedfee | 40 | title = artist + '-' + self._html_search_regex( |
be64b5b0 | 41 | r'minus_track\.title="(.+?)"', webpage, 'title') |
1cdedfee | 42 | duration = int_or_none(self._html_search_regex( |
be64b5b0 PH |
43 | r'minus_track\.dur_sec=\'([0-9]*?)\'', |
44 | webpage, 'duration', fatal=False)) | |
45 | filesize_approx = parse_filesize(self._html_search_regex( | |
5bdc520c | 46 | r'<div id="finfo"[^>]*>\s*↓\s*([0-9.]+\s*[a-zA-Z][bB])', |
be64b5b0 PH |
47 | webpage, 'approximate filesize', fatal=False)) |
48 | tbr = int_or_none(self._html_search_regex( | |
49 | r'<div class="quality[^"]*"></div>\s*([0-9]+)\s*kbps', | |
50 | webpage, 'bitrate', fatal=False)) | |
51 | view_count = int_or_none(self._html_search_regex( | |
52 | r'<div class="quality.*?► ([0-9]+)', | |
53 | webpage, 'view count', fatal=False)) | |
81028ff9 PH |
54 | description = self._html_search_regex( |
55 | r'(?s)<div id="song_texts">(.*?)</div><br', | |
56 | webpage, 'song lyrics', fatal=False) | |
57 | if description: | |
58 | description = re.sub(' *\r *', '\n', description) | |
be64b5b0 | 59 | |
1cdedfee | 60 | enc_token = self._html_search_regex( |
5bdc520c | 61 | r'minus_track\.s?tkn="(.+?)"', webpage, 'enc_token') |
be64b5b0 PH |
62 | token = ''.join( |
63 | c if pos == 3 else compat_chr(compat_ord(c) - 1) | |
64 | for pos, c in enumerate(reversed(enc_token))) | |
65 | video_url = 'http://x-minus.org/dwlf/%s/%s.mp3' % (video_id, token) | |
1cdedfee | 66 | |
67 | return { | |
68 | 'id': video_id, | |
69 | 'title': title, | |
be64b5b0 | 70 | 'url': video_url, |
1cdedfee | 71 | 'duration': duration, |
be64b5b0 PH |
72 | 'filesize_approx': filesize_approx, |
73 | 'tbr': tbr, | |
74 | 'view_count': view_count, | |
81028ff9 | 75 | 'description': description, |
1cdedfee | 76 | } |