def _perpetual_path_request(self, paths, length_params, perpetual_range_start=None, no_limit_req=False): """Perform a perpetual path request against the Shakti API to retrieve a possibly large video list. If the requested video list's size is larger than MAX_PATH_REQUEST_SIZE, multiple path requests will be executed with forward shifting range selectors and the results will be combined into one path response.""" response_type, length_args = length_params context_name = length_args[0] response_length = apipaths.LENGTH_ATTRIBUTES[response_type] request_size = apipaths.MAX_PATH_REQUEST_SIZE response_size = request_size + 1 # Note: when the request is made with 'genres' or 'seasons' context, # the response strangely does not respect the number of objects # requested, returning 1 more item, i couldn't understand why if context_name in ['genres', 'seasons']: response_size += 1 number_of_requests = 100 if no_limit_req else 2 perpetual_range_start = int(perpetual_range_start) if perpetual_range_start else 0 range_start = perpetual_range_start range_end = range_start + request_size merged_response = {} for n_req in range(number_of_requests): path_response = self._path_request( _set_range_selector(paths, range_start, range_end)) if not path_response: break if not common.check_path_exists(length_args, path_response): # It may happen that the number of items to be received # is equal to the number of the response_size # so a second round will be performed, which will return an empty list break common.merge_dicts(path_response, merged_response) response_count = response_length(path_response, *length_args) if response_count < response_size: # There are no other elements to request break range_start += response_size if n_req == (number_of_requests - 1): merged_response['_perpetual_range_selector'] = {'next_start': range_start} common.debug('{} has other elements, added _perpetual_range_selector item', response_type) else: range_end = range_start + request_size if perpetual_range_start > 0: previous_start = perpetual_range_start - (response_size * number_of_requests) if '_perpetual_range_selector' in merged_response: merged_response['_perpetual_range_selector']['previous_start'] = previous_start else: merged_response['_perpetual_range_selector'] = { 'previous_start': previous_start} return merged_response
def req_video_list_chunked(self, chunked_video_list, perpetual_range_selector=None): """Retrieve a video list which contains the video ids specified""" if not any(isinstance(item, list) for item in chunked_video_list): raise InvalidVideoListTypeError('The chunked_video_list not contains a list of a list of videoids') merged_response = {} for videoids_list in chunked_video_list: path = build_paths(['videos', videoids_list], VIDEO_LIST_PARTIAL_PATHS) path_response = self.nfsession.path_request(path) common.merge_dicts(path_response, merged_response) if perpetual_range_selector: merged_response.update(perpetual_range_selector) return CustomVideoList(merged_response)
def perpetual_path_request(self, paths, path_type, length_params1=None, length_params2=None): """Perform a perpetual path request against the Shakti API to retrieve a possibly large video list. If the requested video list's size is larger than MAX_PATH_REQUEST_SIZE, multiple path requests will be executed with forward shifting range selectors and the results will be combined into one path response.""" if length_params2 is None: length_params = [length_params1] else: length_params = [length_params1, length_params2] length = apipaths.LENGTH_ATTRIBUTES[path_type] range_start = 0 range_end = MAX_PATH_REQUEST_SIZE range_limit = int(g.ADDON.getSetting('list_limit_results'))\ if common.is_numeric(g.ADDON.getSetting('list_limit_results')) else 0 merged_response = {} while range_start < range_end: # We limit the number of results of the list, a very high number has more chance of causing, # AddonSignals call timed out, for the time it takes to request information # Would be more suitable that when you reach the end of the list, # you load the next block of results. if range_start >= range_limit > 0: range_start = range_end continue path_response = self._path_request( _set_range_selector(paths, range_start, range_end)) common.debug('perpetual_path_request path_response: ' + str(path_response)) range_start = range_end + 1 if len(path_response) != 0: common.merge_dicts(path_response, merged_response) videos_count = length(path_response, * length_params) - 1 #has zero base # If the number of video elements is lower, we've come to the end # Note: when the request is made with 'genre' context, # the response strangely does not respect the number of objects requested, # returning 2 more items, i couldn't understand why if videos_count >= MAX_PATH_REQUEST_SIZE: common.debug( '{} has more items, doing another path request'.format( path_type)) range_end += MAX_PATH_REQUEST_SIZE + 1 return merged_response
def perpetual_path_request(self, paths, length_params, perpetual_range_start=None): """Perform a perpetual path request against the Shakti API to retrieve a possibly large video list. If the requested video list's size is larger than MAX_PATH_REQUEST_SIZE, multiple path requests will be executed with forward shifting range selectors and the results will be combined into one path response.""" response_type, length_args = length_params context_name = length_args[0] response_length = apipaths.LENGTH_ATTRIBUTES[response_type] request_size = apipaths.MAX_PATH_REQUEST_SIZE response_size = request_size + 1 # Note: when the request is made with 'genres' context, # the response strangely does not respect the number of objects # requested, returning 1 more item, i couldn't understand why if context_name == 'genres': response_size += 1 number_of_requests = 2 perpetual_range_start = int(perpetual_range_start) if perpetual_range_start else 0 range_start = perpetual_range_start range_end = range_start + request_size merged_response = {} for n_req in range(number_of_requests): path_response = self._path_request(_set_range_selector(paths, range_start, range_end)) if len(path_response) != 0: common.merge_dicts(path_response, merged_response) response_count = response_length(path_response, *length_args) if response_count >= response_size: range_start += response_size if n_req == (number_of_requests - 1): merged_response['_perpetual_range_selector'] = {'next_start': range_start} common.debug('{} has other elements, added _perpetual_range_selector item'.format(response_type)) else: range_end = range_start + request_size else: # There are no other elements to request break else: break if perpetual_range_start > 0: previous_start = perpetual_range_start - (response_size * number_of_requests) if '_perpetual_range_selector' in merged_response: merged_response['_perpetual_range_selector']['previous_start'] = previous_start else: merged_response['_perpetual_range_selector'] = {'previous_start': previous_start} return merged_response
def chunked_custom_video_list(chunked_video_list): """Retrieve a video list which contains the videos specified by video_ids""" chunked_video_ids = chunked_video_list['video_ids'] common.debug('Requesting custom video list with {} chunked video list', len(chunked_video_ids)) merged_response = {} for video_ids in chunked_video_ids: path_response = common.make_call( 'path_request', build_paths(['videos', video_ids], VIDEO_LIST_PARTIAL_PATHS)) common.merge_dicts(path_response, merged_response) perpetual_range_selector = chunked_video_list['perpetual_range_selector'] if perpetual_range_selector: merged_response.update(perpetual_range_selector) return CustomVideoList(merged_response)
def perpetual_path_request(self, paths, path_type, length_params=None): """Perform a perpetual path request against the Shakti API to retrieve a possibly large video list. If the requested video list's size is larger than MAX_PATH_REQUEST_SIZE, multiple path requests will be executed with forward shifting range selectors and the results will be combined into one path response.""" length_params = length_params or [] length = apipaths.LENGTH_ATTRIBUTES[path_type] range_start = 0 range_end = MAX_PATH_REQUEST_SIZE merged_response = {} while range_start < range_end: path_response = self._path_request( _set_range_selector(paths, range_start, range_end)) common.merge_dicts(path_response, merged_response) range_start = range_end + 1 if length(path_response, *length_params) > range_end: common.debug( '{} has more items, doing another path request'.format( path_type)) range_end += MAX_PATH_REQUEST_SIZE return merged_response
def perpetual_path_request( self, paths, length_params, perpetual_range_start=None, request_size=apipaths.PATH_REQUEST_SIZE_PAGINATED, no_limit_req=False): """ Perform a perpetual path request against the Shakti API to retrieve a possibly large video list. :param paths: The paths that compose the request :param length_params: A list of two values, e.g. ['stdlist', [...]]: 1: A key of LENGTH_ATTRIBUTES that define where read the total number of objects 2: A list of keys used to get the list of objects in the JSON data of received response :param perpetual_range_start: defines the starting point of the range of objects to be requested :param request_size: defines the size of the range, the total number of objects that will be received :param no_limit_req: if True, the perpetual cycle of requests will be 'unlimited' :return: Union of all JSON raw data received """ # When the requested video list's size is larger than 'request_size', # multiple path requests will be executed with forward shifting range selectors # and the results will be combined into one path response. response_type, length_args = length_params context_name = length_args[0] response_length = apipaths.LENGTH_ATTRIBUTES[response_type] # Note: when the request is made with 'genres' or 'seasons' context, # the response strangely does not respect the number of objects # requested, returning 1 more item, i couldn't understand why if context_name in ['genres', 'seasons']: request_size -= 1 response_size = request_size + 1 if context_name in ['genres', 'seasons']: response_size += 1 number_of_requests = 100 if no_limit_req else int( G.ADDON.getSettingInt('page_results') / 45) perpetual_range_start = int( perpetual_range_start) if perpetual_range_start else 0 range_start = perpetual_range_start range_end = range_start + request_size merged_response = {} for n_req in range(number_of_requests): path_response = self.path_request( _set_range_selector(paths, range_start, range_end)) if not path_response: break if not common.check_path_exists(length_args, path_response): # It may happen that the number of items to be received # is equal to the number of the response_size # so a second round will be performed, which will return an empty list break common.merge_dicts(path_response, merged_response) response_count = response_length(path_response, *length_args) if response_count < response_size: # There are no other elements to request break range_start += response_size if n_req == (number_of_requests - 1): merged_response['_perpetual_range_selector'] = { 'next_start': range_start } common.debug( '{} has other elements, added _perpetual_range_selector item', response_type) else: range_end = range_start + request_size if perpetual_range_start > 0: previous_start = perpetual_range_start - (response_size * number_of_requests) if '_perpetual_range_selector' in merged_response: merged_response['_perpetual_range_selector'][ 'previous_start'] = previous_start else: merged_response['_perpetual_range_selector'] = { 'previous_start': previous_start } return merged_response