From 4c6039385466e4be3a0e20459e75886052653de7 Mon Sep 17 00:00:00 2001
From: Mamay Alexander <alexander@mamay.su>
Date: Mon, 9 Mar 2015 19:06:49 +0600
Subject: [PATCH] [YandexMusic] Add new extractor

---
 youtube_dl/extractor/__init__.py |   5 ++
 youtube_dl/extractor/yamusic.py  | 104 +++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+)
 create mode 100644 youtube_dl/extractor/yamusic.py

diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py
index 14172ca56..2db938516 100644
--- a/youtube_dl/extractor/__init__.py
+++ b/youtube_dl/extractor/__init__.py
@@ -611,6 +611,11 @@ from .yahoo import (
     YahooSearchIE,
 )
 from .yam import YamIE
+from .yamusic import (
+    YandexMusicTrackIE,
+    YandexMusicAlbumIE,
+    YandexMusicPlaylistIE,
+)
 from .yesjapan import YesJapanIE
 from .ynet import YnetIE
 from .youjizz import YouJizzIE
diff --git a/youtube_dl/extractor/yamusic.py b/youtube_dl/extractor/yamusic.py
new file mode 100644
index 000000000..5af6df89d
--- /dev/null
+++ b/youtube_dl/extractor/yamusic.py
@@ -0,0 +1,104 @@
+# coding=utf-8
+from __future__ import unicode_literals
+
+import re
+import hashlib
+import time
+
+from .common import InfoExtractor
+
+class YandexMusicAlbumIE(InfoExtractor):
+    _VALID_URL = r'http://music.yandex.ru/album/(?P<id>\d+)'
+
+    def _get_track_url(self, storage_dir, track_id):
+        data = self._download_json('http://music.yandex.ru/api/v1.5/handlers/api-jsonp.jsx?requestId=2&nc=%d&action=getTrackSrc&p=download-info/%s/2.mp3' % (time.time(), storage_dir), track_id)
+
+        hsh = hashlib.md5()
+        hsh.update('XGRlBW9FXlekgbPrRHuSiA' + data['path'][1:] + data['s'])
+        hash = hsh.hexdigest()
+        storage = storage_dir.split('.')
+
+        return 'http://%s/get-mp3/%s/%s?track-id=%s&from=service-10-track&similarities-experiment=default' % (data['host'], hash, data['ts'] + data['path'], storage[1])
+
+    def _get_album_id_and_data(self, url):
+        matched = re.match(self._VALID_URL, url)
+        id = matched.group('id')
+
+        webpage = self._download_webpage(url, id)
+        data = self._parse_json(
+            self._search_regex(
+                r'var\s+Mu\s+=\s+(.+?);\s+<\/script>', webpage, 'player'),
+            id)
+        return id, data['pageData']
+
+    def _real_extract(self, url):
+
+        id, data = self._get_album_id_and_data(url)
+
+        entries = []
+
+        for track in data['volumes'][0]:
+            entries.append({
+                'id': track['id'],
+                'ext': 'mp3',
+                'url': self._get_track_url(track['storageDir'], track['id']),
+                'title': track['artists'][0]['name'] + ' - ' + track['title'],
+            })
+
+        return {
+            '_type': 'playlist',
+            'entries': entries,
+            'id': id,
+            'title': data['title'],
+        }
+
+class YandexMusicPlaylistIE(YandexMusicAlbumIE):
+    _VALID_URL = r'http://music.yandex.ru/users/(?P<user_name>[^/]+)/playlists/(?P<id>\d+)'
+
+    def _real_extract(self, url):
+        id, data = self._get_album_id_and_data(url)
+        data = data['playlist']
+
+        entries = []
+
+        for track in data['tracks']:
+            entries.append({
+                'id': track['id'],
+                'ext': 'mp3',
+                'url': self._get_track_url(track['storageDir'], track['id']),
+                'title': track['artists'][0]['name'] + ' - ' + track['title'],
+            })
+
+        return {
+            '_type': 'playlist',
+            'entries': entries,
+            'id': id,
+            'title': data['title'],
+        }
+
+class YandexMusicTrackIE(YandexMusicAlbumIE):
+    _VALID_URL = r'http://music.yandex.ru/album/(?P<album_id>\d+)/track/(?P<id>\d+)'
+    _TEST = {
+        'url': 'http://music.yandex.ru/album/540508/track/4878838',
+        'info_dict': {
+            'id': '4878838',
+            'ext': 'mp3',
+            'title': 'Carlo Ambrosio - Gypsy Eyes 1',
+        }
+    }
+
+    def _real_extract(self, url):
+
+        id, data = self._get_album_id_and_data(url)
+
+        for track in data['volumes'][0]:
+            if track['id'] == id:
+                track_url = self._get_track_url(track['storageDir'], id)
+                break
+
+        return {
+            'id': id,
+            'ext': 'mp3',
+            'url': track_url,
+            'title': track['artists'][0]['name'] + ' - ' + track['title'],
+        }