Compare commits

...

6 Commits

Author SHA1 Message Date
schn0sch
452cf7b172
Merge 14bf10c6488b74cc31ef6ae0e1b239a1505ba47a into 3eb8d22ddb8982ca4fb56bb7a8d6517538bf14c6 2025-04-01 10:28:17 +02:00
dirkf
3eb8d22ddb
[JSInterp] Temporary fix for #33102 2025-03-31 04:21:09 +01:00
dirkf
4e714f9df1 [Misc] Correct [_]IE_DESC/NAME in a few IEs
* thx seproDev, yt-dlp/yt-dlp/pull/12694/commits/ae69e3c
* also add documenting comment in `InfoExtractor`
2025-03-26 12:47:19 +00:00
dirkf
c1ea7f5a24 [ITV] Mark ITVX not working
* update old shim
* correct [_]IE_DESC
2025-03-26 12:17:49 +00:00
schn0sch
14bf10c648 [keep2share] share access token across calls to _real_extract 2021-05-17 15:55:14 +02:00
schn0sch
5f3cc3bbea [keep2share] Add new extractor 2021-05-17 15:54:46 +02:00
8 changed files with 107 additions and 15 deletions

View File

@ -32,7 +32,7 @@ class BokeCCBaseIE(InfoExtractor):
class BokeCCIE(BokeCCBaseIE):
_IE_DESC = 'CC视频'
IE_DESC = 'CC视频'
_VALID_URL = r'https?://union\.bokecc\.com/playvideo\.bo\?(?P<query>.*)'
_TESTS = [{

View File

@ -9,7 +9,7 @@ from ..utils import (
class CloudyIE(InfoExtractor):
_IE_DESC = 'cloudy.ec'
IE_DESC = 'cloudy.ec'
_VALID_URL = r'https?://(?:www\.)?cloudy\.ec/(?:v/|embed\.php\?.*?\bid=)(?P<id>[A-Za-z0-9]+)'
_TESTS = [{
'url': 'https://www.cloudy.ec/v/af511e2527aac',

View File

@ -422,6 +422,8 @@ class InfoExtractor(object):
_GEO_COUNTRIES = None
_GEO_IP_BLOCKS = None
_WORKING = True
# supply this in public subclasses: used in supported sites list, etc
# IE_DESC = 'short description of IE'
def __init__(self, downloader=None):
"""Constructor. Receives an optional downloader."""

View File

@ -562,6 +562,7 @@ from .kaltura import KalturaIE
from .kankan import KankanIE
from .karaoketv import KaraoketvIE
from .karrierevideos import KarriereVideosIE
from .keep2share import Keep2ShareIE
from .keezmovies import KeezMoviesIE
from .ketnet import KetnetIE
from .khanacademy import (

View File

@ -35,15 +35,6 @@ from ..utils import (
class ITVBaseIE(InfoExtractor):
def _search_nextjs_data(self, webpage, video_id, **kw):
transform_source = kw.pop('transform_source', None)
fatal = kw.pop('fatal', True)
return self._parse_json(
self._search_regex(
r'''<script\b[^>]+\bid=('|")__NEXT_DATA__\1[^>]*>(?P<js>[^<]+)</script>''',
webpage, 'next.js data', group='js', fatal=fatal, **kw),
video_id, transform_source=transform_source, fatal=fatal)
def __handle_request_webpage_error(self, err, video_id=None, errnote=None, fatal=True):
if errnote is False:
return False
@ -109,7 +100,9 @@ class ITVBaseIE(InfoExtractor):
class ITVIE(ITVBaseIE):
_VALID_URL = r'https?://(?:www\.)?itv\.com/(?:(?P<w>watch)|hub)/[^/]+/(?(w)[\w-]+/)(?P<id>\w+)'
_IE_DESC = 'ITVX'
IE_DESC = 'ITVX'
_WORKING = False
_TESTS = [{
'note': 'Hub URLs redirect to ITVX',
'url': 'https://www.itv.com/hub/liar/2a4547a0012',
@ -270,7 +263,7 @@ class ITVIE(ITVBaseIE):
'ext': determine_ext(href, 'vtt'),
})
next_data = self._search_nextjs_data(webpage, video_id, fatal=False, default='{}')
next_data = self._search_nextjs_data(webpage, video_id, fatal=False, default={})
video_data.update(traverse_obj(next_data, ('props', 'pageProps', ('title', 'episode')), expected_type=dict)[0] or {})
title = traverse_obj(video_data, 'headerTitle', 'episodeTitle')
info = self._og_extract(webpage, require_title=not title)
@ -323,7 +316,7 @@ class ITVIE(ITVBaseIE):
class ITVBTCCIE(ITVBaseIE):
_VALID_URL = r'https?://(?:www\.)?itv\.com/(?!(?:watch|hub)/)(?:[^/]+/)+(?P<id>[^/?#&]+)'
_IE_DESC = 'ITV articles: News, British Touring Car Championship'
IE_DESC = 'ITV articles: News, British Touring Car Championship'
_TESTS = [{
'note': 'British Touring Car Championship',
'url': 'https://www.itv.com/btcc/articles/btcc-2018-all-the-action-from-brands-hatch',

View File

@ -0,0 +1,94 @@
from __future__ import unicode_literals
import json
import re
from .common import (
InfoExtractor,
RegexNotFoundError,
)
from ..utils import (
clean_html,
compat_str,
js_to_json,
urljoin,
try_get,
)
class Keep2ShareIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)?(?:k2s\.cc|keep2share\.cc|keep2share\.com)/file/(?P<id>[^/?#]+)'
_TESTS = [{
'url': 'https://k2s.cc/file/d6f565bcb9581/Big_Buck%20Bunny%20Trailer.mp4',
'md5': '0dbce91e7d1efc506d1461439eb8a4c0',
'info_dict': {
'id': 'd6f565bcb9581',
'ext': 'mp4',
'title': 'Big Buck Bunny Trailer.mp4',
'thumbnail': r're:^https?://.*\.jpe?g$',
'filesize': 4447915,
'duration': 33.019,
},
}]
def _get_app_secret(self, video_id):
""" retrieve REACT_APP_API_CLIENT_SECRET """
if getattr(self, '_app_secret', None) is not None:
return self._app_secret
url = 'https://k2s.cc/file/' + video_id
webpage = self._download_webpage(url, video_id)
scripts = re.finditer(r'<script\s+src="(?P<src>/static/[^"]*)"', webpage)
for mobj in scripts:
src = urljoin(url, clean_html(mobj.group('src')))
script = self._download_webpage(src, video_id)
secret = self._search_regex(
r'REACT_APP_API_CLIENT_SECRET:\s*(?P<secret>%(string)s)' % {
'string': r'"(?:[^"]|\\")*"' + '|' + r"'(?:[^']|\\')*'",
}, script, 'app secret', group='secret', default=None)
if secret is not None:
self._app_secret = self._parse_json(secret, video_id,
transform_source=js_to_json)
return self._app_secret
raise RegexNotFoundError('Unable to extract app secret')
def _get_access_token(self, video_id):
""" retrieve access_token """
if getattr(self, '_access_token', None) is not None:
return self._access_token
data = {
'grant_type': 'client_credentials',
'client_id': 'k2s_web_app',
'client_secret': self._get_app_secret(video_id),
}
data = json.dumps(data, separators=(',', ':')).encode('utf-8')
headers = {'Content-Type': 'application/json'}
tokens = self._download_json('https://api.k2s.cc/v1/auth/token',
video_id, data=data, headers=headers)
self._access_token = tokens['access_token']
return self._access_token
def _real_extract(self, url):
video_id = self._match_id(url)
headers = {'Cookie': 'accessToken=' + self._get_access_token(url)}
info = self._download_json('https://api.k2s.cc/v1/files/' + video_id,
video_id, headers=headers)
return {
'id': video_id,
'title': info.get('name', 'keep2share-file'),
'thumbnail': try_get(info, lambda x: x['videoPreview']['cover'], compat_str),
'duration': try_get(info, lambda x: x['videoInfo']['duration'], (int, float)),
'formats': [{
'url': info['videoPreview']['video'],
'ext': 'mp4',
'filesize': try_get(info, lambda x: x['size'], int),
'width': try_get(info, lambda x: x['videoInfo']['resolution']['width'], int),
'height': try_get(info, lambda x: x['videoInfo']['resolution']['height'], int),
}],
}

View File

@ -47,7 +47,7 @@ class SenateISVPIE(InfoExtractor):
['vetaff', '76462', 'http://vetaff-f.akamaihd.net'],
['arch', '', 'http://ussenate-f.akamaihd.net/']
]
_IE_NAME = 'senate.gov'
IE_NAME = 'senate.gov'
_VALID_URL = r'https?://(?:www\.)?senate\.gov/isvp/?\?(?P<qs>.+)'
_TESTS = [{
'url': 'http://www.senate.gov/isvp/?comm=judiciary&type=live&stt=&filename=judiciary031715&auto_play=false&wmode=transparent&poster=http%3A%2F%2Fwww.judiciary.senate.gov%2Fthemes%2Fjudiciary%2Fimages%2Fvideo-poster-flash-fit.png',

View File

@ -686,6 +686,8 @@ class JSInterpreter(object):
raise self.Exception('Cannot get index {idx!r:.100}'.format(**locals()), expr=repr(obj), cause=e)
def _dump(self, obj, namespace):
if obj is JS_Undefined:
return 'undefined'
try:
return json.dumps(obj)
except TypeError: