diff --git a/app/__init__.py b/app/__init__.py index 304f937d..81766262 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -43,8 +43,8 @@ def create_app(config: Config = Config) -> Flask: message_queue=app.config['NOPAQUE_SOCKETIO_MESSAGE_QUEUE_URI'] ) - from .events import socketio as socketio_events - from .events import sqlalchemy as sqlalchemy_events + from app import socketio_event_listeners + from app import sqlalchemy_event_listeners from .admin import bp as admin_blueprint app.register_blueprint(admin_blueprint, url_prefix='/admin') diff --git a/app/email.py b/app/email.py index 5e76ca9d..50c41caa 100644 --- a/app/email.py +++ b/app/email.py @@ -16,8 +16,8 @@ def create_message( f'{subject_prefix} {subject}', recipients=[recipient] ) - msg.body: Text = render_template(f'{template}.txt.j2', **kwargs) - msg.html: Text = render_template(f'{template}.html.j2', **kwargs) + msg.body = render_template(f'{template}.txt.j2', **kwargs) + msg.html = render_template(f'{template}.html.j2', **kwargs) return msg diff --git a/app/models.py b/app/models.py index 3c4bd94f..84bf7b3c 100644 --- a/app/models.py +++ b/app/models.py @@ -1,4 +1,6 @@ +from app import db, login from app.converters.vrt import normalize_vrt_file +from app.sqlalchemy_custom_types import ContainerColumn, IntEnumColumn from datetime import datetime, timedelta from enum import IntEnum from flask import current_app, url_for @@ -8,7 +10,6 @@ from itsdangerous import BadSignature, TimedJSONWebSignatureSerializer from time import sleep from tqdm import tqdm from werkzeug.security import generate_password_hash, check_password_hash -from . import db, login import base64 import json import os @@ -22,45 +23,10 @@ TRANSKRIBUS_HTR_MODELS = \ json.loads(requests.get('https://transkribus.eu/TrpServer/rest/models/text').content)['trpModelMetadata'] # noqa -class IntEnumColumn(db.TypeDecorator): - impl = db.Integer - - def __init__(self, enum_type, *args, **kwargs): - super().__init__(*args, **kwargs) - self.enum_type = enum_type - - def process_bind_param(self, value, dialect): - if isinstance(value, self.enum_type) and isinstance(value.value, int): - return value.value - elif isinstance(value, int): - return self.enum_type(value).value - else: - return TypeError() - - def process_result_value(self, value, dialect): - return self.enum_type(value) - - -class ContainerColumn(db.TypeDecorator): - impl = db.String - - def __init__(self, container_type, *args, **kwargs): - super().__init__(*args, **kwargs) - self.container_type = container_type - - def process_bind_param(self, value, dialect): - if isinstance(value, self.container_type): - return json.dumps(value) - elif isinstance(value, str) and isinstance(json.loads(value), self.container_type): # noqa - return value - else: - return TypeError() - - def process_result_value(self, value, dialect): - return json.loads(value) - - class FileMixin: + ''' + Mixin for db.Model classes. All file related models should use this. + ''' creation_date = db.Column(db.DateTime, default=datetime.utcnow) filename = db.Column(db.String(255)) last_edited_date = db.Column(db.DateTime, default=datetime.utcnow) @@ -127,7 +93,7 @@ class Role(HashidMixin, db.Model): } if relationships: dict_role['users'] = { - x.to_dict(backrefs=False, relationships=True) + x.hashid: x.to_dict(backrefs=False, relationships=True) for x in self.users } return dict_role diff --git a/app/events/socketio.py b/app/socketio_event_listeners.py similarity index 76% rename from app/events/socketio.py rename to app/socketio_event_listeners.py index e892ea9d..c432687b 100644 --- a/app/events/socketio.py +++ b/app/socketio_event_listeners.py @@ -5,9 +5,6 @@ from flask_login import current_user from flask_socketio import join_room -############################################################################### -# Socket.IO event handlers # -############################################################################### @socketio.on('users.user.get') @socketio_login_required def users_user_get(user_hashid): diff --git a/app/sqlalchemy_custom_types.py b/app/sqlalchemy_custom_types.py new file mode 100644 index 00000000..ac97e308 --- /dev/null +++ b/app/sqlalchemy_custom_types.py @@ -0,0 +1,43 @@ +from app import db +import json + + +class IntEnumColumn(db.TypeDecorator): + impl = db.Integer + + def __init__(self, enum_type, *args, **kwargs): + super().__init__(*args, **kwargs) + self.enum_type = enum_type + + def process_bind_param(self, value, dialect): + if isinstance(value, self.enum_type) and isinstance(value.value, int): + return value.value + elif isinstance(value, int): + return self.enum_type(value).value + else: + return TypeError() + + def process_result_value(self, value, dialect): + return self.enum_type(value) + + +class ContainerColumn(db.TypeDecorator): + impl = db.String + + def __init__(self, container_type, *args, **kwargs): + super().__init__(*args, **kwargs) + self.container_type = container_type + + def process_bind_param(self, value, dialect): + if isinstance(value, self.container_type): + return json.dumps(value) + elif ( + isinstance(value, str) + and isinstance(json.loads(value), self.container_type) + ): + return value + else: + return TypeError() + + def process_result_value(self, value, dialect): + return json.loads(value) \ No newline at end of file diff --git a/app/events/sqlalchemy.py b/app/sqlalchemy_event_listeners.py similarity index 92% rename from app/events/sqlalchemy.py rename to app/sqlalchemy_event_listeners.py index 31ffcb20..94470591 100644 --- a/app/events/sqlalchemy.py +++ b/app/sqlalchemy_event_listeners.py @@ -13,9 +13,6 @@ from datetime import datetime from enum import Enum -############################################################################### -# SQLAlchemy event handlers # -############################################################################### @db.event.listens_for(Corpus, 'after_delete') @db.event.listens_for(CorpusFile, 'after_delete') @db.event.listens_for(Job, 'after_delete')