def _get_url(self, url, params=None, data=None, headers=None, cache_limit=1): if headers is None: headers = {} if data is not None: if isinstance(data, basestring): data = data else: data = urllib.urlencode(data, True) if not url.startswith('http'): url = '%s%s%s' % (self.protocol, self.BASE_URL, url) if params: url += '?' + urllib.urlencode(params) _created, cached_headers, html = db_connection.get_cached_url(url, data, cache_limit=cache_limit) if html: logger.log('Using Cached result for: %s' % (url)) result = html res_headers = dict(cached_headers) else: try: headers['Accept-Encoding'] = 'gzip' logger.log('+++Image Scraper Call: %s, header: %s, data: %s cache_limit: %s' % (url, headers, data, cache_limit), log_utils.LOGDEBUG) request = urllib2.Request(url, data=data, headers=headers) response = urllib2.urlopen(request) result = '' while True: data = response.read() if not data: break result += data res_headers = dict(response.info().items()) if res_headers.get('content-encoding') == 'gzip': result = utils2.ungz(result) db_connection.cache_url(url, result, data, res_header=res_headers) except (ssl.SSLError, socket.timeout) as e: logger.log('Image Scraper Timeout: %s' % (url)) return {} except urllib2.HTTPError as e: if e.code != 404: logger.log('HTTP Error (%s) during image scraper http get: %s' % (e, url), log_utils.LOGWARNING) return {} except Exception as e: logger.log('Error (%s) during image scraper http get: %s' % (str(e), url), log_utils.LOGWARNING) return {} try: if 'application/json' in res_headers.get('content-type', ''): return_data = utils.json_loads_as_str(result) else: # try/except to handle older responses that might be missing headers try: return_data = utils.json_loads_as_str(result) except ValueError: return_data = result except ValueError: return_data = '' if result: logger.log('Invalid JSON API Response: %s - |%s|' % (url, return_data), log_utils.LOGERROR) return return_data
def getTraktAsJson(url, post=None): try: r, res_headers = __getTrakt(url, post) r = utils.json_loads_as_str(r) if 'X-Sort-By' in res_headers and 'X-Sort-How' in res_headers: r = sort_list(res_headers['X-Sort-By'], res_headers['X-Sort-How'], r) return r except: pass
def _get_url(self, url, params=None, data=None, headers=None): if headers is None: headers = {} if data is not None: if isinstance(data, basestring): data = data else: data = urllib.urlencode(data, True) url = "%s%s%s" % (self.protocol, self.BASE_URL, url) if params: url = url + "?" + urllib.urlencode(params) log_utils.log("Calling: %s" % (url)) db_connection = _get_db_connection() _created, _res_header, html = db_connection.get_cached_url(url, data, cache_limit=1) if html: log_utils.log("Using Cached result for: %s" % (url)) result = html else: try: request = urllib2.Request(url, data=data, headers=headers) response = urllib2.urlopen(request) result = "" while True: data = response.read() if not data: break result += data db_connection.cache_url(url, result, data) except (ssl.SSLError, socket.timeout) as e: log_utils.log("Image Scraper Timeout: %s" % (url)) return {} except urllib2.HTTPError as e: if e.code != 404: log_utils.log("HTTP Error (%s) during image scraper http get: %s" % (e, url)) return {} except Exception as e: log_utils.log("Error (%s) during image scraper http get: %s" % (str(e), url), log_utils.LOGWARNING) return {} try: js_data = utils.json_loads_as_str(result) except ValueError: js_data = "" if result: log_utils.log("Invalid JSON API Response: %s - |%s|" % (url, js_data), log_utils.LOGERROR) return js_data
def authTrakt(): try: if getTraktCredentialsInfo() == True: if control.yesnoDialog(control.lang(32511).encode('utf-8'), control.lang(32512).encode('utf-8'), '', 'Trakt'): control.setSetting(id='trakt.user', value='') control.setSetting(id='trakt.token', value='') control.setSetting(id='trakt.refresh', value='') raise Exception() result = getTraktAsJson('/oauth/device/code', {'client_id': V2_API_KEY}) verification_url = (control.lang(32513) % result['verification_url']).encode('utf-8') user_code = (control.lang(32514) % result['user_code']).encode('utf-8') expires_in = int(result['expires_in']) device_code = result['device_code'] interval = result['interval'] progressDialog = control.progressDialog progressDialog.create('Trakt', verification_url, user_code) for i in range(0, expires_in): try: if progressDialog.iscanceled(): break time.sleep(1) if not float(i) % interval == 0: raise Exception() r = getTraktAsJson('/oauth/device/token', {'client_id': V2_API_KEY, 'client_secret': CLIENT_SECRET, 'code': device_code}) if 'access_token' in r: break except: pass try: progressDialog.close() except: pass token, refresh = r['access_token'], r['refresh_token'] headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2, 'Authorization': 'Bearer %s' % token} result = client.request(urlparse.urljoin(BASE_URL, '/users/me'), headers=headers) result = utils.json_loads_as_str(result) user = result['username'] control.setSetting(id='trakt.user', value=user) control.setSetting(id='trakt.token', value=token) control.setSetting(id='trakt.refresh', value=refresh) raise Exception() except: control.openSettings('4.1')
def __getTrakt(url, post=None): try: url = urlparse.urljoin(BASE_URL, url) post = json.dumps(post) if post else None headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2} if getTraktCredentialsInfo(): headers.update({'Authorization': 'Bearer %s' % control.setting('trakt.token')}) result = client.request(url, post=post, headers=headers, output='extended', error=True) resp_code = result[1] resp_header = result[2] result = result[0] if resp_code in ['500', '502', '503', '504', '520', '521', '522', '524']: log_utils.log('Temporary Trakt Error: %s' % resp_code, log_utils.LOGWARNING) return elif resp_code in ['404']: log_utils.log('Object Not Found : %s' % resp_code, log_utils.LOGWARNING) return # elif resp_code in ['429']: # log_utils.log('Trakt Rate Limit Reached: %s' % resp_code, log_utils.LOGWARNING) # return if resp_code not in ['401', '405']: return result, resp_header oauth = urlparse.urljoin(BASE_URL, '/oauth/token') opost = {'client_id': V2_API_KEY, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'refresh_token', 'refresh_token': control.setting('trakt.refresh')} result = client.request(oauth, post=json.dumps(opost), headers=headers) result = utils.json_loads_as_str(result) token, refresh = result['access_token'], result['refresh_token'] control.setSetting(id='trakt.token', value=token) control.setSetting(id='trakt.refresh', value=refresh) headers['Authorization'] = 'Bearer %s' % token result = client.request(url, post=post, headers=headers, output='extended', error=True) return result[0], result[2] except Exception as e: log_utils.log('Unknown Trakt Error: %s' % e, log_utils.LOGWARNING) pass
def manager(name, imdb, tvdb, content): try: post = {"movies": [{"ids": {"imdb": imdb}}]} if content == 'movie' else {"shows": [{"ids": {"tvdb": tvdb}}]} items = [(control.lang(32516).encode('utf-8'), '/sync/collection')] items += [(control.lang(32517).encode('utf-8'), '/sync/collection/remove')] items += [(control.lang(32518).encode('utf-8'), '/sync/watchlist')] items += [(control.lang(32519).encode('utf-8'), '/sync/watchlist/remove')] items += [(control.lang(32520).encode('utf-8'), '/users/me/lists/%s/items')] result = getTraktAsJson('/users/me/lists') lists = [(i['name'], i['ids']['slug']) for i in result] lists = [lists[i//2] for i in range(len(lists)*2)] for i in range(0, len(lists), 2): lists[i] = ((control.lang(32521) % lists[i][0]).encode('utf-8'), '/users/me/lists/%s/items' % lists[i][1]) for i in range(1, len(lists), 2): lists[i] = ((control.lang(32522) % lists[i][0]).encode('utf-8'), '/users/me/lists/%s/items/remove' % lists[i][1]) items += lists select = control.selectDialog([i[0] for i in items], control.lang(32515).encode('utf-8')) if select == -1: return elif select == 4: t = control.lang(32520).encode('utf-8') k = control.keyboard('', t) ; k.doModal() new = k.getText() if k.isConfirmed() else None if (new == None or new == ''): return result = __getTrakt('/users/me/lists', post={"name": new, "privacy": "private"})[0] try: slug = utils.json_loads_as_str(result)['ids']['slug'] except: return control.infoDialog(control.lang(32515).encode('utf-8'), heading=str(name), sound=True, icon='ERROR') result = __getTrakt(items[select][1] % slug, post=post)[0] else: result = __getTrakt(items[select][1], post=post)[0] icon = control.infoLabel('ListItem.Icon') if not result == None else 'ERROR' control.infoDialog(control.lang(32515).encode('utf-8'), heading=str(name), sound=True, icon=icon) except: return
def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=.25, cached=True): res_headers = {} if not cached: cache_limit = 0 if self.offline: db_cache_limit = int(time.time()) / 60 / 60 else: if cache_limit > 8: db_cache_limit = cache_limit else: db_cache_limit = 8 json_data = json.dumps(data) if data else None headers = { 'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2, 'Accept-Encoding': 'gzip' } url = '%s%s%s' % (self.protocol, BASE_URL, url) if params: url += '?' + urllib.urlencode(params) db_connection = self.__get_db_connection() created, cached_headers, cached_result = db_connection.get_cached_url( url, json_data, db_cache_limit) if cached_result and (self.offline or (time.time() - created) < (60 * 60 * cache_limit)): result = cached_result res_headers = dict(cached_headers) logger.log('***Using cached result for: %s' % (url), log_utils.LOGDEBUG) else: auth_retry = False while True: try: if auth: headers.update( {'Authorization': 'Bearer %s' % (self.token)}) logger.log( '***Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s' % (url, headers, json_data, cache_limit, cached), log_utils.LOGDEBUG) request = urllib2.Request(url, data=json_data, headers=headers) if method is not None: request.get_method = lambda: method.upper() response = urllib2.urlopen(request, timeout=self.timeout) result = '' while True: data = response.read() if not data: break result += data res_headers = dict(response.info().items()) if res_headers.get('content-encoding') == 'gzip': result = utils2.ungz(result) db_connection.cache_url(url, result, json_data, response.info().items()) break except (ssl.SSLError, socket.timeout) as e: if cached_result: result = cached_result logger.log( 'Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) except urllib2.URLError as e: if isinstance(e, urllib2.HTTPError): if e.code in TEMP_ERRORS: if cached_result: result = cached_result logger.log( 'Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError( 'Temporary Trakt Error: ' + str(e)) elif e.code == 401 or e.code == 405: # token is fine, profile is private if e.info().getheader('X-Private-User') == 'true': raise TraktAuthError( 'Object is No Longer Available (%s)' % (e.code)) # auth failure retry or a token request elif auth_retry or url.endswith('/oauth/token'): self.token = None kodi.set_setting('trakt_oauth_token', '') kodi.set_setting('trakt_refresh_token', '') raise TraktAuthError( 'Trakt Call Authentication Failed (%s)' % (e.code)) # first try token fail, try to refresh token else: result = self.refresh_token( kodi.get_setting('trakt_refresh_token')) self.token = result['access_token'] kodi.set_setting('trakt_oauth_token', result['access_token']) kodi.set_setting('trakt_refresh_token', result['refresh_token']) auth_retry = True elif e.code == 404: raise TraktNotFoundError( 'Object Not Found (%s): %s' % (e.code, url)) else: raise elif isinstance(e.reason, socket.timeout) or isinstance( e.reason, ssl.SSLError): if cached_result: result = cached_result logger.log( 'Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError( 'Temporary Trakt Error: ' + str(e)) else: raise TraktError('Trakt Error: ' + str(e)) except: raise try: js_data = utils.json_loads_as_str(result) if 'x-sort-by' in res_headers and 'x-sort-how' in res_headers: js_data = utils2.sort_list(res_headers['x-sort-by'], res_headers['x-sort-how'], js_data) except ValueError: js_data = '' if result: logger.log( 'Invalid JSON Trakt API Response: %s - |%s|' % (url, js_data), log_utils.LOGERROR) # logger.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG) return js_data
def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=.25, cached=True): res_headers = {} if not cached: cache_limit = 0 if self.offline: db_cache_limit = int(time.time()) / 60 / 60 else: if cache_limit > 8: db_cache_limit = cache_limit else: db_cache_limit = 8 json_data = json.dumps(data) if data else None headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2, 'Accept-Encoding': 'gzip'} url = '%s%s%s' % (self.protocol, BASE_URL, url) if params: url += '?' + urllib.urlencode(params) db_connection = self.__get_db_connection() created, cached_headers, cached_result = db_connection.get_cached_url(url, json_data, db_cache_limit) if cached_result and (self.offline or (time.time() - created) < (60 * 60 * cache_limit)): result = cached_result res_headers = dict(cached_headers) logger.log('***Using cached result for: %s' % (url), log_utils.LOGDEBUG) else: auth_retry = False while True: try: if auth: headers.update({'Authorization': 'Bearer %s' % (self.token)}) logger.log('***Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s' % (url, headers, json_data, cache_limit, cached), log_utils.LOGDEBUG) request = urllib2.Request(url, data=json_data, headers=headers) if method is not None: request.get_method = lambda: method.upper() response = urllib2.urlopen(request, timeout=self.timeout) result = '' while True: data = response.read() if not data: break result += data res_headers = dict(response.info().items()) if res_headers.get('content-encoding') == 'gzip': result = utils2.ungz(result) db_connection.cache_url(url, result, json_data, response.info().items()) break except (ssl.SSLError, socket.timeout) as e: if cached_result: result = cached_result logger.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) except urllib2.URLError as e: if isinstance(e, urllib2.HTTPError): if e.code in TEMP_ERRORS: if cached_result: result = cached_result logger.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) elif e.code == 401 or e.code == 405: # token is fine, profile is private if e.info().getheader('X-Private-User') == 'true': raise TraktAuthError('Object is No Longer Available (%s)' % (e.code)) # auth failure retry or a token request elif auth_retry or url.endswith('/oauth/token'): self.token = None kodi.set_setting('trakt_oauth_token', '') kodi.set_setting('trakt_refresh_token', '') raise TraktAuthError('Trakt Call Authentication Failed (%s)' % (e.code)) # first try token fail, try to refresh token else: result = self.refresh_token(kodi.get_setting('trakt_refresh_token')) self.token = result['access_token'] kodi.set_setting('trakt_oauth_token', result['access_token']) kodi.set_setting('trakt_refresh_token', result['refresh_token']) auth_retry = True elif e.code == 404: raise TraktNotFoundError('Object Not Found (%s): %s' % (e.code, url)) else: raise elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError): if cached_result: result = cached_result logger.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) else: raise TraktError('Trakt Error: ' + str(e)) except: raise try: js_data = utils.json_loads_as_str(result) if 'x-sort-by' in res_headers and 'x-sort-how' in res_headers: js_data = utils2.sort_list(res_headers['x-sort-by'], res_headers['x-sort-how'], js_data) except ValueError: js_data = '' if result: logger.log('Invalid JSON Trakt API Response: %s - |%s|' % (url, js_data), log_utils.LOGERROR) # logger.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG) return js_data
def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=.25, cached=True): if not cached: cache_limit = 0 json_data = json.dumps(data) if data else None headers = { 'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2 } url = '%s%s%s' % (self.protocol, BASE_URL, url) if params: url = url + '?' + urllib.urlencode(params) args = [url] kwargs = { 'method': method, 'data': data, 'params': params, 'auth': auth } func_name = '__call_trakt' cached, cached_result = cache._get_func(func_name, args=args, kwargs=kwargs, cache_limit=cache_limit) if cached: result = cached_result logger.log('***Using cached result for: %s' % (url), log_utils.LOGDEBUG) else: auth_retry = False while True: try: if auth: headers.update( {'Authorization': 'Bearer %s' % (self.token)}) logger.log( '***Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s' % (url, headers, json_data, cache_limit, cached), log_utils.LOGDEBUG) request = urllib2.Request(url, data=json_data, headers=headers) if method is not None: request.get_method = lambda: method.upper() response = urllib2.urlopen(request, timeout=self.timeout) result = '' while True: data = response.read() if not data: break result += data cache._save_func(func_name, args=args, kwargs=kwargs, result=result) break except (ssl.SSLError, socket.timeout) as e: if cached_result: result = cached_result logger.log( 'Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) except urllib2.URLError as e: if isinstance(e, urllib2.HTTPError): if e.code in TEMP_ERRORS: if cached_result: result = cached_result logger.log( 'Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError( 'Temporary Trakt Error: ' + str(e)) elif e.code == 401 or e.code == 405: # token is fine, profile is private if e.info().getheader('X-Private-User') == 'true': raise TraktAuthError( 'Object is No Longer Available (%s)' % (e.code)) # auth failure retry or a token request elif auth_retry or url.endswith('/oauth/token'): self.token = None kodi.set_setting('trakt_oauth_token', '') kodi.set_setting('trakt_refresh_token', '') raise TraktAuthError( 'Trakt Call Authentication Failed (%s)' % (e.code)) # first try token fail, try to refresh token else: result = self.refresh_token( kodi.get_setting('trakt_refresh_token')) self.token = result['access_token'] kodi.set_setting('trakt_oauth_token', result['access_token']) kodi.set_setting('trakt_refresh_token', result['refresh_token']) auth_retry = True elif e.code == 404: raise TraktNotFoundError('Object Not Found (%s)' % (e.code)) else: raise elif isinstance(e.reason, socket.timeout) or isinstance( e.reason, ssl.SSLError): if cached_result: result = cached_result logger.log( 'Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError( 'Temporary Trakt Error: ' + str(e)) else: raise TraktError('Trakt Error: ' + str(e)) except: raise try: js_data = utils.json_loads_as_str(result) except ValueError: js_data = '' if result: logger.log( 'Invalid JSON Trakt API Response: %s - |%s|' % (url, js_data), log_utils.LOGERROR) # logger.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG) return js_data
def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=.25, cached=True): if not cached: cache_limit = 0 json_data = json.dumps(data) if data else None headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2} url = '%s%s%s' % (self.protocol, BASE_URL, url) if params: url = url + '?' + urllib.urlencode(params) args = [url] kwargs = {'method': method, 'data': data, 'params': params, 'auth': auth} func_name = '__call_trakt' cached, cached_result = cache._get_func(func_name, args=args, kwargs=kwargs, cache_limit=cache_limit) if cached: result = cached_result log_utils.log('***Using cached result for: %s' % (url), log_utils.LOGDEBUG) else: auth_retry = False while True: try: if auth: headers.update({'Authorization': 'Bearer %s' % (self.token)}) log_utils.log('***Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s' % (url, headers, json_data, cache_limit, cached), log_utils.LOGDEBUG) request = urllib2.Request(url, data=json_data, headers=headers) if method is not None: request.get_method = lambda: method.upper() response = urllib2.urlopen(request, timeout=self.timeout) result = '' while True: data = response.read() if not data: break result += data cache._save_func(func_name, args=args, kwargs=kwargs, result=result) break except (ssl.SSLError, socket.timeout) as e: if cached_result: result = cached_result log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) except urllib2.URLError as e: if isinstance(e, urllib2.HTTPError): if e.code in TEMP_ERRORS: if cached_result: result = cached_result log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) elif e.code == 401 or e.code == 405: # token is fine, profile is private if e.info().getheader('X-Private-User') == 'true': raise TraktAuthError('Object is No Longer Available (%s)' % (e.code)) # auth failure retry or a token request elif auth_retry or url.endswith('/oauth/token'): self.token = None kodi.set_setting('trakt_oauth_token', '') kodi.set_setting('trakt_refresh_token', '') raise TraktAuthError('Trakt Call Authentication Failed (%s)' % (e.code)) # first try token fail, try to refresh token else: result = self.refresh_token(kodi.get_setting('trakt_refresh_token')) self.token = result['access_token'] kodi.set_setting('trakt_oauth_token', result['access_token']) kodi.set_setting('trakt_refresh_token', result['refresh_token']) auth_retry = True elif e.code == 404: raise TraktNotFoundError('Object Not Found (%s)' % (e.code)) else: raise elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError): if cached_result: result = cached_result log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING) break else: raise TransientTraktError('Temporary Trakt Error: ' + str(e)) else: raise TraktError('Trakt Error: ' + str(e)) except: raise try: js_data = utils.json_loads_as_str(result) except ValueError: js_data = '' if result: log_utils.log('Invalid JSON Trakt API Response: %s - |%s|' % (url, js_data), log_utils.LOGERROR) # log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG) return js_data