File.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. from contextlib import closing
  2. from json import dumps
  3. from typing import List, Optional
  4. from pycs.database.Result import Result
  5. class File:
  6. """
  7. database class for files
  8. """
  9. def __init__(self, database, row):
  10. self.database = database
  11. self.identifier = row[0]
  12. self.uuid = row[1]
  13. self.project_id = row[2]
  14. self.collection_id = row[3]
  15. self.type = row[4]
  16. self.name = row[5]
  17. self.extension = row[6]
  18. self.size = row[7]
  19. self.created = row[8]
  20. self.path = row[9]
  21. self.frames = row[10]
  22. self.fps = row[11]
  23. def project(self):
  24. """
  25. get the project associated with this file
  26. :return: project
  27. """
  28. return self.database.project(self.project_id)
  29. def collection(self):
  30. """
  31. get the collection associated with this file
  32. :return: collection
  33. """
  34. if self.collection_id is None:
  35. return None
  36. return self.database.collection(self.collection_id)
  37. def set_collection(self, collection_id: Optional[int]):
  38. """
  39. set this file's collection
  40. :param collection_id: new collection
  41. :return:
  42. """
  43. with closing(self.database.con.cursor()) as cursor:
  44. cursor.execute('UPDATE files SET collection = ? WHERE id = ?',
  45. (collection_id, self.identifier))
  46. self.collection_id = collection_id
  47. def set_collection_by_reference(self, collection_reference: Optional[str]):
  48. """
  49. set this file's collection
  50. :param collection_reference: collection reference
  51. :return:
  52. """
  53. if collection_reference is None:
  54. self.set_collection(None)
  55. return
  56. with closing(self.database.con.cursor()) as cursor:
  57. cursor.execute('SELECT id FROM collections WHERE reference = ?', [collection_reference])
  58. row = cursor.fetchone()
  59. self.set_collection(row[0] if row is not None else None)
  60. def remove(self) -> None:
  61. """
  62. remove this file from the database
  63. :return:
  64. """
  65. with closing(self.database.con.cursor()) as cursor:
  66. cursor.execute('DELETE FROM files WHERE id = ?', [self.identifier])
  67. def previous(self):
  68. """
  69. get the predecessor of this file
  70. :return: another file
  71. """
  72. with closing(self.database.con.cursor()) as cursor:
  73. cursor.execute('''
  74. SELECT * FROM files WHERE id < ? AND project = ? ORDER BY id DESC LIMIT 1
  75. ''', (self.identifier, self.project_id))
  76. row = cursor.fetchone()
  77. if row is not None:
  78. return File(self.database, row)
  79. return None
  80. def next(self):
  81. """
  82. get the successor of this file
  83. :return: another file
  84. """
  85. with closing(self.database.con.cursor()) as cursor:
  86. cursor.execute('''
  87. SELECT * FROM files WHERE id > ? AND project = ? ORDER BY id ASC LIMIT 1
  88. ''', (self.identifier, self.project_id))
  89. row = cursor.fetchone()
  90. if row is not None:
  91. return File(self.database, row)
  92. return None
  93. def previous_in_collection(self):
  94. """
  95. get the predecessor of this file
  96. :return: another file
  97. """
  98. with closing(self.database.con.cursor()) as cursor:
  99. if self.collection_id is None:
  100. cursor.execute('''
  101. SELECT * FROM files
  102. WHERE id < ? AND project = ? AND collection IS NULL
  103. ORDER BY id DESC
  104. LIMIT 1
  105. ''', (self.identifier, self.project_id))
  106. else:
  107. cursor.execute('''
  108. SELECT * FROM files
  109. WHERE id < ? AND project = ? AND collection = ?
  110. ORDER BY id DESC
  111. LIMIT 1
  112. ''', (self.identifier, self.project_id, self.collection_id))
  113. row = cursor.fetchone()
  114. if row is not None:
  115. return File(self.database, row)
  116. return None
  117. def next_in_collection(self):
  118. """
  119. get the successor of this file
  120. :return: another file
  121. """
  122. with closing(self.database.con.cursor()) as cursor:
  123. if self.collection_id is None:
  124. cursor.execute('''
  125. SELECT * FROM files
  126. WHERE id > ? AND project = ? AND collection IS NULL
  127. ORDER BY id ASC
  128. LIMIT 1
  129. ''', (self.identifier, self.project_id))
  130. else:
  131. cursor.execute('''
  132. SELECT * FROM files
  133. WHERE id > ? AND project = ? AND collection = ?
  134. ORDER BY id ASC
  135. LIMIT 1
  136. ''', (self.identifier, self.project_id, self.collection_id))
  137. row = cursor.fetchone()
  138. if row is not None:
  139. return File(self.database, row)
  140. return None
  141. def results(self) -> List[Result]:
  142. """
  143. get a list of all results associated with this file
  144. :return: list of results
  145. """
  146. with closing(self.database.con.cursor()) as cursor:
  147. cursor.execute('SELECT * FROM results WHERE file = ?', [self.identifier])
  148. return list(map(
  149. lambda row: Result(self.database, row),
  150. cursor.fetchall()
  151. ))
  152. def result(self, identifier) -> Optional[Result]:
  153. """
  154. get a specific result using its unique identifier
  155. :param identifier: unique identifier
  156. :return: result
  157. """
  158. with closing(self.database.con.cursor()) as cursor:
  159. cursor.execute('''
  160. SELECT * FROM results WHERE id = ? AND file = ?
  161. ''', (identifier, self.identifier))
  162. row = cursor.fetchone()
  163. if row is not None:
  164. return Result(self.database, row)
  165. return None
  166. def create_result(self, origin, result_type, label, data=None):
  167. """
  168. create a result
  169. :param origin:
  170. :param result_type:
  171. :param label:
  172. :param data:
  173. :return:
  174. """
  175. if data is not None:
  176. data = dumps(data)
  177. with closing(self.database.con.cursor()) as cursor:
  178. cursor.execute('''
  179. INSERT INTO results (file, origin, type, label, data)
  180. VALUES ( ?, ?, ?, ?, ?)
  181. ''', (self.identifier, origin, result_type, label, data))
  182. return self.result(cursor.lastrowid)
  183. def remove_results(self, origin='pipeline') -> List[Result]:
  184. with closing(self.database.con.cursor()) as cursor:
  185. cursor.execute('''
  186. SELECT * FROM results WHERE file = ? AND origin = ?
  187. ''', (self.identifier, origin))
  188. results = list(map(lambda row: Result(self.database, row), cursor.fetchall()))
  189. cursor.execute('''
  190. DELETE FROM results WHERE file = ? AND origin = ?
  191. ''', (self.identifier, origin))
  192. return results