removed use of last_entry_in_db (boolean) and replaced with use of current/first_eid/last_eid in PA_USER_STATE so it persists across reloads/back buttons, and allows full use of ajax data retrieval in the background for the viewer (so fullscreen stays across page loads), and the next/prev buttons are set on the image load, not after they have been pressed "one too many times"
This commit is contained in:
5
TODO
5
TODO
@@ -18,7 +18,8 @@
|
|||||||
* viewlist
|
* viewlist
|
||||||
- [DONE] can work out new view_eids server side, and pass them back as json data (fixes loss of fullscreen & back/fwd issues)
|
- [DONE] can work out new view_eids server side, and pass them back as json data (fixes loss of fullscreen & back/fwd issues)
|
||||||
- [DONE] should really define the first/last of a GetEntries search and use definitive logic to show at start or end of entries (for next/prev buttons in viewer.html)
|
- [DONE] should really define the first/last of a GetEntries search and use definitive logic to show at start or end of entries (for next/prev buttons in viewer.html)
|
||||||
- need to keep "current", "first_eid", "last_eid" in pa_user_state to support back button / reloading view/<current> and better handling of next/prev
|
- [DONE] store "current", "first_eid", "last_eid" in pa_user_state
|
||||||
|
- use them on reload, e.g. if current set use it not view eid (should be okay with client-side skipping, and just make sure if it is viewlist we use next/prev logic not current
|
||||||
- can consider an optim-- new_view page makes calls to viewlist to ADD json data only, so only trigger a new "viewlist" if we dont have data for that part of the eids
|
- can consider an optim-- new_view page makes calls to viewlist to ADD json data only, so only trigger a new "viewlist" if we dont have data for that part of the eids
|
||||||
job.py:@app.route("/jobs", methods=["GET", "POST"])
|
job.py:@app.route("/jobs", methods=["GET", "POST"])
|
||||||
job.py:@app.route("/job/<id>", methods=["GET","POST"])
|
job.py:@app.route("/job/<id>", methods=["GET","POST"])
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
|
|
||||||
* refimg locns can lose an array idx of 0 always.
|
* refimg locns can lose an array idx of 0 always.
|
||||||
|
|
||||||
* search allow noo?
|
* search allow noo
|
||||||
|
|
||||||
* delete folder
|
* delete folder
|
||||||
|
|
||||||
|
|||||||
30
files.py
30
files.py
@@ -20,7 +20,7 @@ import re
|
|||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from states import States
|
from states import States, PA_UserState
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Local Class imports
|
# Local Class imports
|
||||||
@@ -291,8 +291,15 @@ def GetEntries( OPT ):
|
|||||||
# can only be 1 due to limit above
|
# can only be 1 due to limit above
|
||||||
for l in last_entry:
|
for l in last_entry:
|
||||||
OPT.last_eid = l.id
|
OPT.last_eid = l.id
|
||||||
|
print( f"c={OPT.current}, f={OPT.first_eid}, l={OPT.last_eid} -- STORE THESE in pa_user_state" )
|
||||||
print( f"f={OPT.first_eid}, l={OPT.last_eid} -- STORE THESE in pa_user_state" )
|
pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==OPT.path_type,PA_UserState.orig_ptype==OPT.orig_ptype,PA_UserState.orig_search_term==search_term).first()
|
||||||
|
pref.current=OPT.current
|
||||||
|
pref.first_eid=OPT.first_eid
|
||||||
|
pref.last_eid=OPT.last_eid
|
||||||
|
print( f"stored pref: {pref}" )
|
||||||
|
db.session.add(pref)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return all_entries
|
return all_entries
|
||||||
|
|
||||||
# if we are a view, then it will be of something else, e.g. a list of
|
# if we are a view, then it will be of something else, e.g. a list of
|
||||||
@@ -564,7 +571,6 @@ def move_files():
|
|||||||
@app.route("/viewlist", methods=["POST"])
|
@app.route("/viewlist", methods=["POST"])
|
||||||
def viewlist():
|
def viewlist():
|
||||||
OPT=States( request )
|
OPT=States( request )
|
||||||
OPT.last_entry_in_db=0
|
|
||||||
# Get next/prev set of data - e.g. if next set, then it will use orig_url
|
# Get next/prev set of data - e.g. if next set, then it will use orig_url
|
||||||
# to go forward how_many from offset and then use viewer.html to show that
|
# to go forward how_many from offset and then use viewer.html to show that
|
||||||
# first obj of the new list of entries
|
# first obj of the new list of entries
|
||||||
@@ -576,7 +582,6 @@ def viewlist():
|
|||||||
OPT.offset -= int(OPT.how_many)
|
OPT.offset -= int(OPT.how_many)
|
||||||
entries=GetEntries( OPT )
|
entries=GetEntries( OPT )
|
||||||
# now flag we are at the last in db, to reset current below
|
# now flag we are at the last in db, to reset current below
|
||||||
OPT.last_entry_in_db=1
|
|
||||||
objs = {}
|
objs = {}
|
||||||
eids=""
|
eids=""
|
||||||
resp={}
|
resp={}
|
||||||
@@ -614,15 +619,19 @@ def viewlist():
|
|||||||
current = int(lst[0])
|
current = int(lst[0])
|
||||||
if 'prev' in request.form:
|
if 'prev' in request.form:
|
||||||
current = int(lst[-1])
|
current = int(lst[-1])
|
||||||
if OPT.last_entry_in_db:
|
|
||||||
# force this back to the last image of the last page - its the last in the DB, so set OPT for it
|
|
||||||
current = int(lst[-1])
|
|
||||||
OPT.last_entry_in_db=current
|
|
||||||
|
|
||||||
resp['current']=current
|
resp['current']=current
|
||||||
|
resp['first_eid']=OPT.first_eid
|
||||||
|
resp['last_eid']=OPT.last_eid
|
||||||
resp['eids']=eids
|
resp['eids']=eids
|
||||||
resp['offset']=OPT.offset
|
resp['offset']=OPT.offset
|
||||||
resp['last_entry_in_db']=OPT.last_entry_in_db
|
print( "DDP: SAVE PREF HERE TO GET NEW CURRENT AND FIX back button WITH view/XXX when you next/prev to different page" )
|
||||||
|
|
||||||
|
pref=PA_UserState.query.filter(PA_UserState.pa_user_dn==current_user.dn,PA_UserState.path_type==OPT.path_type,PA_UserState.view_eid==OPT.view_eid).first()
|
||||||
|
pref.current=current
|
||||||
|
print( f"stored pref: {pref}" )
|
||||||
|
db.session.add(pref)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@@ -630,7 +639,6 @@ def viewlist():
|
|||||||
@app.route("/view/<id>", methods=["GET"])
|
@app.route("/view/<id>", methods=["GET"])
|
||||||
def view(id):
|
def view(id):
|
||||||
OPT=States( request )
|
OPT=States( request )
|
||||||
OPT.last_entry_in_db=0
|
|
||||||
objs = {}
|
objs = {}
|
||||||
entries=GetEntries( OPT )
|
entries=GetEntries( OPT )
|
||||||
eids=""
|
eids=""
|
||||||
|
|||||||
25
states.py
25
states.py
@@ -31,9 +31,12 @@ class PA_UserState(db.Model):
|
|||||||
# only used if view and orig_ptype was search
|
# only used if view and orig_ptype was search
|
||||||
orig_search_term = db.Column(db.String, unique=False, nullable=False )
|
orig_search_term = db.Column(db.String, unique=False, nullable=False )
|
||||||
orig_url = db.Column(db.String, unique=False, nullable=False )
|
orig_url = db.Column(db.String, unique=False, nullable=False )
|
||||||
|
current = db.Column(db.Integer)
|
||||||
|
first_eid = db.Column(db.Integer)
|
||||||
|
last_eid = db.Column(db.Integer)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<pa_user_dn: {self.pa_user_dn}, path_type: {self.path_type}, noo: {self.noo}, grouping: {self.grouping}, how_many: {self.how_many}, st_offset: {self.st_offset}, size: {self.size}, folders: {self.folders}, root: {self.root}, cwd: {self.cwd}, view_eid: {self.view_eid}, orig_ptype: {self.orig_ptype}, orig_search_term: {self.orig_search_term}, orig_url: {self.orig_url}>"
|
return f"<pa_user_dn: {self.pa_user_dn}, path_type: {self.path_type}, noo: {self.noo}, grouping: {self.grouping}, how_many: {self.how_many}, st_offset: {self.st_offset}, size: {self.size}, folders: {self.folders}, root: {self.root}, cwd: {self.cwd}, view_eid: {self.view_eid}, orig_ptype: {self.orig_ptype}, orig_search_term: {self.orig_search_term}, orig_url: {self.orig_url}, current={self.current}, first_eid={self.first_eid}, last_eid={self.last_eid}>"
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@@ -46,8 +49,9 @@ class States(PA):
|
|||||||
self.path_type=''
|
self.path_type=''
|
||||||
self.url = request.path
|
self.url = request.path
|
||||||
self.view_eid = None
|
self.view_eid = None
|
||||||
self.first_eid = 0
|
self.current=0
|
||||||
self.last_eid = 0
|
self.first_eid=0
|
||||||
|
self.last_eid=0
|
||||||
|
|
||||||
print( f"States() - path={request.path}, ref={request.referrer}" )
|
print( f"States() - path={request.path}, ref={request.referrer}" )
|
||||||
|
|
||||||
@@ -135,6 +139,10 @@ class States(PA):
|
|||||||
self.orig_search_term=pref.orig_search_term
|
self.orig_search_term=pref.orig_search_term
|
||||||
self.orig_url = pref.orig_url
|
self.orig_url = pref.orig_url
|
||||||
self.view_eid = pref.view_eid
|
self.view_eid = pref.view_eid
|
||||||
|
self.current = pref.current
|
||||||
|
print( f"from existing pref, set self.first_eid to {pref.first_eid}" )
|
||||||
|
self.first_eid = pref.first_eid
|
||||||
|
self.last_eid = pref.last_eid
|
||||||
else:
|
else:
|
||||||
# retreive defaults from 'PAUser' where defaults are stored
|
# retreive defaults from 'PAUser' where defaults are stored
|
||||||
u=PAUser.query.filter(PAUser.dn==current_user.dn).one()
|
u=PAUser.query.filter(PAUser.dn==current_user.dn).one()
|
||||||
@@ -208,13 +216,16 @@ class States(PA):
|
|||||||
self.offset=0
|
self.offset=0
|
||||||
if 'next' in request.form:
|
if 'next' in request.form:
|
||||||
self.offset += int(self.how_many)
|
self.offset += int(self.how_many)
|
||||||
|
if 'current' in request.form:
|
||||||
|
self.current = int(request.form['current'])
|
||||||
|
|
||||||
# now save pref
|
# now save pref
|
||||||
if not pref:
|
if not pref:
|
||||||
# insert new pref for this combo (might be a new search or view, or first time for a path)
|
# insert new pref for this combo (might be a new search or view, or first time for a path)
|
||||||
pref=PA_UserState( pa_user_dn=current_user.dn, path_type=self.path_type, view_eid=self.view_eid, noo=self.noo, grouping=self.grouping, how_many=self.how_many,
|
pref=PA_UserState( pa_user_dn=current_user.dn, path_type=self.path_type, view_eid=self.view_eid, noo=self.noo,
|
||||||
st_offset=self.offset, size=self.size, folders=self.folders, root=self.root, cwd=self.cwd,
|
grouping=self.grouping, how_many=self.how_many, st_offset=self.offset, size=self.size, folders=self.folders,
|
||||||
orig_ptype=self.orig_ptype, orig_search_term=self.orig_search_term, orig_url=self.orig_url )
|
root=self.root, cwd=self.cwd, orig_ptype=self.orig_ptype, orig_search_term=self.orig_search_term,
|
||||||
|
orig_url=self.orig_url, current=self.current, first_eid=self.first_eid, last_eid=self.last_eid )
|
||||||
else:
|
else:
|
||||||
# update this pref with the values calculated above (most likely from POST to form)
|
# update this pref with the values calculated above (most likely from POST to form)
|
||||||
pref.pa_user_dn=current_user.dn
|
pref.pa_user_dn=current_user.dn
|
||||||
@@ -231,6 +242,8 @@ class States(PA):
|
|||||||
pref.orig_ptype = self.orig_ptype
|
pref.orig_ptype = self.orig_ptype
|
||||||
pref.orig_search_term = self.orig_search_term
|
pref.orig_search_term = self.orig_search_term
|
||||||
pref.orig_url = self.orig_url
|
pref.orig_url = self.orig_url
|
||||||
|
pref.current = self.current
|
||||||
|
# first_eid and last_eid wont change in this func, set only in GetEntries()
|
||||||
|
|
||||||
db.session.add(pref)
|
db.session.add(pref)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|||||||
@@ -28,8 +28,12 @@ create table PA_USER(
|
|||||||
DEFAULT_FULLSCREEN Boolean,
|
DEFAULT_FULLSCREEN Boolean,
|
||||||
constraint PK_PA_USER_ID primary key(ID) );
|
constraint PK_PA_USER_ID primary key(ID) );
|
||||||
|
|
||||||
-- this should reference pa_user_id not pa_user_dn
|
-- this is totally not 3rd normal form, but when I made it that, it was so complex, it was stupid
|
||||||
create table PA_USER_STATE ( ID integer, PA_USER_DN varchar(128), PATH_TYPE varchar(16), NOO varchar(16), GROUPING varchar(16), HOW_MANY integer, ST_OFFSET integer, SIZE integer, FOLDERS Boolean, FULLSCREEN Boolean, ROOT varchar, CWD varchar, VIEW_EID integer, ORIG_PTYPE varchar, ORIG_SEARCH_TERM varchar, ORIG_URL varchar,
|
-- so for the little data here, I'm deliberately doing a redundant data structure
|
||||||
|
create table PA_USER_STATE ( ID integer, PA_USER_DN varchar(128), PATH_TYPE varchar(16), NOO varchar(16),
|
||||||
|
GROUPING varchar(16), HOW_MANY integer, ST_OFFSET integer, SIZE integer, FOLDERS Boolean,
|
||||||
|
FULLSCREEN Boolean, ROOT varchar, CWD varchar, VIEW_EID integer, ORIG_PTYPE varchar, ORIG_SEARCH_TERM varchar,
|
||||||
|
ORIG_URL varchar, CURRENT integer, FIRST_EID integer, LAST_EID integer,
|
||||||
constraint FK_PA_USER_DN foreign key (PA_USER_DN) references PA_USER(DN),
|
constraint FK_PA_USER_DN foreign key (PA_USER_DN) references PA_USER(DN),
|
||||||
constraint PK_PA_USER_STATES_ID primary key(ID ) );
|
constraint PK_PA_USER_STATES_ID primary key(ID ) );
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
var eids="{{eids}}"
|
var eids="{{eids}}"
|
||||||
var eid_lst=eids.split(",")
|
var eid_lst=eids.split(",")
|
||||||
var offset={{OPT.offset}}
|
var offset={{OPT.offset}}
|
||||||
var last_entry_in_db={{OPT.last_entry_in_db}}
|
var first_eid={{OPT.first_eid}}
|
||||||
|
var last_eid={{OPT.last_eid}}
|
||||||
|
|
||||||
{% for id in objs %}
|
{% for id in objs %}
|
||||||
e=new Object()
|
e=new Object()
|
||||||
@@ -54,6 +55,8 @@
|
|||||||
|
|
||||||
function PrettyFname(fname)
|
function PrettyFname(fname)
|
||||||
{
|
{
|
||||||
|
console.log('PrettyFname called')
|
||||||
|
console.log('fname='+fname)
|
||||||
s='<span class="alert alert-secondary py-2">'
|
s='<span class="alert alert-secondary py-2">'
|
||||||
if( fname.indexOf( "static/Import" ) == 0 )
|
if( fname.indexOf( "static/Import" ) == 0 )
|
||||||
{
|
{
|
||||||
@@ -95,7 +98,6 @@
|
|||||||
objs=res.objs
|
objs=res.objs
|
||||||
eid_lst=eids.split(",")
|
eid_lst=eids.split(",")
|
||||||
offset=res.offset
|
offset=res.offset
|
||||||
last_entry_in_db=res.last_entry_in_db
|
|
||||||
ViewImageOrVideo()
|
ViewImageOrVideo()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -109,7 +111,7 @@
|
|||||||
<input type="hidden" name="eids" value={{eids}}>
|
<input type="hidden" name="eids" value={{eids}}>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button title="Show previous image" class="col-auto btn btn-outline-info px-2" style="padding: 10%" id="la"
|
<button title="Show previous image" class="col-auto btn btn-outline-info px-2" style="padding: 10%" id="la"
|
||||||
{% if OPT.offset == 0 and eids.find(current|string) == 0 %}
|
{% if OPT.first_eid == current %}
|
||||||
disabled
|
disabled
|
||||||
{% endif %}
|
{% endif %}
|
||||||
onClick="
|
onClick="
|
||||||
@@ -133,6 +135,8 @@
|
|||||||
$('#ra').attr('disabled', false )
|
$('#ra').attr('disabled', false )
|
||||||
current=eid_lst[prev]
|
current=eid_lst[prev]
|
||||||
ViewImageOrVideo()
|
ViewImageOrVideo()
|
||||||
|
if( current == first_eid )
|
||||||
|
$('#la').attr('disabled', true )
|
||||||
">
|
">
|
||||||
<svg width="16" height="16" fill="currentColor"><use xlink:href="{{url_for('internal', filename='icons.svg')}}#prev"/></svg>
|
<svg width="16" height="16" fill="currentColor"><use xlink:href="{{url_for('internal', filename='icons.svg')}}#prev"/></svg>
|
||||||
</button>
|
</button>
|
||||||
@@ -169,12 +173,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<button title="Show next image" class="col-auto btn btn-outline-info px-2" style="padding: 10%" id="ra"
|
<button title="Show next image" class="col-auto btn btn-outline-info px-2" style="padding: 10%" id="ra"
|
||||||
|
{% if OPT.last_eid == current %}
|
||||||
|
disabled
|
||||||
|
{% endif %}
|
||||||
onClick="
|
onClick="
|
||||||
if( current == last_entry_in_db )
|
|
||||||
{
|
|
||||||
$('#ra').attr('disabled', true )
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if( document.fullscreen == false )
|
if( document.fullscreen == false )
|
||||||
fullscreen = false
|
fullscreen = false
|
||||||
cidx = eid_lst.indexOf(current.toString())
|
cidx = eid_lst.indexOf(current.toString())
|
||||||
@@ -182,13 +184,16 @@
|
|||||||
{
|
{
|
||||||
current=eid_lst[cidx+1]
|
current=eid_lst[cidx+1]
|
||||||
ViewImageOrVideo()
|
ViewImageOrVideo()
|
||||||
$('#la').attr('disabled', false )
|
if( current != first_eid )
|
||||||
|
$('#la').attr('disabled', false )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
CallViewListRoute('next')
|
||||||
|
|
||||||
|
if( current == last_eid )
|
||||||
{
|
{
|
||||||
{# only go next route if list contains as many elements as we asked to display... can be more than how_many on any page in reality, as its really how_many per dir? #}
|
$('#ra').attr('disabled', true )
|
||||||
if( eid_lst.length >= {{OPT.how_many}} )
|
return
|
||||||
CallViewListRoute('next')
|
|
||||||
}
|
}
|
||||||
">
|
">
|
||||||
<svg width="16" height="16" fill="currentColor"><use xlink:href="{{url_for('internal', filename='icons.svg')}}#next"/></svg>
|
<svg width="16" height="16" fill="currentColor"><use xlink:href="{{url_for('internal', filename='icons.svg')}}#next"/></svg>
|
||||||
|
|||||||
Reference in New Issue
Block a user