from contextlib import contextmanager import datetime import mimetypes import os from flask import current_app from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.exc import IntegrityError from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String, unique=True, index=True) jab_id = db.Column(db.String(24), unique=True, index=True) api_key_date = db.Column(db.DateTime, default=datetime.datetime.utcnow) files = db.relation('File', backref='user', order_by='File.date.desc()') def __init__(self, username, jab_id): self.username = username self.jab_id = jab_id class UserSession(db.Model): __tablename__ = 'sessions' id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), index=True) access_token = db.Column(db.String) refresh_token = db.Column(db.String) updated = db.Column(db.DateTime) def __init__(self, user_id, access_token, refresh_token): self.user_id = user_id self.access_token = access_token self.refresh_token = refresh_token class File(db.Model): __tablename__ = 'files' id = db.Column(db.Integer, primary_key=True) hash = db.Column(db.String, unique=True, index=True) filename = db.Column(db.String) size = db.Column(db.BigInteger) date = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True) ip = db.Column(db.String) accessed = db.Column(db.DateTime) scanned = db.Column(db.Boolean, nullable=False, default=False) blocked_reason = db.Column(db.JSON) def __init__(self, hash, filename, size, date, user_id = None, ip = None): self.hash = hash self.filename = filename self.size = size self.date = date self.user_id = user_id self.ip = ip @staticmethod def pretty_size(size): if size is None: return 'N/A' suffixes = (('TiB', 2**40), ('GiB', 2**30), ('MiB', 2**20), ('KiB', 2**10)) for suf, threshold in suffixes: if size >= threshold: return '{:.2f} {}'.format(size / threshold, suf) else: continue return '{} B'.format(size) @property def formatted_size(self): return self.pretty_size(self.size) @property def formatted_date(self): return self.date.strftime('%Y-%m-%d %H:%M:%S UTC') def get_mime_type(self): return mimetypes.guess_type(self.filename, strict = False)[0] or 'application/octet-stream' def is_image(self): return self.get_mime_type().startswith('image') def is_video(self): return self.get_mime_type().startswith('video') @property def ext(self): return os.path.splitext(self.filename)[1]