from __future__ import annotations import os import typing as T from pycs import db from pycs.database.base import NamedBaseModel from pycs.database.util import commit_on_return class Collection(NamedBaseModel): """ DB Model for collections """ # table columns project_id = db.Column( db.Integer, db.ForeignKey("project.id", ondelete="CASCADE"), nullable=False) reference = db.Column( db.String, nullable=False) description = db.Column( db.String) position = db.Column( db.Integer, nullable=False) autoselect = db.Column( db.Boolean, nullable=False) # contraints __table_args__ = ( db.UniqueConstraint('project_id', 'reference'), ) # relationships to other models files = db.relationship("File", backref="collection", lazy="dynamic") serialize_only = NamedBaseModel.serialize_only + ( "project_id", "reference", "description", "position", "autoselect", ) def get_files(self, *filters, offset: int = 0, limit: int = -1): """ get an iterator of files associated with this project :param offset: file offset :param limit: file limit :return: iterator of files """ # pylint: disable=import-outside-toplevel, cyclic-import from pycs.database.File import File return self.files.filter(*filters).order_by(File.id).offset(offset).limit(limit) # pylint: disable=too-many-arguments @commit_on_return def add_file(self, uuid: str, file_type: str, name: str, extension: str, size: int, filename: str, frames: int = None, fps: float = None) -> T.Tuple["File", bool]: """ add a file to this collection :param uuid: unique identifier which is used for temporary files :param file_type: file type (either image or video) :param name: file name :param extension: file extension :param size: file size :param filename: actual name in filesystem :param frames: frame count :param fps: frames per second :return: file """ # pylint: disable=import-outside-toplevel, cyclic-import from pycs.database.File import File path = os.path.join(self.project.data_folder, f"{filename}{extension}") file, is_new = File.get_or_create( project_id=self.project_id, collection_id=self.id, path=path) file.uuid = uuid file.type = file_type file.name = name file.extension = extension file.size = size file.frames = frames file.fps = fps return file, is_new @staticmethod def update_autoselect(collections: T.List[Collection]) -> T.List[Collection]: """ disable autoselect if there are no elements in the collection """ found = False for collection in collections: if not collection.autoselect: continue if found: collection.autoselect = False elif collection.files.count() == 0: collection.autoselect = False found = True return collections