def get_device_token(self, device_code): token_request_params = { "url": API_URL + "/oauth/device/token", "headers": {"Content-Type": "application/json"}, "json": { "code": device_code, "client_id": self.CLIENT_ID, "client_secret": self.CLIENT_SECRET } } token_resp = safe_request('post', token_request_params) if token_resp is None: self._code_fetch_fails += 1 if self._code_fetch_fails == self._CODE_FETCH_FAILS_LIMIT: logger.critical("Unable to get response from trakt.") notify("Unable to get response from trakt.", stdout=True, category="trakt") sys.exit(1) return elif token_resp.status_code == 400: self._code_fetch_fails = 0 return False elif token_resp.status_code == 200: self.token_data = token_resp.json() self._code_fetch_fails = 0 return True else: logger.critical("Invalid status code of token response.") sys.exit(1)
def refresh_token(self): if self._refresh_retries == self._REFRESH_RETRIES_LIMIT: self.token_data = {} self._refresh_retries = 0 logger.critical("Too many failed refreshes. Clearing token.") notify("Trakt token expired. Couldn't auto-refresh token.", stdout=True) self.device_auth() return exchange_params = { "url": API_URL + '/oauth/token', "headers": {"Content-Type": "application/json"}, "json": { "refresh_token": self.token_data['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" } } self._refresh_retries += 1 exchange_resp = safe_request('post', exchange_params) if exchange_resp and exchange_resp.status_code == 200: self.token_data = exchange_resp.json() self._refresh_retries = 0 logger.info('Refreshed access token.') else: logger.error("Error refreshing token.")
def get_device_code(self): code_request_params = { "url": API_URL + "/oauth/device/code", "headers": {"Content-Type": "application/json"}, "json": {"client_id": self.CLIENT_ID} } code_resp = safe_request('post', code_request_params) return code_resp.json() if code_resp else None
def search(query, types=None, year=None, extended=False): if not types: types = ['movie', 'show', 'episode'] search_params = { "url": API_URL + '/search/' + ",".join(types), "params": {'query': query, 'extended': extended, 'field': 'title', 'years': year}, "headers": trakt_auth.headers } r = safe_request('get', search_params) return r.json() if r else None
def scrobble(verb, media_info, progress, *args, **kwargs): scrobble_data = prepare_scrobble_data(**media_info) if not scrobble_data: return None scrobble_data['progress'] = progress scrobble_params = { "url": API_URL + '/scrobble/' + verb, "headers": get_headers(), "json": scrobble_data } scrobble_resp = safe_request('post', scrobble_params) return scrobble_resp.json() if scrobble_resp else False
def plex_token_auth(login, password): auth_params = { "url": "https://plex.tv/users/sign_in.json", "data": { "user[login]": login, "user[password]": password }, "headers": { "X-Plex-Client-Identifier": "com.iamkroot.trakt_scrobbler", "X-Plex-Product": "Trakt Scrobbler", "Accept": "application/json", }, } return safe_request("post", auth_params)
def add_to_history(media_info, updated_at, *args, **kwargs): watched_at = dt.utcfromtimestamp(updated_at).isoformat() + 'Z' history = prepare_history_data(watched_at=watched_at, **media_info) if not history: return params = { "url": API_URL + '/sync/history', "headers": get_headers(), "json": history } resp = safe_request('post', params) if not resp: return False added = resp.json()['added'] return (media_info['type'] == 'movie' and added['movies'] > 0) or \ (media_info['type'] == 'episode' and added['episodes'] > 0)
def refresh_token(token_data): exchange_params = { "url": API_URL + '/oauth/token', "headers": {"Content-Type": "application/json"}, "json": { "refresh_token": token_data['refresh_token'], "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", "grant_type": "refresh_token" } } exchange_resp = safe_request('post', exchange_params) if exchange_resp and exchange_resp.status_code == 200: logger.info('Refreshed access token.') return exchange_resp.json() else: logger.info("Error refreshing token.")
def get_device_token(device_code): token_request_params = { "url": API_URL + "/oauth/device/token", "headers": {"Content-Type": "application/json"}, "json": { "code": device_code, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET } } token_resp = safe_request('post', token_request_params) if not token_resp: return elif token_resp.status_code == 400: return elif token_resp.status_code == 200: return token_resp.json() else: logger.error('Invalid status code of token response.') sys.exit(1)
def scrobble(verb, media_info, progress, *args, **kwargs): scrobble_data = prepare_scrobble_data(**media_info) if not scrobble_data: return None scrobble_data['progress'] = progress scrobble_params = { "url": API_URL + '/scrobble/' + verb, "headers": trakt_auth.headers, "json": scrobble_data, "timeout": 30, } scrobble_resp = safe_request('post', scrobble_params) if scrobble_resp is not None: if scrobble_resp.status_code == HTTPStatus.NOT_FOUND: logger.warning("Not found on trakt. The media info is incorrect.") return None elif scrobble_resp.status_code == HTTPStatus.CONFLICT: logger.warning("Scrobble already exists on trakt server.") return None return scrobble_resp.json() if scrobble_resp else False
def get_data(self, url): resp = safe_request("get", {"url": url}, self.sess) if resp is None: return # TODO: If we get a 401, clear token and restart plex auth flow resp.raise_for_status() try: data = resp.json()["MediaContainer"] except JSONDecodeError: logger.exception("Error with decoding") logger.debug(resp.text) return None if data["size"] <= 0: return None # no user filter if not self.config["scrobble_user"] or "User" not in data["Metadata"][ 0]: return data["Metadata"][0] for metadata in data["Metadata"]: if metadata["User"]["title"] == self.config["scrobble_user"]: return metadata