Collection.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from __future__ import annotations
  2. import os
  3. import typing as T
  4. from pycs import db
  5. from pycs.database.base import NamedBaseModel
  6. from pycs.database.util import commit_on_return
  7. class Collection(NamedBaseModel):
  8. """ DB Model for collections """
  9. # table columns
  10. project_id = db.Column(
  11. db.Integer,
  12. db.ForeignKey("project.id", ondelete="CASCADE"),
  13. nullable=False)
  14. reference = db.Column(
  15. db.String, nullable=False)
  16. description = db.Column(
  17. db.String)
  18. position = db.Column(
  19. db.Integer, nullable=False)
  20. autoselect = db.Column(
  21. db.Boolean, nullable=False)
  22. # contraints
  23. __table_args__ = (
  24. db.UniqueConstraint('project_id', 'reference'),
  25. )
  26. # relationships to other models
  27. files = db.relationship("File", backref="collection", lazy="dynamic")
  28. serialize_only = NamedBaseModel.serialize_only + (
  29. "project_id",
  30. "reference",
  31. "description",
  32. "position",
  33. "autoselect",
  34. )
  35. def get_files(self, *filters, offset: int = 0, limit: int = -1):
  36. """
  37. get an iterator of files associated with this project
  38. :param offset: file offset
  39. :param limit: file limit
  40. :return: iterator of files
  41. """
  42. # pylint: disable=import-outside-toplevel, cyclic-import
  43. from pycs.database.File import File
  44. return self.files.filter(*filters).order_by(File.id).offset(offset).limit(limit)
  45. # pylint: disable=too-many-arguments
  46. @commit_on_return
  47. def add_file(self,
  48. uuid: str,
  49. file_type: str,
  50. name: str,
  51. extension: str,
  52. size: int,
  53. filename: str,
  54. frames: int = None,
  55. fps: float = None) -> T.Tuple["File", bool]:
  56. """
  57. add a file to this collection
  58. :param uuid: unique identifier which is used for temporary files
  59. :param file_type: file type (either image or video)
  60. :param name: file name
  61. :param extension: file extension
  62. :param size: file size
  63. :param filename: actual name in filesystem
  64. :param frames: frame count
  65. :param fps: frames per second
  66. :return: file
  67. """
  68. # pylint: disable=import-outside-toplevel, cyclic-import
  69. from pycs.database.File import File
  70. path = os.path.join(self.project.data_folder, f"{filename}{extension}")
  71. file, is_new = File.get_or_create(
  72. project_id=self.project_id, collection_id=self.id, path=path)
  73. file.uuid = uuid
  74. file.type = file_type
  75. file.name = name
  76. file.extension = extension
  77. file.size = size
  78. file.frames = frames
  79. file.fps = fps
  80. return file, is_new
  81. @staticmethod
  82. def update_autoselect(collections: T.List[Collection]) -> T.List[Collection]:
  83. """ disable autoselect if there are no elements in the collection """
  84. found = False
  85. for collection in collections:
  86. if not collection.autoselect:
  87. continue
  88. if found:
  89. collection.autoselect = False
  90. elif collection.files.count() == 0:
  91. collection.autoselect = False
  92. found = True
  93. return collections