iri_to_uri,
join_nonempty,
locked_file,
+ make_archive_id,
make_dir,
make_HTTPS_handler,
merge_headers,
# Better to do this after potentially exhausting entries
ie_result['playlist_count'] = all_entries.get_full_count()
- ie_copy = collections.ChainMap(
- ie_result, self._playlist_infodict(ie_result, n_entries=int_or_none(n_entries)))
+ extra = self._playlist_infodict(ie_result, n_entries=int_or_none(n_entries))
+ ie_copy = collections.ChainMap(ie_result, extra)
_infojson_written = False
write_playlist_files = self.params.get('allow_playlist_files', True)
if not lazy and 'playlist-index' in self.params.get('compat_opts', []):
playlist_index = ie_result['requested_entries'][i]
- extra = {
+ entry_copy = collections.ChainMap(entry, {
**common_info,
'n_entries': int_or_none(n_entries),
'playlist_index': playlist_index,
'playlist_autonumber': i + 1,
- }
+ })
- if self._match_entry(collections.ChainMap(entry, extra), incomplete=True) is not None:
+ if self._match_entry(entry_copy, incomplete=True) is not None:
continue
self.to_screen('[download] Downloading video %s of %s' % (
break
else:
return
- return f'{extractor.lower()} {video_id}'
+ return make_archive_id(extractor, video_id)
def in_download_archive(self, info_dict):
fn = self.params.get('download_archive')
-f'You are using an unsupported version of Python. Only Python versions 3.7 and above are supported by yt-dlp' # noqa: F541
+try:
+ import contextvars # noqa: F401
+except Exception:
+ raise Exception(
+ f'You are using an unsupported version of Python. Only Python versions 3.7 and above are supported by yt-dlp') # noqa: F541
__license__ = 'Public Domain'
live stream that goes on instead of a fixed-length video.
was_live: True, False, or None (=unknown). Whether this video was
originally a live stream.
- live_status: None (=unknown), 'is_live', 'is_upcoming', 'was_live', 'not_live'
+ live_status: None (=unknown), 'is_live', 'is_upcoming', 'was_live', 'not_live',
or 'post_live' (was live, but VOD is not yet processed)
If absent, automatically set from is_live, was_live
start_time: Time in seconds where the reproduction should start, as
class CommonMistakesIE(InfoExtractor):
IE_DESC = False # Do not list
- _VALID_URL = r'''(?x)
- (?:url|URL)$
- '''
+ _VALID_URL = r'(?:url|URL|yt-dlp)$'
_TESTS = [{
'url': 'url',
from .common import InfoExtractor
from ..compat import compat_HTTPError
from ..utils import (
+ ExtractorError,
determine_ext,
int_or_none,
join_nonempty,
js_to_json,
+ make_archive_id,
orderedSet,
qualities,
str_or_none,
traverse_obj,
try_get,
urlencode_postdata,
- ExtractorError,
)
return {
'id': episode_id,
- '_old_archive_ids': [initial_experience_id],
+ '_old_archive_ids': [make_archive_id(self, initial_experience_id)],
'display_id': display_id,
'duration': duration,
'title': episode['episodeTitle'],
from .common import InfoExtractor
+from ..utils import make_archive_id
class HTML5MediaEmbedIE(InfoExtractor):
'id': f'{video_id}-{num}',
'title': f'{title} ({num})',
'_old_archive_ids': [
- f'Generic {f"{video_id}-{num}" if len(entries) > 1 else video_id}',
+ make_archive_id('generic', f'{video_id}-{num}' if len(entries) > 1 else video_id),
],
})
self._sort_formats(entry['formats'])
dict_get,
float_or_none,
int_or_none,
+ make_archive_id,
parse_duration,
parse_iso8601,
parse_qs,
return {
'id': clip.get('id') or video_id,
- '_old_archive_ids': [f'{self.ie_key()} {old_id}'] if old_id else None,
+ '_old_archive_ids': [make_archive_id(self, old_id)] if old_id else None,
'display_id': video_id,
'title': clip.get('title') or video_id,
'formats': formats,
time.sleep(delay)
+def make_archive_id(ie, video_id):
+ ie_key = ie if isinstance(ie, str) else ie.ie_key()
+ return f'{ie_key.lower()} {video_id}'
+
+
# Deprecated
has_certifi = bool(certifi)
has_websockets = bool(websockets)