
* #39 Add Flask-Migrate dep * #39 Make it such that flask db init can run https://github.com/miguelgrinberg/Flask-Migrate/issues/196#issuecomment-381343393 * Run flask db init, update migrations.env, commit artifacts * Set up a script such that you can `docker-compose exec files bash -c 'cd /service; FLASK_APP="files/cli:app" flask '` and have it do whatever flask thing you want * Fix circular dependency * import * is evil * Initial alembic migration, has issues with constraints and nullable columns * Bring alts table up to date with alembic autogenerate * Rerun flask db revision autogenerate * Bring award_relationships table up to date with alembic autogenerate * [#39/alembic] files/classes/__init__.py is evil but is at least explicitly evil now * #39 fix model in files/classes/badges.py * #39 fix model in files/classes/domains.py and files/classes/clients.py * #39 fix models: comment saves, comment flags * #39 fix models: comments * Few more imports * #39 columns that are not nullable should be flagged as not nullable * #39 Add missing indexes to model defs * [#39] add missing unique constraints to model defs * [#39] Temporarily undo any model changes which cause the sqlalchemy model to be out of sync with the actual dump * #39 Deforeignkeyify the correct column to make alembic happy * #39 flask db revision --autogenerate now creates an empty migration * #39 Migration format such that files are listed in creation order * #39 Better first revision * #39 Revert the model changes that were required to get to zero differences between db revision --autogenerate and the existing schema * #39 The first real migration * #39 Ensure that foreign key constraints are named in migration * #39 Alembic migrations for FK constraints, column defs * [#39] Run DB migrations before starting tests * [#39] New test to ensure migrations are up to date * [#39] More descriptive test failure message * Add -T flag to docker-compose exec * [#39] Run alembic migrations when starting the container
77 lines
2.3 KiB
Python
77 lines
2.3 KiB
Python
from sqlalchemy import *
|
|
from sqlalchemy.orm import relationship
|
|
from files.__main__ import Base, app
|
|
from os import environ
|
|
from files.helpers.lazy import lazy
|
|
from files.helpers.const import *
|
|
from datetime import datetime
|
|
from json import loads
|
|
|
|
class BadgeDef(Base):
|
|
__tablename__ = "badge_defs"
|
|
__table_args__ = (
|
|
UniqueConstraint('name', name='badge_def_name_unique'),
|
|
)
|
|
|
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
name = Column(String, nullable=False)
|
|
description = Column(String)
|
|
|
|
def __repr__(self):
|
|
return f"<BadgeDef(id={self.id})>"
|
|
|
|
class Badge(Base):
|
|
|
|
__tablename__ = "badges"
|
|
|
|
user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
|
|
badge_id = Column(Integer, ForeignKey('badge_defs.id'), primary_key=True)
|
|
description = Column(String)
|
|
url = Column(String)
|
|
|
|
Index('badges_badge_id_idx', badge_id)
|
|
|
|
user = relationship("User", viewonly=True)
|
|
badge = relationship("BadgeDef", primaryjoin="foreign(Badge.badge_id) == remote(BadgeDef.id)", viewonly=True)
|
|
|
|
def __repr__(self):
|
|
return f"<Badge(user_id={self.user_id}, badge_id={self.badge_id})>"
|
|
|
|
@property
|
|
@lazy
|
|
def text(self):
|
|
if self.name == "Chud":
|
|
ti = self.user.agendaposter
|
|
if ti: text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S')
|
|
else: text = self.badge.description + " permanently"
|
|
elif self.badge_id in {94,95,96,97,98,109}:
|
|
if self.badge_id == 94: ti = self.user.progressivestack
|
|
elif self.badge_id == 95: ti = self.user.bird
|
|
elif self.badge_id == 96: ti = self.user.flairchanged
|
|
elif self.badge_id == 97: ti = self.user.longpost
|
|
elif self.badge_id == 98: ti = self.user.marseyawarded
|
|
elif self.badge_id == 109: ti = self.user.rehab
|
|
text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S')
|
|
elif self.description: text = self.description
|
|
elif self.badge.description: text = self.badge.description
|
|
else: return self.name
|
|
return f'{self.name} - {text}'
|
|
|
|
@property
|
|
@lazy
|
|
def name(self):
|
|
return self.badge.name
|
|
|
|
@property
|
|
@lazy
|
|
def path(self):
|
|
return f"/assets/images/badges/{self.badge_id}.webp"
|
|
|
|
@property
|
|
@lazy
|
|
def json(self):
|
|
return {'text': self.text,
|
|
'name': self.name,
|
|
'url': self.url,
|
|
'icon_url':self.path
|
|
}
|