start of noo for Search, and rewrite of GetEnt* to use eval(), search and flat done, but also fixed OLD bug I just noticed where prev/next buttons would not work when sorting by "A to Z", etc. as the value of the form.input has a space in it and serializeArray() was not dealing with it properly
This commit is contained in:
5
TODO
5
TODO
@@ -1,5 +1,10 @@
|
|||||||
## GENERAL
|
## GENERAL
|
||||||
* search allow noo
|
* search allow noo
|
||||||
|
- PREFS:
|
||||||
|
- allow default and choosing search noo
|
||||||
|
- can't force fullscreen on page load, so remove it from prefs
|
||||||
|
- also need to extend the OPT.order / eval usage to the Fold views
|
||||||
|
-- also, does search of matching dirname give all entries of subdirs of subdirs, etc. (think not) -- maybe a TODO?
|
||||||
|
|
||||||
* [DONE] order/ find face with largest size and at least show that as unmatched
|
* [DONE] order/ find face with largest size and at least show that as unmatched
|
||||||
- could also try to check it vs. other faces, if it matches more than say 10? we offer it up as a required ref img, then cut that face (with margin) out and use it is a new ref image / person
|
- could also try to check it vs. other faces, if it matches more than say 10? we offer it up as a required ref img, then cut that face (with margin) out and use it is a new ref image / person
|
||||||
|
|||||||
94
files.py
94
files.py
@@ -200,26 +200,17 @@ def GetEntriesInFlatView( OPT, prefix ):
|
|||||||
entries=[]
|
entries=[]
|
||||||
num_entries=0
|
num_entries=0
|
||||||
|
|
||||||
if OPT.noo == "Oldest":
|
join = "Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix)"
|
||||||
entries+=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(File.year,File.month,File.day,Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
entries = eval( f"{join}.{OPT.order}.offset({OPT.offset}).limit({OPT.how_many}).all()" )
|
||||||
last_entry=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name.desc()).limit(1)
|
|
||||||
elif OPT.noo == "Newest":
|
|
||||||
entries+=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
|
||||||
last_entry=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(File.year,File.month,File.day,Entry.name).limit(1)
|
|
||||||
elif OPT.noo == "Z to A":
|
|
||||||
entries+=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(Entry.name.desc()).offset(OPT.offset).limit(OPT.how_many).all()
|
|
||||||
last_entry=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(Entry.name).limit(1)
|
|
||||||
else:
|
|
||||||
entries+=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
|
||||||
last_entry=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).order_by(Entry.name.desc()).limit(1)
|
|
||||||
if OPT.first_eid == 0 and OPT.offset == 0 and len(entries):
|
if OPT.first_eid == 0 and OPT.offset == 0 and len(entries):
|
||||||
OPT.first_eid = entries[0].id
|
OPT.first_eid = entries[0].id
|
||||||
|
|
||||||
if OPT.last_eid==0:
|
if OPT.last_eid==0:
|
||||||
num_entries=Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix).count()
|
num_entries = eval( f"{join}.count()" )
|
||||||
le=last_entry.all()
|
last_entry = eval( f"{join}.{OPT.last_order}.limit(1).first()" )
|
||||||
if len(le):
|
if last_entry:
|
||||||
OPT.last_eid = le[0].id
|
OPT.last_eid = last_entry.id
|
||||||
|
|
||||||
return entries, num_entries
|
return entries, num_entries
|
||||||
|
|
||||||
@@ -278,26 +269,29 @@ def GetEntriesInFolderView( OPT, prefix ):
|
|||||||
entries += file_entries;
|
entries += file_entries;
|
||||||
return entries, num_entries
|
return entries, num_entries
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# /GetEntries -> helper function that Gets Entries for required files to show
|
# GetEntriesInSearchView: func. to retrieve DB entries appropriate for Search view
|
||||||
# for several routes (files_ip, files_sp, files_rbp, search, viewlist)
|
# Defaults search is for any matching filename, contents of any matching dirname
|
||||||
|
# and any match with AI / face for that term. Explicit, only AI match via
|
||||||
|
# AI:<tag> syntax
|
||||||
################################################################################
|
################################################################################
|
||||||
def GetEntries( OPT ):
|
def GetEntriesInSearchView( OPT ):
|
||||||
entries=[]
|
|
||||||
if OPT.path_type == 'Search' or (OPT.path_type == 'View' and OPT.orig_ptype=='Search'):
|
|
||||||
search_term=OPT.orig_search_term
|
search_term=OPT.orig_search_term
|
||||||
if 'AI:' in search_term:
|
if 'AI:' in OPT.orig_search_term:
|
||||||
search_term = search_term.replace('AI:','')
|
search_term = search_term.replace('AI:','')
|
||||||
all_entries = Entry.query.join(File).distinct().join(FaceFileLink).join(Face).join(FaceRefimgLink).join(Refimg).join(PersonRefimgLink).join(Person).filter(Person.tag.ilike(f"%{search_term}%")).order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
join=f"Entry.query.join(File).distinct().join(FaceFileLink).join(Face).join(FaceRefimgLink).join(Refimg).join(PersonRefimgLink).join(Person).filter(Person.tag.ilike('%{search_term}%'))"
|
||||||
|
if 'AI:' in OPT.orig_search_term:
|
||||||
|
all_entries = eval( f"{join}.{OPT.order}.offset(OPT.offset).limit(OPT.how_many).all()")
|
||||||
if OPT.last_eid == 0:
|
if OPT.last_eid == 0:
|
||||||
OPT.num_entries = Entry.query.join(File).distinct().join(FaceFileLink).join(Face).join(FaceRefimgLink).join(Refimg).join(PersonRefimgLink).join(Person).filter(Person.tag.ilike(f"%{search_term}%")).count()
|
OPT.num_entries = eval( f"{join}.count()" )
|
||||||
last_entry=Entry.query.join(File).distinct().join(FaceFileLink).join(Face).join(FaceRefimgLink).join(Refimg).join(PersonRefimgLink).join(Person).filter(Person.tag.ilike(f"%{search_term}%")).order_by(File.year,File.month,File.day,Entry.name.desc()).limit(1).all()
|
last_entry = eval( f"{join}.{OPT.last_order}.limit(1).first()" )
|
||||||
if len(last_entry):
|
if last_entry:
|
||||||
OPT.last_eid = last_entry[0].id
|
OPT.last_eid = last_entry.id
|
||||||
else:
|
else:
|
||||||
file_data=Entry.query.join(File).filter(Entry.name.ilike(f"%{search_term}%")).order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
file_data=eval( f"Entry.query.join(File).filter(Entry.name.ilike('%{search_term}%')).{OPT.order}.offset({OPT.offset}).limit({OPT.how_many}).all()" )
|
||||||
dir_data=Entry.query.join(File).join(EntryDirLink).join(Dir).filter(Dir.rel_path.ilike(f"%{search_term}%")).order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
dir_data =eval( f"Entry.query.join(File).join(EntryDirLink).join(Dir).filter(Dir.rel_path.ilike('%{search_term}%')).{OPT.order}.offset({OPT.offset}).limit({OPT.how_many}).all()" )
|
||||||
ai_data=Entry.query.join(File).join(FaceFileLink).join(Face).join(FaceRefimgLink).join(Refimg).join(PersonRefimgLink).join(Person).filter(Person.tag.ilike(f"%{search_term}%")).order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name).offset(OPT.offset).limit(OPT.how_many).all()
|
ai_data =eval( f"{join}.{OPT.order}.offset({OPT.offset}).limit({OPT.how_many}).all()")
|
||||||
|
|
||||||
# remove any duplicates from combined data
|
# remove any duplicates from combined data
|
||||||
all_entries = []
|
all_entries = []
|
||||||
@@ -329,8 +323,6 @@ def GetEntries( OPT ):
|
|||||||
by_ai =f"select e.id from entry e, face_file_link ffl, face_refimg_link frl, person_refimg_link prl, person p where e.id = ffl.file_eid and frl.face_id = ffl.face_id and frl.refimg_id = prl.refimg_id and prl.person_id = p.id and p.tag ilike '%%{search_term}%%'"
|
by_ai =f"select e.id from entry e, face_file_link ffl, face_refimg_link frl, person_refimg_link prl, person p where e.id = ffl.file_eid and frl.face_id = ffl.face_id and frl.refimg_id = prl.refimg_id and prl.person_id = p.id and p.tag ilike '%%{search_term}%%'"
|
||||||
|
|
||||||
sel_no_order=f"select e.*, f.* from entry e, file f where e.id=f.eid and e.id in ( {by_fname} union {by_dirname} union {by_ai} ) "
|
sel_no_order=f"select e.*, f.* from entry e, file f where e.id=f.eid and e.id in ( {by_fname} union {by_dirname} union {by_ai} ) "
|
||||||
order_desc=f"f.year desc, f.month desc, f.day desc, e.name"
|
|
||||||
order_asc=f"f.year, f.month, f.day, e.name desc"
|
|
||||||
|
|
||||||
#num_entries
|
#num_entries
|
||||||
num_e_sql = f"select count(1) from ( {by_fname} union {by_dirname} union {by_ai} ) as foo"
|
num_e_sql = f"select count(1) from ( {by_fname} union {by_dirname} union {by_ai} ) as foo"
|
||||||
@@ -338,7 +330,7 @@ def GetEntries( OPT ):
|
|||||||
for res in num_e_result:
|
for res in num_e_result:
|
||||||
OPT.num_entries=res.count
|
OPT.num_entries=res.count
|
||||||
|
|
||||||
last_entry_sql= f"{sel_no_order} order by {order_asc} limit 1"
|
last_entry_sql= f"{sel_no_order} order by {OPT.last_order_raw} limit 1"
|
||||||
last_entry=db.engine.execute( last_entry_sql )
|
last_entry=db.engine.execute( last_entry_sql )
|
||||||
# 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:
|
||||||
@@ -346,9 +338,43 @@ def GetEntries( OPT ):
|
|||||||
# store first/last eid into prefs
|
# store first/last eid into prefs
|
||||||
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=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()
|
||||||
UpdatePref( pref, OPT )
|
UpdatePref( pref, OPT )
|
||||||
|
|
||||||
return all_entries
|
return all_entries
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# set up "order strings" to use in ORM and raw queries as needed for
|
||||||
|
# GetEntries*Search*, GetEntries*Flat*, GetEntries*Fold*
|
||||||
|
################################################################################
|
||||||
|
def SetOrderStrings( OPT ):
|
||||||
|
if OPT.noo == "Newest":
|
||||||
|
OPT.order="order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name.desc())"
|
||||||
|
OPT.last_order="order_by(File.year,File.month,File.day,Entry.name)"
|
||||||
|
OPT.last_order_raw=f"f.year, f.month, f.day, e.name"
|
||||||
|
elif OPT.noo == "Oldest":
|
||||||
|
OPT.order="order_by(File.year,File.month,File.day,Entry.name)"
|
||||||
|
OPT.last_order="order_by(File.year.desc(),File.month.desc(),File.day.desc(),Entry.name.desc())"
|
||||||
|
OPT.last_order_raw=f"f.year desc, f.month desc, f.day desc, e.name desc"
|
||||||
|
elif OPT.noo == "Z to A":
|
||||||
|
OPT.order="order_by(Entry.name.desc())"
|
||||||
|
OPT.last_order="order_by(Entry.name)"
|
||||||
|
OPT.last_order_raw=f"e.name"
|
||||||
|
else:
|
||||||
|
# A to Z
|
||||||
|
OPT.order="order_by(Entry.name)"
|
||||||
|
OPT.last_order="order_by(Entry.name.desc())"
|
||||||
|
OPT.last_order_raw=f"e.name desc"
|
||||||
|
return
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# /GetEntries -> helper function that Gets Entries for required files to show
|
||||||
|
# for several routes (files_ip, files_sp, files_rbp, search, viewlist)
|
||||||
|
################################################################################
|
||||||
|
def GetEntries( OPT ):
|
||||||
|
entries=[]
|
||||||
|
|
||||||
|
SetOrderStrings( OPT )
|
||||||
|
if OPT.path_type == 'Search' or (OPT.path_type == 'View' and OPT.orig_ptype=='Search'):
|
||||||
|
return GetEntriesInSearchView( OPT )
|
||||||
|
|
||||||
# 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
|
||||||
# import, storage, or bin images, reset OPT.path_type so that the paths array below works
|
# import, storage, or bin images, reset OPT.path_type so that the paths array below works
|
||||||
if 'View' in OPT.path_type:
|
if 'View' in OPT.path_type:
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
// this is needed as serliazeArray doesnt handle spaces in values
|
||||||
|
// so we wrap it in this func
|
||||||
|
$.fn.serializeAndEncode = function() {
|
||||||
|
return $.map(this.serializeArray(), function(val) {
|
||||||
|
return [val.name, encodeURIComponent(val.value)].join('=');
|
||||||
|
}).join('&');
|
||||||
|
};
|
||||||
|
|
||||||
// grab all selected thumbnails and return a <div> containing the thumbnails
|
// grab all selected thumbnails and return a <div> containing the thumbnails
|
||||||
// with extra yr and date attached as attributes so we can set the default
|
// with extra yr and date attached as attributes so we can set the default
|
||||||
// dir name for a move directory - not used in del, but no harm to include them
|
// dir name for a move directory - not used in del, but no harm to include them
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ class States(PA):
|
|||||||
else:
|
else:
|
||||||
# is a search so...
|
# is a search so...
|
||||||
print( "For now, search defaults for noo / folders are hardcoded" )
|
print( "For now, search defaults for noo / folders are hardcoded" )
|
||||||
self.noo = 'Oldest'
|
self.noo = 'Newest'
|
||||||
self.folders=False
|
self.folders=False
|
||||||
|
|
||||||
self.cwd=self.root
|
self.cwd=self.root
|
||||||
|
|||||||
@@ -57,7 +57,6 @@
|
|||||||
<span class="alert alert-primary p-2">Searched for: '{{search_term}}'</span>
|
<span class="alert alert-primary p-2">Searched for: '{{search_term}}'</span>
|
||||||
</div class="col my-auto">
|
</div class="col my-auto">
|
||||||
<script>
|
<script>
|
||||||
$('#noo').prop('disabled', 'disabled').removeClass('border-info').addClass('border-secondary').removeClass('text-info').addClass('text-secondary');
|
|
||||||
$('#folders').prop('disabled', 'disabled').removeClass('border-info').addClass('border-secondary').removeClass('text-info').addClass('text-secondary');
|
$('#folders').prop('disabled', 'disabled').removeClass('border-info').addClass('border-secondary').removeClass('text-info').addClass('text-secondary');
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -258,11 +257,11 @@
|
|||||||
<input type="hidden" name="cwd" id="cwd" value="{{OPT.cwd}}">
|
<input type="hidden" name="cwd" id="cwd" value="{{OPT.cwd}}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col my-auto d-flex justify-content-center">
|
<div class="col my-auto d-flex justify-content-center">
|
||||||
<button aria-label="prev" onClick="$.each( $('#main_form').serializeArray() , function( index, value ) { $('#nav_form').append( '<input type=hidden name=' + value['name'] +' value='+value['value'] + '>' ); })" id="prev" name="prev" class="prev sm-txt btn btn-outline-secondary">
|
<button aria-label="prev" onClick="$.each( $('#main_form').serializeAndEncode() , function( index, value ) { $('#nav_form').append( '<input type=hidden name=' + value['name'] +' value='+value['value'] + '>' ); })" id="prev" name="prev" class="prev sm-txt btn btn-outline-secondary">
|
||||||
<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>
|
||||||
<span class="sm-txt my-auto"> {{OPT.how_many}} files </span>
|
<span class="sm-txt my-auto"> {{OPT.how_many}} files </span>
|
||||||
<button aria-label="next" onClick="$.each( $('#main_form').serializeArray() , function( index, value ) { $('#nav_form').append( '<input type=hidden name=' + value['name'] +' value='+value['value'] + '>' ); });" id="next" {{nxt_disabled}} name="next" class="next sm-txt btn btn-outline-secondary">
|
<button aria-label="next" onClick="$.each( $('#main_form').serializeAndEncode() , function( index, value ) { $('#nav_form').append( '<input type=hidden name=' + value['name'] +' value='+value['value'] + '>' ); });" id="next" {{nxt_disabled}} name="next" class="next sm-txt btn btn-outline-secondary">
|
||||||
<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>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user