From 58a8f8b05947a803a265bb62e20d297a63204483 Mon Sep 17 00:00:00 2001 From: Poschi Date: Fri, 18 Sep 2020 15:26:10 +0200 Subject: [PATCH 1/2] [extractor/gotostage] Add GoToStage extractor --- youtube_dl/extractor/extractors.py | 1 + youtube_dl/extractor/gotostage.py | 70 ++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 youtube_dl/extractor/gotostage.py diff --git a/youtube_dl/extractor/extractors.py b/youtube_dl/extractor/extractors.py index ae7079a6a..1102cf3d8 100644 --- a/youtube_dl/extractor/extractors.py +++ b/youtube_dl/extractor/extractors.py @@ -418,6 +418,7 @@ from .googledrive import GoogleDriveIE from .googleplus import GooglePlusIE from .googlesearch import GoogleSearchIE from .goshgay import GoshgayIE +from .gotostage import GoToStageIE from .gputechconf import GPUTechConfIE from .groupon import GrouponIE from .hbo import HBOIE diff --git a/youtube_dl/extractor/gotostage.py b/youtube_dl/extractor/gotostage.py new file mode 100644 index 000000000..53776c1e5 --- /dev/null +++ b/youtube_dl/extractor/gotostage.py @@ -0,0 +1,70 @@ +# coding: utf-8 +from __future__ import unicode_literals + +from .common import InfoExtractor + +import json + + +class GoToStageIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?gotostage\.com/channel/[a-z0-9]+/recording/(?P[a-z0-9]+)/watch' + _TESTS = [{ + 'url': 'https://www.gotostage.com/channel/8901680603948959494/recording/60bb55548d434f21b9ce4f0e225c4895/watch', + 'md5': 'ca72ce990cdcd7a2bd152f7217e319a2', + 'info_dict': { + 'id': '60bb55548d434f21b9ce4f0e225c4895', + 'ext': 'mp4', + 'title': 'What is GoToStage?', + 'thumbnail': r're:^https?://.*\.jpg$', + } + }, { + 'url': 'https://www.gotostage.com/channel/bacc3d3535b34bafacc3f4ef8d4df78a/recording/831e74cd3e0042be96defba627b6f676/watch?source=HOMEPAGE', + 'only_matching': True, + }] + + def _real_extract(self, url): + video_id = self._match_id(url) + metadata = self._download_json( + 'https://api.gotostage.com/contents?ids=%s' % video_id, + video_id, + note='Downloading video metadata', + errnote='Unable to download video metadata', + ) + + registration_data = { + 'product': metadata[0].get('product'), + 'resourceType': metadata[0].get('contentType'), + 'productReferenceKey': metadata[0].get('productRefKey'), + 'firstName': 'foo', + 'lastName': 'bar', + 'email': 'foobar@example.com' + } + + registration_response = self._download_json( + 'https://api-registrations.logmeininc.com/registrations', + video_id, + data=json.dumps(registration_data).encode(), + expected_status=409, + headers={'Content-Type': 'application/json'}, + note='Register user', + errnote='Unable to register user', + ) + + content_response = self._download_json( + 'https://api.gotostage.com/contents/%s/asset' % video_id, + video_id, + headers={'x-registrantkey': registration_response.get('registrationKey')}, + note='Get download url', + errnote='Unable to get download url', + ) + + return { + 'id': video_id, + 'title': metadata[0].get('title'), + 'url': content_response.get('cdnLocation'), + 'ext': 'mp4', + 'thumbnail': metadata[0].get('thumbnail').get('location'), + 'duration': metadata[0].get('duration'), + 'categories': [metadata[0].get('category')], + 'is_live': False + } From a7170b62443adf6cafa0d1408a92a7175b7742e3 Mon Sep 17 00:00:00 2001 From: Poschi Date: Sun, 20 Sep 2020 22:43:39 +0200 Subject: [PATCH 2/2] Fixed coding styles --- youtube_dl/extractor/gotostage.py | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/youtube_dl/extractor/gotostage.py b/youtube_dl/extractor/gotostage.py index 53776c1e5..1bc88fffb 100644 --- a/youtube_dl/extractor/gotostage.py +++ b/youtube_dl/extractor/gotostage.py @@ -2,6 +2,10 @@ from __future__ import unicode_literals from .common import InfoExtractor +from ..compat import compat_str +from ..utils import ( + url_or_none, + try_get) import json @@ -16,6 +20,7 @@ class GoToStageIE(InfoExtractor): 'ext': 'mp4', 'title': 'What is GoToStage?', 'thumbnail': r're:^https?://.*\.jpg$', + 'duration': 93.924711 } }, { 'url': 'https://www.gotostage.com/channel/bacc3d3535b34bafacc3f4ef8d4df78a/recording/831e74cd3e0042be96defba627b6f676/watch?source=HOMEPAGE', @@ -28,17 +33,15 @@ class GoToStageIE(InfoExtractor): 'https://api.gotostage.com/contents?ids=%s' % video_id, video_id, note='Downloading video metadata', - errnote='Unable to download video metadata', - ) + errnote='Unable to download video metadata') registration_data = { - 'product': metadata[0].get('product'), - 'resourceType': metadata[0].get('contentType'), - 'productReferenceKey': metadata[0].get('productRefKey'), + 'product': try_get(metadata, lambda x: x[0]['product'], compat_str), + 'resourceType': try_get(metadata, lambda x: x[0]['contentType'], compat_str), + 'productReferenceKey': try_get(metadata, lambda x: x[0]['productRefKey'], compat_str), 'firstName': 'foo', 'lastName': 'bar', - 'email': 'foobar@example.com' - } + 'email': 'foobar@example.com'} registration_response = self._download_json( 'https://api-registrations.logmeininc.com/registrations', @@ -47,24 +50,21 @@ class GoToStageIE(InfoExtractor): expected_status=409, headers={'Content-Type': 'application/json'}, note='Register user', - errnote='Unable to register user', - ) + errnote='Unable to register user') content_response = self._download_json( 'https://api.gotostage.com/contents/%s/asset' % video_id, video_id, - headers={'x-registrantkey': registration_response.get('registrationKey')}, + headers={'x-registrantkey': try_get(registration_response, lambda x: x['registrationKey'], compat_str)}, note='Get download url', - errnote='Unable to get download url', - ) + errnote='Unable to get download url') return { 'id': video_id, - 'title': metadata[0].get('title'), - 'url': content_response.get('cdnLocation'), + 'title': try_get(metadata, lambda x: x[0]['title'], compat_str), + 'url': try_get(content_response, lambda x: x['cdnLocation'], compat_str), 'ext': 'mp4', - 'thumbnail': metadata[0].get('thumbnail').get('location'), - 'duration': metadata[0].get('duration'), - 'categories': [metadata[0].get('category')], - 'is_live': False - } + 'thumbnail': url_or_none(try_get(metadata, lambda x: x[0]['thumbnail']['location'])), + 'duration': try_get(metadata, lambda x: x[0]['duration'], float), + 'categories': [try_get(metadata, lambda x: x[0]['category'], compat_str)], + 'is_live': False}