def _request(self, method, url, **kwargs): self.config['headers'].update({'Content-type': 'application/json'}) if self.config['apitoken']: self.config['headers']['authorization'] = 'Bearer {}'.format( self.config['apitoken']) if self.config['language']: self.config['headers'].update( {'Accept-Language': self.config['language']}) # get response from theTVDB try: resp = sickrage.srCore.srWebSession.request( method, urlparse.urljoin(self.config['api']['base'], url), cache=self.config['cache_enabled'], headers=self.config['headers'], timeout=sickrage.srCore.srConfig.INDEXER_TIMEOUT, **kwargs) except Exception as e: raise tvdb_error(e.message) # handle requests exceptions if resp.status_code == 401: raise tvdb_unauthorized(resp.json()['Error']) elif resp.status_code >= 400: raise tvdb_error(resp.json()['Error']) return to_lowercase(resp.json())
def _loadUrl(self, url, params=None): data = {} try: # get api v2 token self.getToken() sickrage.srCore.srLogger.debug("Retrieving URL {}".format(url)) # get response from theTVDB resp = sickrage.srCore.srWebSession.get( url, cache=self.config['cache_enabled'], headers=self.config['headers'], params=params, timeout=sickrage.srCore.srConfig.INDEXER_TIMEOUT) # handle requests exceptions resp.raise_for_status() data = resp.json()['data'] except requests.exceptions.HTTPError as e: if e.response.status_code == 401: self.getToken(True) raise tvdb_error() except Exception as e: pass return data
def _loadUrl(self, url, params=None): data = {} try: # get api v2 token self.getToken() sickrage.srCore.srLogger.debug("Retrieving URL {}".format(url)) # get response from theTVDB resp = sickrage.srCore.srWebSession.get(url, cache=self.config['cache_enabled'], headers=self.config['headers'], params=params, timeout=sickrage.srCore.srConfig.INDEXER_TIMEOUT) # handle requests exceptions resp.raise_for_status() data = resp.json()['data'] except requests.exceptions.HTTPError as e: if e.response.status_code == 401: self.getToken(True) raise tvdb_error() except Exception as e: pass return data
def _loadUrl(self, url, params=None): try: # get api v2 token self.getToken() sickrage.srCore.srLogger.debug("Retrieving URL {}".format(url)) # get response from theTVDB resp = sickrage.srCore.srWebSession.get( url, cache=self.config['cache_enabled'], headers=self.config['headers'], params=params, raise_exceptions=False, timeout=sickrage.srCore.srConfig.INDEXER_TIMEOUT) # handle requests exceptions resp.raise_for_status() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: self.getToken(True) raise tvdb_error( "HTTP Error {}: Session token expired, retrieving new token" .format(e.errno)) raise tvdb_error("HTTP Error {}: while loading URL {}".format( e.errno, url)) except requests.exceptions.ConnectionError as e: raise tvdb_error("Connection error {} while loading URL {}".format( e.message, url)) except requests.exceptions.Timeout as e: raise tvdb_error( "Connection timed out {} while loading URL {}".format( e.message, url)) except Exception as e: raise tvdb_error( "Unknown exception while loading URL {}: {}".format( url, repr(e))) try: if 'application/zip' in resp.headers.get("Content-Type", ''): try: import StringIO sickrage.srCore.srLogger.debug( "We received a zip file unpacking now ...") return json.loads( json.dumps( xmltodict.parse( zipfile.ZipFile(StringIO.StringIO( resp.content)).read("{}.xml".format( self.config['language']))))) except zipfile.BadZipfile: raise tvdb_error( "Bad zip file received from theTVDB.com, could not read it" ) try: return resp.json() except: return json.loads(json.dumps(xmltodict.parse(resp.content))) except: pass
def _loadUrl(self, url, params=None, language=None): try: # get api v2 token if self.config['apiver'] == 2: self.getToken() self.config['headers'].update({ 'Accept-Language': language or self.config['language'] }) sickrage.srCore.srLogger.debug("Retrieving URL {}".format(url)) # get response from theTVDB resp = sickrage.srCore.srWebSession.get(url, cache=self.config['cache_enabled'], headers=self.config['headers'], params=params, raise_exceptions=False, timeout=sickrage.srCore.srConfig.INDEXER_TIMEOUT) # handle requests exceptions resp.raise_for_status() except requests.exceptions.HTTPError as e: if e.response.status_code == 401: self.getToken(True) raise tvdb_error("HTTP Error {}: Session token expired, retrieving new token".format(e.errno)) elif e.response.status_code == 404: return tvdb_error("HTTP Error {}: Show not found".format(e.errno)) raise tvdb_error("HTTP Error {}: while loading URL {}".format(e.errno, url)) except requests.exceptions.ConnectionError as e: raise tvdb_error("Connection error {} while loading URL {}".format(e.message, url)) except requests.exceptions.Timeout as e: raise tvdb_error("Connection timed out {} while loading URL {}".format(e.message, url)) except Exception as e: raise tvdb_error("Unknown exception while loading URL {}: {}".format(url, repr(e))) try: if 'application/zip' in resp.headers.get("Content-Type", ''): try: import StringIO sickrage.srCore.srLogger.debug("We received a zip file unpacking now ...") return json.loads(json.dumps(xmltodict.parse( zipfile.ZipFile(StringIO.StringIO(resp.content)).read( "{}.xml".format(language or self.config['language'])))) ) except zipfile.BadZipfile: raise tvdb_error("Bad zip file received from theTVDB.com, could not read it") try: return resp.json() except: return json.loads(json.dumps(xmltodict.parse(resp.content))) except: pass
def _getetsrc(self, url, params=None): """Loads a URL using caching, returns an ElementTree of the source """ def renameKeys(iterable): if type(iterable) is dict: for key in iterable.keys(): iterable[key.lower()] = iterable.pop(key) if type(iterable[key.lower()]) is dict or type(iterable[key.lower()]) is list: iterable[key.lower()] = renameKeys(iterable[key.lower()]) elif type(iterable) is list: for item in iterable: item = renameKeys(item) return iterable try: return renameKeys(self._loadUrl(url, params=params)) except Exception as e: raise tvdb_error(e.message)
def _getetsrc(self, url, params=None, language=None): """Loads a URL using caching, returns an ElementTree of the source """ def keys2lower(in_dict): if type(in_dict) is dict: out_dict = {} for key, item in in_dict.items(): out_dict[key.lower()] = keys2lower(item) return out_dict elif type(in_dict) is list: return [keys2lower(obj) for obj in in_dict] return in_dict try: return keys2lower(self._loadUrl(url, params=params, language=language)).values()[0] except Exception as e: raise tvdb_error(e)
def _getetsrc(self, url, params=None): """Loads a URL using caching, returns an ElementTree of the source """ def renameKeys(iterable): if type(iterable) is dict: for key in iterable.keys(): iterable[key.lower()] = iterable.pop(key) if type(iterable[key.lower()]) is dict or type( iterable[key.lower()]) is list: iterable[key.lower()] = renameKeys( iterable[key.lower()]) elif type(iterable) is list: for item in iterable: item = renameKeys(item) return iterable try: return renameKeys(self._loadUrl(url, params=params)) except Exception as e: raise tvdb_error(e.message)
def _getShowData(self, sid, language, getEpInfo=False): """Takes a series ID, gets the episodes URL and parses the TVDB XML file into the shows dict in layout: shows[series_id][season_number][episode_number] """ if self.config['language'] is None: sickrage.srCore.srLogger.debug( 'Config language is none, using show language') if language is None: raise tvdb_error( "config['language'] was None, this should not happen") getShowInLanguage = language else: sickrage.srCore.srLogger.debug( 'Configured language {} override show language of {}'.format( self.config['language'], language)) getShowInLanguage = self.config['language'] # Parse show information sickrage.srCore.srLogger.debug( 'Getting all series data for {}'.format(sid)) seriesInfoEt = self._getetsrc(self.config['api']['series'].format(sid), language=getShowInLanguage) if not seriesInfoEt: sickrage.srCore.srLogger.debug('Series result returned zero') raise tvdb_error("Series result returned zero") # get series data for k, v in seriesInfoEt.items(): if v is not None: if k in ['banner', 'fanart', 'poster']: v = self.config['api']['imagesPrefix'].format(v) elif isinstance(v, list): v = '|'.join(v) else: v = self._cleanData(v) self._setShowData(sid, k, v) # get episode data if getEpInfo: # Parse images self._parseImages(sid) # Parse actors self._parseActors(sid) # Parse episode data sickrage.srCore.srLogger.debug( 'Getting all episodes of {}'.format(sid)) episodes = self._getetsrc( self.config['api']['episodes'].format(sid), language=language) if not episodes: sickrage.srCore.srLogger.debug('Series results incomplete') else: for cur_ep in episodes: # cur_ep = self._getetsrc(self.config['api']['episode_info'].format(eid), language=language) try: use_dvd = False if self.config['dvdorder']: sickrage.srCore.srLogger.debug( 'Using DVD ordering.') use_dvd = all([ cur_ep.get('dvdseason'), cur_ep.get('dvdepisodenumber') ]) seasnum, epno = cur_ep.get('airedseason'), cur_ep.get( 'airedepisodenumber') if use_dvd: seasnum, epno = cur_ep.get( 'dvdseason'), cur_ep.get('dvdepisodenumber') if seasnum is None or epno is None: raise Exception except Exception as e: sickrage.srCore.srLogger.warning( "Episode has incomplete season/episode numbers, skipping!" ) continue seas_no = int(float(seasnum)) ep_no = int(float(epno)) for k, v in cur_ep.items(): k = k.lower() if v is not None: if k == 'filename': v = self.config['api']['imagesPrefix'].format( v) elif isinstance(v, list): v = '|'.join(v) else: v = self._cleanData(v) self._setItem(sid, seas_no, ep_no, k, v) # save persistent data self.shows.save() return self.shows[int(sid)]
def _getShowData(self, sid, getEpInfo=False): """Takes a series ID, gets the episodes URL and parses the TVDB XML file into the shows dict in layout: shows[series_id][season_number][episode_number] """ # Parse show information sickrage.srCore.srLogger.debug( 'Getting all series data for {}'.format(sid)) seriesInfoEt = self._getetsrc(self.config['api']['series'].format(sid)) if not seriesInfoEt: sickrage.srCore.srLogger.debug('Series result returned zero') raise tvdb_error("Series result returned zero") # get series data for k, v in seriesInfoEt.items(): if v is not None: if k in ['banner', 'fanart', 'poster']: v = self.config['api']['imagesPrefix'].format(v) elif isinstance(v, list): v = '|'.join(v) else: v = self._cleanData(v) self._setShowData(sid, k, v) # get episode data if getEpInfo: # Parse images self._parseImages(sid) # Parse actors self._parseActors(sid) # Parse episode data sickrage.srCore.srLogger.debug( 'Getting all episodes of {}'.format(sid)) p = 1 episodes = [] while True: data = self._getetsrc( self.config['api']['episodes'].format(sid), params={'page': p}) if not data: break episodes += data p += 1 if not len(episodes): sickrage.srCore.srLogger.debug('Series results incomplete') return for cur_ep in episodes: try: use_dvd = False if self.config['dvdorder']: sickrage.srCore.srLogger.debug('Using DVD ordering.') use_dvd = all([ cur_ep.get('dvdseason'), cur_ep.get('dvdepisodenumber') ]) seasnum, epno = cur_ep.get('airedseason'), cur_ep.get( 'airedepisodenumber') if use_dvd: seasnum, epno = cur_ep.get('dvdseason'), cur_ep.get( 'dvdepisodenumber') if seasnum is None or epno is None: raise Exception except Exception as e: sickrage.srCore.srLogger.warning( "Episode has incomplete season/episode numbers, skipping!" ) continue seas_no = int(float(seasnum)) ep_no = int(float(epno)) for k, v in cur_ep.items(): k = k.lower() if v is not None: if k == 'filename': v = self.config['api']['imagesPrefix'].format(v) elif isinstance(v, list): v = '|'.join(v) else: v = self._cleanData(v) self._setItem(sid, seas_no, ep_no, k, v) return self.shows[int(sid)]
def _getShowData(self, sid, getEpInfo=False): """Takes a series ID, gets the episodes URL and parses the TVDB XML file into the shows dict in layout: shows[series_id][season_number][episode_number] """ # Parse show information sickrage.srCore.srLogger.debug('Getting all series data for {}'.format(sid)) seriesInfoEt = self._getetsrc(self.config['api']['series'].format(sid)) if not seriesInfoEt: sickrage.srCore.srLogger.debug('Series result returned zero') raise tvdb_error("Series result returned zero") # get series data for k, v in seriesInfoEt.items(): if v is not None: if k in ['banner', 'fanart', 'poster']: v = self.config['api']['imagesPrefix'].format(v) elif isinstance(v, list): v = '|'.join(v) else: v = self._cleanData(v) self._setShowData(sid, k, v) # get episode data if getEpInfo: # Parse images self._parseImages(sid) # Parse actors self._parseActors(sid) # Parse episode data sickrage.srCore.srLogger.debug('Getting all episodes of {}'.format(sid)) p = 1 episodes = [] while True: data = self._getetsrc(self.config['api']['episodes'].format(sid), params={'page': p}) if not data: break episodes += data p += 1 if not len(episodes): sickrage.srCore.srLogger.debug('Series results incomplete') return for cur_ep in episodes: try: use_dvd = False if self.config['dvdorder']: sickrage.srCore.srLogger.debug('Using DVD ordering.') use_dvd = all([cur_ep.get('dvdseason'), cur_ep.get('dvdepisodenumber')]) seasnum, epno = cur_ep.get('airedseason'), cur_ep.get('airedepisodenumber') if use_dvd: seasnum, epno = cur_ep.get('dvdseason'), cur_ep.get('dvdepisodenumber') if seasnum is None or epno is None: raise Exception except Exception as e: sickrage.srCore.srLogger.warning("Episode has incomplete season/episode numbers, skipping!") continue seas_no = int(float(seasnum)) ep_no = int(float(epno)) for k, v in cur_ep.items(): k = k.lower() if v is not None: if k == 'filename': v = self.config['api']['imagesPrefix'].format(v) elif isinstance(v, list): v = '|'.join(v) else: v = self._cleanData(v) self._setItem(sid, seas_no, ep_no, k, v) return self.shows[int(sid)]
def _getShowData(self, sid, language, getEpInfo=False): """Takes a series ID, gets the epInfo URL and parses the TVDB XML file into the shows dict in layout: shows[series_id][season_number][episode_number] """ if self.config['language'] is None: sickrage.srCore.srLogger.debug('Config language is none, using show language') if language is None: raise tvdb_error("config['language'] was None, this should not happen") getShowInLanguage = language else: sickrage.srCore.srLogger.debug( 'Configured language {} override show language of {}'.format( self.config['language'], language ) ) getShowInLanguage = self.config['language'] # Parse show information sickrage.srCore.srLogger.debug('Getting all series data for {}'.format(sid)) seriesInfoEt = None for v in self.config['api']: seriesInfoEt = self._getetsrc(self.config['api'][v]['seriesInfo'].format(sid, getShowInLanguage)) if seriesInfoEt: break if not seriesInfoEt: sickrage.srCore.srLogger.debug('Series result returned zero') raise tvdb_error("Series result returned zero") # get series data for k, v in seriesInfoEt['series'].items(): if v is not None: if k in ['banner', 'fanart', 'poster']: v = self.config['api'][self.config['apiver']]['artworkPrefix'].format(v) else: v = self._cleanData(v) self._setShowData(sid, k, v) # get episode data if getEpInfo: # Parse banners if self.config['banners_enabled']: self._parseBanners(sid) # Parse actors if self.config['actors_enabled']: self._parseActors(sid) # Parse episode data sickrage.srCore.srLogger.debug('Getting all episodes of {}'.format(sid)) epsEt = None for v in self.config['api']: url = self.config['api'][v]['epInfo'].format(sid, language) if self.config['useZip']: url = self.config['api'][v]['epInfo_zip'].format(sid, language) epsEt = self._getetsrc(url, language=language) if epsEt: break if not epsEt: sickrage.srCore.srLogger.debug('Series results incomplete') if epsEt and 'episode' in epsEt: episodes = epsEt['episode'] if not isinstance(episodes, list): episodes = [episodes] for cur_ep in episodes: if self.config['dvdorder']: sickrage.srCore.srLogger.debug('Using DVD ordering.') use_dvd = cur_ep['dvd_season'] is not None and cur_ep['dvd_episodenumber'] is not None else: use_dvd = False if use_dvd: seasnum, epno = cur_ep['dvd_season'], cur_ep['dvd_episodenumber'] else: seasnum, epno = cur_ep['seasonnumber'], cur_ep['episodenumber'] if seasnum is None or epno is None: sickrage.srCore.srLogger.warning( "An episode has incomplete season/episode number (season: %r, episode: %r)".format( seasnum, epno)) continue # Skip to next episode # float() is because https://github.com/dbr/tvnamer/issues/95 - should probably be fixed in TVDB data seas_no = int(float(seasnum)) ep_no = int(float(epno)) for k, v in cur_ep.items(): k = k.lower() if v is not None: if k == 'filename': v = self.config['api'][self.config['apiver']]['artworkPrefix'].format(v) else: v = self._cleanData(v) self._setItem(sid, seas_no, ep_no, k, v) # save persistent data self.shows.save() return self.shows[int(sid)]