aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpukkandan <pukkandan.ytdlp@gmail.com>2022-08-24 07:38:55 +0530
committerpukkandan <pukkandan.ytdlp@gmail.com>2022-08-24 07:38:55 +0530
commit5314b521925498356e78652fe59866116d56e1d1 (patch)
treee36730034f23bb8cdfc8376c3052071d5b19c38f
parent13db4e7b9e3932595c6b78df47ab4a0382f031f8 (diff)
downloadhypervideo-pre-5314b521925498356e78652fe59866116d56e1d1.tar.lz
hypervideo-pre-5314b521925498356e78652fe59866116d56e1d1.tar.xz
hypervideo-pre-5314b521925498356e78652fe59866116d56e1d1.zip
[utils] Add orderedSet_from_options
-rw-r--r--yt_dlp/YoutubeDL.py27
-rw-r--r--yt_dlp/options.py35
-rw-r--r--yt_dlp/utils.py30
3 files changed, 47 insertions, 45 deletions
diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py
index c2b306d70..872e0bdc3 100644
--- a/yt_dlp/YoutubeDL.py
+++ b/yt_dlp/YoutubeDL.py
@@ -115,6 +115,7 @@ from .utils import (
network_exceptions,
number_of_digits,
orderedSet,
+ orderedSet_from_options,
parse_filesize,
preferredencoding,
prepend_extension,
@@ -2737,27 +2738,11 @@ class YoutubeDL:
if self.params.get('allsubtitles', False):
requested_langs = all_sub_langs
elif self.params.get('subtitleslangs', False):
- # A list is used so that the order of languages will be the same as
- # given in subtitleslangs. See https://github.com/yt-dlp/yt-dlp/issues/1041
- requested_langs = []
- for lang_re in self.params.get('subtitleslangs'):
- discard = lang_re[0] == '-'
- if discard:
- lang_re = lang_re[1:]
- if lang_re == 'all':
- if discard:
- requested_langs = []
- else:
- requested_langs.extend(all_sub_langs)
- continue
- current_langs = filter(re.compile(lang_re + '$').match, all_sub_langs)
- if discard:
- for lang in current_langs:
- while lang in requested_langs:
- requested_langs.remove(lang)
- else:
- requested_langs.extend(current_langs)
- requested_langs = orderedSet(requested_langs)
+ try:
+ requested_langs = orderedSet_from_options(
+ self.params.get('subtitleslangs'), {'all': all_sub_langs}, use_regex=True)
+ except re.error as e:
+ raise ValueError(f'Wrong regex for subtitlelangs: {e.pattern}')
elif normal_sub_langs:
requested_langs = ['en'] if 'en' in normal_sub_langs else normal_sub_langs[:1]
else:
diff --git a/yt_dlp/options.py b/yt_dlp/options.py
index 6373ff8c0..0cddb7fd5 100644
--- a/yt_dlp/options.py
+++ b/yt_dlp/options.py
@@ -29,6 +29,7 @@ from .utils import (
format_field,
get_executable_path,
join_nonempty,
+ orderedSet_from_options,
remove_end,
write_string,
)
@@ -232,30 +233,16 @@ def create_parser():
current + value if append is True else value + current)
def _set_from_options_callback(
- option, opt_str, value, parser, delim=',', allowed_values=None, aliases={},
+ option, opt_str, value, parser, allowed_values, delim=',', aliases={},
process=lambda x: x.lower().strip()):
- current = set(getattr(parser.values, option.dest))
- values = [process(value)] if delim is None else list(map(process, value.split(delim)[::-1]))
- while values:
- actual_val = val = values.pop()
- if not val:
- raise optparse.OptionValueError(f'Invalid {option.metavar} for {opt_str}: {value}')
- if val == 'all':
- current.update(allowed_values)
- elif val == '-all':
- current = set()
- elif val in aliases:
- values.extend(aliases[val])
- else:
- if val[0] == '-':
- val = val[1:]
- current.discard(val)
- else:
- current.update([val])
- if allowed_values is not None and val not in allowed_values:
- raise optparse.OptionValueError(f'wrong {option.metavar} for {opt_str}: {actual_val}')
+ values = [process(value)] if delim is None else map(process, value.split(delim))
+ try:
+ requested = orderedSet_from_options(values, collections.ChainMap(aliases, {'all': allowed_values}),
+ start=getattr(parser.values, option.dest))
+ except ValueError as e:
+ raise optparse.OptionValueError(f'wrong {option.metavar} for {opt_str}: {e.args[0]}')
- setattr(parser.values, option.dest, current)
+ setattr(parser.values, option.dest, set(requested))
def _dict_from_options_callback(
option, opt_str, value, parser,
@@ -447,8 +434,8 @@ def create_parser():
'no-youtube-channel-redirect', 'no-youtube-unavailable-videos', 'no-attach-info-json', 'embed-metadata',
'embed-thumbnail-atomicparsley', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs', 'no-certifi',
}, 'aliases': {
- 'youtube-dl': ['-multistreams', 'all'],
- 'youtube-dlc': ['-no-youtube-channel-redirect', '-no-live-chat', 'all'],
+ 'youtube-dl': ['all', '-multistreams'],
+ 'youtube-dlc': ['all', '-no-youtube-channel-redirect', '-no-live-chat'],
}
}, help=(
'Options that can help keep compatibility with youtube-dl or youtube-dlc '
diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py
index 13768d846..957c7eaa7 100644
--- a/yt_dlp/utils.py
+++ b/yt_dlp/utils.py
@@ -5785,6 +5785,36 @@ def truncate_string(s, left, right=0):
return f'{s[:left-3]}...{s[-right:]}'
+def orderedSet_from_options(options, alias_dict, *, use_regex=False, start=None):
+ assert 'all' in alias_dict, '"all" alias is required'
+ requested = list(start or [])
+ for val in options:
+ discard = val.startswith('-')
+ if discard:
+ val = val[1:]
+
+ if val in alias_dict:
+ val = alias_dict[val] if not discard else [
+ i[1:] if i.startswith('-') else f'-{i}' for i in alias_dict[val]]
+ # NB: Do not allow regex in aliases for performance
+ requested = orderedSet_from_options(val, alias_dict, start=requested)
+ continue
+
+ current = (filter(re.compile(val, re.I).fullmatch, alias_dict['all']) if use_regex
+ else [val] if val in alias_dict['all'] else None)
+ if current is None:
+ raise ValueError(val)
+
+ if discard:
+ for item in current:
+ while item in requested:
+ requested.remove(item)
+ else:
+ requested.extend(current)
+
+ return orderedSet(requested)
+
+
# Deprecated
has_certifi = bool(certifi)
has_websockets = bool(websockets)