mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 19:10:00 +00:00
[DB Changes! Read PR!] Merge pull request #201 from nyaadevs/update-alembic-migrations
Rewrite database models for declarative and update Alembic migrations
This commit is contained in:
commit
279ec26f7c
61
db_create.py
61
db_create.py
|
@ -1,35 +1,60 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
import sys
|
import sys
|
||||||
|
import sqlalchemy
|
||||||
from nyaa import app, db, models
|
from nyaa import app, db, models
|
||||||
|
|
||||||
# Create tables
|
NYAA_CATEGORIES = [
|
||||||
|
|
||||||
db.create_all()
|
|
||||||
|
|
||||||
# Insert categories and insert if it doesn't eixst
|
|
||||||
existing_cats = models.MainCategory.query.all()
|
|
||||||
if not existing_cats:
|
|
||||||
if app.config['SITE_FLAVOR'] == 'nyaa':
|
|
||||||
CATEGORIES = [
|
|
||||||
('Anime', ['Anime Music Video', 'English-translated', 'Non-English-translated', 'Raw']),
|
('Anime', ['Anime Music Video', 'English-translated', 'Non-English-translated', 'Raw']),
|
||||||
('Audio', ['Lossless', 'Lossy']),
|
('Audio', ['Lossless', 'Lossy']),
|
||||||
('Literature', ['English-translated', 'Non-English-translated', 'Raw']),
|
('Literature', ['English-translated', 'Non-English-translated', 'Raw']),
|
||||||
('Live Action', ['English-translated', 'Idol/Promotional Video', 'Non-English-translated', 'Raw']),
|
('Live Action', ['English-translated', 'Idol/Promotional Video', 'Non-English-translated', 'Raw']),
|
||||||
('Pictures', ['Graphics', 'Photos']),
|
('Pictures', ['Graphics', 'Photos']),
|
||||||
('Software', ['Applications', 'Games']),
|
('Software', ['Applications', 'Games']),
|
||||||
]
|
]
|
||||||
elif app.config['SITE_FLAVOR'] == 'sukebei':
|
|
||||||
CATEGORIES = [
|
|
||||||
|
SUKEBEI_CATEGORIES = [
|
||||||
('Art', ['Anime', 'Doujinshi', 'Games', 'Manga', 'Pictures']),
|
('Art', ['Anime', 'Doujinshi', 'Games', 'Manga', 'Pictures']),
|
||||||
('Real Life', ['Photobooks / Pictures', 'Videos']),
|
('Real Life', ['Photobooks / Pictures', 'Videos']),
|
||||||
]
|
]
|
||||||
else:
|
|
||||||
CATEGORIES = []
|
|
||||||
|
|
||||||
for main_cat_name, sub_cat_names in CATEGORIES:
|
|
||||||
main_cat = models.MainCategory(name=main_cat_name)
|
def add_categories(categories, main_class, sub_class):
|
||||||
|
for main_cat_name, sub_cat_names in categories:
|
||||||
|
main_cat = main_class(name=main_cat_name)
|
||||||
for i, sub_cat_name in enumerate(sub_cat_names):
|
for i, sub_cat_name in enumerate(sub_cat_names):
|
||||||
# Composite keys can't autoincrement, set sub_cat id manually (1-index)
|
# Composite keys can't autoincrement, set sub_cat id manually (1-index)
|
||||||
sub_cat = models.SubCategory(id=i+1, name=sub_cat_name, main_category=main_cat)
|
sub_cat = sub_class(id=i+1, name=sub_cat_name, main_category=main_cat)
|
||||||
db.session.add(main_cat)
|
db.session.add(main_cat)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Test for the user table, assume db is empty if it's not created
|
||||||
|
database_empty = False
|
||||||
|
try:
|
||||||
|
models.User.query.first()
|
||||||
|
except (sqlalchemy.exc.ProgrammingError, sqlalchemy.exc.OperationalError):
|
||||||
|
database_empty = True
|
||||||
|
|
||||||
|
|
||||||
|
print('Creating all tables...')
|
||||||
|
db.create_all()
|
||||||
|
|
||||||
|
|
||||||
|
nyaa_category_test = models.NyaaMainCategory.query.first()
|
||||||
|
if not nyaa_category_test:
|
||||||
|
print('Adding Nyaa categories...')
|
||||||
|
add_categories(NYAA_CATEGORIES, models.NyaaMainCategory, models.NyaaSubCategory)
|
||||||
|
|
||||||
|
sukebei_category_test = models.SukebeiMainCategory.query.first()
|
||||||
|
if not sukebei_category_test:
|
||||||
|
print('Adding Sukebei categories...')
|
||||||
|
add_categories(SUKEBEI_CATEGORIES, models.SukebeiMainCategory, models.SukebeiSubCategory)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
if database_empty:
|
||||||
|
print('Remember to run the following to mark the database up-to-date for Alembic:')
|
||||||
|
print('./db_migrate.py db stamp head')
|
||||||
|
# Technically we should be able to do this here, but when you have
|
||||||
|
# Flask-Migrate and Flask-SQA and everything... I didn't get it working.
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from nyaa import app, db
|
from nyaa import app, db
|
||||||
from flask_script import Manager
|
from flask_script import Manager
|
||||||
|
|
|
@ -11,20 +11,19 @@ import sqlalchemy as sa
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '3001f79b7722'
|
revision = '3001f79b7722'
|
||||||
down_revision = None
|
down_revision = '97ddefed1834'
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
TABLE_PREFIXES = ('nyaa', 'sukebei')
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
for prefix in TABLE_PREFIXES:
|
||||||
op.add_column('nyaa_torrents', sa.Column('uploader_ip', sa.Binary(), nullable=True))
|
op.add_column(prefix + '_torrents', sa.Column('uploader_ip', sa.Binary(), nullable=True))
|
||||||
op.add_column('sukebei_torrents', sa.Column('uploader_ip', sa.Binary(), nullable=True))
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
for prefix in TABLE_PREFIXES:
|
||||||
op.drop_column('nyaa_torrents', 'uploader_ip')
|
op.drop_column(prefix + '_torrents', 'uploader_ip')
|
||||||
op.drop_column('sukebei_torrents', 'uploader_ip')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
166
migrations/versions/97ddefed1834_initial_database_state.py
Normal file
166
migrations/versions/97ddefed1834_initial_database_state.py
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
"""Initial database state
|
||||||
|
|
||||||
|
Revision ID: 97ddefed1834
|
||||||
|
Revises:
|
||||||
|
Create Date: 2017-05-26 18:46:14.440040
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
import sqlalchemy_utils
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '97ddefed1834'
|
||||||
|
down_revision = None
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
TABLE_PREFIXES = ('nyaa', 'sukebei')
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# Shared tables
|
||||||
|
op.create_table('users',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('username', sa.String(length=32, collation='ascii_general_ci'), nullable=False),
|
||||||
|
sa.Column('email', sqlalchemy_utils.types.email.EmailType(length=255), nullable=True),
|
||||||
|
|
||||||
|
# These are actually PasswordType, UserStatusType and UserLevelType,
|
||||||
|
# but database-wise binary and integers are what's being used
|
||||||
|
sa.Column('password_hash', sa.Binary(length=255), nullable=False),
|
||||||
|
sa.Column('status', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('level', sa.Integer(), nullable=False),
|
||||||
|
|
||||||
|
sa.Column('created_time', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('last_login_date', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('last_login_ip', sa.Binary(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('email'),
|
||||||
|
sa.UniqueConstraint('username')
|
||||||
|
)
|
||||||
|
|
||||||
|
op.create_table('trackers',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('uri', sa.String(length=255, collation='utf8_general_ci'), nullable=False),
|
||||||
|
sa.Column('disabled', sa.Boolean(), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('uri')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Nyaa and Sukebei
|
||||||
|
for prefix in TABLE_PREFIXES:
|
||||||
|
# Main categories
|
||||||
|
op.create_table(prefix + '_main_categories',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(length=64), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
# Sub categories
|
||||||
|
op.create_table(prefix + '_sub_categories',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('main_category_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('name', sa.String(length=64), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['main_category_id'], [prefix + '_main_categories.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id', 'main_category_id')
|
||||||
|
)
|
||||||
|
# Main torrent table
|
||||||
|
op.create_table(prefix + '_torrents',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('info_hash', sa.BINARY(length=20), nullable=False),
|
||||||
|
sa.Column('display_name', sa.String(length=255, collation='utf8_general_ci'), nullable=False),
|
||||||
|
sa.Column('torrent_name', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('information', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('description', mysql.TEXT(collation='utf8mb4_bin'), nullable=False),
|
||||||
|
sa.Column('filesize', sa.BIGINT(), nullable=False),
|
||||||
|
sa.Column('encoding', sa.String(length=32), nullable=False),
|
||||||
|
sa.Column('flags', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('uploader_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('has_torrent', sa.Boolean(), nullable=False),
|
||||||
|
sa.Column('created_time', sa.DateTime(), nullable=False),
|
||||||
|
sa.Column('updated_time', sa.DateTime(), nullable=False),
|
||||||
|
sa.Column('main_category_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('sub_category_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('redirect', sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['main_category_id', 'sub_category_id'], [prefix + '_sub_categories.main_category_id', prefix + '_sub_categories.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['main_category_id'], [prefix + '_main_categories.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['redirect'], [prefix + '_torrents.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['uploader_id'], ['users.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_torrents_display_name'), prefix + '_torrents', ['display_name'], unique=False)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_torrents_filesize'), prefix + '_torrents', ['filesize'], unique=False)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_torrents_flags'), prefix + '_torrents', ['flags'], unique=False)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_torrents_info_hash'), prefix + '_torrents', ['info_hash'], unique=True)
|
||||||
|
op.create_index(prefix + '_uploader_flag_idx', prefix + '_torrents', ['uploader_id', 'flags'], unique=False)
|
||||||
|
|
||||||
|
# Statistics for torrents
|
||||||
|
op.create_table(prefix + '_statistics',
|
||||||
|
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('seed_count', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('leech_count', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('download_count', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('last_updated', sa.DateTime(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['torrent_id'], [prefix + '_torrents.id'], ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('torrent_id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_statistics_download_count'), prefix + '_statistics', ['download_count'], unique=False)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_statistics_leech_count'), prefix + '_statistics', ['leech_count'], unique=False)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_statistics_seed_count'), prefix + '_statistics', ['seed_count'], unique=False)
|
||||||
|
|
||||||
|
# Trackers relationships for torrents
|
||||||
|
op.create_table(prefix + '_torrent_trackers',
|
||||||
|
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('tracker_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('order', sa.Integer(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['torrent_id'], [prefix + '_torrents.id'], ondelete='CASCADE'),
|
||||||
|
sa.ForeignKeyConstraint(['tracker_id'], ['trackers.id'], ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('torrent_id', 'tracker_id')
|
||||||
|
)
|
||||||
|
op.create_index(op.f('ix_' + prefix + '_torrent_trackers_order'), prefix + '_torrent_trackers', ['order'], unique=False)
|
||||||
|
|
||||||
|
# Torrent filelists
|
||||||
|
op.create_table(prefix + '_torrents_filelist',
|
||||||
|
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('filelist_blob', mysql.MEDIUMBLOB(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['torrent_id'], [prefix + '_torrents.id'], ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('torrent_id'),
|
||||||
|
mysql_row_format='COMPRESSED'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Torrent info_dicts
|
||||||
|
op.create_table(prefix + '_torrents_info',
|
||||||
|
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('info_dict', mysql.MEDIUMBLOB(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['torrent_id'], [prefix + '_torrents.id'], ondelete='CASCADE'),
|
||||||
|
sa.PrimaryKeyConstraint('torrent_id'),
|
||||||
|
mysql_row_format='COMPRESSED'
|
||||||
|
)
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# Note: this may fail. It's better to just drop all tables instead (or reset the database)
|
||||||
|
|
||||||
|
# Nyaa and Sukebei
|
||||||
|
for prefix in TABLE_PREFIXES:
|
||||||
|
op.drop_table(prefix + '_torrents_info')
|
||||||
|
op.drop_table(prefix + '_torrents_filelist')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_torrent_trackers_order'), table_name=prefix + '_torrent_trackers')
|
||||||
|
op.drop_table(prefix + '_torrent_trackers')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_statistics_seed_count'), table_name=prefix + '_statistics')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_statistics_leech_count'), table_name=prefix + '_statistics')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_statistics_download_count'), table_name=prefix + '_statistics')
|
||||||
|
op.drop_table(prefix + '_statistics')
|
||||||
|
op.drop_table(prefix + '_torrents')
|
||||||
|
op.drop_index(prefix + '_uploader_flag_idx', table_name=prefix + '_torrents')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_torrents_info_hash'), table_name=prefix + '_torrents')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_torrents_flags'), table_name=prefix + '_torrents')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_torrents_filesize'), table_name=prefix + '_torrents')
|
||||||
|
op.drop_index(op.f('ix_' + prefix + '_torrents_display_name'), table_name=prefix + '_torrents')
|
||||||
|
op.drop_table(prefix + '_sub_categories')
|
||||||
|
op.drop_table(prefix + '_main_categories')
|
||||||
|
|
||||||
|
# Shared tables
|
||||||
|
op.drop_table('users')
|
||||||
|
op.drop_table('trackers')
|
||||||
|
# ### end Alembic commands ###
|
|
@ -15,34 +15,23 @@ down_revision = '3001f79b7722'
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
TABLE_PREFIXES = ('nyaa', 'sukebei')
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
for prefix in TABLE_PREFIXES:
|
||||||
op.create_table('nyaa_comments',
|
op.create_table(prefix + '_comments',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
sa.Column('user_id', sa.Integer(), nullable=True),
|
||||||
sa.Column('created_time', sa.DateTime(), nullable=True),
|
sa.Column('created_time', sa.DateTime(), nullable=True),
|
||||||
sa.Column('text', sa.String(length=255, collation='utf8mb4_bin'), nullable=False),
|
sa.Column('text', sa.String(length=255, collation='utf8mb4_bin'), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['torrent_id'], ['nyaa_torrents.id'], ondelete='CASCADE'),
|
sa.ForeignKeyConstraint(['torrent_id'], [prefix + '_torrents.id'], ondelete='CASCADE'),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.PrimaryKeyConstraint('id')
|
||||||
)
|
)
|
||||||
op.create_table('sukebei_comments',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('torrent_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('created_time', sa.DateTime(), nullable=True),
|
|
||||||
sa.Column('text', sa.String(length=255, collation='utf8mb4_bin'), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['torrent_id'], ['sukebei_torrents.id'], ondelete='CASCADE'),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ondelete='CASCADE'),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
for prefix in TABLE_PREFIXES:
|
||||||
op.drop_table('nyaa_comments')
|
op.drop_table(prefix + '_comments')
|
||||||
op.drop_table('sukebei_comments')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
386
nyaa/models.py
386
nyaa/models.py
|
@ -3,10 +3,13 @@ from enum import Enum, IntEnum
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from nyaa import app, db
|
from nyaa import app, db
|
||||||
from nyaa.torrents import create_magnet
|
from nyaa.torrents import create_magnet
|
||||||
|
|
||||||
from sqlalchemy import func, ForeignKeyConstraint, Index
|
from sqlalchemy import func, ForeignKeyConstraint, Index
|
||||||
|
from sqlalchemy.ext import declarative
|
||||||
from sqlalchemy_utils import ChoiceType, EmailType, PasswordType
|
from sqlalchemy_utils import ChoiceType, EmailType, PasswordType
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
|
||||||
from sqlalchemy_fulltext import FullText
|
from sqlalchemy_fulltext import FullText
|
||||||
|
|
||||||
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from ipaddress import ip_address
|
from ipaddress import ip_address
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
@ -36,6 +39,31 @@ else:
|
||||||
UTC_EPOCH = datetime.utcfromtimestamp(0)
|
UTC_EPOCH = datetime.utcfromtimestamp(0)
|
||||||
|
|
||||||
|
|
||||||
|
class DeclarativeHelperBase(object):
|
||||||
|
''' This class eases our nyaa-sukebei shenanigans by automatically adjusting
|
||||||
|
__tablename__ and providing class methods for renaming references. '''
|
||||||
|
# See http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/api.html
|
||||||
|
|
||||||
|
__tablename_base__ = None
|
||||||
|
__flavor__ = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _table_prefix_string(cls):
|
||||||
|
return cls.__flavor__.lower() + '_'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _table_prefix(cls, table_name):
|
||||||
|
return cls._table_prefix_string() + table_name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _flavor_prefix(cls, table_name):
|
||||||
|
return cls.__flavor__ + table_name
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def __tablename__(cls):
|
||||||
|
return cls._table_prefix(cls.__tablename_base__)
|
||||||
|
|
||||||
|
|
||||||
class TorrentFlags(IntEnum):
|
class TorrentFlags(IntEnum):
|
||||||
NONE = 0
|
NONE = 0
|
||||||
ANONYMOUS = 1
|
ANONYMOUS = 1
|
||||||
|
@ -46,16 +74,13 @@ class TorrentFlags(IntEnum):
|
||||||
DELETED = 32
|
DELETED = 32
|
||||||
|
|
||||||
|
|
||||||
DB_TABLE_PREFIX = app.config['TABLE_PREFIX']
|
class TorrentBase(DeclarativeHelperBase):
|
||||||
|
__tablename_base__ = 'torrents'
|
||||||
|
|
||||||
class Torrent(db.Model):
|
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'torrents'
|
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
info_hash = db.Column(BinaryType(length=20), unique=True, nullable=False, index=True)
|
info_hash = db.Column(BinaryType(length=20), unique=True, nullable=False, index=True)
|
||||||
display_name = db.Column(
|
display_name = db.Column(db.String(length=255, collation=COL_UTF8_GENERAL_CI),
|
||||||
db.String(length=255, collation=COL_UTF8_GENERAL_CI), nullable=False, index=True)
|
nullable=False, index=True)
|
||||||
torrent_name = db.Column(db.String(length=255), nullable=False)
|
torrent_name = db.Column(db.String(length=255), nullable=False)
|
||||||
information = db.Column(db.String(length=255), nullable=False)
|
information = db.Column(db.String(length=255), nullable=False)
|
||||||
description = db.Column(DescriptionTextType(collation=COL_UTF8MB4_BIN), nullable=False)
|
description = db.Column(DescriptionTextType(collation=COL_UTF8MB4_BIN), nullable=False)
|
||||||
|
@ -63,45 +88,84 @@ class Torrent(db.Model):
|
||||||
filesize = db.Column(db.BIGINT, default=0, nullable=False, index=True)
|
filesize = db.Column(db.BIGINT, default=0, nullable=False, index=True)
|
||||||
encoding = db.Column(db.String(length=32), nullable=False)
|
encoding = db.Column(db.String(length=32), nullable=False)
|
||||||
flags = db.Column(db.Integer, default=0, nullable=False, index=True)
|
flags = db.Column(db.Integer, default=0, nullable=False, index=True)
|
||||||
uploader_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def uploader_id(cls):
|
||||||
|
# Even though this is same for both tables, declarative requires this
|
||||||
|
return db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
|
||||||
|
|
||||||
uploader_ip = db.Column(db.Binary(length=16), default=None, nullable=True)
|
uploader_ip = db.Column(db.Binary(length=16), default=None, nullable=True)
|
||||||
has_torrent = db.Column(db.Boolean, nullable=False, default=False)
|
has_torrent = db.Column(db.Boolean, nullable=False, default=False)
|
||||||
|
|
||||||
created_time = db.Column(db.DateTime(timezone=False), default=datetime.utcnow, nullable=False)
|
created_time = db.Column(db.DateTime(timezone=False), default=datetime.utcnow, nullable=False)
|
||||||
updated_time = db.Column(db.DateTime(timezone=False),
|
updated_time = db.Column(db.DateTime(timezone=False), default=datetime.utcnow,
|
||||||
default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
|
onupdate=datetime.utcnow, nullable=False)
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def main_category_id(cls):
|
||||||
|
fk = db.ForeignKey(cls._table_prefix('main_categories.id'))
|
||||||
|
return db.Column(db.Integer, fk, nullable=False)
|
||||||
|
|
||||||
main_category_id = db.Column(db.Integer, db.ForeignKey(
|
|
||||||
DB_TABLE_PREFIX + 'main_categories.id'), nullable=False)
|
|
||||||
sub_category_id = db.Column(db.Integer, nullable=False)
|
sub_category_id = db.Column(db.Integer, nullable=False)
|
||||||
redirect = db.Column(db.Integer, db.ForeignKey(
|
|
||||||
DB_TABLE_PREFIX + 'torrents.id'), nullable=True)
|
|
||||||
|
|
||||||
__table_args__ = (
|
@declarative.declared_attr
|
||||||
Index('uploader_flag_idx', 'uploader_id', 'flags'),
|
def redirect(cls):
|
||||||
|
fk = db.ForeignKey(cls._table_prefix('torrents.id'))
|
||||||
|
return db.Column(db.Integer, fk, nullable=True)
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def __table_args__(cls):
|
||||||
|
return (
|
||||||
|
Index(cls._table_prefix('uploader_flag_idx'), 'uploader_id', 'flags'),
|
||||||
ForeignKeyConstraint(
|
ForeignKeyConstraint(
|
||||||
['main_category_id', 'sub_category_id'],
|
['main_category_id', 'sub_category_id'],
|
||||||
[DB_TABLE_PREFIX + 'sub_categories.main_category_id',
|
[cls._table_prefix('sub_categories.main_category_id'),
|
||||||
DB_TABLE_PREFIX + 'sub_categories.id']
|
cls._table_prefix('sub_categories.id')]
|
||||||
), {}
|
), {}
|
||||||
)
|
)
|
||||||
|
|
||||||
user = db.relationship('User', uselist=False, back_populates='torrents')
|
@declarative.declared_attr
|
||||||
main_category = db.relationship('MainCategory', uselist=False,
|
def user(cls):
|
||||||
|
return db.relationship('User', uselist=False, back_populates=cls._table_prefix('torrents'))
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def main_category(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('MainCategory'), uselist=False,
|
||||||
back_populates='torrents', lazy="joined")
|
back_populates='torrents', lazy="joined")
|
||||||
sub_category = db.relationship('SubCategory', uselist=False, backref='torrents', lazy="joined",
|
|
||||||
primaryjoin=(
|
@declarative.declared_attr
|
||||||
"and_(SubCategory.id == foreign(Torrent.sub_category_id), "
|
def sub_category(cls):
|
||||||
"SubCategory.main_category_id == Torrent.main_category_id)"))
|
join_sql = ("and_({0}SubCategory.id == foreign({0}Torrent.sub_category_id), "
|
||||||
info = db.relationship('TorrentInfo', uselist=False,
|
"{0}SubCategory.main_category_id == {0}Torrent.main_category_id)")
|
||||||
|
return db.relationship(cls._flavor_prefix('SubCategory'), uselist=False,
|
||||||
|
backref='torrents', lazy="joined",
|
||||||
|
primaryjoin=join_sql.format(cls.__flavor__))
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def info(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('TorrentInfo'), uselist=False,
|
||||||
cascade="all, delete-orphan", back_populates='torrent')
|
cascade="all, delete-orphan", back_populates='torrent')
|
||||||
filelist = db.relationship('TorrentFilelist', uselist=False,
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def filelist(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('TorrentFilelist'), uselist=False,
|
||||||
cascade="all, delete-orphan", back_populates='torrent')
|
cascade="all, delete-orphan", back_populates='torrent')
|
||||||
stats = db.relationship('Statistic', uselist=False,
|
|
||||||
cascade="all, delete-orphan", back_populates='torrent', lazy='joined')
|
@declarative.declared_attr
|
||||||
trackers = db.relationship('TorrentTrackers', uselist=True, cascade="all, delete-orphan",
|
def stats(cls):
|
||||||
lazy='joined', order_by='TorrentTrackers.order')
|
return db.relationship(cls._flavor_prefix('Statistic'), uselist=False,
|
||||||
comments = db.relationship('Comment', uselist=True,
|
cascade="all, delete-orphan", back_populates='torrent',
|
||||||
|
lazy='joined')
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def trackers(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('TorrentTrackers'), uselist=True,
|
||||||
|
cascade="all, delete-orphan", lazy='joined',
|
||||||
|
order_by=cls._flavor_prefix('TorrentTrackers.order'))
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def comments(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('Comment'), uselist=True,
|
||||||
cascade="all, delete-orphan")
|
cascade="all, delete-orphan")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -211,44 +275,57 @@ class Torrent(db.Model):
|
||||||
return cls.by_info_hash(info_hash_bytes)
|
return cls.by_info_hash(info_hash_bytes)
|
||||||
|
|
||||||
|
|
||||||
class TorrentNameSearch(FullText, Torrent):
|
class TorrentFilelistBase(DeclarativeHelperBase):
|
||||||
__fulltext_columns__ = ('display_name',)
|
__tablename_base__ = 'torrents_filelist'
|
||||||
|
|
||||||
|
|
||||||
class TorrentFilelist(db.Model):
|
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'torrents_filelist'
|
|
||||||
__table_args__ = {'mysql_row_format': 'COMPRESSED'}
|
__table_args__ = {'mysql_row_format': 'COMPRESSED'}
|
||||||
|
|
||||||
torrent_id = db.Column(db.Integer, db.ForeignKey(
|
@declarative.declared_attr
|
||||||
DB_TABLE_PREFIX + 'torrents.id', ondelete="CASCADE"), primary_key=True)
|
def torrent_id(cls):
|
||||||
|
fk = db.ForeignKey(cls._table_prefix('torrents.id'), ondelete="CASCADE")
|
||||||
|
return db.Column(db.Integer, fk, primary_key=True)
|
||||||
|
|
||||||
filelist_blob = db.Column(MediumBlobType, nullable=True)
|
filelist_blob = db.Column(MediumBlobType, nullable=True)
|
||||||
|
|
||||||
torrent = db.relationship('Torrent', uselist=False, back_populates='filelist')
|
@declarative.declared_attr
|
||||||
|
def torrent(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('Torrent'), uselist=False,
|
||||||
|
back_populates='filelist')
|
||||||
|
|
||||||
|
|
||||||
class TorrentInfo(db.Model):
|
class TorrentInfoBase(DeclarativeHelperBase):
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'torrents_info'
|
__tablename_base__ = 'torrents_info'
|
||||||
|
|
||||||
__table_args__ = {'mysql_row_format': 'COMPRESSED'}
|
__table_args__ = {'mysql_row_format': 'COMPRESSED'}
|
||||||
|
|
||||||
torrent_id = db.Column(db.Integer, db.ForeignKey(
|
@declarative.declared_attr
|
||||||
DB_TABLE_PREFIX + 'torrents.id', ondelete="CASCADE"), primary_key=True)
|
def torrent_id(cls):
|
||||||
|
return db.Column(db.Integer, db.ForeignKey(
|
||||||
|
cls._table_prefix('torrents.id'), ondelete="CASCADE"), primary_key=True)
|
||||||
info_dict = db.Column(MediumBlobType, nullable=True)
|
info_dict = db.Column(MediumBlobType, nullable=True)
|
||||||
|
|
||||||
torrent = db.relationship('Torrent', uselist=False, back_populates='info')
|
@declarative.declared_attr
|
||||||
|
def torrent(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('Torrent'), uselist=False, back_populates='info')
|
||||||
|
|
||||||
|
|
||||||
class Statistic(db.Model):
|
class StatisticBase(DeclarativeHelperBase):
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'statistics'
|
__tablename_base__ = 'statistics'
|
||||||
|
|
||||||
torrent_id = db.Column(db.Integer, db.ForeignKey(
|
@declarative.declared_attr
|
||||||
DB_TABLE_PREFIX + 'torrents.id', ondelete="CASCADE"), primary_key=True)
|
def torrent_id(cls):
|
||||||
|
fk = db.ForeignKey(cls._table_prefix('torrents.id'), ondelete="CASCADE")
|
||||||
|
return db.Column(db.Integer, fk, primary_key=True)
|
||||||
|
|
||||||
seed_count = db.Column(db.Integer, default=0, nullable=False, index=True)
|
seed_count = db.Column(db.Integer, default=0, nullable=False, index=True)
|
||||||
leech_count = db.Column(db.Integer, default=0, nullable=False, index=True)
|
leech_count = db.Column(db.Integer, default=0, nullable=False, index=True)
|
||||||
download_count = db.Column(db.Integer, default=0, nullable=False, index=True)
|
download_count = db.Column(db.Integer, default=0, nullable=False, index=True)
|
||||||
last_updated = db.Column(db.DateTime(timezone=False))
|
last_updated = db.Column(db.DateTime(timezone=False))
|
||||||
|
|
||||||
torrent = db.relationship('Torrent', uselist=False, back_populates='stats')
|
@declarative.declared_attr
|
||||||
|
def torrent(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('Torrent'), uselist=False,
|
||||||
|
back_populates='stats')
|
||||||
|
|
||||||
|
|
||||||
class Trackers(db.Model):
|
class Trackers(db.Model):
|
||||||
|
@ -264,30 +341,43 @@ class Trackers(db.Model):
|
||||||
return cls.query.filter_by(uri=uri).first()
|
return cls.query.filter_by(uri=uri).first()
|
||||||
|
|
||||||
|
|
||||||
class TorrentTrackers(db.Model):
|
class TorrentTrackersBase(DeclarativeHelperBase):
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'torrent_trackers'
|
__tablename_base__ = 'torrent_trackers'
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def torrent_id(cls):
|
||||||
|
fk = db.ForeignKey(cls._table_prefix('torrents.id'), ondelete="CASCADE")
|
||||||
|
return db.Column(db.Integer, fk, primary_key=True)
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def tracker_id(cls):
|
||||||
|
fk = db.ForeignKey('trackers.id', ondelete="CASCADE")
|
||||||
|
return db.Column(db.Integer, fk, primary_key=True)
|
||||||
|
|
||||||
torrent_id = db.Column(db.Integer, db.ForeignKey(
|
|
||||||
DB_TABLE_PREFIX + 'torrents.id', ondelete="CASCADE"), primary_key=True)
|
|
||||||
tracker_id = db.Column(db.Integer, db.ForeignKey(
|
|
||||||
'trackers.id', ondelete="CASCADE"), primary_key=True)
|
|
||||||
order = db.Column(db.Integer, nullable=False, index=True)
|
order = db.Column(db.Integer, nullable=False, index=True)
|
||||||
|
|
||||||
tracker = db.relationship('Trackers', uselist=False, lazy='joined')
|
@declarative.declared_attr
|
||||||
|
def tracker(cls):
|
||||||
|
return db.relationship('Trackers', uselist=False, lazy='joined')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def by_torrent_id(cls, torrent_id):
|
def by_torrent_id(cls, torrent_id):
|
||||||
return cls.query.filter_by(torrent_id=torrent_id).order_by(cls.order.desc())
|
return cls.query.filter_by(torrent_id=torrent_id).order_by(cls.order.desc())
|
||||||
|
|
||||||
|
|
||||||
class MainCategory(db.Model):
|
class MainCategoryBase(DeclarativeHelperBase):
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'main_categories'
|
__tablename_base__ = 'main_categories'
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(length=64), nullable=False)
|
name = db.Column(db.String(length=64), nullable=False)
|
||||||
|
|
||||||
sub_categories = db.relationship('SubCategory', back_populates='main_category')
|
@declarative.declared_attr
|
||||||
torrents = db.relationship('Torrent', back_populates='main_category')
|
def sub_categories(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('SubCategory'), back_populates='main_category')
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def torrents(cls):
|
||||||
|
return db.relationship(cls._flavor_prefix('Torrent'), back_populates='main_category')
|
||||||
|
|
||||||
def get_category_ids(self):
|
def get_category_ids(self):
|
||||||
return (self.id, 0)
|
return (self.id, 0)
|
||||||
|
@ -301,18 +391,22 @@ class MainCategory(db.Model):
|
||||||
return cls.query.get(id)
|
return cls.query.get(id)
|
||||||
|
|
||||||
|
|
||||||
class SubCategory(db.Model):
|
class SubCategoryBase(DeclarativeHelperBase):
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'sub_categories'
|
__tablename_base__ = 'sub_categories'
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
main_category_id = db.Column(db.Integer, db.ForeignKey(
|
|
||||||
DB_TABLE_PREFIX + 'main_categories.id'), primary_key=True)
|
@declarative.declared_attr
|
||||||
|
def main_category_id(cls):
|
||||||
|
fk = db.ForeignKey(cls._table_prefix('main_categories.id'))
|
||||||
|
return db.Column(db.Integer, fk, primary_key=True)
|
||||||
|
|
||||||
name = db.Column(db.String(length=64), nullable=False)
|
name = db.Column(db.String(length=64), nullable=False)
|
||||||
|
|
||||||
main_category = db.relationship('MainCategory', uselist=False, back_populates='sub_categories')
|
@declarative.declared_attr
|
||||||
# torrents = db.relationship('Torrent', back_populates='sub_category'),
|
def main_category(cls):
|
||||||
# primaryjoin="and_(Torrent.sub_category_id == foreign(SubCategory.id), "
|
return db.relationship(cls._flavor_prefix('MainCategory'), uselist=False,
|
||||||
# "Torrent.main_category_id == SubCategory.main_category_id)")
|
back_populates='sub_categories')
|
||||||
|
|
||||||
def get_category_ids(self):
|
def get_category_ids(self):
|
||||||
return (self.main_category_id, self.id)
|
return (self.main_category_id, self.id)
|
||||||
|
@ -326,17 +420,27 @@ class SubCategory(db.Model):
|
||||||
return cls.query.get((sub_cat_id, main_cat_id))
|
return cls.query.get((sub_cat_id, main_cat_id))
|
||||||
|
|
||||||
|
|
||||||
class Comment(db.Model):
|
class CommentBase(DeclarativeHelperBase):
|
||||||
__tablename__ = DB_TABLE_PREFIX + 'comments'
|
__tablename_base__ = 'comments'
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
torrent_id = db.Column(db.Integer, db.ForeignKey(
|
|
||||||
DB_TABLE_PREFIX + 'torrents.id', ondelete='CASCADE'), nullable=False)
|
@declarative.declared_attr
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'))
|
def torrent_id(cls):
|
||||||
|
return db.Column(db.Integer, db.ForeignKey(
|
||||||
|
cls._table_prefix('torrents.id'), ondelete='CASCADE'), nullable=False)
|
||||||
|
|
||||||
|
@declarative.declared_attr
|
||||||
|
def user_id(cls):
|
||||||
|
return db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'))
|
||||||
|
|
||||||
created_time = db.Column(db.DateTime(timezone=False), default=datetime.utcnow)
|
created_time = db.Column(db.DateTime(timezone=False), default=datetime.utcnow)
|
||||||
text = db.Column(db.String(length=255, collation=COL_UTF8MB4_BIN), nullable=False)
|
text = db.Column(db.String(length=255, collation=COL_UTF8MB4_BIN), nullable=False)
|
||||||
|
|
||||||
user = db.relationship('User', uselist=False, back_populates='comments', lazy="joined")
|
@declarative.declared_attr
|
||||||
|
def user(cls):
|
||||||
|
return db.relationship('User', uselist=False,
|
||||||
|
back_populates=cls._table_prefix('comments'), lazy="joined")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Comment %r>' % self.id
|
return '<Comment %r>' % self.id
|
||||||
|
@ -376,9 +480,11 @@ class User(db.Model):
|
||||||
last_login_date = db.Column(db.DateTime(timezone=False), default=None, nullable=True)
|
last_login_date = db.Column(db.DateTime(timezone=False), default=None, nullable=True)
|
||||||
last_login_ip = db.Column(db.Binary(length=16), default=None, nullable=True)
|
last_login_ip = db.Column(db.Binary(length=16), default=None, nullable=True)
|
||||||
|
|
||||||
torrents = db.relationship('Torrent', back_populates='user', lazy='dynamic')
|
nyaa_torrents = db.relationship('NyaaTorrent', back_populates='user', lazy='dynamic')
|
||||||
comments = db.relationship('Comment', back_populates='user', lazy='dynamic')
|
nyaa_comments = db.relationship('NyaaComment', back_populates='user', lazy='dynamic')
|
||||||
# session = db.relationship('Session', uselist=False, back_populates='user')
|
|
||||||
|
sukebei_torrents = db.relationship('SukebeiTorrent', back_populates='user', lazy='dynamic')
|
||||||
|
sukebei_comments = db.relationship('SukebeiComment', back_populates='user', lazy='dynamic')
|
||||||
|
|
||||||
def __init__(self, username, email, password):
|
def __init__(self, username, email, password):
|
||||||
self.username = username
|
self.username = username
|
||||||
|
@ -464,12 +570,118 @@ class User(db.Model):
|
||||||
return self.level >= UserLevelType.TRUSTED
|
return self.level >= UserLevelType.TRUSTED
|
||||||
|
|
||||||
|
|
||||||
# class Session(db.Model):
|
# Actually declare our site-specific classes
|
||||||
# __tablename__ = 'sessions'
|
|
||||||
#
|
# Torrent
|
||||||
# session_id = db.Column(db.Integer, primary_key=True)
|
class NyaaTorrent(TorrentBase, db.Model):
|
||||||
# user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
__flavor__ = 'Nyaa'
|
||||||
# login_ip = db.Column(db.Binary(length=16), nullable=True)
|
|
||||||
# login_date = db.Column(db.DateTime(timezone=False), nullable=True)
|
|
||||||
#
|
class SukebeiTorrent(TorrentBase, db.Model):
|
||||||
# user = db.relationship('User', back_populates='session')
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# Fulltext models for MySQL
|
||||||
|
if app.config['USE_MYSQL']:
|
||||||
|
class NyaaTorrentNameSearch(FullText, NyaaTorrent):
|
||||||
|
__fulltext_columns__ = ('display_name',)
|
||||||
|
__table_args__ = {'extend_existing': True}
|
||||||
|
|
||||||
|
class SukebeiTorrentNameSearch(FullText, SukebeiTorrent):
|
||||||
|
__fulltext_columns__ = ('display_name',)
|
||||||
|
__table_args__ = {'extend_existing': True}
|
||||||
|
else:
|
||||||
|
# Bogus classes for Sqlite
|
||||||
|
class NyaaTorrentNameSearch(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SukebeiTorrentNameSearch(object):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# TorrentFilelist
|
||||||
|
class NyaaTorrentFilelist(TorrentFilelistBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiTorrentFilelist(TorrentFilelistBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# TorrentInfo
|
||||||
|
class NyaaTorrentInfo(TorrentInfoBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiTorrentInfo(TorrentInfoBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# Statistic
|
||||||
|
class NyaaStatistic(StatisticBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiStatistic(StatisticBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# TorrentTrackers
|
||||||
|
class NyaaTorrentTrackers(TorrentTrackersBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiTorrentTrackers(TorrentTrackersBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# MainCategory
|
||||||
|
class NyaaMainCategory(MainCategoryBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiMainCategory(MainCategoryBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# SubCategory
|
||||||
|
class NyaaSubCategory(SubCategoryBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiSubCategory(SubCategoryBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# Comment
|
||||||
|
class NyaaComment(CommentBase, db.Model):
|
||||||
|
__flavor__ = 'Nyaa'
|
||||||
|
|
||||||
|
|
||||||
|
class SukebeiComment(CommentBase, db.Model):
|
||||||
|
__flavor__ = 'Sukebei'
|
||||||
|
|
||||||
|
|
||||||
|
# Choose our defaults for models.Torrent etc
|
||||||
|
if app.config['SITE_FLAVOR'] == 'nyaa':
|
||||||
|
Torrent = NyaaTorrent
|
||||||
|
TorrentFilelist = NyaaTorrentFilelist
|
||||||
|
TorrentInfo = NyaaTorrentInfo
|
||||||
|
Statistic = NyaaStatistic
|
||||||
|
TorrentTrackers = NyaaTorrentTrackers
|
||||||
|
MainCategory = NyaaMainCategory
|
||||||
|
SubCategory = NyaaSubCategory
|
||||||
|
Comment = NyaaComment
|
||||||
|
|
||||||
|
TorrentNameSearch = NyaaTorrentNameSearch
|
||||||
|
elif app.config['SITE_FLAVOR'] == 'sukebei':
|
||||||
|
Torrent = SukebeiTorrent
|
||||||
|
TorrentFilelist = SukebeiTorrentFilelist
|
||||||
|
TorrentInfo = SukebeiTorrentInfo
|
||||||
|
Statistic = SukebeiStatistic
|
||||||
|
TorrentTrackers = SukebeiTorrentTrackers
|
||||||
|
MainCategory = SukebeiMainCategory
|
||||||
|
SubCategory = SukebeiSubCategory
|
||||||
|
Comment = SukebeiComment
|
||||||
|
|
||||||
|
TorrentNameSearch = SukebeiTorrentNameSearch
|
||||||
|
|
Loading…
Reference in a new issue