diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index 3da5f8020..97c2e4783 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -1317,6 +1317,7 @@ from .toggle import ( ) from .tonline import TOnlineIE from .toongoggles import ToonGogglesIE +from .torrins import TorrinsIE from .toutv import TouTvIE from .toypics import ToypicsUserIE, ToypicsIE from .traileraddict import TrailerAddictIE diff --git a/youtube_dl/extractor/torrins.py b/youtube_dl/extractor/torrins.py new file mode 100644 index 000000000..77a8584b2 --- /dev/null +++ b/youtube_dl/extractor/torrins.py @@ -0,0 +1,112 @@ +from __future__ import unicode_literals + +import re + +from .common import InfoExtractor + +from ..utils import ( + ExtractorError, + urlencode_postdata, +) + + +class TorrinsIE(InfoExtractor): + IE_NAME = 'torrins' + _VALID_URL = r'''(?x) + https?:// + www\.torrins\.com/(?:guitar|piano|bass)-lessons/(?:song-lessons|style-genre)/[^/]+/(?P[^/]+)/[^\.]+\.html + ''' + _LOGIN_URL = 'https://www.torrins.com/services/user/sign-in' + _ORIGIN_URL = 'https://www.torrins.com' + _NETRC_MACHINE = 'torrins' + + _TEST = { + 'url': 'https://www.torrins.com/guitar-lessons/song-lessons/english-songs/another-brick-in-the-wall/song-demo.html', + 'info_dict': { + 'id': 'another-brick-in-the-wall', + 'ext': 'mp4', + 'title': 'Another Brick in the Wall Guitar - Song Demo', + 'description': 'md5:c0d51f6f21ef4ec65f091055a5eef876', + 'duration': 579.29, + }, + 'skip': 'Requires torrins premium account credentials', + } + + def _handle_error(self, response): + if not isinstance(response, dict): + return + error = response['error'] + if error: + error_str = 'Torrins returned error #%s: %s' % (error['code'], error.get['message']) + error_data = error['data'] + if error_data: + error_str += ' - %s' % error_data['formErrors'] + raise ExtractorError(error_str, expected=True) + + def _real_initialize(self): + self._login() + + def _login(self): + (username, password) = self._get_login_info() + if username is None: + return + + def is_logged(reason): + webpage = self._download_webpage(self._ORIGIN_URL, None, reason) + + return any(re.search(p, webpage) for p in ( + r'id=["\'](?:bt-logout)', + r'>Logout<')) + + # already logged in + if is_logged('Checking if already logged in'): + return + + login_form = { + 'email': username, + 'password': password, + } + + response = self._download_webpage( + self._LOGIN_URL, None, 'Logging in', + data=urlencode_postdata(login_form), + headers={ + 'Referer': self._ORIGIN_URL, + 'Origin': self._ORIGIN_URL, + }) + + if not is_logged('Post login check'): + error = self._html_search_regex( + r'(?s)]+class="form-errors[^"]*">(.+?)', + response, 'error message', default=None) + if error: + raise ExtractorError('Unable to login: %s' % error, expected=True) + raise ExtractorError('Unable to log in') + + def _real_extract(self, url): + course_id = self._match_id(url) + + webpage = self._download_webpage(url, course_id) + + video_json = self._html_search_regex(r"