[utils] `traverse_obj`: Allow filtering by value

This commit is contained in:
pukkandan 2022-03-31 13:25:50 +05:30
parent c4f60dd7cd
commit e6f868a63c
No known key found for this signature in database
GPG Key ID: 7EEE9E1E817D0A39
3 changed files with 6 additions and 6 deletions

View File

@ -333,7 +333,7 @@ class FunimationShowIE(FunimationBaseIE):
'https://prod-api-funimationnow.dadcdigital.com/api/funimation/episodes/?limit=99999&title_id=%s' 'https://prod-api-funimationnow.dadcdigital.com/api/funimation/episodes/?limit=99999&title_id=%s'
% show_info.get('id'), display_id) % show_info.get('id'), display_id)
vod_items = traverse_obj(items_info, ('items', ..., re.compile('(?i)mostRecent[AS]vod').match, 'item')) vod_items = traverse_obj(items_info, ('items', ..., lambda k, _: re.match(r'(?i)mostRecent[AS]vod', k), 'item'))
return { return {
'_type': 'playlist', '_type': 'playlist',

View File

@ -626,8 +626,8 @@ class IqIE(InfoExtractor):
note=f'Downloading format data for {self._BID_TAGS[bid]}', errnote='Unable to download format data', note=f'Downloading format data for {self._BID_TAGS[bid]}', errnote='Unable to download format data',
fatal=False), 'data', expected_type=dict) fatal=False), 'data', expected_type=dict)
video_format = next((video_format for video_format in traverse_obj( video_format = traverse_obj(format_data, ('program', 'video', lambda _, v: str(v['bid']) == bid),
format_data, ('program', 'video', ...), expected_type=dict, default=[]) if str(video_format['bid']) == bid), {}) expected_type=dict, default=[], get_all=False) or {}
extracted_formats = [] extracted_formats = []
if video_format.get('m3u8Url'): if video_format.get('m3u8Url'):
extracted_formats.extend(self._extract_m3u8_formats( extracted_formats.extend(self._extract_m3u8_formats(

View File

@ -5152,8 +5152,8 @@ def traverse_obj(
@param path_list A list of paths which are checked one by one. @param path_list A list of paths which are checked one by one.
Each path is a list of keys where each key is a string, Each path is a list of keys where each key is a string,
a function, a tuple of strings/None or "...". a function, a tuple of strings/None or "...".
When a fuction is given, it takes the key as argument and When a fuction is given, it takes the key and value as arguments
returns whether the key matches or not. When a tuple is given, and returns whether the key matches or not. When a tuple is given,
all the keys given in the tuple are traversed, and all the keys given in the tuple are traversed, and
"..." traverses all the keys in the object "..." traverses all the keys in the object
"None" returns the object without traversal "None" returns the object without traversal
@ -5198,7 +5198,7 @@ def traverse_obj(
obj = str(obj) obj = str(obj)
_current_depth += 1 _current_depth += 1
depth = max(depth, _current_depth) depth = max(depth, _current_depth)
return [_traverse_obj(v, path[i + 1:], _current_depth) for k, v in obj if key(k)] return [_traverse_obj(v, path[i + 1:], _current_depth) for k, v in obj if try_call(key, args=(k, v))]
elif isinstance(obj, dict) and not (is_user_input and key == ':'): elif isinstance(obj, dict) and not (is_user_input and key == ':'):
obj = (obj.get(key) if casesense or (key in obj) obj = (obj.get(key) if casesense or (key in obj)
else next((v for k, v in obj.items() if _lower(k) == key), None)) else next((v for k, v in obj.items() if _lower(k) == key), None))