diff --git a/TODO b/TODO
index c80772b..1582dda 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,9 @@
###
#
+# fix all face, right-click options:
+# partial fix for face to new and existing person - the person and refimg
+# data are correct, but the face_file_link is not connected (do this in person) - and if we do run AI jobs, they will overwrite it anyway (watch out for race condition)
+#
#1 get override data into view
# also all the add ref img/add override, etc are non-functional - FIX the override* stuff first to get table/naming consistency as that is half the problem
# NMO data -> there is an NMO object (just NMO names/types - |json), then there is per face level data - this should be a reference from Face and Schema/marshmallow
diff --git a/internal/js/view_support.js b/internal/js/view_support.js
index 2df2168..c0d5198 100644
--- a/internal/js/view_support.js
+++ b/internal/js/view_support.js
@@ -298,6 +298,23 @@ function OverrideForceMatch( person_id, key )
} )
}
+// function that handles the POSTed data that comes back when we add a
+// reference image to a new or existing person (right-click on a face)
+// used in success callbacks from CreatePersonAndRefimg() and AddRefimgTo()
+function handleAddRefimgData(key, data)
+{
+ document.viewing.file_details.faces[item[key].which_face].refimg=data.refimg
+ document.viewing.file_details.faces[item[key].which_face].refimg_lnk={}
+ // if we used this img, for now set distance to 0 - it is an exact match!
+ document.viewing.file_details.faces[item[key].which_face].refimg_lnk.face_distance=0.0
+ $('#dbox').modal('hide')
+ $('#faces').prop('checked',true)
+ DrawImg()
+ CheckForJobs()
+}
+
+// when we right-click a face and make a new person, this code creates and
+// associates the face
function CreatePersonAndRefimg( key )
{
d='&face_id='+item[key].id
@@ -306,29 +323,17 @@ function CreatePersonAndRefimg( key )
+'&surname='+$('#surname').val()
+'&refimg_data='+item[key].refimg_data
$.ajax({ type: 'POST', data: d, url: '/match_with_create_person',
- success: function(data) {
- document.viewing.file_details.faces[item[key].which_face].refimg.person.tag=data.who
- document.viewing.file_details.faces[item[key].which_face].facefile_lnk.face_distance=data.distance
- $('#dbox').modal('hide')
- $('#faces').prop('checked',true)
- DrawImg()
- CheckForJobs()
- }
+ success: function(data) { handleAddRefimgData(key, data ) },
})
}
+// when we right-click a face and connect to an existing person, this connects
+// the refimg and associates the face
function AddRefimgTo( person_id, key, search )
{
d='&face_id='+item[key].id+'&person_id='+person_id+'&refimg_data='+item[key].refimg_data+'&search='+search
$.ajax({ type: 'POST', data: d, url: '/add_refimg_to_person',
- success: function(data) {
- document.viewing.file_details.faces[item[key].which_face].refimg.person.tag=data.who
- document.viewing.file_details.faces[item[key].which_face].facefile_lnk.face_distance=data.distance
- $('#dbox').modal('hide')
- $('#faces').prop('checked',true)
- DrawImg()
- CheckForJobs()
- }
+ success: function(data) { handleAddRefimgData(key, data ) },
})
}
diff --git a/person.py b/person.py
index 95694aa..556caa4 100644
--- a/person.py
+++ b/person.py
@@ -3,8 +3,9 @@ from flask_wtf import FlaskForm
from flask import request, render_template, redirect, url_for, make_response, jsonify
from main import db, app, ma
from settings import Settings, AIModel
-from sqlalchemy import Sequence, func
+from sqlalchemy import Sequence, func, select
from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.orm import joinedload
from flask_login import login_required, current_user
from werkzeug.utils import secure_filename
from shared import GenFace, GenThumb, PA
@@ -114,7 +115,7 @@ def AddRefimgToPerson( filename, person ):
SetFELog( f"Failed to add Refimg: {e.orig}", "danger" )
except Exception as e:
SetFELog( f"Failed to modify Refimg: {e}", "danger" )
- return
+ return refimg
################################################################################
# TempRefimgFile: helper function that takes data POST'd (from dialog box to
@@ -182,9 +183,12 @@ def match_with_create_person():
p = Person( tag=request.form["tag"], surname=request.form["surname"], firstname=request.form["firstname"] )
# add this fname (of temp refimg) to person
fname=TempRefimgFile( request.form['refimg_data'], p.tag )
- AddRefimgToPerson( fname, p )
+ r=AddRefimgToPerson( fname, p )
SetFELog( f"Created person: {p.tag}" )
- return make_response( jsonify( who=p.tag, distance='0.0' ) )
+ refimg_schema=RefimgSchema(many=False)
+ r_data=refimg_schema.dump(r)
+
+ return make_response( jsonify( refimg=r_data, who=p.tag, distance='0.0' ) )
################################################################################
# /person/ -> GET/POST(save or delete) -> shows/edits/delets a single person
@@ -267,7 +271,7 @@ def add_refimg():
except Exception as e:
SetFELog( f"Failed to load reference image: {e}", "danger" )
- AddRefimgToPerson( fname, person )
+ r=AddRefimgToPerson( fname, person )
return redirect( url_for( 'person', id=person.id) )
################################################################################
@@ -289,6 +293,28 @@ def find_persons(who):
return make_response( resp )
+class FaceRefimgLinkSchema(ma.SQLAlchemyAutoSchema):
+ class Meta: model = FaceRefimgLink
+ load_instance = True
+
+class PersonSchema(ma.SQLAlchemyAutoSchema):
+ class Meta: model=Person
+ load_instance = True
+
+class RefimgSchema(ma.SQLAlchemyAutoSchema):
+ class Meta:
+ model = Refimg
+ exclude = ('face',)
+ load_instance = True
+ person = ma.Nested(PersonSchema)
+
+class FaceSchema(ma.SQLAlchemyAutoSchema):
+ class Meta:
+ model=Face
+ exclude = ('face',)
+ load_instance = True
+ refimg = ma.Nested(RefimgSchema,allow_none=True)
+ refimg_lnk = ma.Nested(FaceRefimgLinkSchema,allow_none=True)
################################################################################
# /add_refimg_to_person/ -> POST
@@ -296,12 +322,14 @@ def find_persons(who):
@app.route("/add_refimg_to_person", methods=["POST"])
@login_required
def add_refimg_to_person():
- f = Face.query.get( request.form['face_id'] )
- p = Person.query.get( request.form['person_id'] )
+ stmt = select(Face).options( joinedload(Face.refimg_lnk) ).where(Face.id == request.form['face_id'])
+ f=db.session.execute(stmt).scalars().first()
+ stmt = select(Person).options( joinedload(Person.refimg) ).where(Person.id == request.form['person_id'])
+ p=db.session.execute(stmt).scalars().first()
# add this fname (of temp refimg) to person
fname=TempRefimgFile( request.form['refimg_data'], p.tag )
- AddRefimgToPerson( fname, p )
+ r=AddRefimgToPerson( fname, p )
if request.form['search'] == "true":
jex=[]
@@ -316,7 +344,10 @@ def add_refimg_to_person():
jex.append( JobExtra( name=f"path_type", value=str(ptype.id) ) )
job=NewJob( name="run_ai_on_path", num_files=0, wait_for=None, jex=jex, desc="Look for face(s) in storage path(s)" )
- return make_response( jsonify( who=p.tag, distance='0.0' ) )
+ refimg_schema=RefimgSchema(many=False)
+ r_data=refimg_schema.dump(r)
+
+ return make_response( jsonify( refimg=r_data, who=p.tag, distance='0.0' ) )
################################################################################
# /add_force_match_override -> POST