Source code for flexget.components.imdb.db

from datetime import datetime, timedelta

from loguru import logger
from sqlalchemy import Boolean, Column, DateTime, Float, Integer, String, Table, Unicode
from sqlalchemy.orm import relationship
from sqlalchemy.schema import ForeignKey, Index

from flexget import db_schema
from flexget.components.imdb.utils import extract_id
from flexget.db_schema import UpgradeImpossible

logger = logger.bind(name='imdb.db')

SCHEMA_VER = 10

Base = db_schema.versioned_base('imdb_lookup', SCHEMA_VER)

# association tables
genres_table = Table(
    'imdb_movie_genres',
    Base.metadata,
    Column('movie_id', Integer, ForeignKey('imdb_movies.id')),
    Column('genre_id', Integer, ForeignKey('imdb_genres.id')),
    Index('ix_imdb_movie_genres', 'movie_id', 'genre_id'),
)
Base.register_table(genres_table)

actors_table = Table(
    'imdb_movie_actors',
    Base.metadata,
    Column('movie_id', Integer, ForeignKey('imdb_movies.id')),
    Column('actor_id', Integer, ForeignKey('imdb_actors.id')),
    Index('ix_imdb_movie_actors', 'movie_id', 'actor_id'),
)
Base.register_table(actors_table)

directors_table = Table(
    'imdb_movie_directors',
    Base.metadata,
    Column('movie_id', Integer, ForeignKey('imdb_movies.id')),
    Column('director_id', Integer, ForeignKey('imdb_directors.id')),
    Index('ix_imdb_movie_directors', 'movie_id', 'director_id'),
)
Base.register_table(directors_table)

writers_table = Table(
    'imdb_movie_writers',
    Base.metadata,
    Column('movie_id', Integer, ForeignKey('imdb_movies.id')),
    Column('writer_id', Integer, ForeignKey('imdb_writers.id')),
    Index('ix_imdb_movie_writers', 'movie_id', 'writer_id'),
)
Base.register_table(writers_table)

plot_keywords_table = Table(
    'imdb_movie_plot_keywords',
    Base.metadata,
    Column('movie_id', Integer, ForeignKey('imdb_movies.id')),
    Column('keyword_id', Integer, ForeignKey('imdb_plot_keywords.id')),
    Index('ix_imdb_movie_plot_keywords', 'movie_id', 'keyword_id'),
)
Base.register_table(plot_keywords_table)


[docs] class Movie(Base): __tablename__ = 'imdb_movies' id = Column(Integer, primary_key=True) title = Column(Unicode) original_title = Column(Unicode) url = Column(String, index=True) # many-to-many relations genres = relationship('Genre', secondary=genres_table, backref='movies') actors = relationship('Actor', secondary=actors_table, backref='movies') directors = relationship('Director', secondary=directors_table, backref='movies') writers = relationship('Writer', secondary=writers_table, backref='movies') plot_keywords = relationship('PlotKeyword', secondary=plot_keywords_table, backref='movies') languages = relationship('MovieLanguage', order_by='MovieLanguage.prominence') score = Column(Float) votes = Column(Integer) meta_score = Column(Integer) year = Column(Integer) plot_outline = Column(Unicode) mpaa_rating = Column(String, default='') photo = Column(String) # updated time, so we can grab new rating counts after 48 hours # set a default, so existing data gets updated with a rating updated = Column(DateTime) @property def imdb_id(self): return extract_id(self.url) @property def expired(self): """:return: True if movie details are considered to be expired, ie. need of update""" if self.updated is None: logger.debug('updated is None: {}', self) return True refresh_interval = 2 if self.year: # Make sure age is not negative age = max((datetime.now().year - self.year), 0) refresh_interval += age * 5 logger.debug('movie `{}` age {} expires in {} days', self.title, age, refresh_interval) return self.updated < datetime.now() - timedelta(days=refresh_interval) def __repr__(self): return f'<Movie(name={self.title},votes={self.votes},year={self.year})>'
[docs] class MovieLanguage(Base): __tablename__ = 'imdb_movie_languages' movie_id = Column(Integer, ForeignKey('imdb_movies.id'), primary_key=True) language_id = Column(Integer, ForeignKey('imdb_languages.id'), primary_key=True) prominence = Column(Integer) language = relationship('Language') def __init__(self, language, prominence=None): self.language = language self.prominence = prominence
[docs] class Language(Base): __tablename__ = 'imdb_languages' id = Column(Integer, primary_key=True) name = Column(Unicode) def __init__(self, name): self.name = name
[docs] class Genre(Base): __tablename__ = 'imdb_genres' id = Column(Integer, primary_key=True) name = Column(String) def __init__(self, name): self.name = name
[docs] class Actor(Base): __tablename__ = 'imdb_actors' id = Column(Integer, primary_key=True) imdb_id = Column(String) name = Column(Unicode) def __init__(self, imdb_id, name=None): self.imdb_id = imdb_id self.name = name
[docs] class Director(Base): __tablename__ = 'imdb_directors' id = Column(Integer, primary_key=True) imdb_id = Column(String) name = Column(Unicode) def __init__(self, imdb_id, name=None): self.imdb_id = imdb_id self.name = name
[docs] class Writer(Base): __tablename__ = 'imdb_writers' id = Column(Integer, primary_key=True) imdb_id = Column(String) name = Column(Unicode) def __init__(self, imdb_id, name=None): self.imdb_id = imdb_id self.name = name
[docs] class PlotKeyword(Base): __tablename__ = 'imdb_plot_keywords' id = Column(Integer, primary_key=True) name = Column(String) def __init__(self, name): self.name = name
[docs] class SearchResult(Base): __tablename__ = 'imdb_search' id = Column(Integer, primary_key=True) title = Column(Unicode, index=True) url = Column(String) fails = Column(Boolean, default=False) queried = Column(DateTime) @property def imdb_id(self): return extract_id(self.url) def __init__(self, title, url=None): self.title = title self.url = url self.queried = datetime.now() def __repr__(self): return f'<SearchResult(title={self.title},url={self.url},fails={self.fails})>'
@db_schema.upgrade('imdb_lookup') def upgrade(ver, session): # v5 We may have cached bad data due to imdb changes, just wipe everything. GitHub #697 # v6 The association tables were not cleared on the last upgrade, clear again. GitHub #714 # v7 Another layout change cached bad data. GitHub #729 # v8 Added writers to the DB Schema # v9 Added Metacritic score exftraction/filtering # v10 Added plot keywords to the DB schema if ver is None or ver <= 9: raise UpgradeImpossible( 'Resetting imdb_lookup caches because bad data may have been cached.' ) return ver