Esempio n. 1
0
	def wait_for_infolabel(self, label_name, expected_value, sleep_msecs=5, cycles=1000):

		# sadly it's necessary to wait until kodi has the new Container infolabel ...
		label_value = ''
		counter = 0

		while counter <= cycles:
			counter += 1
			xbmc_sleep(sleep_msecs)
			label_value = str(getInfoLabel(label_name))
			if label_value == expected_value:
				break

		self.log_debug('wait_for_infolabel {}: msecs waited: {} values do match {} final value {}', label_name,
		               (counter * sleep_msecs), (expected_value == label_value), label_value)
Esempio n. 2
0
	def set_folder(self, list_items, pluginurl, pluginhandle, pluginquery, folder_type, title=None):

		folder_defs = CONST['FOLDERS'].get(folder_type)
		old_pluginurl = getInfoLabel('Container.FolderPath')
		old_postion = getInfoLabel('Container.CurrentItem')

		addDirectoryItems(pluginhandle, list_items, len(list_items))

		if title is not None:
			setPluginCategory(pluginhandle, title)

		if 'content_type' in folder_defs.keys():
			self.log_debug('set_folder: set content_type: {}', folder_defs['content_type'])
			setContent(pluginhandle, folder_defs['content_type'])
		endOfDirectory(handle=pluginhandle,
		               cacheToDisc=(folder_defs.get('cacheable', False) and (self.get_bool_setting('disable_foldercache') is False)))

		self.wait_for_infolabel('Container.FolderPath', compat._format('{}{}', pluginurl, pluginquery))

		if 'view_mode' in folder_defs.keys():
			self.set_view_mode(folder_defs['view_mode'])

		if 'sort' in folder_defs.keys():
			self.set_folder_sort(folder_defs['sort'])

		# reset the postion to the last "known" if it is gt 1, if pluginurls matching -> likely to be a 'refresh'
		if getInfoLabel('Container.FolderPath') == old_pluginurl and old_postion.isdigit() and int(old_postion) > 1:
			from xbmcgui import Window, getCurrentWindowId, getCurrentWindowDialogId

			# wait untl all Dialogs are closed; 10099 => WINDOW_DIALOG_POINTER => smallest dialog_id; max 500 msecs
			dialog_wait_counter = 0
			while dialog_wait_counter <= 100 and getCurrentWindowDialogId() >= 10099:
				xbmc_sleep(5)
				dialog_wait_counter += 1
			self.log_debug('waited {} msecs for all dialogs to be closed', (dialog_wait_counter * 5))

			self.log_debug('FolderPath old pos {} ', old_postion)
			focus_id = Window(getCurrentWindowId()).getFocusId()
			set_postion = old_postion

			cmd = compat._format('Control.SetFocus({},{})', focus_id, set_postion)
			executebuiltin(cmd)
			self.log_debug('set current pos executebuiltin({})', cmd)

			# wait for the correct postion to be applied; max 500 msecs
			self.wait_for_infolabel('Container.CurrentItem', old_postion, cycles=100)
Esempio n. 3
0
	def get_graphql_response(self, operation, variables={}, retry_count=0, force_refresh_auth=False, force_cache=False):

		xbmc_helper().log_debug('get_graphql_response: Operation: {}', operation)

		if isinstance(CONST['GRAPHQL'][operation].get('REQUIRED_VARIABLES', None), list):
			for required_var in CONST['GRAPHQL'][operation]['REQUIRED_VARIABLES']:
				if required_var not in variables.keys():
					if required_var in CONST['GRAPHQL']['STATIC_VARIABLES'].keys():
						variables.update({required_var: CONST['GRAPHQL']['STATIC_VARIABLES'][required_var]})
					else:
						xbmc_helper().log_error('Not all required variables set for operation {} required var {} set vars{}', operation,
						                        required_var, variables)
						exit(0)

		if force_refresh_auth is True:
			self.get_auth_token(force_refresh=True)

		request_url = CONST['GRAPHQL']['API_URL']

		if CONST['GRAPHQL'][operation].get('BOOKMARKS', False) is True and self.get_auth_token().get('has_account', False) is False:
			query = CONST['GRAPHQL'][operation]['QUERY'].replace('isBookmarked ', '')
		else:
			query = CONST['GRAPHQL'][operation]['QUERY']

		params = {
		        'query':
		        compat._format(
		                '{} {} {}', 'query' if CONST['GRAPHQL'][operation].get('IS_MUTATION', False) is False else 'mutation', ''
		                if CONST['GRAPHQL'][operation].get('OPERATION', None) is None else CONST['GRAPHQL'][operation]['OPERATION'],
		                query)
		}

		if len(variables.keys()) != 0:
			if CONST['GRAPHQL'][operation].get('IS_MUTATION', False) is False:
				params.update({'variables': dumps(variables)})
			else:
				params.update({'variables': variables})

		if CONST['GRAPHQL'][operation].get('OPERATION', None) is not None:
			params.update({
			        'operationName': CONST['GRAPHQL'][operation].get('OPERATION'),
			        'extensions': {
			                'persistedQuery': {
			                        'version': 1,
			                        'sha256Hash': sha256(params['query'].encode('utf-8')).hexdigest(),
			                },
			        }
			})

			if CONST['GRAPHQL'][operation].get('IS_MUTATION', False) is False:
				params.update({'extensions': dumps(params['extensions'])})

		headers = copy(self.config['GRAPHQL_HEADERS'])

		account_state = False
		if operation != 'ACCOUNT' and operation != 'USER_PROFILE' and self.get_auth_token().get('has_account', False) is not False:
			account_state = self.get_account_state()
			if account_state is not False:
				headers.append(('Joyn-User-State', account_state))

		headers.append(('Authorization', self.get_access_token()))

		api_response = {}
		no_cache = False if force_cache is True else CONST['GRAPHQL'][operation].get('NO_CACHE', False)

		try:
			if CONST['GRAPHQL'][operation].get('IS_MUTATION', False) is False:

				api_response = request_helper.get_json_response(url=request_url,
				                                                config=self.config,
				                                                params=params,
				                                                headers=headers,
				                                                no_cache=no_cache,
				                                                return_json_errors=['INVALID_JWT'])
			else:
				api_response = request_helper.post_json(url=request_url,
				                                        config=self.config,
				                                        data=params,
				                                        additional_headers=headers,
				                                        no_cache=no_cache,
				                                        return_json_errors=['INVALID_JWT'])

			if isinstance(api_response, dict) and 'json_errors' in api_response.keys():
				if 'INVALID_JWT' in api_response['json_errors']:
					self.get_graphql_response(operation=operation, variables=variables, retry_count=retry_count, force_refresh_auth=True)

		except Exception as e:
			xbmc_helper().log_error('Could not complete graphql request: {} params {}', e, params)

		if isinstance(api_response, dict) and 'errors' in api_response.keys():
			xbmc_helper().log_error('GraphQL query returned errors: {} params {}', api_response['errors'], params)

		if isinstance(api_response, dict) and 'data' in api_response.keys() and api_response['data'] is not None:
			return api_response['data']
		else:
			xbmc_helper().log_error('GraphQL query returned no data - response: {} params {}', api_response, params)

			if retry_count < 3:
				xbmc_helper().log_error('Retrying to complete graphql request ... retry count: {}', retry_count)
				xbmc_sleep(500)
				return self.get_graphql_response(operation=operation, variables=variables, retry_count=(retry_count + 1))
			else:
				xbmc_helper().notification(
				        compat._format(xbmc_helper().translation('ERROR'), 'GraphQL'),
				        xbmc_helper().translation('MSG_GAPHQL_ERROR'),
				)
				exit(0)