class SeriesEpisodesPerSeason(db.Model): id = db.Column(db.Integer, primary_key=True) series_id = db.Column(db.Integer, db.ForeignKey('series.id'), nullable=False) season = db.Column(db.Integer, nullable=False) episodes = db.Column(db.Integer, nullable=False)
class MoviesGenre(db.Model): id = db.Column(db.Integer, primary_key=True) movies_id = db.Column(db.Integer, db.ForeignKey('movies.id'), nullable=False) genre = db.Column(db.String(100), nullable=False) genre_id = db.Column(db.Integer, nullable=False)
class MoviesList(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) movies_id = db.Column(db.Integer, db.ForeignKey('movies.id'), nullable=False) status = db.Column(db.Enum(Status), nullable=False) score = db.Column(db.Float)
class MoviesList(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) media_id = db.Column(db.Integer, db.ForeignKey('movies.id'), nullable=False) status = db.Column(db.Enum(Status), nullable=False) rewatched = db.Column(db.Integer, nullable=False, default=0) eps_watched = db.Column(db.Integer) favorite = db.Column(db.Boolean) score = db.Column(db.Float) comment = db.Column(db.Text)
class AnimeList(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) anime_id = db.Column(db.Integer, db.ForeignKey('anime.id'), nullable=False) current_season = db.Column(db.Integer, nullable=False) last_episode_watched = db.Column(db.Integer, nullable=False) status = db.Column(db.Enum(Status), nullable=False) score = db.Column(db.Float)
class Badges(db.Model): id = db.Column(db.Integer, primary_key=True) threshold = db.Column(db.Integer, nullable=False) image_id = db.Column(db.String(100), nullable=False) title = db.Column(db.String(100), nullable=False) type = db.Column(db.String(100), nullable=False) genres_id = db.Column(db.String(100))
class Notifications(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) media_type = db.Column(db.String(50)) media_id = db.Column(db.Integer) payload_json = db.Column(db.Text) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
class MoviesProd(db.Model): id = db.Column(db.Integer, primary_key=True) movies_id = db.Column(db.Integer, db.ForeignKey('movies.id'), nullable=False) production_company = db.Column(db.String(150), nullable=False)
class Anime(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) original_name = db.Column(db.String(50), nullable=False) first_air_date = db.Column(db.String(30)) last_air_date = db.Column(db.String(30)) next_episode_to_air = db.Column(db.String(30)) season_to_air = db.Column(db.Integer) episode_to_air = db.Column(db.Integer) homepage = db.Column(db.String(200)) in_production = db.Column(db.Boolean) created_by = db.Column(db.String(100)) episode_duration = db.Column(db.Integer) total_seasons = db.Column(db.Integer, nullable=False) total_episodes = db.Column(db.Integer) origin_country = db.Column(db.String(20)) status = db.Column(db.String(50)) vote_average = db.Column(db.Float) vote_count = db.Column(db.Float) synopsis = db.Column(db.Text) popularity = db.Column(db.Float) image_cover = db.Column(db.String(100), nullable=False) themoviedb_id = db.Column(db.Integer, nullable=False) last_update = db.Column(db.DateTime, nullable=False) lock_status = db.Column(db.Boolean, default=0) genres = db.relationship('AnimeGenre', backref='anime', lazy=True) actors = db.relationship('AnimeActors', backref='anime', lazy=True) eps_per_season = db.relationship('AnimeEpisodesPerSeason', backref='anime', lazy=False) list_info = db.relationship('AnimeList', backref='anime', lazy='dynamic') networks = db.relationship('AnimeNetwork', backref='anime', lazy=True) def get_same_genres(self, genres_list, genre_str): same_genres = db.session.query(Anime, AnimeGenre) \ .join(Anime, Anime.id == AnimeGenre.media_id) \ .filter(AnimeGenre.genre.in_(genres_list), AnimeGenre.media_id != self.id) \ .group_by(AnimeGenre.media_id) \ .having(func.group_concat(AnimeGenre.genre.distinct()) == genre_str).limit(8).all() return same_genres def in_follows_lists(self, user_id): in_follows_lists = db.session.query(User, AnimeList, followers) \ .join(User, User.id == followers.c.followed_id) \ .join(AnimeList, AnimeList.user_id == followers.c.followed_id) \ .filter(followers.c.follower_id == user_id, AnimeList.media_id == self.id).all() return in_follows_lists def in_user_list(self, user_id): in_user_list = self.list_info.filter_by(user_id=user_id).first() return in_user_list
class AnimeList(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) media_id = db.Column(db.Integer, db.ForeignKey('anime.id'), nullable=False) current_season = db.Column(db.Integer, nullable=False) last_episode_watched = db.Column(db.Integer, nullable=False) status = db.Column(db.Enum(Status), nullable=False) rewatched = db.Column(db.Integer, nullable=False, default=0) favorite = db.Column(db.Boolean) score = db.Column(db.Float) eps_watched = db.Column(db.Integer) comment = db.Column(db.Text)
class Movies(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) original_name = db.Column(db.String(50), nullable=False) release_date = db.Column(db.String(30)) homepage = db.Column(db.String(200)) released = db.Column(db.String(30)) runtime = db.Column(db.Integer) original_language = db.Column(db.String(20)) synopsis = db.Column(db.Text) vote_average = db.Column(db.Float) vote_count = db.Column(db.Float) popularity = db.Column(db.Float) budget = db.Column(db.Float) revenue = db.Column(db.Float) tagline = db.Column(db.String(30)) image_cover = db.Column(db.String(100), nullable=False) themoviedb_id = db.Column(db.Integer, nullable=False)
class AnimeActors(db.Model): id = db.Column(db.Integer, primary_key=True) anime_id = db.Column(db.Integer, db.ForeignKey('anime.id'), nullable=False) name = db.Column(db.String(150))
class AnimeNetwork(db.Model): id = db.Column(db.Integer, primary_key=True) anime_id = db.Column(db.Integer, db.ForeignKey('anime.id'), nullable=False) network = db.Column(db.String(150), nullable=False)
class MyListsStats(db.Model): id = db.Column(db.Integer, primary_key=True) total_time = db.Column(db.Text) top_media = db.Column(db.Text) top_genres = db.Column(db.Text) top_actors = db.Column(db.Text) top_directors = db.Column(db.Text) top_dropped = db.Column(db.Text) total_episodes = db.Column(db.Text) total_seasons = db.Column(db.Text) total_movies = db.Column(db.Text) timestamp = db.Column(db.DateTime, default=datetime.utcnow)
class AnimeEpisodesPerSeason(db.Model): id = db.Column(db.Integer, primary_key=True) anime_id = db.Column(db.Integer, db.ForeignKey('anime.id'), nullable=False) season = db.Column(db.Integer, nullable=False) episodes = db.Column(db.Integer, nullable=False)
class SeriesNetwork(db.Model): id = db.Column(db.Integer, primary_key=True) series_id = db.Column(db.Integer, db.ForeignKey('series.id'), nullable=False) network = db.Column(db.String(150), nullable=False)
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(15), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) registered_on = db.Column(db.DateTime, nullable=False) password = db.Column(db.String(60), nullable=False) homepage = db.Column(db.Enum(HomePage), nullable=False, default=HomePage.MYSERIESLIST) image_file = db.Column(db.String(20), nullable=False, default='default.jpg') time_spent_series = db.Column(db.Integer, nullable=False, default=0) time_spent_movies = db.Column(db.Integer, nullable=False, default=0) time_spent_anime = db.Column(db.Integer, nullable=False, default=0) private = db.Column(db.Boolean, nullable=False, default=False) active = db.Column(db.Boolean, nullable=False, default=False) profile_views = db.Column(db.Integer, nullable=False, default=0) series_views = db.Column(db.Integer, nullable=False, default=0) anime_views = db.Column(db.Integer, nullable=False, default=0) movies_views = db.Column(db.Integer, nullable=False, default=0) biography = db.Column(db.Text) transition_email = db.Column(db.String(120)) activated_on = db.Column(db.DateTime) def get_reset_token(self, expires_sec=1800): s = Serializer(app.config['SECRET_KEY'], expires_sec) return s.dumps({'user_id': self.id}).decode('utf-8') def get_register_token(self): s = Serializer(app.config['SECRET_KEY']) return s.dumps({'user_id': self.id}).decode('utf-8') def get_email_update_token(self): s = Serializer(app.config['SECRET_KEY']) return s.dumps({'user_id': self.id}).decode('utf-8') @staticmethod def verify_reset_token(token): s = Serializer(app.config['SECRET_KEY']) try: user_id = s.loads(token)["user_id"] except: return None user = User.query.get(user_id) if user is None: return None else: return user
class Movies(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) original_name = db.Column(db.String(50), nullable=False) director_name = db.Column(db.String(100)) release_date = db.Column(db.String(30)) homepage = db.Column(db.String(200)) released = db.Column(db.String(30)) runtime = db.Column(db.Integer) original_language = db.Column(db.String(20)) synopsis = db.Column(db.Text) vote_average = db.Column(db.Float) vote_count = db.Column(db.Float) popularity = db.Column(db.Float) budget = db.Column(db.Float) revenue = db.Column(db.Float) tagline = db.Column(db.String(30)) image_cover = db.Column(db.String(100), nullable=False) themoviedb_id = db.Column(db.Integer, nullable=False) lock_status = db.Column(db.Boolean, default=0) genres = db.relationship('MoviesGenre', backref='movies', lazy=True) actors = db.relationship('MoviesActors', backref='movies', lazy=True) list_info = db.relationship('MoviesList', backref='movies', lazy='dynamic') def get_same_genres(self, genres_list, genre_str): same_genres = db.session.query(Movies, MoviesGenre) \ .join(Movies, Movies.id == MoviesGenre.media_id) \ .filter(MoviesGenre.genre.in_(genres_list), MoviesGenre.media_id != self.id) \ .group_by(MoviesGenre.media_id) \ .having(func.group_concat(MoviesGenre.genre.distinct()) == genre_str).limit(8).all() return same_genres def in_follows_lists(self, user_id): in_follows_lists = db.session.query(User, MoviesList, followers) \ .join(User, User.id == followers.c.followed_id) \ .join(MoviesList, MoviesList.user_id == followers.c.followed_id) \ .filter(followers.c.follower_id == user_id, MoviesList.media_id == self.id).all() return in_follows_lists def in_user_list(self, user_id): in_user_list = self.list_info.filter_by(user_id=user_id).first() return in_user_list
class Follow(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) follow_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(15), unique=True, nullable=False) oauth_id = db.Column(db.String(50), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) registered_on = db.Column(db.DateTime, nullable=False) password = db.Column(db.String(60), nullable=False) homepage = db.Column(db.Enum(HomePage), nullable=False, default=HomePage.ACCOUNT) image_file = db.Column(db.String(20), nullable=False, default='default.jpg') time_spent_series = db.Column(db.Integer, nullable=False, default=0) time_spent_movies = db.Column(db.Integer, nullable=False, default=0) time_spent_anime = db.Column(db.Integer, nullable=False, default=0) private = db.Column(db.Boolean, nullable=False, default=False) active = db.Column(db.Boolean, nullable=False, default=False) profile_views = db.Column(db.Integer, nullable=False, default=0) series_views = db.Column(db.Integer, nullable=False, default=0) anime_views = db.Column(db.Integer, nullable=False, default=0) movies_views = db.Column(db.Integer, nullable=False, default=0) biography = db.Column(db.Text) transition_email = db.Column(db.String(120)) activated_on = db.Column(db.DateTime) last_notif_read_time = db.Column(db.DateTime) role = db.Column(db.Enum(RoleType), nullable=False, default=RoleType.USER) series_list = db.relationship('SeriesList', backref='user', lazy=True) anime_list = db.relationship('AnimeList', backref='user', lazy=True) movies_list = db.relationship('MoviesList', backref='user', lazy=True) followed = db.relationship('User', secondary=followers, primaryjoin=(followers.c.follower_id == id), secondaryjoin=(followers.c.followed_id == id), backref=db.backref('followers', lazy='dynamic'), lazy='dynamic') def add_follow(self, user): if not self.is_following(user): self.followed.append(user) def remove_follow(self, user): if self.is_following(user): self.followed.remove(user) def is_following(self, user): return self.followed.filter(followers.c.followed_id == user.id).count() > 0 def get_reset_token(self, expires_sec=1800): s = Serializer(app.config['SECRET_KEY'], expires_sec) return s.dumps({'user_id': self.id}).decode('utf-8') def get_register_token(self): s = Serializer(app.config['SECRET_KEY']) return s.dumps({'user_id': self.id}).decode('utf-8') def get_email_update_token(self): s = Serializer(app.config['SECRET_KEY']) return s.dumps({'user_id': self.id}).decode('utf-8') def count_notifications(self): last_notif_time = self.last_notif_read_time or datetime(1900, 1, 1) return Notifications.query.filter_by(user_id=self.id) \ .filter(Notifications.timestamp > last_notif_time).count() def get_notifications(self): return Notifications.query.filter_by(user_id=self.id).order_by(desc(Notifications.timestamp)).limit(8).all() def check_autorization(self, user_name): # retrieve the user user = User.query.filter_by(username=user_name).first() # No account with this username if not user: abort(404) # Protection of the admin account if self.role != RoleType.ADMIN and user.role == RoleType.ADMIN: abort(404) # Check if the current account can see the target's account if self.id == user.id or self.role == RoleType.ADMIN: pass elif user.private and not self.is_following(user): abort(404) return user def add_view_count(self, user, list_type): if self.role != RoleType.ADMIN and user.id != self.id: if list_type == ListType.SERIES: user.series_views += 1 elif list_type == ListType.ANIME: user.anime_views += 1 elif list_type == ListType.MOVIES: user.movies_views += 1 db.session.commit() @staticmethod def verify_reset_token(token): s = Serializer(app.config['SECRET_KEY']) try: user_id = s.loads(token)["user_id"] except: return None user = User.query.get(user_id) if not user: return None else: return user
class MoviesActors(db.Model): id = db.Column(db.Integer, primary_key=True) movies_id = db.Column(db.Integer, db.ForeignKey('movies.id'), nullable=False) name = db.Column(db.String(150))
class AnimeGenre(db.Model): id = db.Column(db.Integer, primary_key=True) anime_id = db.Column(db.Integer, db.ForeignKey('anime.id'), nullable=False) genre = db.Column(db.String(100), nullable=False) genre_id = db.Column(db.Integer, nullable=False)
class Anime(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) original_name = db.Column(db.String(50), nullable=False) first_air_date = db.Column(db.String(30)) last_air_date = db.Column(db.String(30)) homepage = db.Column(db.String(200)) in_production = db.Column(db.Boolean) created_by = db.Column(db.String(100)) episode_duration = db.Column(db.Integer) total_seasons = db.Column(db.Integer, nullable=False) total_episodes = db.Column(db.Integer) origin_country = db.Column(db.String(20)) status = db.Column(db.String(50)) vote_average = db.Column(db.Float) vote_count = db.Column(db.Float) synopsis = db.Column(db.Text) popularity = db.Column(db.Float) image_cover = db.Column(db.String(100), nullable=False) themoviedb_id = db.Column(db.Integer, nullable=False) last_update = db.Column(db.DateTime, nullable=False)
class Frames(db.Model): id = db.Column(db.Integer, primary_key=True) level = db.Column(db.Integer, nullable=False) image_id = db.Column(db.String(50), nullable=False)
class UserLastUpdate(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) media_name = db.Column(db.String(50), nullable=False) media_type = db.Column(db.Enum(ListType), nullable=False) old_status = db.Column(db.Enum(Status)) new_status = db.Column(db.Enum(Status)) old_season = db.Column(db.Integer) new_season = db.Column(db.Integer) old_episode = db.Column(db.Integer) new_episode = db.Column(db.Integer) date = db.Column(db.DateTime, nullable=False)
class HomePage(enum.Enum): ACCOUNT = "account" HALL_OF_FAME = "hall_of_fame" MYSERIESLIST = "serieslist" MYANIMELIST = "animelist" MYMOVIESLIST = "movieslist" class RoleType(enum.Enum): ADMIN = "admin" # Can access to the admin dashboard (/admin) MANAGER = "manager" # Can lock and edit media (/lock_media & /media_sheet_form) USER = "******" # Standard user followers = db.Table('followers', db.Column('follower_id', db.Integer, db.ForeignKey('user.id')), db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))) class User(db.Model, UserMixin): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(15), unique=True, nullable=False) oauth_id = db.Column(db.String(50), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) registered_on = db.Column(db.DateTime, nullable=False) password = db.Column(db.String(60), nullable=False) homepage = db.Column(db.Enum(HomePage), nullable=False, default=HomePage.ACCOUNT) image_file = db.Column(db.String(20), nullable=False, default='default.jpg') time_spent_series = db.Column(db.Integer, nullable=False, default=0) time_spent_movies = db.Column(db.Integer, nullable=False, default=0) time_spent_anime = db.Column(db.Integer, nullable=False, default=0)