added BUG-120, somehow losing pref info. No prints are working in PROD, so changed a lot of printf( in the F/E to SetFELog with error and persistent/cant_close set across many files. Also used opportunity to remove a few unnecessary debugs

This commit is contained in:
2023-04-09 13:10:28 +10:00
parent cdef403187
commit a84ff49413
6 changed files with 40 additions and 23 deletions

20
BUGs
View File

@@ -1,4 +1,4 @@
### Next: 120 ### Next: 121
BUG-100: I managed to get 2 photos matching mich in the NOT_WORKING photo (probably dif refimgs but same p.tag?) BUG-100: I managed to get 2 photos matching mich in the NOT_WORKING photo (probably dif refimgs but same p.tag?)
= /photos/2012/20120414-damien/IMG_8467.JPG = /photos/2012/20120414-damien/IMG_8467.JPG
BUG-106: cant add trudy /pat? as refimgs via FaceDBox BUG-106: cant add trudy /pat? as refimgs via FaceDBox
@@ -10,3 +10,21 @@ BUG-119: "Uncaught (in promise) Error: A listener indicated an asynchronous
response by returning true, but the message channel closed before a response response by returning true, but the message channel closed before a response
was received" was received"
investigate this (possible I'm calling check_for_jobs and maybe not doing the async right?) investigate this (possible I'm calling check_for_jobs and maybe not doing the async right?)
BUG-120: on tablet:
[2023-04-09 12:21:21,214] ERROR in app: Exception on /view/16978 [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "/code/files.py", line 655, in view
OPT=States( request )
File "/code/states.py", line 92, in __init__
self.url = pref.orig_url
AttributeError: 'NoneType' object has no attribute 'orig_url'

View File

@@ -588,7 +588,7 @@ def view_list():
# this occurs when we went from the last image on a page (with how_many on # this occurs when we went from the last image on a page (with how_many on
# it) and it just happened to also be the last in the DB... # it) and it just happened to also be the last in the DB...
if not entries: if not entries:
print("DDP: DONT think this can happen anymore") SetFELog( message="DDP: DONT think this can happen anymore", log_level="error", job=None, persistent=True, cant_close=True )
# undo the skip by how_many and getentries again # undo the skip by how_many and getentries again
OPT.offset -= int(OPT.how_many) OPT.offset -= int(OPT.how_many)
@@ -676,7 +676,7 @@ def view(id):
eids=eids.rstrip(",") eids=eids.rstrip(",")
# jic, sometimes we trip this, and rather than show broken pages / destroy # jic, sometimes we trip this, and rather than show broken pages / destroy
if id not in eids: if id not in eids:
print( f"ERROR: viewing an id, but its not in eids OPT={OPT}, id={id}, eids={eids}") SetFELog( message=f"ERROR: viewing an id, but its not in eids OPT={OPT}, id={id}, eids={eids}", log_level="error", persistent=True, cant_close=True)
msg="Sorry, viewing data is confused, cannot view this image now" msg="Sorry, viewing data is confused, cannot view this image now"
if os.environ['ENV'] == "production": if os.environ['ENV'] == "production":
msg += "Clearing out all states. This means browser back buttons will not work, please start a new tab and try again" msg += "Clearing out all states. This means browser back buttons will not work, please start a new tab and try again"

View File

@@ -23,7 +23,6 @@ from flask_ldap3_login.forms import LDAPLoginForm
####################################### Flask App globals ####################################### ####################################### Flask App globals #######################################
hostname = socket.gethostname() hostname = socket.gethostname()
print( "Running on: {}".format( hostname) )
app = Flask(__name__) app = Flask(__name__)
@@ -38,8 +37,6 @@ try:
except Exception: except Exception:
app.config['SECRET_KEY'] = b'my_insecure_PA_token_with_random_2134876adsfjhlkasdf87' app.config['SECRET_KEY'] = b'my_insecure_PA_token_with_random_2134876adsfjhlkasdf87'
print(app.config['SECRET_KEY'])
# ldap config vars: (the last one is required, or python ldap freaks out) # ldap config vars: (the last one is required, or python ldap freaks out)
app.config['LDAP_HOST'] = 'mara.ddp.net' app.config['LDAP_HOST'] = 'mara.ddp.net'
app.config['LDAP_BASE_DN'] = 'dc=depaoli,dc=id,dc=au' app.config['LDAP_BASE_DN'] = 'dc=depaoli,dc=id,dc=au'
@@ -67,6 +64,7 @@ from files import Entry
from person import Person from person import Person
from settings import Settings from settings import Settings
from user import PAUser from user import PAUser
from job import SetFELog
####################################### GLOBALS ####################################### ####################################### GLOBALS #######################################
# allow jinja2 to call these python functions directly # allow jinja2 to call these python functions directly
@@ -122,7 +120,7 @@ def login():
# the re matches on any special LDAP chars, we dont want someone # the re matches on any special LDAP chars, we dont want someone
# ldap-injecting our username, so send them back to the login page instead # ldap-injecting our username, so send them back to the login page instead
if request.method == 'POST' and re.search( r'[()\\*&!]', request.form['username']): if request.method == 'POST' and re.search( r'[()\\*&!]', request.form['username']):
print( f"WARNING: Detected special LDAP chars in username: {request.form['username']}") SetFELog( message=f"ERROR: Detected special LDAP chars in username: {request.form['username']}", log_level="error", persistent=True, cant_close=True )
return redirect(url_for('login')) return redirect(url_for('login'))
if form.validate_on_submit(): if form.validate_on_submit():
# Successfully logged in, We can now access the saved user object via form.user. # Successfully logged in, We can now access the saved user object via form.user.

View File

@@ -94,12 +94,11 @@ def AddRefimgToPerson( filename, person ):
except Exception as e: except Exception as e:
# can fail "silently" here, if the face_locn worked, great, its only # can fail "silently" here, if the face_locn worked, great, its only
# a tmp file in /tmp - if not, the next if will send a msg to the front-end # a tmp file in /tmp - if not, the next if will send a msg to the front-end
print( f"Failed to delete tmp file for refimg addition: {e}" ) SetFELog( message=f"Failed to delete tmp file for refimg addition: {e}", log_level="danger", persistent=True, cant_close=True )
if not face_locn: if not face_locn:
SetFELog( f"<b>Failed to find face in Refimg:</b>", "danger" ) SetFELog( f"<b>Failed to find face in Refimg:</b>", "danger" )
raise Exception("Could not find face in uploaded reference image" ) raise Exception("Could not find face in uploaded reference image" )
return
refimg.face_top = face_locn[0] refimg.face_top = face_locn[0]
refimg.face_right = face_locn[1] refimg.face_right = face_locn[1]
refimg.face_bottom = face_locn[2] refimg.face_bottom = face_locn[2]
@@ -344,7 +343,6 @@ def add_force_match_override():
# dont do status update here, the F/E is in the middle of a dbox, just send metadata through to the B/E # 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", num_files=0, wait_for=None, jex=jex, desc="create metadata for adding forced match" ) 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 # this will reply to the Ajax / POST, and cause the page to re-draw with new face override to person_tag
return make_response( jsonify( person_tag=p.tag ) ) return make_response( jsonify( person_tag=p.tag ) )
@@ -357,7 +355,6 @@ def remove_force_match_override():
face_id = request.form['face_id'] face_id = request.form['face_id']
person_tag = request.form['person_tag'] person_tag = request.form['person_tag']
file_eid = request.form['file_eid'] file_eid = request.form['file_eid']
print( f"Remove override force match of face_id={face_id} to person_tag={person_tag}" )
FaceForceMatchOverride.query.filter( FaceForceMatchOverride.face_id==face_id ).delete() FaceForceMatchOverride.query.filter( FaceForceMatchOverride.face_id==face_id ).delete()
db.session.commit() db.session.commit()
@@ -383,7 +380,6 @@ def remove_force_match_override():
def remove_no_match_override(): def remove_no_match_override():
face_id = request.form['face_id'] face_id = request.form['face_id']
type_id = request.form['type_id'] type_id = request.form['type_id']
print( f"Remove override of no match (type_id={type_id}) for face_id={face_id}" )
FaceNoMatchOverride.query.filter( FaceNoMatchOverride.face_id==face_id, FaceNoMatchOverride.type_id==type_id ).delete() FaceNoMatchOverride.query.filter( FaceNoMatchOverride.face_id==face_id, FaceNoMatchOverride.type_id==type_id ).delete()
db.session.commit() db.session.commit()
@@ -426,6 +422,5 @@ def add_no_match_override():
# dont do status update here, the F/E is in the middle of a dbox, just send metadata through to the B/E # 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", num_files=0, wait_for=None, jex=jex, desc="create metadata for adding forced non-match" ) 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 # this will reply to the Ajax / POST, and cause the page to re-draw with new face override to person_tag
return make_response( jsonify( type=t.name ) ) return make_response( jsonify( type=t.name ) )

View File

@@ -5,6 +5,7 @@ from sqlalchemy import Sequence
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from flask_login import login_required, current_user from flask_login import login_required, current_user
from main import db, app, ma from main import db, app, ma
from job import SetFELog
# pylint: disable=no-member # pylint: disable=no-member
@@ -136,7 +137,7 @@ def settings():
def SettingsRBPath(): def SettingsRBPath():
settings = Settings.query.first() settings = Settings.query.first()
if settings == None: if settings == None:
print("Cannot create file data with no settings / recycle bin path is missing") SetFELog( message="Cannot create file data with no settings / recycle bin path is missing", log_level="error", persistent=True, cant_close=False)
return return
# path setting is an absolute path, just use it, otherwise prepend base_path first # path setting is an absolute path, just use it, otherwise prepend base_path first
if settings.recycle_bin_path[0] == '/': if settings.recycle_bin_path[0] == '/':
@@ -153,7 +154,7 @@ def SettingsSPath():
paths=[] paths=[]
settings = Settings.query.first() settings = Settings.query.first()
if settings == None: if settings == None:
print("Cannot create file data with no settings / storage path is missing") SetFELog( message="Cannot create file data with no settings / storage path is missing", log_level="error", persistent=True, cant_close=False)
return return
if settings.storage_path[0] == '/': if settings.storage_path[0] == '/':
path=settings.storage_path path=settings.storage_path

View File

@@ -4,6 +4,7 @@ from main import db, app, ma
from shared import PA from shared import PA
from user import PAUser from user import PAUser
from datetime import datetime from datetime import datetime
from job import SetFELog
import pytz import pytz
import re import re
@@ -88,8 +89,10 @@ class States(PA):
st='' st=''
pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type,PA_UserState.view_eid==self.view_eid,PA_UserState.orig_search_term==st).first() pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type,PA_UserState.view_eid==self.view_eid,PA_UserState.orig_search_term==st).first()
if not pref: if not pref:
print( f"pref not found dn={current_user.dn}, st={st}, s={self}????" ) SetFELog( message=f"ERROR: pref not found - DONT CLOSE THIS!!! dn={current_user.dn}, st={st}, s={self}????" , log_level="error", persistent=True, cant_close=True )
self.url = pref.orig_url redirect("/")
else:
self.url = pref.orig_url
if 'files_ip' in self.url or 'file_list_ip' in self.url: if 'files_ip' in self.url or 'file_list_ip' in self.url:
if self.path_type == "View": if self.path_type == "View":
@@ -123,8 +126,9 @@ class States(PA):
self.path_type="View" self.path_type="View"
self.orig_url=self.url self.orig_url=self.url
elif 'change_file_opts' not in self.url: elif 'change_file_opts' not in self.url:
print( f"ERROR: DDP messed up, failed to match URL {self.url} for settings this will fail, redirecting to home" ) SetFELog( message=f"ERROR: DDP messed up, failed to match URL {self.url} for settings this will fail, redirecting to home" , log_level="error", persistent=True, cant_close=True )
print( f"referrer={request.referrer}" ) SetFELog( message=f"referrer={request.referrer}" , log_level="error",
persistent=True, cant_close=True )
return return
if self.path_type == 'View': if self.path_type == 'View':
@@ -132,8 +136,9 @@ class States(PA):
# should find original path or search for this view (if not a search, search_term='') # should find original path or search for this view (if not a search, search_term='')
orig_pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.orig_ptype,PA_UserState.orig_search_term==self.orig_search_term).first() orig_pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.orig_ptype,PA_UserState.orig_search_term==self.orig_search_term).first()
if not orig_pref: if not orig_pref:
print( f"ERROR: DDP messed up 2, failed to find orig_pref for a view pt={self.path_type} for search={self.orig_search_term}" ) SetFELog( message=f"ERROR: DDP messed up 2, failed to find orig_pref for a view pt={self.path_type} for search={self.orig_search_term}" , log_level="error", persistent=True, cant_close=True )
print( f"referrer={request.referrer}" ) SetFELog( message=f"referrer={request.referrer}" , log_level="error",
persistent=True, cant_close=True )
return return
elif self.path_type == 'Search': elif self.path_type == 'Search':
pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type,PA_UserState.orig_search_term==self.orig_search_term).first() pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==self.path_type,PA_UserState.orig_search_term==self.orig_search_term).first()
@@ -250,8 +255,8 @@ class States(PA):
self.offset += int(self.how_many) self.offset += int(self.how_many)
else: else:
# should be impossible now, but leave jic # should be impossible now, but leave jic
print( f"WARNING: next image requested, but would go past end of list? - ignore this" ) SetFELog( message=f"WARNING: next image requested, but would go past end of list? - ignore this" , log_level="warning", persistent=True, cant_close=True )
print( f"DDP - offset={self.offset} + how_many={self.how_many} > num_entries={self.num_entries}" ) SetFELog( message=f"DDP - offset={self.offset} + how_many={self.how_many} > num_entries={self.num_entries}" , log_level="error", persistent=True, cant_close=True )
if 'current' in request.form: if 'current' in request.form:
self.current = int(request.form['current']) self.current = int(request.form['current'])