def sync_activities(self, silent=False): with GlobalLock("trakt.sync"): trakt_auth = g.get_setting("trakt.auth") update_time = str(datetime.utcnow().strftime(g.DATE_TIME_FORMAT)) if not trakt_auth: g.log("TraktSync: No Trakt auth present, no sync will occur", "warning") return self.refresh_activities() remote_activities = self.fetch_remote_activities(silent) if remote_activities is None: g.log( "Activities Sync Failure: Unable to connect to Trakt or activities called to often", "error") return True if self.requires_update(remote_activities["all"], self.activities["all_activities"]): self._check_for_first_run(silent, trakt_auth) self._do_sync_acitivites(remote_activities) self._finalize_process(update_time) self._update_all_shows_statisics() self._update_all_season_statistics() return self.sync_errors
def try_refresh_token(self, force=False): """ Attempts to refresh current Trakt Auth Token :param force: Set to True to force refresh :return: None """ if not self.refresh_token: return if not force and self.token_expires > float(time.time()): return try: with GlobalLock(self.__class__.__name__, True, self.access_token): g.log("Trakt Token requires refreshing...") response = self.post( "/oauth/token", { "refresh_token": self.refresh_token, "client_id": self.client_id, "client_secret": self.client_secret, "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", "grant_type": "refresh_token", }, ).json() self._save_settings(response) g.log("Refreshed Trakt Token") except RanOnceAlready: self._load_settings() return
def try_refresh_token(self, force=False): if not force and self.tokenExpires > float(time.time()): return try: with GlobalLock(self.__class__.__name__, True, self.jwToken) as lock: try: g.log("TVDB Token requires refreshing...") response = self.session.post( tools.urljoin(self.baseUrl, "refresh_token"), headers=self._get_headers(), ).json() if "Error" in response: response = self.session.post( self.baseUrl + "login", json={ "apikey": self.apiKey }, headers=self._get_headers(), ).json() self._save_settings(response) g.log("Refreshed Tvdbs Token") except Exception: g.log("Failed to refresh Tvdb Access Token", "error") return except RanOnceAlready: return
def sync_activities(self, silent=False): with GlobalLock("trakt.sync"): trakt_auth = g.get_setting("trakt.auth") update_time = str(datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S")) if trakt_auth is None: g.log("TraktSync: No Trakt auth present, no sync will occur", "warning") return self.refresh_activities() remote_activites = self.trakt_api.get_json("sync/last_activities") if remote_activites is None: g.log("Activities Sync Failure: Unable to connect to Trakt", "error") return True if not self.requires_update(remote_activites["all"], self.activities["all_activities"]): return self._check_for_first_run(silent, trakt_auth) self._do_sync_acitivites(remote_activites) # Begin iterating sync items self._finalize_process(update_time) return self.sync_errors
def wrapper(*args, **kwarg): method_class = args[0] try: response = func(*args, **kwarg) if response.status_code in [200, 201]: return response if response.status_code == 401: with GlobalLock("tvdb.oauth", run_once=True, check_sum=method_class.jwToken) as lock: if not lock.runned_once(): if method_class.jwToken is not None: method_class.try_refresh_token(True) if method_class.refresh_token is not None: return func(*args, **kwarg) g.log( "TVDB returned a {} ({}): while requesting {}".format( response.status_code, TVDBAPI.http_codes[response.status_code] if response.status_code != 404 else response.json()["Error"], response.url, ), "warning", ) return None except requests.exceptions.ConnectionError: return None except: xbmcgui.Dialog().ok(g.ADDON_NAME, g.get_language_string(30025).format("TVDB")) if g.get_global_setting("run.mode") == "test": raise return None
def try_refresh_token(self, force=False): if not self.refresh: return if not force and self.expiry > float(time.time()): return try: with GlobalLock(self.__class__.__name__, True, self.token): url = self.oauth_url + "token" response = self.session.post( url, data={ "grant_type": "http://oauth.net/grant_type/device/1.0", "code": self.refresh, "client_secret": self.client_secret, "client_id": self.client_id, }, ) if not self._is_response_ok(response): response = response.json() g.notification( g.ADDON_NAME, "Failed to refresh RD token, please manually re-auth" ) g.log("RD Refresh error: {}".format(response["error"])) g.log( "Invalid response from Real Debrid - {}".format(response), "error" ) return False response = response.json() self._save_settings(response) g.log("Real Debrid Token Refreshed") return True except RanOnceAlready: self._load_settings() return
def init_token(self): try: with GlobalLock(self.__class__.__name__, True): response = self.session.post( self.baseUrl + "login", json={"apikey": self.apiKey}, headers=self._get_headers(), ).json() self._save_settings(response) except RanOnceAlready: return
def remove_download_task(self, url_hash): """ Takes a download id a handles the clearing of download task from the window :param url_hash: :return: None """ self._get_download_index() with GlobalLock("SerenDownloaderUpdate"): self._get_download_index() self._win.clearProperty("sdm.{}".format(url_hash)) if url_hash in self.download_ids: self.remove_from_index(url_hash)
def _integrity_check_db(self): db_file_checksum = tools.md5_hash(self._database_layout) with GlobalLock(self.__class__.__name__, self._threading_lock, True, db_file_checksum) as lock: if lock.runned_once(): return if g.read_all_text("{}.md5".format( self._db_file)) == db_file_checksum: return g.log("Integrity checked failed - {} - {} - rebuilding db".format( self._db_file, db_file_checksum)) self.rebuild_database() g.write_all_text("{}.md5".format(self._db_file), db_file_checksum)
def init_token(self): with GlobalLock(self.__class__.__name__, self._threading_lock, True) as lock: if lock.runned_once(): return response = self.session.post( self.baseUrl + "login", json={ "apikey": self.apiKey }, headers=self._get_headers(), ).json() self._save_settings(response)
def _integrity_check_db(self): db_file_checksum = tools.md5_hash(self._database_layout) try: with GlobalLock(self.__class__.__name__, True, db_file_checksum): if xbmcvfs.exists(self._db_file) and g.read_all_text( "{}.md5".format(self._db_file)) == db_file_checksum: return g.log("Integrity checked failed - {} - {} - rebuilding db". format(self._db_file, db_file_checksum)) self.rebuild_database() g.write_all_text("{}.md5".format(self._db_file), db_file_checksum) except RanOnceAlready: return
def create_download_task(self, url_hash): """ Takes a download id and handles window property population :param url_hash: string :return: bool """ with GlobalLock("SerenDownloaderUpdate"): self._get_download_index() if url_hash in self.download_ids: xbmcgui.Dialog().ok( g.ADDON_NAME, "Can not create download task as it already exists!" ) return False self.download_ids.append(url_hash) self._insert_into_index() self.download_init_status["hash"] = url_hash self.downloads[url_hash] = self.download_init_status self.update_task_info(url_hash, self.downloads[url_hash]) return True
def __init__(self): super(CustomProviders, self).__init__() self.deploy_init() self.providers_module = self._try_add_providers_path() self.pre_update_collection = [] self.language = "en" self.known_packages = None self.known_providers = None self.providers_path = os.path.join(g.ADDON_USERDATA_PATH, "providers") self.modules_path = os.path.join(g.ADDON_USERDATA_PATH, "providerModules") self.meta_path = os.path.join(g.ADDON_USERDATA_PATH, "providerMeta") self.provider_types = ["torrent", "hosters", "adaptive"] with GlobalLock(self.__class__.__name__, provider_lock, True) as lock: if not lock.runned_once(): self._init_providers() self.poll_database() self.provider_settings = SettingsManager()
def wrapper(*args, **kwarg): method_class = args[0] import requests try: response = func(*args, **kwarg) if response.status_code in [200, 201]: return response if response.status_code == 401: try: with GlobalLock("tvdb.oauth", run_once=True, check_sum=method_class.jwToken) as lock: if method_class.jwToken is not None: method_class.try_refresh_token(True) except RanOnceAlready: pass if method_class.refresh_token is not None: return func(*args, **kwarg) g.log( "TVDB returned a {} ({}): while requesting {}".format( response.status_code, TVDBAPI.http_codes[response.status_code] if not response.status_code == 404 else response.json()["Error"], response.url, ), "warning" if not response.status_code == 404 else "debug", ) return None except requests.exceptions.ConnectionError: return None except Exception: xbmcgui.Dialog().notification( g.ADDON_NAME, g.get_language_string(30024).format("TVDB") ) if g.get_runtime_setting("run.mode") == "test": raise else: g.log_stacktrace() return None
def try_refresh_token(self): if not self.token or float(time.time()) < (self.expiry - (15 * 60)): return with GlobalLock(self.__class__.__name__, self._threading_lock, True, self.refresh): url = self.oauth_url + "token" response = self.session.post( url, data={ "grant_type": "http://oauth.net/grant_type/device/1.0", "code": self.refresh, "client_secret": self.client_secret, "client_id": self.client_id, }, ) if not self._is_response_ok(response): response = response.json() g.notification( g.ADDON_NAME, "Failed to refresh RD token, please manually re-auth") g.log("RD Refresh error: {}".format(response["error"])) g.log( "Invalid response from Real Debrid - {}".format(response), "error") return False response = response.json() if "access_token" in response: self.token = response["access_token"] if "refresh_token" in response: self.refresh = response["refresh_token"] g.set_setting(RD_AUTH_KEY, self.token) g.set_setting(RD_REFRESH_KEY, self.refresh) g.set_setting(RD_EXPIRY_KEY, str(time.time() + int(response["expires_in"]))) g.log("Real Debrid Token Refreshed") return True
def wrapper(*args, **kwargs): """ Wrapper method for decorator :param args: method args :param kwargs: method kwargs :return: """ method_class = args[0] method_class._load_settings() import requests try: response = func(*args, **kwargs) if response.status_code in [200, 201, 204]: return response if (response.status_code == 400 and response.url == "https://api.trakt.tv/oauth/device/token"): return response if (response.status_code == 400 and response.url == "https://api.trakt.tv/oauth/token"): _reset_trakt_auth() raise Exception("Unable to refresh Trakt auth") if response.status_code == 403: g.log( "Trakt: invalid API key or unapproved app, resetting auth", "error") _reset_trakt_auth() g.cancel_directory() return None if response.status_code == 401: import inspect if inspect.stack(1)[1][3] == "try_refresh_token": xbmcgui.Dialog().notification(g.ADDON_NAME, g.get_language_string(30340)) g.log( "Attempts to refresh Trakt token have failed. User intervention is required", "error", ) else: try: with GlobalLock("trakt.oauth", run_once=True, check_sum=method_class.access_token): if method_class.refresh_token is not None: method_class.try_refresh_token(True) if (method_class.refresh_token is None and method_class.username is not None): xbmcgui.Dialog().ok( g.ADDON_NAME, g.get_language_string(30340)) except RanOnceAlready: pass if method_class.refresh_token is not None: return func(*args, **kwargs) if response.status_code == 423: xbmcgui.Dialog().notification( g.ADDON_NAME, TRAKT_STATUS_CODES.get(response.status_code)) g.log( "Locked User Account - Contact Trakt support", "error", ) g.log( "Trakt returned a {} ({}): while requesting {}".format( response.status_code, TRAKT_STATUS_CODES.get(response.status_code, "*Unknown status code*"), response.url, ), "error", ) return response except requests.exceptions.ConnectionError as e: _log_connection_error(args, kwargs, e) raise except Exception as e: _connection_failure_dialog() _log_connection_error(args, kwargs, e) raise