removed __repr__ from classes in files.py, and added in sqlalchemy class and marshmallow schemas for entry amendments, then load amendments on get_entry_by_id - so any page load (first or next/prev) will see amendments, we then display them into the files list and now add a white circle inside the throbber and overlay that with approrpiate icon/image - all of which is taken from amendment type and eid. tables.sql also updated to create the amendment data, tweaked icons.svg to remove hardcoded-colours for flip_[vh]
This commit is contained in:
72
files.py
72
files.py
@@ -31,7 +31,7 @@ from job import Job, JobExtra, Joblog, NewJob, SetFELog
|
||||
from path import PathType, Path
|
||||
from person import Refimg, Person, PersonRefimgLink
|
||||
from settings import Settings, SettingsIPath, SettingsSPath, SettingsRBPath
|
||||
from shared import SymlinkName, ICON
|
||||
from shared import SymlinkName, ICON, PA
|
||||
from dups import Duplicates
|
||||
from face import Face, FaceFileLink, FaceRefimgLink, FaceOverrideType, FaceNoMatchOverride, FaceForceMatchOverride
|
||||
|
||||
@@ -41,41 +41,32 @@ from face import Face, FaceFileLink, FaceRefimgLink, FaceOverrideType, FaceNoMat
|
||||
# Class describing PathDirLink and in the DB (via sqlalchemy)
|
||||
# connects the entry (dir) with a path
|
||||
################################################################################
|
||||
class PathDirLink(db.Model):
|
||||
class PathDirLink(PA,db.Model):
|
||||
__tablename__ = "path_dir_link"
|
||||
path_id = db.Column(db.Integer, db.ForeignKey("path.id"), primary_key=True )
|
||||
dir_eid = db.Column(db.Integer, db.ForeignKey("dir.eid"), primary_key=True )
|
||||
|
||||
def __repr__(self):
|
||||
return f"<path_id: {self.path_id}, dir_eid: {self.dir_eid}>"
|
||||
|
||||
################################################################################
|
||||
# Class describing EntryDirLInk and in the DB (via sqlalchemy)
|
||||
# connects (many) entry contained in a directory (which is also an entry)
|
||||
################################################################################
|
||||
class EntryDirLink(db.Model):
|
||||
class EntryDirLink(PA,db.Model):
|
||||
__tablename__ = "entry_dir_link"
|
||||
entry_id = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
|
||||
dir_eid = db.Column(db.Integer, db.ForeignKey("dir.eid"), primary_key=True )
|
||||
|
||||
def __repr__(self):
|
||||
return f"<entry_id: {self.entry_id}, dir_eid: {self.dir_eid}>"
|
||||
|
||||
################################################################################
|
||||
# Class describing Dir and in the DB (via sqlalchemy)
|
||||
# rel_path: rest of dir after path, e.g. if path = /..../storage, then
|
||||
# rel_path could be 2021/20210101-new-years-day-pics
|
||||
# in_path: only in this structure, not DB, quick ref to the path this dir is in
|
||||
################################################################################
|
||||
class Dir(db.Model):
|
||||
class Dir(PA,db.Model):
|
||||
__tablename__ = "dir"
|
||||
eid = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
|
||||
rel_path = db.Column(db.String, unique=True )
|
||||
in_path = db.relationship("Path", secondary="path_dir_link", uselist=False)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<eid: {self.eid}, rel_path: {self.rel_path}, in_path: {self.in_path}>"
|
||||
|
||||
################################################################################
|
||||
# Class describing Entry and in the DB (via sqlalchemy)
|
||||
# an entry is the common bits between files and dirs
|
||||
@@ -85,7 +76,7 @@ class Dir(db.Model):
|
||||
# in_dir - is the Dir that this entry is located in (convenience for class only)
|
||||
# FullPathOnFS(): method to get path on the FS for this Entry
|
||||
################################################################################
|
||||
class Entry(db.Model):
|
||||
class Entry(PA,db.Model):
|
||||
__tablename__ = "entry"
|
||||
id = db.Column(db.Integer, db.Sequence('file_id_seq'), primary_key=True )
|
||||
name = db.Column(db.String, unique=False, nullable=False )
|
||||
@@ -106,9 +97,6 @@ class Entry(db.Model):
|
||||
s=self.dir_details.in_path.path_prefix
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return f"<id: {self.id}, name: {self.name}, type={self.type}, dir_details={self.dir_details}, file_details={self.file_details}, in_dir={self.in_dir}"
|
||||
|
||||
################################################################################
|
||||
# Class describing File and in the DB (via sqlalchemy)
|
||||
# all files are entries, this is the extra bits only for a file, of note:
|
||||
@@ -117,7 +105,7 @@ class Entry(db.Model):
|
||||
# info can be from exif, or file system, or file name (rarely)
|
||||
# faces: convenience field to show connected face(s) for this file
|
||||
################################################################################
|
||||
class File(db.Model):
|
||||
class File(PA,db.Model):
|
||||
__tablename__ = "file"
|
||||
eid = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
|
||||
size_mb = db.Column(db.Integer, unique=False, nullable=False)
|
||||
@@ -129,20 +117,27 @@ class File(db.Model):
|
||||
woy = db.Column(db.Integer)
|
||||
faces = db.relationship ("Face", secondary="face_file_link" )
|
||||
|
||||
def __repr__(self):
|
||||
return f"<eid: {self.eid}, size_mb={self.size_mb}, hash={self.hash}, year={self.year}, month={self.month}, day={self.day}, woy={self.woy}, faces={self.faces}>"
|
||||
|
||||
################################################################################
|
||||
# Class describing FileType and in the DB (via sqlalchemy)
|
||||
# pre-defined list of file types (image, dir, etc.)
|
||||
################################################################################
|
||||
class FileType(db.Model):
|
||||
class FileType(PA,db.Model):
|
||||
__tablename__ = "file_type"
|
||||
id = db.Column(db.Integer, db.Sequence('file_type_id_seq'), primary_key=True )
|
||||
name = db.Column(db.String, unique=True, nullable=False )
|
||||
|
||||
def __repr__(self):
|
||||
return f"<id: {self.id}, name={self.name}>"
|
||||
class AmendmentType(PA,db.Model):
|
||||
__tablename__ = "amendment_type"
|
||||
id = db.Column(db.Integer, db.Sequence('file_type_id_seq'), primary_key=True )
|
||||
which = db.Column(db.String, nullable=False )
|
||||
what = db.Column(db.String, nullable=False )
|
||||
colour = db.Column(db.String, nullable=False )
|
||||
|
||||
class EntryAmendment(PA,db.Model):
|
||||
__tablename__ = "entry_amendment"
|
||||
eid = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
|
||||
amend_type = db.Column(db.Integer, db.ForeignKey("amendment_type.id"))
|
||||
type = db.relationship("AmendmentType", backref="entry_amendment")
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -249,6 +244,18 @@ class FileSchema(ma.SQLAlchemyAutoSchema):
|
||||
load_instance = True
|
||||
faces = ma.Nested(FaceSchema,many=True,allow_none=True)
|
||||
|
||||
class AmendmentTypeSchema(ma.SQLAlchemyAutoSchema):
|
||||
class Meta:
|
||||
model = AmendmentType
|
||||
load_instance = True
|
||||
|
||||
class EntryAmendmentSchema(ma.SQLAlchemyAutoSchema):
|
||||
class Meta:
|
||||
model = EntryAmendment
|
||||
load_instance = True
|
||||
eid = ma.auto_field()
|
||||
type = ma.Nested(AmendmentTypeSchema)
|
||||
|
||||
################################################################################
|
||||
# Schema for Entry so we can json for data to the client
|
||||
################################################################################
|
||||
@@ -309,7 +316,14 @@ def process_ids():
|
||||
# Sort the entries according to the order of ids
|
||||
sorted_data = [entry_map[id_] for id_ in ids if id_ in entry_map]
|
||||
|
||||
return jsonify(entries_schema.dump(sorted_data))
|
||||
# get any pending entry amendments
|
||||
stmt = select(EntryAmendment).join(AmendmentType)
|
||||
ea = db.session.execute(stmt).unique().scalars().all()
|
||||
ea_schema = EntryAmendmentSchema(many=True)
|
||||
ea_data=ea_schema.dump(ea)
|
||||
print( ea_data )
|
||||
|
||||
return jsonify(entries=entries_schema.dump(sorted_data), amend=ea_data)
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -328,21 +342,21 @@ def get_dir_entries():
|
||||
# if we are going back, find the parent id and use that instead
|
||||
if back:
|
||||
# get parent of this dir, to go back
|
||||
stmt=( select(EntryDirLink.dir_eid).filter(EntryDirLink.entry_id==dir_id) )
|
||||
stmt=select(EntryDirLink.dir_eid).filter(EntryDirLink.entry_id==dir_id)
|
||||
dir_id = db.session.execute(stmt).scalars().one_or_none()
|
||||
if not dir_id:
|
||||
# return valid as false, we need to let user know this is not an empty dir, it does not exist
|
||||
return jsonify( valid=False, entry_list=[] )
|
||||
|
||||
# Just double-check this is still in the DB, in case it got deleted since client made view
|
||||
stmt=( select(Entry.id).where(Entry.id==dir_id) )
|
||||
stmt=select(Entry.id).where(Entry.id==dir_id)
|
||||
ent_id = db.session.execute(stmt).scalars().one_or_none()
|
||||
if not ent_id:
|
||||
# return valid as false, we need to let user know this is not an empty dir, it does not exist
|
||||
return jsonify( valid=False, entry_list=[] )
|
||||
|
||||
# get content of dir_id
|
||||
stmt=( select(Entry.id).join(EntryDirLink).filter(EntryDirLink.dir_eid==dir_id) )
|
||||
stmt=select(Entry.id).join(EntryDirLink).filter(EntryDirLink.dir_eid==dir_id)
|
||||
stmt=stmt.order_by(*order_map.get(noo) )
|
||||
return jsonify( valid=True, entry_list=db.session.execute(stmt).scalars().all() )
|
||||
|
||||
@@ -435,7 +449,7 @@ def GetQueryData( OPT ):
|
||||
|
||||
if OPT.folders:
|
||||
# start folder view with only the root folder
|
||||
stmt=( select(Entry.id).join(EntryDirLink).filter(EntryDirLink.dir_eid==dir_id) )
|
||||
stmt=select(Entry.id).join(EntryDirLink).filter(EntryDirLink.dir_eid==dir_id)
|
||||
else:
|
||||
# get every File that is in the OPT.prefix Path
|
||||
stmt=(
|
||||
|
||||
Reference in New Issue
Block a user