move MoveDBox into full javascript and fold it into internal/js/files_support.js, also remove unused parameter for MoveDBox, and use marshmallow to pass people in query_data - overall just cleaner more consistent code for existing functionality

This commit is contained in:
2025-10-05 23:20:17 +11:00
parent e0654edd21
commit e5d6ce9b73
4 changed files with 149 additions and 121 deletions

View File

@@ -2,7 +2,7 @@ from flask_wtf import FlaskForm
from flask import request, render_template, redirect, send_from_directory, url_for, jsonify, make_response
from marshmallow import Schema, fields
from main import db, app, ma
from sqlalchemy import Sequence, text, select, union
from sqlalchemy import Sequence, text, select, union, or_
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import joinedload
import os
@@ -28,10 +28,10 @@ from types import SimpleNamespace
from states import States, PA_UserState
from query import Query
from job import Job, JobExtra, Joblog, NewJob, SetFELog
from path import PathType, Path, MovePathDetails
from path import PathType, Path
from person import Refimg, Person, PersonRefimgLink
from settings import Settings, SettingsIPath, SettingsSPath, SettingsRBPath
from shared import SymlinkName
from shared import SymlinkName, ICON
from dups import Duplicates
from face import Face, FaceFileLink, FaceRefimgLink, FaceOverrideType, FaceNoMatchOverride, FaceForceMatchOverride
@@ -170,6 +170,14 @@ class PathSchema(ma.SQLAlchemyAutoSchema):
class Meta: model = Path
load_instance = True
type = ma.Nested(PathType)
root_dir = fields.Method("get_root_dir")
icon_url = fields.Method("get_icon_url")
def get_icon_url(self, obj):
return url_for("internal", filename="icons.svg") + "#" + ICON[obj.type.name]
def get_root_dir(self, obj):
parts = obj.path_prefix.split('/')
return ''.join(parts[2:])
class FileTypeSchema(ma.SQLAlchemyAutoSchema):
class Meta: model = FileType
@@ -216,6 +224,11 @@ class FileSchema(ma.SQLAlchemyAutoSchema):
load_instance = True
faces = ma.Nested(FaceSchema,many=True,allow_none=True)
# used just in NMO var
class FaceOverrideTypeSchema(ma.SQLAlchemyAutoSchema):
class Meta: model = FaceOverrideType
load_instance = True
################################################################################
# Schema for Entry so we can json for data to the client
################################################################################
@@ -238,6 +251,9 @@ class EntrySchema(ma.SQLAlchemyAutoSchema):
# global - this will be use more than once below, so do it once for efficiency
entries_schema = EntrySchema(many=True)
FOT_Schema = FaceOverrideTypeSchema(many=True)
path_Schema = PathSchema(many=True)
person_Schema = PersonSchema(many=True)
################################################################################
# util function to just update the current/first/last positions needed for
@@ -314,6 +330,25 @@ def get_dir_entries():
entries = Entry.query.filter(Entry.id.in_(ids)).all()
return jsonify(entries_schema.dump(entries))
# get Face overrid details
def getFOT():
stmt = select(FaceOverrideType)
fot=db.session.execute(stmt).scalars().all()
return FOT_Schema.dump(fot)
# get import/storage path details for move dbox
def getMoveDetails():
stmt = select(Path).where( or_( Path.type.has(name="Import"), Path.type.has(name="Storage")))
mp=db.session.execute(stmt).scalars().all()
return path_Schema.dump(mp)
# get people data for the menu for AI matching (of person.tag)
def getPeople():
stmt = select(Person)
people=db.session.execute(stmt).scalars().all()
return person_Schema.dump(people)
################################################################################
# Get all relevant Entry.ids based on search_term passed in and OPT visuals
@@ -322,6 +357,9 @@ def GetSearchQueryData(OPT):
query_data={}
query_data['entry_list']=None
query_data['root_eid']=0
query_data['NMO'] = getFOT()
query_data['move_paths'] = getMoveDetails()
query_data['people'] = getPeople()
search_term = OPT.search_term
# turn * wildcard into sql wildcard of %
@@ -352,13 +390,15 @@ def GetSearchQueryData(OPT):
query_data['entry_list']=all_entries
return query_data
#################################################################################
# Get all relevant Entry.ids based on files_ip/files_sp/files_rbp and OPT visuals
#################################################################################
def GetQueryData( OPT ):
query_data={}
query_data['entry_list']=None
query_data['NMO'] = getFOT()
query_data['move_paths'] = getMoveDetails()
query_data['people'] = getPeople()
# always get the top of the (OPT.prefix) Path's eid and keep it for OPT.folders toggling/use
dir_stmt=(
@@ -388,7 +428,6 @@ def GetQueryData( OPT ):
stmt=stmt.order_by(*order_map.get(OPT.noo) )
query_data['entry_list']=db.session.execute(stmt).scalars().all()
return query_data
################################################################################
@@ -428,9 +467,8 @@ def file_list_ip():
def files_ip():
OPT=States( request )
people = Person.query.all()
move_paths = MovePathDetails()
query_data = GetQueryData( OPT )
return render_template("files.html", page_title=f"View Files ({OPT.path_type} Path)", OPT=OPT, people=people, move_paths=move_paths, query_data=query_data )
return render_template("files.html", page_title=f"View Files ({OPT.path_type} Path)", OPT=OPT, people=people, query_data=query_data )
################################################################################
# /files -> show thumbnail view of files from storage_path
@@ -440,9 +478,8 @@ def files_ip():
def files_sp():
OPT=States( request )
people = Person.query.all()
move_paths = MovePathDetails()
query_data = GetQueryData( OPT )
return render_template("files.html", page_title=f"View Files ({OPT.path_type} Path)", OPT=OPT, people=people, move_paths=move_paths, query_data=query_data )
return render_template("files.html", page_title=f"View Files ({OPT.path_type} Path)", OPT=OPT, people=people, query_data=query_data )
################################################################################
@@ -453,9 +490,8 @@ def files_sp():
def files_rbp():
OPT=States( request )
people = Person.query.all()
move_paths = MovePathDetails()
query_data = GetQueryData( OPT )
return render_template("files.html", page_title=f"View Files ({OPT.path_type} Path)", OPT=OPT, people=people, move_paths=move_paths, query_data=query_data )
return render_template("files.html", page_title=f"View Files ({OPT.path_type} Path)", OPT=OPT, people=people, query_data=query_data )
################################################################################
# search -> GET version -> has search_term in the URL and is therefore able to
@@ -470,8 +506,7 @@ def search(search_term):
OPT.folders = False
query_data=GetSearchQueryData( OPT )
move_paths = MovePathDetails()
return render_template("files.html", page_title='View Files', search_term=search_term, query_data=query_data, OPT=OPT, move_paths=move_paths )
return render_template("files.html", page_title='View Files', search_term=search_term, query_data=query_data, OPT=OPT )
################################################################################
# /files/scan_ip -> allows us to force a check for new files