diff --git a/TODO b/TODO index ffda7fe..10e373e 100644 --- a/TODO +++ b/TODO @@ -1,20 +1,21 @@ ## GENERAL - * refimg - - remove AI menu from top-level -> make a sub-of Person, and just have Match or AI - - store the face locations? (good for debugging later, and we calc them as part of GenFace anyway) ... - (really, doing this properly, we shoudl keep the face locns for ALL images)... - ---> may well mean in a week or so, we move to the new DB structure, and START FORM SCRATCH) - * allow rotate of image (permanently on FS, so its right everywhere) * improve photo browser -> view file, rather than just allowing browser to show image + * face locations: + START FORM SCRATCH so all images have face_locn data + right now GenThumb is in shared, and does width, height as well --> in person.py BUT need this for pa_job_manager + * allow for threshold/settings to be tweaked from the GUI - it would be good to then say, just run the scanner against this image or maybe this DIR, to see how it IDs ppl ---> settings for default value ---> override table to do per file combos? + * refimg + - remove AI menu from top-level -> make a sub-of Person, and just have Match or AI + * fix up logging in general * comment your code * more OO goodness :) @@ -33,9 +34,6 @@ *** Need to use thread-safe sessions per Thread, half-assed version did not work - - would it be quicker/smarter to use md5 hash matching on import (and if - so, not re-do face* ) ??? - need a manual button to restart a job in the GUI, (based on file-level optims, just run the job as new and it will optim over already done parts and continue) @@ -67,7 +65,6 @@ need to copy into here the jquery/fa files so we don't need internet to function - for that matter run lightspeed against all this - timelineview? (I think maybe sunburst for large amounts of files, then maybe something more timeline-series for drilling in?) (vertical timeline, date has thumbnails (small) horizontally along a page, etc.? @@ -81,3 +78,8 @@ * exif processing? * location stuff - test a new photo from my camera out -- image is in dir, need to look at exifread output + +### FUTURE: + * can emby use nfo for images (for AI/tags?) + -NO sadly + diff --git a/person.py b/person.py index 4bf7d16..369d1d2 100644 --- a/person.py +++ b/person.py @@ -10,6 +10,7 @@ from werkzeug import secure_filename from shared import GenFace, GenThumb from face import FaceRefimgLink import os +import json # pylint: disable=no-member @@ -21,6 +22,9 @@ class Refimg(db.Model): id = db.Column(db.Integer, db.Sequence('refimg_id_seq'), primary_key=True ) fname = db.Column(db.String(256), unique=True, nullable=False) face = db.Column(db.LargeBinary, unique=True, nullable=False) + orig_w = db.Column(db.Integer) + orig_h = db.Column(db.Integer) + face_locn = db.Column(db.String) thumbnail = db.Column(db.String, unique=True, nullable=False) created_on = db.Column(db.Float) @@ -41,7 +45,7 @@ class Person(db.Model): tag = db.Column(db.String(48), unique=False, nullable=False) surname = db.Column(db.String(48), unique=False, nullable=False) firstname = db.Column(db.String(48), unique=False, nullable=False) - refimg = db.relationship('Refimg', secondary=PersonRefimgLink.__table__) + refimg = db.relationship('Refimg', secondary=PersonRefimgLink.__table__, order_by=Refimg.id) def __repr__(self): return "".format(self.tag,self.firstname, self.surname, self.refimg) @@ -94,7 +98,7 @@ def new_person(): db.session.add(person) db.session.commit() st.SetMessage( "Created new Person ({})".format(person.tag) ) - return redirect( '/persons' ) + return redirect( f'/person/{person.id}' ) except SQLAlchemyError as e: st.SetAlert( "danger" ) st.SetMessage( "Failed to add Person: {}".format(e.orig) ) @@ -141,6 +145,8 @@ def person(id): return render_template("person.html", form=form, page_title=page_title) else: person = Person.query.get(id) + for r in person.refimg: + r.face_locn=json.loads(r.face_locn) form = PersonForm(request.values, obj=person) return render_template("person.html", person=person, form=form, page_title = page_title) @@ -164,8 +170,9 @@ def add_refimg(): fname = f"/tmp/{fname}" f.save( fname ) - refimg.thumbnail = GenThumb( fname ) - refimg.face = GenFace( fname ) + refimg.thumbnail, refimg.orig_w, refimg.orig_h = GenThumb( fname ) + refimg.face, face_locn = GenFace( fname ) + refimg.face_locn = json.dumps(face_locn) os.remove(fname) person.refimg.append(refimg) db.session.add(person) diff --git a/templates/person.html b/templates/person.html index a46ec94..827f052 100644 --- a/templates/person.html +++ b/templates/person.html @@ -1,67 +1,118 @@ {% extends "base.html" %} {% block main_content %} -
-

{{page_title}}

-
- {% for field in form %} - {% if field.type == 'HiddenField' or field.type == 'CSRFTokenField' %} - {{field}}
- {% elif field.type != 'SubmitField' %} -
- {{ field.label( class="col-lg-3" ) }} - {{ field( class="form-control col" ) }} -
- {% endif %} - {% endfor %} -
-
Reference Images:
- {% for ref_img in person.refimg %} - {% set offset="" %} - {% if (loop.index % 10) == 0 %} - {% set offset= "offset-lg-3" %} - {% endif %} -
- -
-
-
-
- -
-
{{ref_img.fname}}
-
-
-
- {% endfor %} -
-
-
-
-
- {{ form.save( id="save", class="btn btn-primary offset-lg-3 col-lg-2" )}} - {% if 'Edit' in page_title %} - {{ form.delete( class="btn btn-outline-danger col-lg-2" )}} - {% endif %} -
-
-
- - -
-
- + + +
+

{{page_title}}

+
+ {% for field in form %} + {% if field.type == 'HiddenField' or field.type == 'CSRFTokenField' %} + {{field}}
+ {% elif field.type != 'SubmitField' %} +
+ {{ field.label( class="col-lg-3" ) }} + {{ field( class="form-control col" ) }} +
+ {% endif %} + {% endfor %} +
+
Reference Images:
+ {% for refimg in person.refimg %} + {% set offset="" %} + {% if (loop.index % 10) == 0 %} + {% set offset= "offset-lg-3" %} + {% endif %} +
+
+ +
+
+ + +
+ +
+
{{refimg.fname}}
+
+
+
+
+ {% endfor %} +
+
+
+
+
+ {{ form.save( id="save", class="btn btn-primary offset-lg-3 col-lg-2" )}} + {% if 'Edit' in page_title %} + {{ form.delete( class="btn btn-outline-danger col-lg-2" )}} + {% endif %} +
+
+ {% if person.id %} +
+ + +
+ {% endif %} +
{% endblock main_content %} {% block script_content %} {% endblock script_content %} -