diff --git a/TODO b/TODO
index ac30fb9..d78f430 100644
--- a/TODO
+++ b/TODO
@@ -1,17 +1,7 @@
### GENERAL
* get all status messages to use toasts AND get func to also increase/descrease the job counter as appropriate)
- [DONE] all (success/creation) status messages use toasts
- -- [DONE] make a helper func for setting toast body and use it in base.html && file_support.js
- -- [DONE] make a helper func for setting 'Active Jobs' text/badge and call it when document ready (rather/both than start of base.html)
- -- [DONE] trigger a timeout to play back pa_job_mgr message to FE and reset 'Active Jobs' text/badge until it hits 0
- -- [DONE] (re)start this code if any new jobs is created (on move ONLY FOR NOW
- -- [DONE] make js StatusMsg() take a 'data' (json response) and process that
- -- [DONE] make it include message from the API endpoint doing the work, not in the js code...
- -- [TODO] fix base.html to only call toast() and only in document.ready()
- -- [DONE] this means handling danger, and persistent / no time-out toast()s
- -- [DONE] warning works now (colors, etc.)
- -- [DONE] clean up has to be a POST back to server to clear DB (jscript/async has no other way)
- -- [TODO] go through the crazy persistent status msgs for checkdups, etc. and make sure they all work
+ -- [TODO] ensure all pa_job_mgr jobs are sending messages back to the FE -- SHOULD??? I just hook FinishJob???
* should be using jsonify to return real json to my API calls, e.g:
use make_response( jsonify (... ) )
@@ -19,7 +9,8 @@
all GETs stay as is for now (as they expect a html reply, not data, and then html is base.html+ and it handles the status)
-- ONLY time this will fail is multiple status messages (which can occur I believe if a Wake of job mgr and then a job is created in DB, the success will only be shown)
-- [TODO] simple fix will be to get 'hidden' jobs (wake job_mgr and maybe? metadata) to post failure events to the JobMgr_FE DB queue
- -- [TODO] when ALL converted, replace 'alert="..."' with 'status="..."'
+ -- [TODO] -- change class Status to class UILog
+ -- [TODO] -- change alert to level
* delete files should behave like /move_files (stay on same page) as well as the status messages above
diff --git a/files.py b/files.py
index 3084a68..dbbf540 100644
--- a/files.py
+++ b/files.py
@@ -593,7 +593,7 @@ def move_files():
return make_response( jsonify(
job_id=job.id,
message=f"Created Job #{job.id} to move selected file(s)",
- status="success", alert="success" ) )
+ level="success", alert="success", persistent=False, cant_close=False ) )
@login_required
@app.route("/viewlist", methods=["POST"])
diff --git a/internal/js/jobs.js b/internal/js/jobs.js
index 25a64f4..f26bab2 100644
--- a/internal/js/jobs.js
+++ b/internal/js/jobs.js
@@ -3,11 +3,14 @@ var next_toast_id=1
function NewToast(data)
{
+ console.log(data)
// make new div, include data.alert as background colour, and data.message as toast body
d_id='st' + String(next_toast_id)
div='
Job # ' + str(msg.job_id) + ': '
- sts.append( { 'message': u+msg.message, 'alert': msg.alert, 'job_id': msg.job_id } )
+ sts.append( { 'message': u+msg.message, 'alert': msg.alert, 'job_id': msg.job_id, 'persistent': msg.persistent, 'cant_close': msg.cant_close } )
return make_response( jsonify( num_active_jobs=num, sts=sts ) )
###############################################################################
diff --git a/pa_job_manager.py b/pa_job_manager.py
index 49dc19d..deb52aa 100644
--- a/pa_job_manager.py
+++ b/pa_job_manager.py
@@ -503,6 +503,8 @@ class PA_JobManager_FE_Message(Base):
job_id = Column(Integer, ForeignKey('job.id') )
alert = Column(String)
message = Column(String)
+ persistent = Column(Boolean)
+ cant_close = Column(Boolean)
def __repr__(self):
return "
here to restart or cancel' )
+ MessageToFE( job.id, "danger", f'Stale job, click here to restart or cancel', True, False )
session.commit()
continue
if job.pa_job_state == 'New':
@@ -930,7 +932,7 @@ def HandleJobs(first_run=False):
# threading.Thread(target=RunJob, args=(job,)).start()
except Exception as e:
try:
- MessageToFE( job.id, "danger", "Failed with: {} (try job log for details)".format(e) )
+ MessageToFE( job.id, "danger", "Failed with: {} (try job log for details)".format(e), True, False )
except Exception as e2:
print("ERROR: Failed to let front-end know, but back-end Failed to run job (id: {}, name: {} -- orig exep was: {}, this exception was: {})".format( job.id, job.name, e, e2) )
print("INFO: PA job manager is waiting for a job")
@@ -954,7 +956,7 @@ def JobScanNow(job):
JobProgressState( job, "In Progress" )
ProcessImportDirs(job)
FinishJob( job, "Completed (scan for new files)" )
- MessageToFE( job.id, "success", "Completed (scan for new files)" )
+ MessageToFE( job.id, "success", "Completed (scan for new files)", False, False )
return
##############################################################################
@@ -964,7 +966,7 @@ def JobScanStorageDir(job):
JobProgressState( job, "In Progress" )
ProcessStorageDirs(job)
FinishJob( job, "Completed (scan for new files)" )
- MessageToFE( job.id, "success", "Completed (scan for new files)" )
+ MessageToFE( job.id, "success", "Completed (scan for new files)", False, False )
return
@@ -1078,7 +1080,7 @@ def JobForceScan(job):
ProcessImportDirs(job)
ProcessStorageDirs(job)
FinishJob(job, "Completed (forced remove and recreation of all file data)")
- MessageToFE( job.id, "success", "Completed (forced remove and recreation of all file data)" )
+ MessageToFE( job.id, "success", "Completed (forced remove and recreation of all file data)", False, False )
return
##############################################################################
@@ -1319,6 +1321,10 @@ def MoveFileToRecycleBin(job,del_me):
bin_path=session.query(Path).join(PathType).filter(PathType.name=='Bin').first()
parent_dir=session.query(Dir).join(PathDirLink).filter(PathDirLink.path_id==bin_path.id).first()
+ # check/delete if we already have a deleted file of this name/number (only # happened in testing, but jic)
+ # 99.9% of the time, this will just delete nothing
+ session.query(DelFile).filter(DelFile.file_eid==del_me.id).delete()
+
# if we ever need to restore, lets remember this file's original path
# (use a string in case the dir/path is ever deleted from FS (and then DB) and we need to recreate)
del_file_details = DelFile( file_eid=del_me.id, orig_path_prefix=del_me.in_dir.in_path.path_prefix )
@@ -2036,7 +2042,7 @@ def JobCheckForDups(job):
for row in res:
if row.count > 0:
AddLogForJob(job, f"Found duplicates, Creating Status message in front-end for attention")
- MessageToFE( job.id, "danger", f'Found duplicate(s), click here to finalise import by removing duplicates' )
+ MessageToFE( job.id, "danger", f'Found duplicate(s), click here to finalise import by removing duplicates', True, True )
else:
FinishJob(job, f"No duplicates found")
FinishJob(job, f"Finished looking for duplicates")
@@ -2107,7 +2113,8 @@ def JobRemoveDups(job):
# Need to put another checkdups job in now to force / validate we have no dups
next_job=NewJob( "checkdups" )
- AddLogForJob(job, "adding job id={} {} to confirm there are no more duplicates".format( next_job.id, next_job.id, next_job.name ) )
+ AddLogForJob(job, f"adding job id={next_job.id} {next_job.name} to confirm there are no more duplicates" )
+ MessageToFE( job.id, "success", f"Finished Job#{job.id} removing duplicate files", False, False )
return
####################################################################################################################################
@@ -2137,7 +2144,7 @@ def JobMoveFiles(job):
move_me=session.query(Entry).get(jex.value)
MoveEntriesToOtherFolder( job, move_me, dst_storage_path, f"{prefix}{suffix}" )
next_job=NewJob( "checkdups" )
- MessageToFE( job.id, "success", "Completed (move of selected files)" )
+ MessageToFE( job.id, "success", "Completed (move of selected files)", False, False )
FinishJob(job, f"Finished move selected file(s)")
return
@@ -2152,7 +2159,7 @@ def JobDeleteFiles(job):
del_me=session.query(Entry).join(File).filter(Entry.id==jex.value).first()
MoveFileToRecycleBin(job,del_me)
next_job=NewJob( "checkdups" )
- MessageToFE( job.id, "success", "Completed (delete of selected files)" )
+ MessageToFE( job.id, "success", "Completed (delete of selected files)", False, False )
FinishJob(job, f"Finished deleting selected file(s)")
return
@@ -2167,7 +2174,7 @@ def JobRestoreFiles(job):
restore_me=session.query(Entry).join(File).filter(Entry.id==jex.value).first()
RestoreFile(job,restore_me)
next_job=NewJob( "checkdups" )
- MessageToFE( job.id, "success", "Completed (restore of selected files)" )
+ MessageToFE( job.id, "success", "Completed (restore of selected files)", False, False )
FinishJob(job, f"Finished restoring selected file(s)")
return
diff --git a/status.py b/status.py
index 311ee76..0b25ce1 100644
--- a/status.py
+++ b/status.py
@@ -5,18 +5,18 @@ from shared import PA
# including when duplicates are found on import. These status messages are exposed into
# the html files, and they show once for success/green, and sticky for danger/red
class Status(PA):
- alert="success"
+ level="success"
message=""
def GetAlert(self):
- return self.alert
+ return self.level
def GetMessage(self):
return self.message
- def SetMessage(self, msg, al="success"):
+ def SetMessage(self, msg, l="success"):
self.message=msg
- self.alert=al
+ self.level=l
return
def AppendMessage(self, msg):
@@ -24,7 +24,7 @@ class Status(PA):
return
def ClearStatus(self):
- self.alert="success"
+ self.level="success"
self.message=""
return ""
diff --git a/tables.sql b/tables.sql
index d5e414d..009df67 100644
--- a/tables.sql
+++ b/tables.sql
@@ -160,7 +160,7 @@ create table JOBEXTRA ( ID integer, JOB_ID integer, NAME varchar(32), VALUE varc
create table JOBLOG ( ID integer, JOB_ID integer, LOG_DATE timestamptz, LOG varchar,
constraint PK_JL_ID primary key(ID), constraint FK_JL_JOB_ID foreign key(JOB_ID) references JOB(ID) );
-create table PA_JOB_MANAGER_FE_MESSAGE ( ID integer, JOB_ID integer, ALERT varchar(16), MESSAGE varchar(1024),
+create table PA_JOB_MANAGER_FE_MESSAGE ( ID integer, JOB_ID integer, ALERT varchar(16), MESSAGE varchar(1024), PERSISTENT boolean, CANT_CLOSE boolean,
constraint PA_JOB_MANAGER_FE_ACKS_ID primary key(ID),
constraint FK_PA_JOB_MANAGER_FE_MESSAGE_JOB_ID foreign key(JOB_ID) references JOB(ID) );
diff --git a/templates/base.html b/templates/base.html
index 0803ade..058bae1 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -128,40 +128,14 @@
-
- {% if GetJM_Message() != None %}
- {% set msg=GetJM_Message() %}
-
- {% if request.endpoint != "fix_dups" and request.endpoint != "rm_dups" and request.endpoint != "stale_jobs" %}
- {% if msg.alert != "success" %}
-
- {% if msg.job.name != "checkdups" %}
-
-
- {# if a JM is a danger message, allow code to remove the status, it should be 'permanent' until addressed -- e.g. you have duplicates, fix them #}
- {% if msg.alert != "danger" %}
- {% set dont_print=ClearJM_Message(msg.id) %}
- {% endif %}
- {% endif %}
- {% endif %}
- {% endif %}
-{% endif %}
+{% endif %} {# not InDBox #}
{% block main_content %}
{% endblock main_content %}
{% if not InDBox %}
{%block script_content %}{% endblock script_content %}
-
+
@@ -177,7 +151,6 @@
msg = "{{ GetMessage()|safe }}"
msg=msg.replace('href=', 'class=link-light href=')
st=Object; st.message=msg; st.alert='{{GetAlert()}}'; StatusMsg(st)
- alert( '{{GetAlert()}}' )
{{ ClearStatus() }}
{% endif %}