class TVDBEpisode(TVDBContainer, Base): __tablename__ = 'tvdb_episodes' id = Column(Integer, primary_key=True, autoincrement=False) expired = Column(Boolean) lastupdated = Column(Integer) seasonnumber = Column(Integer) episodenumber = Column(Integer) absolute_number = Column(Integer) episodename = Column(Unicode) overview = Column(Unicode) _director = Column('director', Unicode) director = pipe_list_synonym('_director') _writer = Column('writer', Unicode) writer = pipe_list_synonym('_writer') _gueststars = Column('gueststars', Unicode) gueststars = pipe_list_synonym('_gueststars') rating = Column(Float) filename = Column(Unicode) _firstaired = Column('firstaired', DateTime) firstaired = text_date_synonym('_firstaired') series_id = Column(Integer, ForeignKey('tvdb_series.id'), nullable=False) def update(self): if not self.id: raise LookupError( 'Cannot update an episode without an episode id.') url = get_mirror() + api_key + '/episodes/%s/%s.xml' % (self.id, language) try: data = requests.get(url).content except RequestException as e: raise LookupError('Request failed %s' % url) result = BeautifulStoneSoup( data, convertEntities=BeautifulStoneSoup.HTML_ENTITIES).find('episode') if result: self.update_from_bss(result) else: raise LookupError('Could not retrieve information from thetvdb') def __repr__(self): return '<TVDBEpisode series=%s,season=%s,episode=%s>' %\ (self.series.seriesname, self.seasonnumber, self.episodenumber)
class TVRageSeries(Base): __tablename__ = 'tvrage_series' id = Column(Integer, primary_key=True) name = Column(String) episodes = relation( 'TVRageEpisodes', order_by='TVRageEpisodes.season, TVRageEpisodes.episode', cascade='all, delete, delete-orphan') showid = Column(String) link = Column(String) classification = Column(String) _genres = Column('genres', String) genres = pipe_list_synonym('_genres') country = Column(String) started = Column(Integer) ended = Column(Integer) seasons = Column(Integer) last_update = Column(DateTime) # last time we updated the db for the show def __init__(self, series): self.update(series) def update(self, series): self.name = series.name self.showid = series.showid self.link = series.link self.classification = series.classification self.genres = [g for g in series.genres if g] # Sometimes tvrage has a None in the genres list self.country = series.country self.started = series.started self.ended = series.ended self.seasons = series.seasons self.last_update = datetime.datetime.now() # Clear old eps before repopulating del self.episodes[:] for i in range(1, series.seasons + 1): season = series.season(i) for j in season.keys(): episode = TVRageEpisodes(season.episode(j)) self.episodes.append(episode) @with_session def find_episode(self, season, episode, session=None): return (session.query(TVRageEpisodes).filter( TVRageEpisodes.tvrage_series_id == self.id).filter( TVRageEpisodes.season == season).filter( TVRageEpisodes.episode == episode).first()) def __str__(self): return '<TvrageSeries(title=%s,id=%s,last_update=%s)>' % ( self.name, self.id, self.last_update) def finished(self): return self.ended != 0
class TVDBSeries(TVDBContainer, Base): __tablename__ = "tvdb_series" id = Column(Integer, primary_key=True, autoincrement=False) lastupdated = Column(Integer) expired = Column(Boolean) seriesname = Column(Unicode) language = Column(Unicode) rating = Column(Float) status = Column(Unicode) runtime = Column(Integer) airs_time = Column(Unicode) airs_dayofweek = Column(Unicode) contentrating = Column(Unicode) network = Column(Unicode) imdb_id = Column(String) zap2it_id = Column(String) banner = Column(String) fanart = Column(String) poster = Column(String) poster_file = Column(Unicode) _genre = Column('genre', Unicode) genre = pipe_list_synonym('_genre') _firstaired = Column('firstaired', DateTime) firstaired = text_date_synonym('_firstaired') episodes = relation('TVDBEpisode', backref='series', cascade='all, delete, delete-orphan') def update(self): if not self.id: raise LookupError('Cannot update a series without a tvdb id.') url = get_mirror() + api_key + '/series/%s/%s.xml' % (self.id, language) try: data = requests.get(url).content except RequestException, e: raise LookupError('Request failed %s' % url) result = BeautifulStoneSoup( data, convertEntities=BeautifulStoneSoup.HTML_ENTITIES).find('series') if result: self.update_from_bss(result) else: raise LookupError('Could not retrieve information from thetvdb')
class ThetvdbFavorites(Base): __tablename__ = 'thetvdb_favorites' id = Column(Integer, primary_key=True) account_id = Column(String, index=True) _series_ids = Column('series_ids', Unicode) series_ids = pipe_list_synonym('_series_ids') updated = Column(DateTime) def __init__(self, account_id, series_ids): self.account_id = account_id self.series_ids = series_ids self.updated = datetime.now() def __repr__(self): return '<series_favorites(account_id=%s, series_id=%s)>' % (self.account_id, self.series_ids)
class TVDBSeries(TVDBContainer, Base): __tablename__ = "tvdb_series" id = Column(Integer, primary_key=True, autoincrement=False) lastupdated = Column(Integer) expired = Column(Boolean) seriesname = Column(Unicode) language = Column(Unicode) rating = Column(Float) status = Column(Unicode) runtime = Column(Integer) airs_time = Column(Unicode) airs_dayofweek = Column(Unicode) contentrating = Column(Unicode) network = Column(Unicode) imdb_id = Column(String) zap2it_id = Column(String) banner = Column(String) fanart = Column(String) poster = Column(String) poster_file = Column(Unicode) _genre = Column('genre', Unicode) genre = pipe_list_synonym('_genre') _firstaired = Column('firstaired', DateTime) firstaired = text_date_synonym('_firstaired') episodes = relation('TVDBEpisode', backref='series', cascade='all, delete, delete-orphan') def update(self): if not self.id: raise LookupError('Cannot update a series without a tvdb id.') url = get_mirror() + api_key + '/series/%s/%s.xml' % (self.id, language) try: data = requests.get(url).content except RequestException as e: raise LookupError('Request failed %s' % url) result = BeautifulStoneSoup( data, convertEntities=BeautifulStoneSoup.HTML_ENTITIES).find('series') if result: self.update_from_bss(result) else: raise LookupError('Could not retrieve information from thetvdb') def get_poster(self, only_cached=False): """Downloads this poster to a local cache and returns the path""" from flexget.manager import manager base_dir = os.path.join(manager.config_base, 'userstatic') if os.path.isfile(os.path.join(base_dir, self.poster_file or '')): return self.poster_file elif only_cached: return # If we don't already have a local copy, download one. url = get_mirror('banner') + self.poster log.debug('Downloading poster %s' % url) dirname = os.path.join('tvdb', 'posters') # Create folders if the don't exist fullpath = os.path.join(base_dir, dirname) if not os.path.isdir(fullpath): os.makedirs(fullpath) filename = os.path.join(dirname, posixpath.basename(self.poster)) thefile = file(os.path.join(base_dir, filename), 'wb') thefile.write(requests.get(url).content) self.poster_file = filename # If we are detached from a session, update the db if not Session.object_session(self): session = Session() session.query(TVDBSeries).filter(TVDBSeries.id == self.id).update( values={'poster_file': filename}) session.close() return filename def __repr__(self): return '<TVDBSeries name=%s,tvdb_id=%s>' % (self.seriesname, self.id)
class TVDBSeries(TVDBContainer, Base): __tablename__ = "tvdb_series" id = Column(Integer, primary_key=True, autoincrement=False) lastupdated = Column(Integer) expired = Column(Boolean) seriesname = Column(Unicode) language = Column(Unicode) rating = Column(Float) status = Column(Unicode) runtime = Column(Integer) airs_time = Column(Unicode) airs_dayofweek = Column(Unicode) contentrating = Column(Unicode) network = Column(Unicode) overview = Column(Unicode) imdb_id = Column(String) zap2it_id = Column(String) banner = Column(String) fanart = Column(String) poster = Column(String) poster_file = Column(Unicode) _genre = Column('genre', Unicode) genre = pipe_list_synonym('_genre') _firstaired = Column('firstaired', DateTime) firstaired = text_date_synonym('_firstaired') _actors = Column('actors', Unicode) actors = pipe_list_synonym('_actors') episodes = relation('TVDBEpisode', backref='series', cascade='all, delete, delete-orphan') def update(self, tvdb_id=None): tvdb_id = tvdb_id or self.id url = get_mirror() + api_key + '/series/%s/%s.xml' % (tvdb_id, language) try: data = requests.get(url).content except RequestException as e: raise LookupError('Request failed %s' % url) result = ElementTree.fromstring(data).find('Series') if result is not None: self.update_from_xml(result) else: raise LookupError('Could not retrieve information from thetvdb') def get_poster(self, only_cached=False): """Downloads this poster to a local cache and returns the path""" from flexget.manager import manager base_dir = os.path.join(manager.config_base, 'userstatic') if os.path.isfile(os.path.join(base_dir, self.poster_file or '')): return self.poster_file elif only_cached: return # If we don't already have a local copy, download one. url = get_mirror('banner') + self.poster log.debug('Downloading poster %s', url) dirname = os.path.join('tvdb', 'posters') # Create folders if the don't exist fullpath = os.path.join(base_dir, dirname) if not os.path.isdir(fullpath): os.makedirs(fullpath) filename = os.path.join(dirname, posixpath.basename(self.poster)) thefile = file(os.path.join(base_dir, filename), 'wb') thefile.write(requests.get(url).content) self.poster_file = filename # If we are detached from a session, update the db if not Session.object_session(self): with Session() as session: session.query(TVDBSeries).filter( TVDBSeries.id == self.id).update( values={'poster_file': filename}) return filename def __repr__(self): return '<TVDBSeries name=%s,tvdb_id=%s>' % (self.seriesname, self.id) def to_dict(self): return { 'TVDB_id': self.id, 'last_updated': datetime.fromtimestamp( self.lastupdated).strftime('%Y-%m-%d %H:%M:%S'), 'expired': self.expired, 'series_name': self.seriesname, 'language': self.language, 'rating': self.rating, 'status': self.status, 'runtime': self.runtime, 'airs_time': self.airs_time, 'airs_dayofweek': self.airs_dayofweek, 'content_rating': self.contentrating, 'network': self.network, 'overview': self.overview, 'imdb_id': self.imdb_id, 'zap2it_id': self.zap2it_id, 'banner': self.banner, 'fan_art': self.fanart, 'poster': self.poster, 'poster_file': self.poster_file, 'genres': self.genre, 'first_aired': self.firstaired, 'actors': self.actors }