Huge change, removed Status class and all "alert" messages are now shown as BS toast() and are via the DB and handled async in the F/E in jscript via Ajax. Fixed BUG-113 where toasts() were repeating. Removed many of the explicit alert messages (other than errors) and hooked {New|Finish}Job to consistently send messages to the F/E. Other messages (F/E without a job, like save settings) now use this model as well. Finally converted most of the older POST responses to formal json
This commit is contained in:
74
person.py
74
person.py
@@ -1,17 +1,16 @@
|
||||
from wtforms import SubmitField, StringField, HiddenField, validators, Form
|
||||
from flask_wtf import FlaskForm
|
||||
from flask import request, render_template, redirect, url_for
|
||||
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
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from status import st, Status
|
||||
from flask_login import login_required, current_user
|
||||
from werkzeug.utils import secure_filename
|
||||
from shared import GenFace, GenThumb, PA
|
||||
from face import Face, FaceRefimgLink, FaceOverrideType, FaceNoMatchOverride, FaceForceMatchOverride
|
||||
from path import Path, PathType
|
||||
from job import JobExtra, NewJob
|
||||
from job import JobExtra, NewJob, SetFELog
|
||||
|
||||
import os
|
||||
import time
|
||||
@@ -98,7 +97,7 @@ def AddRefimgToPerson( filename, person ):
|
||||
print( f"Failed to delete tmp file for refimg addition: {e}" )
|
||||
|
||||
if not face_locn:
|
||||
st.SetMessage( f"<b>Failed to find face in Refimg:</b>" )
|
||||
SetFELog( f"<b>Failed to find face in Refimg:</b>", "danger" )
|
||||
raise Exception("Could not find face in uploaded reference image" )
|
||||
return
|
||||
refimg.face_top = face_locn[0]
|
||||
@@ -111,11 +110,11 @@ def AddRefimgToPerson( filename, person ):
|
||||
db.session.add(person)
|
||||
db.session.add(refimg)
|
||||
db.session.commit()
|
||||
st.SetMessage( f"Associated new Refimg ({refimg.fname}) with person: {person.tag}" )
|
||||
SetFELog( f"Associated new Refimg ({refimg.fname}) with person: {person.tag}" )
|
||||
except SQLAlchemyError as e:
|
||||
st.SetMessage( f"<b>Failed to add Refimg:</b> {e.orig}", "danger" )
|
||||
SetFELog( f"<b>Failed to add Refimg:</b> {e.orig}", "danger" )
|
||||
except Exception as e:
|
||||
st.SetMessage( f"<b>Failed to modify Refimg:</b> {e}", "danger" )
|
||||
SetFELog( f"<b>Failed to modify Refimg:</b> {e}", "danger" )
|
||||
return
|
||||
|
||||
################################################################################
|
||||
@@ -171,10 +170,10 @@ def new_person():
|
||||
try:
|
||||
db.session.add(person)
|
||||
db.session.commit()
|
||||
st.SetMessage( "Created new Person ({})".format(person.tag) )
|
||||
SetFELog( f"Created new Person ({person.tag})" )
|
||||
return redirect( url_for( 'person', id=person.id) )
|
||||
except SQLAlchemyError as e:
|
||||
st.SetMessage( f"<b>Failed to add Person:</b> {e.orig}", "danger" )
|
||||
SetFELog( f"<b>Failed to add Person:</b> {e.orig}", "danger" )
|
||||
return redirect( url_for( '/persons') )
|
||||
else:
|
||||
return render_template("person.html", person=None, form=form, page_title=page_title )
|
||||
@@ -186,10 +185,8 @@ def match_with_create_person():
|
||||
# add this fname (of temp refimg) to person
|
||||
fname=TempRefimgFile( request.form['refimg_data'], p.tag )
|
||||
AddRefimgToPerson( fname, p )
|
||||
resp={}
|
||||
resp['who']=p.tag
|
||||
resp['distance']='0.0'
|
||||
return resp
|
||||
SetFELog( f"Created person: {p.tag}" )
|
||||
return make_response( jsonify( who=p.tag, distance='0.0' ) )
|
||||
|
||||
################################################################################
|
||||
# /person/<id> -> GET/POST(save or delete) -> shows/edits/delets a single person
|
||||
@@ -204,7 +201,7 @@ def person(id):
|
||||
try:
|
||||
person = Person.query.get(id)
|
||||
if 'delete' in request.form:
|
||||
st.SetMessage("Successfully deleted Person: ({})".format( person.tag ) )
|
||||
SetFELog( f"Successfully deleted Person: ({person.tag})" )
|
||||
# do linkages by hand, or one day replace with delete cascade in the DB defintions
|
||||
db.session.execute( f"delete from face_refimg_link frl where refimg_id in ( select refimg_id from person_refimg_link where person_id = {id} )" )
|
||||
db.session.execute( f"delete from person_refimg_link where person_id = {id}" )
|
||||
@@ -225,23 +222,23 @@ def person(id):
|
||||
# delete the "match" between a face found in a file and this ref img
|
||||
FaceRefimgLink.query.filter(FaceRefimgLink.refimg_id==deld[0].id).delete()
|
||||
Refimg.query.filter(Refimg.id==deld[0].id).delete()
|
||||
st.SetMessage( f"Successfully Updated Person: removed reference image {deld[0].fname}" )
|
||||
SetFELog( f"Successfully Updated Person: removed reference image {deld[0].fname}" )
|
||||
else:
|
||||
st.SetMessage("Successfully Updated Person: (From: {}, {}, {})".format(person.tag, person.firstname, person.surname) )
|
||||
s=f"Successfully Updated Person: (From: {person.tag}, {person.firstname}, {person.surname})"
|
||||
person.tag = request.form['tag']
|
||||
person.surname = request.form['surname']
|
||||
person.firstname = request.form['firstname']
|
||||
st.AppendMessage(" To: ({}, {}, {})".format(person.tag, person.firstname, person.surname) )
|
||||
SetFELog( f"{s} To: ({person.tag}, {person.firstname}, {person.surname})" )
|
||||
db.session.add(person)
|
||||
db.session.commit()
|
||||
return redirect( url_for( 'person', id=person.id) )
|
||||
except SQLAlchemyError as e:
|
||||
st.SetMessage( f"<b>Failed to modify Person:</b> {e}", "danger" )
|
||||
SetFELog( f"<b>Failed to modify Person:</b> {e}", "danger" )
|
||||
return redirect( url_for( 'persons' ) )
|
||||
else:
|
||||
person = Person.query.get(id)
|
||||
if not person:
|
||||
st.SetMessage( f"No such person with id: {id}", "danger" )
|
||||
SetFELog( f"No such person with id: {id}", "danger" )
|
||||
return redirect("/")
|
||||
form = PersonForm(request.values, obj=person)
|
||||
return render_template("person.html", person=person, form=form, page_title = page_title)
|
||||
@@ -266,7 +263,7 @@ def add_refimg():
|
||||
fname = f"/tmp/{fname}"
|
||||
f.save( fname )
|
||||
except Exception as e:
|
||||
st.SetMessage( f"<b>Failed to load reference image:</b> {e}", "danger" )
|
||||
SetFELog( f"<b>Failed to load reference image:</b> {e}", "danger" )
|
||||
|
||||
AddRefimgToPerson( fname, person )
|
||||
return redirect( url_for( 'person', id=person.id) )
|
||||
@@ -297,7 +294,6 @@ def find_persons(who):
|
||||
@app.route("/add_refimg_to_person", methods=["POST"])
|
||||
@login_required
|
||||
def add_refimg_to_person():
|
||||
resp={}
|
||||
f = Face.query.get( request.form['face_id'] )
|
||||
p = Person.query.get( request.form['person_id'] )
|
||||
|
||||
@@ -310,19 +306,15 @@ def add_refimg_to_person():
|
||||
ptype=PathType.query.filter(PathType.name=='Import').first()
|
||||
jex.append( JobExtra( name=f"person", value="all" ) )
|
||||
jex.append( JobExtra( name=f"path_type", value=ptype.id ) )
|
||||
job=NewJob( "run_ai_on_path", 0, None, jex )
|
||||
st.SetMessage( f"Created <a href=/job/{job.id}>Job #{job.id}</a> to Look for face(s) in import path(s)")
|
||||
job=NewJob( name="run_ai_on_path", num_files=0, wait_for=None, jex=jex, desc="Look for face(s) in import path(s)" )
|
||||
|
||||
jex=[]
|
||||
ptype=PathType.query.filter(PathType.name=='Storage').first()
|
||||
jex.append( JobExtra( name=f"person", value="all" ) )
|
||||
jex.append( JobExtra( name=f"path_type", value=ptype.id ) )
|
||||
job=NewJob( "run_ai_on_path", 0, None, jex )
|
||||
st.SetMessage( f"Created <a href=/job/{job.id}>Job #{job.id}</a> to Look for face(s) in storage path(s)")
|
||||
job=NewJob( name="run_ai_on_path", num_files=0, wait_for=None, jex=jex, desc="Look for face(s) in storage path(s)" )
|
||||
|
||||
resp['who']=p.tag
|
||||
resp['distance']='0.0'
|
||||
return resp
|
||||
return make_response( jsonify( who=p.tag, distance='0.0' ) )
|
||||
|
||||
################################################################################
|
||||
# /add_force_match_override -> POST
|
||||
@@ -349,13 +341,11 @@ def add_force_match_override():
|
||||
jex.append( JobExtra( name="face_id", value=f.id ) )
|
||||
jex.append( JobExtra( name="person_id", value=p.id ) )
|
||||
# dont do status update here, the F/E is in the middle of a dbox, just send metadata through to the B/E
|
||||
NewJob( "metadata", 0, None, jex )
|
||||
NewJob( "metadata", num_files=0, wait_for=None, jex=jex, desc="create metadata for adding forced match" )
|
||||
|
||||
print( f"Placing an override match with face_id {face_id}, for person: {p.tag}" )
|
||||
# this will reply to the Ajax / POST, and cause the page to re-draw with new face override to person_tag
|
||||
resp={}
|
||||
resp['person_tag']=p.tag
|
||||
return resp
|
||||
return make_response( jsonify( person_tag=p.tag ) )
|
||||
|
||||
################################################################################
|
||||
# /remove_force_match_override -> POST
|
||||
@@ -379,11 +369,10 @@ def remove_force_match_override():
|
||||
jex.append( JobExtra( name="face_id", value=face_id ) )
|
||||
jex.append( JobExtra( name="person_id", value=p.id ) )
|
||||
# dont do status update here, the F/E is in the middle of a dbox, just send metadata through to the B/E
|
||||
NewJob( "metadata", 0, None, jex )
|
||||
NewJob( "metadata", num_files=0, wait_for=None, jex=jex, desc="create metadata for removing forced match" )
|
||||
|
||||
# this will reply to the Ajax / POST, and cause the page to re-draw with new face override
|
||||
resp={}
|
||||
return resp
|
||||
# this will reply to the Ajax / POST, and cause the page to re-draw with new face override (data is not used)
|
||||
return make_response( jsonify( person_tag=p.tag ) )
|
||||
|
||||
################################################################################
|
||||
# /remove_no_match_override -> POST
|
||||
@@ -403,11 +392,10 @@ def remove_no_match_override():
|
||||
jex.append( JobExtra( name="face_id", value=face_id ) )
|
||||
jex.append( JobExtra( name="type_id", value=type_id ) )
|
||||
# dont do status update here, the F/E is in the middle of a dbox, just send metadata through to the B/E
|
||||
NewJob( "metadata", 0, None, jex )
|
||||
NewJob( "metadata", num_files=0, wait_for=None, jex=jex, desc="create metadata for removing forced non-match" )
|
||||
|
||||
# this will reply to the Ajax / POST, and cause the page to re-draw with new face override
|
||||
resp={}
|
||||
return resp
|
||||
# this will reply to the Ajax / POST, and cause the page to re-draw with new face override (data is not used)
|
||||
return make_response( jsonify( face_id=face_id ) )
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -435,10 +423,8 @@ def add_no_match_override():
|
||||
jex.append( JobExtra( name="face_id", value=f.id ) )
|
||||
jex.append( JobExtra( name="type_id", value=t.id ) )
|
||||
# dont do status update here, the F/E is in the middle of a dbox, just send metadata through to the B/E
|
||||
NewJob( "metadata", 0, None, jex )
|
||||
NewJob( "metadata", num_files=0, wait_for=None, jex=jex, desc="create metadata for adding forced non-match" )
|
||||
|
||||
print( f"Placing an override of NO Match for face_id {face_id}" )
|
||||
# this will reply to the Ajax / POST, and cause the page to re-draw with new face override to person_tag
|
||||
resp={}
|
||||
resp['type']=t.name
|
||||
return resp
|
||||
return make_response( jsonify( type=t.name ) )
|
||||
|
||||
Reference in New Issue
Block a user