import base64
import functools
-import re
import itertools
+import re
+import urllib.parse
from .common import InfoExtractor
-from ..compat import compat_str, compat_urlparse
from ..networking import HEADRequest, Request
from ..networking.exceptions import HTTPError
from ..utils import (
+ ExtractorError,
+ OnDemandPagedList,
clean_html,
determine_ext,
- ExtractorError,
get_element_by_class,
- js_to_json,
int_or_none,
+ js_to_json,
merge_dicts,
- OnDemandPagedList,
parse_filesize,
parse_iso8601,
parse_qs,
smuggle_url,
str_or_none,
+ traverse_obj,
try_get,
unified_timestamp,
unsmuggle_url,
urlencode_postdata,
- urljoin,
urlhandle_detect_ext,
+ urljoin,
)
return url, data, headers
def _perform_login(self, username, password):
- webpage = self._download_webpage(
- self._LOGIN_URL, None, 'Downloading login page')
- token, vuid = self._extract_xsrft_and_vuid(webpage)
+ viewer = self._download_json('https://vimeo.com/_next/viewer', None, 'Downloading login token')
data = {
'action': 'login',
'email': username,
'password': password,
'service': 'vimeo',
- 'token': token,
+ 'token': viewer['xsrft'],
}
- self._set_vimeo_cookie('vuid', vuid)
+ self._set_vimeo_cookie('vuid', viewer['vuid'])
try:
self._download_webpage(
self._LOGIN_URL, None, 'Logging in',
video_data = config['video']
video_title = video_data.get('title')
live_event = video_data.get('live_event') or {}
- is_live = live_event.get('status') == 'started'
+ live_status = {
+ 'pending': 'is_upcoming',
+ 'active': 'is_upcoming',
+ 'started': 'is_live',
+ 'ended': 'post_live',
+ }.get(live_event.get('status'))
+ is_live = live_status == 'is_live'
request = config.get('request') or {}
formats = []
continue
formats.append({
'url': video_url,
- 'format_id': 'http-%s' % f.get('quality'),
+ 'format_id': 'http-{}'.format(f.get('quality')),
'source_preference': 10,
'width': int_or_none(f.get('width')),
'height': int_or_none(f.get('height')),
manifest_url = cdn_data.get('url')
if not manifest_url:
continue
- format_id = '%s-%s' % (files_type, cdn_name)
+ format_id = f'{files_type}-{cdn_name}'
sep_manifest_urls = []
if re.search(sep_pattern, manifest_url):
for suffix, repl in (('', 'video'), ('_sep', 'sep/video')):
sep_manifest_urls.append((format_id + suffix, re.sub(
- sep_pattern, '/%s/' % repl, manifest_url)))
+ sep_pattern, f'/{repl}/', manifest_url)))
else:
sep_manifest_urls = [(format_id, manifest_url)]
for f_id, m_url in sep_manifest_urls:
if files_type == 'hls':
fmts, subs = self._extract_m3u8_formats_and_subtitles(
m_url, video_id, 'mp4', live=is_live, m3u8_id=f_id,
- note='Downloading %s m3u8 information' % cdn_name,
+ note=f'Downloading {cdn_name} m3u8 information',
fatal=False)
formats.extend(fmts)
self._merge_subtitles(subs, target=subtitles)
m_url = real_m_url
fmts, subs = self._extract_mpd_formats_and_subtitles(
m_url.replace('/master.json', '/master.mpd'), video_id, f_id,
- 'Downloading %s MPD information' % cdn_name,
+ f'Downloading {cdn_name} MPD information',
fatal=False)
formats.extend(fmts)
self._merge_subtitles(subs, target=subtitles)
'chapters': chapters or None,
'formats': formats,
'subtitles': subtitles,
- 'is_live': is_live,
+ 'live_status': live_status,
+ 'release_timestamp': traverse_obj(live_event, ('ingest', 'scheduled_start_time', {parse_iso8601})),
# Note: Bitrates are completely broken. Single m3u8 may contain entries in kbps and bps
# at the same time without actual units specified.
'_format_sort_fields': ('quality', 'res', 'fps', 'hdr:12', 'source'),
download_url = try_get(source_file, lambda x: x['download_url'])
if download_url and not source_file.get('is_cold') and not source_file.get('is_defrosting'):
source_name = source_file.get('public_name', 'Original')
- if self._is_valid_url(download_url, video_id, '%s video' % source_name):
+ if self._is_valid_url(download_url, video_id, f'{source_name} video'):
ext = (try_get(
source_file, lambda x: x['extension'],
- compat_str) or determine_ext(
+ str) or determine_ext(
download_url, None) or 'mp4').lower()
return {
'url': download_url,
'https://vimeo.com/_rv/viewer', video_id, note='Downloading jwt token', fatal=False) or {}
if not jwt_response.get('jwt'):
return
- headers = {'Authorization': 'jwt %s' % jwt_response['jwt'], 'Accept': 'application/json'}
+ headers = {'Authorization': 'jwt {}'.format(jwt_response['jwt']), 'Accept': 'application/json'}
original_response = self._download_json(
f'https://api.vimeo.com/videos/{video_id}', video_id,
headers=headers, fatal=False, expected_status=(403, 404)) or {}
'params': {
'format': 'best[protocol=https]',
},
- 'skip': 'No longer available'
+ 'skip': 'No longer available',
},
{
'url': 'http://player.vimeo.com/video/54469442',
'uploader_url': r're:https?://(?:www\.)?vimeo\.com/businessofsoftware',
'uploader_id': 'businessofsoftware',
'duration': 3610,
- 'description': None,
'thumbnail': 'https://i.vimeocdn.com/video/376682406-f34043e7b766af6bef2af81366eacd6724f3fc3173179a11a97a1e26587c9529-d_1280',
},
'params': {
'Content-Type': 'application/x-www-form-urlencoded',
})
checked = self._download_json(
- f'{compat_urlparse.urlsplit(url)._replace(query=None).geturl()}/check-password',
+ f'{urllib.parse.urlsplit(url)._replace(query=None).geturl()}/check-password',
video_id, 'Verifying the password', data=data, headers=headers)
if checked is False:
raise ExtractorError('Wrong video password', expected=True)
def _extract_from_api(self, video_id, unlisted_hash=None):
token = self._download_json(
'https://vimeo.com/_rv/jwt', video_id, headers={
- 'X-Requested-With': 'XMLHttpRequest'
+ 'X-Requested-With': 'XMLHttpRequest',
})['token']
api_url = 'https://api.vimeo.com/videos/' + video_id
if unlisted_hash:
self._set_vimeo_cookie('vuid', viewer['vuid'])
try:
self._download_json(
- 'https://vimeo.com/showcase/%s/auth' % album_id,
+ f'https://vimeo.com/showcase/{album_id}/auth',
album_id, 'Verifying the password', data=urlencode_postdata({
'password': password,
'token': viewer['xsrft'],
seed_status = vimeo_config.get('seed_status') or {}
if seed_status.get('state') == 'failed':
raise ExtractorError(
- '%s said: %s' % (self.IE_NAME, seed_status['title']),
+ '{} said: {}'.format(self.IE_NAME, seed_status['title']),
expected=True)
cc_license = None
feature_id = vod.get('feature_id')
if feature_id and not data.get('force_feature_id', False):
return self.url_result(smuggle_url(
- 'https://player.vimeo.com/player/%s' % feature_id,
+ f'https://player.vimeo.com/player/{feature_id}',
{'force_feature_id': True}), 'Vimeo')
if not video_description:
_BASE_URL_TEMPL = 'https://vimeo.com/channels/%s'
def _page_url(self, base_url, pagenum):
- return '%s/videos/page:%d/' % (base_url, pagenum)
+ return f'{base_url}/videos/page:{pagenum}/'
def _extract_list_title(self, webpage):
return self._TITLE or self._html_search_regex(
page_url = self._page_url(base_url, pagenum)
webpage = self._download_webpage(
page_url, list_id,
- 'Downloading page %s' % pagenum)
+ f'Downloading page {pagenum}')
if pagenum == 1:
yield self._extract_list_title(webpage)
if clips:
for video_id, video_url, video_title in clips:
yield self.url_result(
- compat_urlparse.urljoin(base_url, video_url),
+ urllib.parse.urljoin(base_url, video_url),
VimeoIE.ie_key(), video_id=video_id, video_title=video_title)
# More relaxed fallback
else:
for video_id in re.findall(r'id=["\']clip_(\d+)', webpage):
yield self.url_result(
- 'https://vimeo.com/%s' % video_id,
+ f'https://vimeo.com/{video_id}',
VimeoIE.ie_key(), video_id=video_id)
if re.search(self._MORE_PAGES_INDICATOR, webpage, re.DOTALL) is None:
'playlist_count': 1,
'params': {
'videopassword': 'youtube-dl',
- }
+ },
}]
_PAGE_SIZE = 100
query['_hashed_pass'] = hashed_pass
try:
videos = self._download_json(
- 'https://api.vimeo.com/albums/%s/videos' % album_id,
- album_id, 'Downloading page %d' % api_page, query=query, headers={
+ f'https://api.vimeo.com/albums/{album_id}/videos',
+ album_id, f'Downloading page {api_page}', query=query, headers={
'Authorization': 'jwt ' + authorization,
'Accept': 'application/json',
})['data']
self._set_vimeo_cookie('vuid', viewer['vuid'])
try:
hashed_pass = self._download_json(
- 'https://vimeo.com/showcase/%s/auth' % album_id,
+ f'https://vimeo.com/showcase/{album_id}/auth',
album_id, 'Verifying the password', data=urlencode_postdata({
'password': password,
'token': viewer['xsrft'],
}]
def _page_url(self, base_url, pagenum):
- url = '%s/page:%d/' % (base_url, pagenum)
+ url = f'{base_url}/page:{pagenum}/'
request = Request(url)
# Set the header to get a partial html page with the ids,
# the normal page doesn't contain them.
}]
def _page_url(self, base_url, pagenum):
- return '%s/page:%d/' % (base_url, pagenum)
+ return f'{base_url}/page:{pagenum}/'
def _real_extract(self, url):
user_id = self._match_id(url)
- return self._extract_videos(user_id, 'https://vimeo.com/%s/likes' % user_id)
+ return self._extract_videos(user_id, f'https://vimeo.com/{user_id}/likes')
class VHXEmbedIE(VimeoBaseInfoExtractor):