mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 14:45:14 +00:00 
			
		
		
		
	[utils] Add orderedSet_from_options
This commit is contained in:
		| @@ -115,6 +115,7 @@ from .utils import ( | |||||||
|     network_exceptions, |     network_exceptions, | ||||||
|     number_of_digits, |     number_of_digits, | ||||||
|     orderedSet, |     orderedSet, | ||||||
|  |     orderedSet_from_options, | ||||||
|     parse_filesize, |     parse_filesize, | ||||||
|     preferredencoding, |     preferredencoding, | ||||||
|     prepend_extension, |     prepend_extension, | ||||||
| @@ -2737,27 +2738,11 @@ class YoutubeDL: | |||||||
|         if self.params.get('allsubtitles', False): |         if self.params.get('allsubtitles', False): | ||||||
|             requested_langs = all_sub_langs |             requested_langs = all_sub_langs | ||||||
|         elif self.params.get('subtitleslangs', False): |         elif self.params.get('subtitleslangs', False): | ||||||
|             # A list is used so that the order of languages will be the same as |             try: | ||||||
|             # given in subtitleslangs. See https://github.com/yt-dlp/yt-dlp/issues/1041 |                 requested_langs = orderedSet_from_options( | ||||||
|             requested_langs = [] |                     self.params.get('subtitleslangs'), {'all': all_sub_langs}, use_regex=True) | ||||||
|             for lang_re in self.params.get('subtitleslangs'): |             except re.error as e: | ||||||
|                 discard = lang_re[0] == '-' |                 raise ValueError(f'Wrong regex for subtitlelangs: {e.pattern}') | ||||||
|                 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) |  | ||||||
|         elif normal_sub_langs: |         elif normal_sub_langs: | ||||||
|             requested_langs = ['en'] if 'en' in normal_sub_langs else normal_sub_langs[:1] |             requested_langs = ['en'] if 'en' in normal_sub_langs else normal_sub_langs[:1] | ||||||
|         else: |         else: | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ from .utils import ( | |||||||
|     format_field, |     format_field, | ||||||
|     get_executable_path, |     get_executable_path, | ||||||
|     join_nonempty, |     join_nonempty, | ||||||
|  |     orderedSet_from_options, | ||||||
|     remove_end, |     remove_end, | ||||||
|     write_string, |     write_string, | ||||||
| ) | ) | ||||||
| @@ -232,30 +233,16 @@ def create_parser(): | |||||||
|             current + value if append is True else value + current) |             current + value if append is True else value + current) | ||||||
| 
 | 
 | ||||||
|     def _set_from_options_callback( |     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()): |             process=lambda x: x.lower().strip()): | ||||||
|         current = set(getattr(parser.values, option.dest)) |         values = [process(value)] if delim is None else map(process, value.split(delim)) | ||||||
|         values = [process(value)] if delim is None else list(map(process, value.split(delim)[::-1])) |         try: | ||||||
|         while values: |             requested = orderedSet_from_options(values, collections.ChainMap(aliases, {'all': allowed_values}), | ||||||
|             actual_val = val = values.pop() |                                                 start=getattr(parser.values, option.dest)) | ||||||
|             if not val: |         except ValueError as e: | ||||||
|                 raise optparse.OptionValueError(f'Invalid {option.metavar} for {opt_str}: {value}') |             raise optparse.OptionValueError(f'wrong {option.metavar} for {opt_str}: {e.args[0]}') | ||||||
|             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}') |  | ||||||
| 
 | 
 | ||||||
|         setattr(parser.values, option.dest, current) |         setattr(parser.values, option.dest, set(requested)) | ||||||
| 
 | 
 | ||||||
|     def _dict_from_options_callback( |     def _dict_from_options_callback( | ||||||
|             option, opt_str, value, parser, |             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', |                 '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', |                 'embed-thumbnail-atomicparsley', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs', 'no-certifi', | ||||||
|             }, 'aliases': { |             }, 'aliases': { | ||||||
|                 'youtube-dl': ['-multistreams', 'all'], |                 'youtube-dl': ['all', '-multistreams'], | ||||||
|                 'youtube-dlc': ['-no-youtube-channel-redirect', '-no-live-chat', 'all'], |                 'youtube-dlc': ['all', '-no-youtube-channel-redirect', '-no-live-chat'], | ||||||
|             } |             } | ||||||
|         }, help=( |         }, help=( | ||||||
|             'Options that can help keep compatibility with youtube-dl or youtube-dlc ' |             'Options that can help keep compatibility with youtube-dl or youtube-dlc ' | ||||||
|   | |||||||
| @@ -5785,6 +5785,36 @@ def truncate_string(s, left, right=0): | |||||||
|     return f'{s[:left-3]}...{s[-right:]}' |     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 | # Deprecated | ||||||
| has_certifi = bool(certifi) | has_certifi = bool(certifi) | ||||||
| has_websockets = bool(websockets) | has_websockets = bool(websockets) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 pukkandan
					pukkandan