From 87d5b0c7b1c461a36bf77e08048dd2d00cdfc9ac Mon Sep 17 00:00:00 2001 From: CastagnaIT Date: Sat, 18 Nov 2023 17:20:06 +0100 Subject: [PATCH] Fix search by language menus --- resources/lib/navigation/directory_search.py | 6 ++-- .../nfsession/directorybuilder/dir_builder.py | 8 ++--- .../directorybuilder/dir_path_requests.py | 33 ++++++++++++++++++- resources/lib/utils/api_paths.py | 1 + resources/lib/utils/api_requests.py | 13 +++++--- resources/lib/utils/data_types.py | 18 ++++++++++ 6 files changed, 66 insertions(+), 13 deletions(-) diff --git a/resources/lib/navigation/directory_search.py b/resources/lib/navigation/directory_search.py index ad148d4d4..672ebb1dd 100644 --- a/resources/lib/navigation/directory_search.py +++ b/resources/lib/navigation/directory_search.py @@ -197,22 +197,20 @@ def exec_query(row_id, search_type, search_params, search_value, perpetual_range } dir_items, extra_data = common.make_call('get_video_list_search', call_args) elif search_type == 'audio_lang': - menu_data['query_without_reference'] = True call_args = { 'menu_data': menu_data, 'pathitems': ['search', 'search', row_id], 'perpetual_range_start': perpetual_range_start, - 'context_name': 'spokenAudio', + 'context_name': 'genres', 'context_id': common.convert_from_string(search_params, dict)['lang_code'] } dir_items, extra_data = common.make_call('get_video_list_sorted_sp', call_args) elif search_type == 'subtitles_lang': - menu_data['query_without_reference'] = True call_args = { 'menu_data': menu_data, 'pathitems': ['search', 'search', row_id], 'perpetual_range_start': perpetual_range_start, - 'context_name': 'subtitles', + 'context_name': 'genres', 'context_id': common.convert_from_string(search_params, dict)['lang_code'] } dir_items, extra_data = common.make_call('get_video_list_sorted_sp', call_args) diff --git a/resources/lib/services/nfsession/directorybuilder/dir_builder.py b/resources/lib/services/nfsession/directorybuilder/dir_builder.py index b7d6a971f..67e9c8165 100644 --- a/resources/lib/services/nfsession/directorybuilder/dir_builder.py +++ b/resources/lib/services/nfsession/directorybuilder/dir_builder.py @@ -105,10 +105,10 @@ def get_video_list_sorted(self, pathitems, menu_data, sub_genre_id, perpetual_ra @measure_exec_time_decorator(is_immediate=True) def get_video_list_sorted_sp(self, pathitems, menu_data, context_name, context_id, perpetual_range_start): # Method used for the menu search - video_list = self.req_video_list_sorted(context_name, - context_id=context_id, - perpetual_range_start=perpetual_range_start, - menu_data=menu_data) + video_list = self.req_videos_list_sorted(context_name, + context_id=context_id, + perpetual_range_start=perpetual_range_start, + menu_data=menu_data) return build_video_listing(video_list, menu_data, None, pathitems, perpetual_range_start, self.req_mylist_items()) diff --git a/resources/lib/services/nfsession/directorybuilder/dir_path_requests.py b/resources/lib/services/nfsession/directorybuilder/dir_path_requests.py index 90a7c9a8f..b8d4d4cc7 100644 --- a/resources/lib/services/nfsession/directorybuilder/dir_path_requests.py +++ b/resources/lib/services/nfsession/directorybuilder/dir_path_requests.py @@ -11,7 +11,8 @@ from resources.lib import common from resources.lib.utils.data_types import (VideoListSorted, SubgenreList, SeasonList, EpisodeList, LoCo, VideoList, - SearchVideoList, CustomVideoList, LoLoMoCategory, VideoListSupplemental) + SearchVideoList, CustomVideoList, LoLoMoCategory, VideoListSupplemental, + VideosList) from resources.lib.common.exceptions import InvalidVideoListTypeError, InvalidVideoId from resources.lib.utils.api_paths import (VIDEO_LIST_PARTIAL_PATHS, RANGE_PLACEHOLDER, VIDEO_LIST_BASIC_PARTIAL_PATHS, SEASONS_PARTIAL_PATHS, EPISODES_PARTIAL_PATHS, ART_PARTIAL_PATHS, @@ -187,6 +188,36 @@ def req_video_list_sorted(self, context_name, context_id=None, perpetual_range_s path_response = self.nfsession.perpetual_path_request(paths, [response_type, base_path], perpetual_range_start) return VideoListSorted(path_response, context_name, context_id, req_sort_order_type) + + @cache_utils.cache_output(cache_utils.CACHE_COMMON, identify_from_kwarg_name='context_id', + identify_append_from_kwarg_name='perpetual_range_start', ignore_self_class=True) + def req_videos_list_sorted(self, context_name, context_id=None, perpetual_range_start=None, menu_data=None): + """Retrieve a video's list sorted""" + # This type of request allows to obtain more than ~40 results + LOG.debug('Requesting video\'s list sorted for context name: "{}", context id: "{}"', + context_name, context_id) + base_path = [context_name] + response_type = 'videoslist' + if context_id: + base_path.append(context_id) + + # enum order: AZ|ZA|Suggested|Year + # sort order the "mylist" is supported only in US country, the only way to query is use 'az' + sort_order_types = ['az', 'za', 'su', 'yr'] if context_name != 'mylist' else ['az', 'az'] + req_sort_order_type = sort_order_types[ + int(G.ADDON.getSettingInt('menu_sortorder_' + menu_data.get('initial_menu_id', menu_data['path'][1]))) + ] + base_path.append(req_sort_order_type) + _base_path = list(base_path) + _base_path.append(RANGE_PLACEHOLDER) + if not menu_data.get('query_without_reference', False): + _base_path.append('reference') + paths = (build_paths(_base_path, VIDEO_LIST_PARTIAL_PATHS) + + [base_path[:-1] + [['id', 'name', 'requestId', 'trackIds']]]) + + path_response = self.nfsession.perpetual_path_request(paths, [response_type, ['videos']], perpetual_range_start) + return VideosList(path_response) + @cache_utils.cache_output(cache_utils.CACHE_SUPPLEMENTAL, identify_append_from_kwarg_name='supplemental_type', ignore_self_class=True) def req_video_list_supplemental(self, videoid, supplemental_type): diff --git a/resources/lib/utils/api_paths.py b/resources/lib/utils/api_paths.py index e260ac44c..049685d88 100644 --- a/resources/lib/utils/api_paths.py +++ b/resources/lib/utils/api_paths.py @@ -30,6 +30,7 @@ 'stdlist': lambda r, context, key: jgrapgh_len(r[context][key]), 'stdlist_wid': lambda r, context, uid, key: jgrapgh_len(r[context][uid][key]), 'searchlist': lambda r, context, key: len(list(r[context][key].values())[0]), + 'videoslist': lambda r, list_name: jgrapgh_len(r[list_name]) } """Predefined lambda expressions that return the number of video results within a path response dict""" diff --git a/resources/lib/utils/api_requests.py b/resources/lib/utils/api_requests.py index 05453a08b..b75039823 100644 --- a/resources/lib/utils/api_requests.py +++ b/resources/lib/utils/api_requests.py @@ -218,27 +218,32 @@ def verify_profile_lock(guid, pin): def get_available_audio_languages(): """Get the list of available audio languages of videos""" + # originalAudioLanguages genres: 81555714 call_args = { - 'paths': [['spokenAudioLanguages', {'from': 0, 'to': 25}, ['id', 'name']]] + 'paths': [['genres', 81555714, 'subgenres', {'to': 50}, ['id', 'name', 'languageCode']]] } response = common.make_call('path_request', call_args) lang_list = {} - for lang_dict in response.get('spokenAudioLanguages', {}).values(): + data_list = response.get('genres', {}).get('81555714', {}).get('subgenres', {}) + for lang_dict in data_list.values(): lang_id = lang_dict['id'].get('value') if lang_id is None: # If none the list is ended break lang_list[lang_id] = lang_dict['name']['value'] return lang_list +# todo: dubbingLanguages genres: 81586478 def get_available_subtitles_languages(): """Get the list of available subtitles languages of videos""" + # subtitleLanguages genres: 81586477 call_args = { - 'paths': [['subtitleLanguages', {'from': 0, 'to': 25}, ['id', 'name']]] + 'paths': [['genres', 81586477, 'subgenres', {'to': 50}, ['id', 'name', 'languageCode']]] } response = common.make_call('path_request', call_args) lang_list = {} - for lang_dict in response.get('subtitleLanguages', {}).values(): + data_list = response.get('genres', {}).get('81586477', {}).get('subgenres', {}) + for lang_dict in data_list.values(): lang_id = lang_dict['id'].get('value') if lang_id is None: # If none the list is ended break diff --git a/resources/lib/utils/data_types.py b/resources/lib/utils/data_types.py index 1502f73cc..135d958c5 100644 --- a/resources/lib/utils/data_types.py +++ b/resources/lib/utils/data_types.py @@ -221,6 +221,24 @@ def get(self, key, default=None): return _check_sentinel(self.data.get(key, default)) +class VideosList: + """A video's list""" + def __init__(self, path_response): + # LOG.debug('VideosList data: {}', path_response) + self.perpetual_range_selector = path_response.get('_perpetual_range_selector') + self.data = path_response + self.videos = OrderedDict(self.data.get('videos', {})) + self.artitem = list(self.videos.values())[0] if self.videos else None + self.contained_titles = _get_titles(self.videos) + + def __getitem__(self, key): + return _check_sentinel(self.data[key]) + + def get(self, key, default=None): + """Pass call on to the backing dict of this VideoList.""" + return _check_sentinel(self.data.get(key, default)) + + class SeasonList: """A list of seasons. Includes tvshow art.""" def __init__(self, videoid, path_response):