updated comments

This commit is contained in:
2021-08-12 20:03:13 +10:00
parent 0c1691d495
commit 0180703ae4

View File

@@ -33,8 +33,8 @@ from face import Face, FaceFileLink, FaceRefimgLink
# pylint: disable=no-member
################################################################################
# Class describing File in the database, and via sqlalchemy, connected to the DB as well
# This has to match one-for-one the DB table
# Class describing PathDirLink and in the DB (via sqlalchemy)
# connects the entry (dir) with a path
################################################################################
class PathDirLink(db.Model):
__tablename__ = "path_dir_link"
@@ -44,6 +44,10 @@ class PathDirLink(db.Model):
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):
__tablename__ = "entry_dir_link"
entry_id = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
@@ -52,6 +56,12 @@ class EntryDirLink(db.Model):
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):
__tablename__ = "dir"
eid = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
@@ -61,6 +71,14 @@ class Dir(db.Model):
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
# type is a convenience var only in this class, not in DB
# {dir|file}_etails are convenience data for the relevant details from the Dir
# or File class - not in DB
# in_dir - is the Dir that this entry is located in (convenience for class only)
################################################################################
class Entry(db.Model):
__tablename__ = "entry"
id = db.Column(db.Integer, db.Sequence('file_id_seq'), primary_key=True )
@@ -74,6 +92,14 @@ class Entry(db.Model):
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:
# hash is unique for files, and used to validate duplicates
# woy == week of year, all date fields are used to sort/show content. Date
# 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):
__tablename__ = "file"
eid = db.Column(db.Integer, db.ForeignKey("entry.id"), primary_key=True )
@@ -89,6 +115,10 @@ class File(db.Model):
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):
__tablename__ = "file_type"
id = db.Column(db.Integer, db.Sequence('file_type_id_seq'), primary_key=True )
@@ -97,6 +127,12 @@ class FileType(db.Model):
def __repr__(self):
return "<id: {}, name={}>".format(self.id, self.name )
################################################################################
# Class describing PA_JobManager_Message and in the DB (via sqlalchemy)
# the job manager can send a message back to the front end (this code) via the
# DB. has to be about a specific job_id and is success/danger, etc. (alert)
# and a message
################################################################################
class PA_JobManager_Message(db.Model):
__tablename__ = "pa_job_manager_fe_message"
id = db.Column(db.Integer, db.Sequence('pa_job_manager_fe_message_id_seq'), primary_key=True )
@@ -108,18 +144,25 @@ class PA_JobManager_Message(db.Model):
################################################################################
# Local utility functions
# GetJM_Message: used in html to display any message for this front-end
################################################################################
def GetJM_Message():
msg=PA_JobManager_Message.query.first()
return msg
################################################################################
# ClearJM_Message: used in html to clear any message just displayed
################################################################################
def ClearJM_Message(id):
PA_JobManager_Message.query.filter(PA_JobManager_Message.id==id).delete()
db.session.commit()
return
################################################################################
# ViewingOptions: defines set of default values for viewing (order/size, etc.)
# and if a request object (from a POST) is passed in, it returns those instead
# it also handles the cwd appropriately
################################################################################
def ViewingOptions( request ):
noo="Oldest"
grouping="None"
@@ -165,6 +208,9 @@ def ViewingOptions( request ):
return noo, grouping, how_many, offset, size, folders, cwd, root
################################################################################
# GetEntriesInFlatView: func. to retrieve DB entries appropriate for flat view
################################################################################
def GetEntriesInFlatView( cwd, prefix, noo, offset, how_many ):
entries=[]
@@ -178,6 +224,10 @@ def GetEntriesInFlatView( cwd, prefix, noo, offset, how_many ):
entries+=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(Entry.name).offset(offset).limit(how_many).all()
return entries
################################################################################
# GetEntriesInFolderView: func. to retrieve DB entries appropriate for folder view
# read inline comments to deal with variations / ordering...
################################################################################
def GetEntriesInFolderView( cwd, prefix, noo, offset, how_many ):
entries=[]
# okay the root cwd is fake, so treat it specially - its Dir can be found by path with dir.rel_path=''
@@ -365,6 +415,11 @@ def scan_sp():
return render_template("base.html")
################################################################################
# /fix_dups -> use sql to find duplicates based on same hash, different
# filenames, or directories. Pass this straight through to the job manager
# as job extras to a new job.
################################################################################
@app.route("/fix_dups", methods=["POST"])
@login_required
def fix_dups():
@@ -391,6 +446,10 @@ def fix_dups():
return render_template("dups.html", DD=DD, pagesize=pagesize )
################################################################################
# /rm_dups -> f/e that shows actual duplicates so that we can delete some dups
# this code creates a new job with extras that have hashes/ids to allow removal
################################################################################
@app.route("/rm_dups", methods=["POST"])
@login_required
def rm_dups():
@@ -416,6 +475,9 @@ def rm_dups():
return render_template("base.html")
################################################################################
# /restore_files -> create a job to restore files for the b/e to process
################################################################################
@app.route("/restore_files", methods=["POST"])
@login_required
def restore_files():
@@ -428,6 +490,9 @@ def restore_files():
st.SetMessage( f"Created&nbsp;<a href=/job/{job.id}>Job #{job.id}</a>&nbsp;to restore selected file(s)")
return render_template("base.html")
################################################################################
# /delete_files -> create a job to delete files for the b/e to process
################################################################################
@app.route("/delete_files", methods=["POST"])
@login_required
def delete_files():
@@ -440,6 +505,9 @@ def delete_files():
st.SetMessage( f"Created&nbsp;<a href=/job/{job.id}>Job #{job.id}</a>&nbsp;to delete selected file(s)")
return render_template("base.html")
################################################################################
# /move_files -> create a job to move files for the b/e to process
################################################################################
@app.route("/move_files", methods=["POST"])
@login_required
def move_files():
@@ -451,6 +519,9 @@ def move_files():
st.SetMessage( f"Created&nbsp;<a href=/job/{job.id}>Job #{job.id}</a>&nbsp;to move selected file(s)")
return render_template("base.html")
################################################################################
# /viewnext -> moves to the next entry and grabs data from DB and views it
################################################################################
@app.route("/viewnext", methods=["GET","POST"])
@login_required
def viewnext():
@@ -472,6 +543,9 @@ def viewnext():
face.locn = json.loads(face.locn)
return render_template("viewer.html", obj=obj, eids=eids, sels=sels )
################################################################################
# /viewprev -> moves to the prev entry and grabs data from DB and views it
################################################################################
@app.route("/viewprev", methods=["GET","POST"])
@login_required
def viewprev():
@@ -493,6 +567,9 @@ def viewprev():
face.locn = json.loads(face.locn)
return render_template("viewer.html", obj=obj, eids=eids, sels=sels )
################################################################################
# /view/id -> grabs data from DB and views it
################################################################################
@app.route("/view/<id>", methods=["GET","POST"])
@login_required
def view_img(id):
@@ -534,6 +611,12 @@ def rotate():
# TODO: make this return data with the job number, then the f/e can poll checkrotatejob
return resp
################################################################################
# /checkrotatejob -> URL that is called repeatedly by front-end waiting for the
# b/e to finish the rotate job. Once done, the new / now
# rotated image's thumbnail is returned so the f/e can
# update with it
################################################################################
@app.route("/checkrotatejob", methods=["POST"])
@login_required
def checkrotatejob():