|
@@ -3,6 +3,7 @@ from os.path import join
|
|
|
from time import time
|
|
|
from typing import List, Optional, Tuple
|
|
|
|
|
|
+from pycs.database.Collection import Collection
|
|
|
from pycs.database.File import File
|
|
|
from pycs.database.Label import Label
|
|
|
from pycs.database.LabelProvider import LabelProvider
|
|
@@ -108,6 +109,69 @@ class Project:
|
|
|
|
|
|
return self.label(row_id), insert
|
|
|
|
|
|
+ def collections(self) -> List[Collection]:
|
|
|
+ """
|
|
|
+ get a list of collections associated with this project
|
|
|
+
|
|
|
+ :return: list of collections
|
|
|
+ """
|
|
|
+ with closing(self.database.con.cursor()) as cursor:
|
|
|
+ cursor.execute('SELECT * FROM collections WHERE project = ? ORDER BY position ASC',
|
|
|
+ [self.identifier])
|
|
|
+
|
|
|
+ return list(map(
|
|
|
+ lambda row: Collection(self.database, row),
|
|
|
+ cursor.fetchall()
|
|
|
+ ))
|
|
|
+
|
|
|
+ def collection(self, identifier: int) -> Optional[Collection]:
|
|
|
+ """
|
|
|
+ get a collection using its unique identifier
|
|
|
+
|
|
|
+ :param identifier: unique identifier
|
|
|
+ :return: collection
|
|
|
+ """
|
|
|
+ with closing(self.database.con.cursor()) as cursor:
|
|
|
+ cursor.execute('SELECT * FROM collections WHERE id = ? AND project = ?',
|
|
|
+ (identifier, self.identifier))
|
|
|
+ row = cursor.fetchone()
|
|
|
+
|
|
|
+ if row is not None:
|
|
|
+ return Collection(self.database, row)
|
|
|
+
|
|
|
+ return None
|
|
|
+
|
|
|
+ def create_collection(self,
|
|
|
+ reference: str,
|
|
|
+ name: str,
|
|
|
+ description: str,
|
|
|
+ position: int,
|
|
|
+ autoselect: bool):
|
|
|
+ autoselect = 1 if autoselect else 0
|
|
|
+
|
|
|
+ with closing(self.database.con.cursor()) as cursor:
|
|
|
+ cursor.execute('''
|
|
|
+ INSERT INTO collections
|
|
|
+ (project, reference, name, description, position, autoselect)
|
|
|
+ VALUES (?, ?, ?, ?, ?, ?)
|
|
|
+ ON CONFLICT (project, reference) DO
|
|
|
+ UPDATE SET name = ?, description = ?, position = ?, autoselect = ?
|
|
|
+ ''', (self.identifier, reference, name, description, position, autoselect,
|
|
|
+ name, description, position, autoselect))
|
|
|
+
|
|
|
+ # lastrowid is 0 if on conflict clause applies.
|
|
|
+ # If this is the case we do an extra query to receive the row id.
|
|
|
+ if cursor.lastrowid > 0:
|
|
|
+ row_id = cursor.lastrowid
|
|
|
+ insert = True
|
|
|
+ else:
|
|
|
+ cursor.execute('SELECT id FROM collections WHERE project = ? AND reference = ?',
|
|
|
+ (self.identifier, reference))
|
|
|
+ row_id = cursor.fetchone()[0]
|
|
|
+ insert = False
|
|
|
+
|
|
|
+ return self.collection(row_id), insert
|
|
|
+
|
|
|
def remove(self) -> None:
|
|
|
"""
|
|
|
remove this project from the database
|
|
@@ -187,6 +251,36 @@ class Project:
|
|
|
cursor.fetchall()
|
|
|
))
|
|
|
|
|
|
+ def count_files_without_collection(self) -> int:
|
|
|
+ """
|
|
|
+ count files associated with this project but with no collection
|
|
|
+
|
|
|
+ :return: count
|
|
|
+ """
|
|
|
+ with closing(self.database.con.cursor()) as cursor:
|
|
|
+ cursor.execute('SELECT COUNT(*) FROM files WHERE project = ? AND collection IS NULL',
|
|
|
+ [self.identifier])
|
|
|
+ return cursor.fetchone()[0]
|
|
|
+
|
|
|
+ def files_without_collection(self, offset=0, limit=-1) -> List[File]:
|
|
|
+ """
|
|
|
+ get a list of files without not associated with any collection
|
|
|
+
|
|
|
+ :return: list of files
|
|
|
+ """
|
|
|
+ with closing(self.database.con.cursor()) as cursor:
|
|
|
+ cursor.execute('''
|
|
|
+ SELECT * FROM files
|
|
|
+ WHERE files.project = ? AND files.collection IS NULL
|
|
|
+ ORDER BY id ASC
|
|
|
+ LIMIT ? OFFSET ?
|
|
|
+ ''', (self.identifier, limit, offset))
|
|
|
+
|
|
|
+ return list(map(
|
|
|
+ lambda row: File(self.database, row),
|
|
|
+ cursor.fetchall()
|
|
|
+ ))
|
|
|
+
|
|
|
def file(self, identifier) -> Optional[File]:
|
|
|
"""
|
|
|
get a file using its unique identifier
|