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:
2023-01-11 13:50:05 +11:00
parent 2be2c504b2
commit a29cbb143c
15 changed files with 162 additions and 217 deletions

View File

@@ -4,7 +4,6 @@ from flask import request, render_template, redirect, send_from_directory, url_f
from main import db, app, ma
from sqlalchemy import Sequence
from sqlalchemy.exc import SQLAlchemyError
from status import st, Status
import os
import glob
from PIL import Image
@@ -24,7 +23,7 @@ from states import States, PA_UserState
################################################################################
# Local Class imports
################################################################################
from job import Job, JobExtra, Joblog, NewJob
from job import Job, JobExtra, Joblog, NewJob, SetFELog
from path import PathType, Path, MovePathDetails
from person import Refimg, Person, PersonRefimgLink
from settings import Settings, SettingsIPath, SettingsSPath, SettingsRBPath
@@ -463,13 +462,12 @@ def search(search_term):
return render_template("files.html", page_title='View Files', search_term=search_term, entry_data=entries, OPT=OPT, move_paths=move_paths )
################################################################################
# /files/scannow -> allows us to force a check for new files
# /files/scan_ip -> allows us to force a check for new files
################################################################################
@app.route("/files/scannow", methods=["GET"])
@app.route("/files/scan_ip", methods=["GET"])
@login_required
def scannow():
job=NewJob("scannow" )
st.SetMessage("scanning for new files in:&nbsp;<a href=/job/{}>Job #{}</a>&nbsp;(Click the link to follow progress)".format( job.id, job.id) )
def scan_ip():
job=NewJob( name="scan_ip", num_files=0, wait_for=None, jex=None, desc="scan for new files in import path" )
return redirect("/jobs")
################################################################################
@@ -478,8 +476,7 @@ def scannow():
@app.route("/files/forcescan", methods=["GET"])
@login_required
def forcescan():
job=NewJob("forcescan" )
st.SetMessage("force scan & rebuild data for files in:&nbsp;<a href=/job/{}>Job #{}</a>&nbsp;(Click the link to follow progress)".format( job.id, job.id) )
job=NewJob( name="forcescan", num_files=0, wait_for=None, jex=None, desc="remove data and rescan import & storage paths" )
return redirect("/jobs")
################################################################################
@@ -488,8 +485,7 @@ def forcescan():
@app.route("/files/scan_sp", methods=["GET"])
@login_required
def scan_sp():
job=NewJob("scan_sp" )
st.SetMessage("scanning for new files in:&nbsp;<a href=/job/{}>Job #{}</a>&nbsp;(Click the link to follow progress)".format( job.id, job.id) )
job=NewJob( name="scan_sp", num_files=0, wait_for=None, jex=None, desc="scan for new files in storage path" )
return redirect("/jobs")
@@ -504,7 +500,7 @@ def fix_dups():
rows = db.engine.execute( "select e1.id as id1, f1.hash, d1.rel_path as rel_path1, d1.eid as did1, e1.name as fname1, p1.id as path1, p1.type_id as path_type1, e2.id as id2, d2.rel_path as rel_path2, d2.eid as did2, e2.name as fname2, p2.id as path2, p2.type_id as path_type2 from entry e1, file f1, dir d1, entry_dir_link edl1, path_dir_link pdl1, path p1, entry e2, file f2, dir d2, entry_dir_link edl2, path_dir_link pdl2, path p2 where e1.id = f1.eid and e2.id = f2.eid and d1.eid = edl1.dir_eid and edl1.entry_id = e1.id and edl2.dir_eid = d2.eid and edl2.entry_id = e2.id and p1.type_id != (select id from path_type where name = 'Bin') and p1.id = pdl1.path_id and pdl1.dir_eid = d1.eid and p2.type_id != (select id from path_type where name = 'Bin') and p2.id = pdl2.path_id and pdl2.dir_eid = d2.eid and f1.hash = f2.hash and e1.id != e2.id and f1.size_mb = f2.size_mb order by path1, rel_path1, fname1");
if rows.returns_rows == False:
st.SetMessage(f"Err, no dups - should now clear the FE 'danger' message?")
SetFELog(f"Err, no dups - should now clear the FE 'danger' message?", "warning")
return redirect("/")
if 'pagesize' not in request.form:
@@ -546,8 +542,7 @@ def rm_dups():
jex.append( JobExtra( name="pagesize", value=10 ) )
job=NewJob( "rmdups", 0, None, jex )
st.SetMessage( f"Created&nbsp;<a href=/job/{job.id}>Job #{job.id}</a>&nbsp;to delete duplicate files")
job=NewJob( name="rmdups", num_files=0, wait_for=None, jex=jex, desc="to delete duplicate files" )
return redirect("/jobs")
@@ -561,8 +556,7 @@ def restore_files():
for el in request.form:
jex.append( JobExtra( name=f"{el}", value=request.form[el] ) )
job=NewJob( "restore_files", 0, None, jex )
st.SetMessage( f"Created&nbsp;<a href=/job/{job.id}>Job #{job.id}</a>&nbsp;to restore selected file(s)")
job=NewJob( name="restore_files", num_files=0, wait_for=None, jex=jex, desc="to restore selected file(s)" )
return redirect("/jobs")
################################################################################
@@ -575,8 +569,7 @@ def delete_files():
for el in request.form:
jex.append( JobExtra( name=f"{el}", value=request.form[el] ) )
job=NewJob( "delete_files", 0, None, jex )
st.SetMessage( f"Created&nbsp;<a href=/job/{job.id}>Job #{job.id}</a>&nbsp;to delete selected file(s)")
job=NewJob( name="delete_files", num_files=0, wait_for=None, jex=jex, desc="to delete selected file(s)" )
return redirect("/jobs")
################################################################################
@@ -589,11 +582,9 @@ def move_files():
jex=[]
for el in request.form:
jex.append( JobExtra( name=f"{el}", value=request.form[el] ) )
job=NewJob( "move_files", 0, None, jex )
return make_response( jsonify(
job_id=job.id,
message=f"Created&nbsp;<a class='link-light' href=/job/{job.id}>Job #{job.id}</a>&nbsp;to move selected file(s)",
level="success", alert="success", persistent=False, cant_close=False ) )
job=NewJob( name="move_files", num_files=0, wait_for=None, jex=jex, desc="to move selected file(s)" )
# data is not used, but send response to trigger CheckForJobs()
return make_response( jsonify( job_id=job.id ) )
@login_required
@app.route("/viewlist", methods=["POST"])
@@ -700,7 +691,7 @@ def view(id):
msg += "Clearing out all states. This means browser back buttons will not work, please start a new tab and try again"
PA_UserState.query.delete()
db.session.commit()
st.SetMessage( msg, "warning" )
SetFELog( msg, "warning" )
return redirect("/")
else:
NMO_data = FaceOverrideType.query.all()
@@ -735,12 +726,8 @@ def transform():
for el in request.form:
jex.append( JobExtra( name=f"{el}", value=request.form[el] ) )
job=NewJob( "transform_image", 0, None, jex )
resp={}
resp['job_id']=job.id
return resp
job=NewJob( name="transform_image", num_files=0, wait_for=None, jex=jex, desc="to transform selected file(s)" )
return make_response( jsonify( job_id=job.id ) )
################################################################################
# /checktransformjob -> URL that is called repeatedly by front-end waiting for the
@@ -753,14 +740,12 @@ def transform():
def checktransformjob():
job_id = request.form['job_id']
job = Job.query.get(job_id)
resp={}
resp['finished']=False
j=jsonify( finished=False )
if job.pa_job_state == 'Completed':
id=[jex.value for jex in job.extra if jex.name == "id"][0]
e=Entry.query.join(File).filter(Entry.id==id).first()
resp['thumbnail']=e.file_details.thumbnail
resp['finished']=True
return resp
j=jsonify( finished=True, thumbnail=e.file_details.thumbnail )
return make_response( j )
################################################################################
# /include -> return contents on /include and does not need a login, so we