1
0
mirror of https://codeberg.org/polarisfm/youtube-dl synced 2024-11-29 19:47:54 +01:00

[zattoo] Adopt to website redesign (closes #22258)

This commit is contained in:
Alexander Seiler 2019-10-18 14:05:37 +02:00
parent 824fa51165
commit 4462ead5b6
No known key found for this signature in database
GPG Key ID: E6F17669C3711DC0
2 changed files with 143 additions and 48 deletions

View File

@ -1512,7 +1512,6 @@ from .zattoo import (
VTXTVIE, VTXTVIE,
WalyTVIE, WalyTVIE,
ZattooIE, ZattooIE,
ZattooLiveIE,
) )
from .zdf import ZDFIE, ZDFChannelIE from .zdf import ZDFIE, ZDFChannelIE
from .zingmp3 import ZingMp3IE from .zingmp3 import ZingMp3IE

View File

@ -58,7 +58,8 @@ class ZattooPlatformBaseIE(InfoExtractor):
r'appToken\s*=\s*(["\'])(?P<token>(?:(?!\1).)+?)\1', r'appToken\s*=\s*(["\'])(?P<token>(?:(?!\1).)+?)\1',
webpage, 'app token', group='token') webpage, 'app token', group='token')
app_version = self._html_search_regex( app_version = self._html_search_regex(
r'<!--\w+-(.+?)-', webpage, 'app version', default='2.8.2') r'<!--\w+-(.+?)-', webpage,
'app version', default='2.8.2').lstrip('v')
# Will setup appropriate cookies # Will setup appropriate cookies
self._request_webpage( self._request_webpage(
@ -73,6 +74,20 @@ class ZattooPlatformBaseIE(InfoExtractor):
self._login() self._login()
def _extract_video_id_from_recording(self, recid):
playlist = self._download_json(
'%s/zapi/v2/playlist' % self._host_url(),
recid, 'Downloading playlist')
try:
recordings = playlist['recordings']
return next(
compat_str(item['program_id']) for item in recordings
if item.get('program_id') and compat_str(
item.get('id')) == recid
)
except (StopIteration, KeyError):
raise ExtractorError('Could not extract video id from recording')
def _extract_cid(self, video_id, channel_name): def _extract_cid(self, video_id, channel_name):
channel_groups = self._download_json( channel_groups = self._download_json(
'%s/zapi/v2/cached/channels/%s' % (self._host_url(), '%s/zapi/v2/cached/channels/%s' % (self._host_url(),
@ -121,7 +136,24 @@ class ZattooPlatformBaseIE(InfoExtractor):
return cid, info_dict return cid, info_dict
def _extract_formats(self, cid, video_id, record_id=None, is_live=False): def _extract_ondemand_info(self, ondemand_id):
data = self._download_json(
'%s/zapi/avod/videos/%s' % (self._host_url(), ondemand_id),
ondemand_id, 'Downloading ondemand information'
)
info_dict = {
'id': ondemand_id,
'title': data['title'],
'description': data.get('description'),
'duration': int_or_none(data.get('duration')),
'release_year': int_or_none(data.get('year')),
'episode_number': int_or_none(data.get('episode_number')),
'season_number': int_or_none(data.get('season_number')),
'categories': try_get(data, lambda x: x['categories'], list),
}
return info_dict
def _extract_formats(self, cid, video_id, record_id=None, ondemand_id=None, is_live=False):
postdata_common = { postdata_common = {
'https_watch_urls': True, 'https_watch_urls': True,
} }
@ -131,6 +163,8 @@ class ZattooPlatformBaseIE(InfoExtractor):
url = '%s/zapi/watch/live/%s' % (self._host_url(), cid) url = '%s/zapi/watch/live/%s' % (self._host_url(), cid)
elif record_id: elif record_id:
url = '%s/zapi/watch/recording/%s' % (self._host_url(), record_id) url = '%s/zapi/watch/recording/%s' % (self._host_url(), record_id)
elif ondemand_id:
url = '%s/zapi/avod/videos/%s/watch' % (self._host_url(), ondemand_id)
else: else:
url = '%s/zapi/watch/recall/%s/%s' % (self._host_url(), cid, video_id) url = '%s/zapi/watch/recall/%s/%s' % (self._host_url(), cid, video_id)
@ -187,18 +221,34 @@ class ZattooPlatformBaseIE(InfoExtractor):
self._sort_formats(formats) self._sort_formats(formats)
return formats return formats
def _extract_video(self, channel_name, video_id, record_id=None, is_live=False): def _extract_video(self, channel_name, video_id, record_id=None):
if is_live: cid, info_dict = self._extract_cid_and_video_info(video_id)
cid = self._extract_cid(video_id, channel_name) formats = self._extract_formats(cid, video_id, record_id=record_id)
info_dict['formats'] = formats
return info_dict
def _extract_live(self, channel_name):
cid = self._extract_cid(channel_name, channel_name)
info_dict = { info_dict = {
'id': channel_name, 'id': channel_name,
'title': self._live_title(channel_name), 'title': self._live_title(channel_name),
'is_live': True, 'is_live': True,
} }
else: formats = self._extract_formats(cid, cid, is_live=True)
info_dict['formats'] = formats
return info_dict
def _extract_record(self, record_id):
video_id = self._extract_video_id_from_recording(record_id)
cid, info_dict = self._extract_cid_and_video_info(video_id) cid, info_dict = self._extract_cid_and_video_info(video_id)
formats = self._extract_formats(cid, video_id, record_id=record_id)
info_dict['formats'] = formats
return info_dict
def _extract_ondemand(self, ondemand_id):
info_dict = self._extract_ondemand_info(ondemand_id)
formats = self._extract_formats( formats = self._extract_formats(
cid, video_id, record_id=record_id, is_live=is_live) None, ondemand_id, ondemand_id=ondemand_id)
info_dict['formats'] = formats info_dict['formats'] = formats
return info_dict return info_dict
@ -234,8 +284,8 @@ class QuicklineLiveIE(QuicklineBaseIE):
return False if QuicklineIE.suitable(url) else super(QuicklineLiveIE, cls).suitable(url) return False if QuicklineIE.suitable(url) else super(QuicklineLiveIE, cls).suitable(url)
def _real_extract(self, url): def _real_extract(self, url):
channel_name = video_id = self._match_id(url) channel_name = self._match_id(url)
return self._extract_video(channel_name, video_id, is_live=True) return self._extract_live(channel_name)
class ZattooBaseIE(ZattooPlatformBaseIE): class ZattooBaseIE(ZattooPlatformBaseIE):
@ -248,6 +298,50 @@ def _make_valid_url(tmpl, host):
class ZattooIE(ZattooBaseIE): class ZattooIE(ZattooBaseIE):
_VALID_URL_TEMPLATE = r'''(?x)
https?://(?:www\.)?%s/
(?:
.+\?recording=(?P<recid>[0-9]+)|
.+\?video=(?P<ondemandid>[A-Za-z0-9]+)|
.+\?channel=(?P<channelid>[^&]+)(?:
&program=(?P<programid>\d+)
)?
)'''
_VALID_URL = _make_valid_url(_VALID_URL_TEMPLATE, ZattooBaseIE._HOST)
_TESTS = [{
'url': 'https://zattoo.com/channels/german?channel=srf_zwei',
'only_matching': True,
}, {
'url': 'https://zattoo.com/guide/german?channel=srf1&program=169860555',
'only_matching': True,
}, {
'url': 'https://zattoo.com/channels/german?channel=3plus&program=169860178',
'only_matching': True,
}, {
'url': 'https://zattoo.com/recordings?recording=193615508',
'only_matching': True,
}, {
'url': 'https://zattoo.com/tc/ptc_recordings_all_recordings?recording=193615420',
'only_matching': True,
}, {
'url': 'https://zattoo.com/ondemand?video=dvSHj79rsRqHuAHFqsYZHdox',
'only_matching': True,
}]
def _real_extract(self, url):
record_id, ondemand_id, channel_id, program_id = re.match(
self._VALID_URL, url).groups()
if record_id:
return self._extract_record(record_id)
elif ondemand_id:
return self._extract_ondemand(ondemand_id)
elif channel_id:
if program_id:
return self._extract_video(channel_id, program_id)
return self._extract_live(channel_id)
class ZattooOldIE(ZattooBaseIE):
_VALID_URL_TEMPLATE = r'https?://(?:www\.)?%s/watch/(?P<channel>[^/]+?)/(?P<id>[0-9]+)[^/]+(?:/(?P<recid>[0-9]+))?' _VALID_URL_TEMPLATE = r'https?://(?:www\.)?%s/watch/(?P<channel>[^/]+?)/(?P<id>[0-9]+)[^/]+(?:/(?P<recid>[0-9]+))?'
_VALID_URL = _make_valid_url(_VALID_URL_TEMPLATE, ZattooBaseIE._HOST) _VALID_URL = _make_valid_url(_VALID_URL_TEMPLATE, ZattooBaseIE._HOST)
@ -262,11 +356,13 @@ class ZattooIE(ZattooBaseIE):
}] }]
def _real_extract(self, url): def _real_extract(self, url):
channel_name, video_id, record_id = re.match(self._VALID_URL, url).groups() channel_name, video_id, record_id = re.match(
return self._extract_video(channel_name, video_id, record_id) self._VALID_URL, url).groups()
return self._extract_video(
channel_name, video_id, record_id=record_id)
class ZattooLiveIE(ZattooBaseIE): class ZattooOldLiveIE(ZattooBaseIE):
_VALID_URL = r'https?://(?:www\.)?zattoo\.com/watch/(?P<id>[^/]+)' _VALID_URL = r'https?://(?:www\.)?zattoo\.com/watch/(?P<id>[^/]+)'
_TEST = { _TEST = {
@ -276,18 +372,18 @@ class ZattooLiveIE(ZattooBaseIE):
@classmethod @classmethod
def suitable(cls, url): def suitable(cls, url):
return False if ZattooIE.suitable(url) else super(ZattooLiveIE, cls).suitable(url) return False if ZattooOldIE.suitable(url) else super(ZattooOldLiveIE, cls).suitable(url)
def _real_extract(self, url): def _real_extract(self, url):
channel_name = video_id = self._match_id(url) channel_name = self._match_id(url)
return self._extract_video(channel_name, video_id, is_live=True) return self._extract_live(channel_name)
class NetPlusIE(ZattooIE): class NetPlusIE(ZattooOldIE):
_NETRC_MACHINE = 'netplus' _NETRC_MACHINE = 'netplus'
_HOST = 'netplus.tv' _HOST = 'netplus.tv'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.netplus.tv/watch/abc/123-abc', 'url': 'https://www.netplus.tv/watch/abc/123-abc',
@ -295,10 +391,10 @@ class NetPlusIE(ZattooIE):
}] }]
class MNetTVIE(ZattooIE): class MNetTVIE(ZattooOldIE):
_NETRC_MACHINE = 'mnettv' _NETRC_MACHINE = 'mnettv'
_HOST = 'tvplus.m-net.de' _HOST = 'tvplus.m-net.de'
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://tvplus.m-net.de/watch/abc/123-abc', 'url': 'https://tvplus.m-net.de/watch/abc/123-abc',
@ -306,10 +402,10 @@ class MNetTVIE(ZattooIE):
}] }]
class WalyTVIE(ZattooIE): class WalyTVIE(ZattooOldIE):
_NETRC_MACHINE = 'walytv' _NETRC_MACHINE = 'walytv'
_HOST = 'player.waly.tv' _HOST = 'player.waly.tv'
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://player.waly.tv/watch/abc/123-abc', 'url': 'https://player.waly.tv/watch/abc/123-abc',
@ -317,11 +413,11 @@ class WalyTVIE(ZattooIE):
}] }]
class BBVTVIE(ZattooIE): class BBVTVIE(ZattooOldIE):
_NETRC_MACHINE = 'bbvtv' _NETRC_MACHINE = 'bbvtv'
_HOST = 'bbv-tv.net' _HOST = 'bbv-tv.net'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.bbv-tv.net/watch/abc/123-abc', 'url': 'https://www.bbv-tv.net/watch/abc/123-abc',
@ -329,11 +425,11 @@ class BBVTVIE(ZattooIE):
}] }]
class VTXTVIE(ZattooIE): class VTXTVIE(ZattooOldIE):
_NETRC_MACHINE = 'vtxtv' _NETRC_MACHINE = 'vtxtv'
_HOST = 'vtxtv.ch' _HOST = 'vtxtv.ch'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.vtxtv.ch/watch/abc/123-abc', 'url': 'https://www.vtxtv.ch/watch/abc/123-abc',
@ -341,11 +437,11 @@ class VTXTVIE(ZattooIE):
}] }]
class MyVisionTVIE(ZattooIE): class MyVisionTVIE(ZattooOldIE):
_NETRC_MACHINE = 'myvisiontv' _NETRC_MACHINE = 'myvisiontv'
_HOST = 'myvisiontv.ch' _HOST = 'myvisiontv.ch'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.myvisiontv.ch/watch/abc/123-abc', 'url': 'https://www.myvisiontv.ch/watch/abc/123-abc',
@ -353,10 +449,10 @@ class MyVisionTVIE(ZattooIE):
}] }]
class GlattvisionTVIE(ZattooIE): class GlattvisionTVIE(ZattooOldIE):
_NETRC_MACHINE = 'glattvisiontv' _NETRC_MACHINE = 'glattvisiontv'
_HOST = 'iptv.glattvision.ch' _HOST = 'iptv.glattvision.ch'
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://iptv.glattvision.ch/watch/abc/123-abc', 'url': 'https://iptv.glattvision.ch/watch/abc/123-abc',
@ -364,11 +460,11 @@ class GlattvisionTVIE(ZattooIE):
}] }]
class SAKTVIE(ZattooIE): class SAKTVIE(ZattooOldIE):
_NETRC_MACHINE = 'saktv' _NETRC_MACHINE = 'saktv'
_HOST = 'saktv.ch' _HOST = 'saktv.ch'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.saktv.ch/watch/abc/123-abc', 'url': 'https://www.saktv.ch/watch/abc/123-abc',
@ -376,10 +472,10 @@ class SAKTVIE(ZattooIE):
}] }]
class EWETVIE(ZattooIE): class EWETVIE(ZattooOldIE):
_NETRC_MACHINE = 'ewetv' _NETRC_MACHINE = 'ewetv'
_HOST = 'tvonline.ewe.de' _HOST = 'tvonline.ewe.de'
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://tvonline.ewe.de/watch/abc/123-abc', 'url': 'https://tvonline.ewe.de/watch/abc/123-abc',
@ -387,11 +483,11 @@ class EWETVIE(ZattooIE):
}] }]
class QuantumTVIE(ZattooIE): class QuantumTVIE(ZattooOldIE):
_NETRC_MACHINE = 'quantumtv' _NETRC_MACHINE = 'quantumtv'
_HOST = 'quantum-tv.com' _HOST = 'quantum-tv.com'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.quantum-tv.com/watch/abc/123-abc', 'url': 'https://www.quantum-tv.com/watch/abc/123-abc',
@ -399,10 +495,10 @@ class QuantumTVIE(ZattooIE):
}] }]
class OsnatelTVIE(ZattooIE): class OsnatelTVIE(ZattooOldIE):
_NETRC_MACHINE = 'osnateltv' _NETRC_MACHINE = 'osnateltv'
_HOST = 'tvonline.osnatel.de' _HOST = 'tvonline.osnatel.de'
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://tvonline.osnatel.de/watch/abc/123-abc', 'url': 'https://tvonline.osnatel.de/watch/abc/123-abc',
@ -410,11 +506,11 @@ class OsnatelTVIE(ZattooIE):
}] }]
class EinsUndEinsTVIE(ZattooIE): class EinsUndEinsTVIE(ZattooOldIE):
_NETRC_MACHINE = '1und1tv' _NETRC_MACHINE = '1und1tv'
_HOST = '1und1.tv' _HOST = '1und1.tv'
_API_HOST = 'www.%s' % _HOST _API_HOST = 'www.%s' % _HOST
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://www.1und1.tv/watch/abc/123-abc', 'url': 'https://www.1und1.tv/watch/abc/123-abc',
@ -422,10 +518,10 @@ class EinsUndEinsTVIE(ZattooIE):
}] }]
class SaltTVIE(ZattooIE): class SaltTVIE(ZattooOldIE):
_NETRC_MACHINE = 'salttv' _NETRC_MACHINE = 'salttv'
_HOST = 'tv.salt.ch' _HOST = 'tv.salt.ch'
_VALID_URL = _make_valid_url(ZattooIE._VALID_URL_TEMPLATE, _HOST) _VALID_URL = _make_valid_url(ZattooOldIE._VALID_URL_TEMPLATE, _HOST)
_TESTS = [{ _TESTS = [{
'url': 'https://tv.salt.ch/watch/abc/123-abc', 'url': 'https://tv.salt.ch/watch/abc/123-abc',