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
|
||||
* 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
|
||||
- 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
|
||||
|
||||
184
files.py
184
files.py
@@ -200,26 +200,17 @@ def GetEntriesInFlatView( OPT, prefix ):
|
||||
entries=[]
|
||||
num_entries=0
|
||||
|
||||
if OPT.noo == "Oldest":
|
||||
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()
|
||||
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)
|
||||
join = "Entry.query.join(File).join(EntryDirLink).join(Dir).join(PathDirLink).join(Path).filter(Path.path_prefix==prefix)"
|
||||
entries = eval( f"{join}.{OPT.order}.offset({OPT.offset}).limit({OPT.how_many}).all()" )
|
||||
|
||||
if OPT.first_eid == 0 and OPT.offset == 0 and len(entries):
|
||||
OPT.first_eid = entries[0].id
|
||||
|
||||
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()
|
||||
le=last_entry.all()
|
||||
if len(le):
|
||||
OPT.last_eid = le[0].id
|
||||
num_entries = eval( f"{join}.count()" )
|
||||
last_entry = eval( f"{join}.{OPT.last_order}.limit(1).first()" )
|
||||
if last_entry:
|
||||
OPT.last_eid = last_entry.id
|
||||
|
||||
return entries, num_entries
|
||||
|
||||
@@ -278,76 +269,111 @@ def GetEntriesInFolderView( OPT, prefix ):
|
||||
entries += file_entries;
|
||||
return entries, num_entries
|
||||
|
||||
|
||||
################################################################################
|
||||
# GetEntriesInSearchView: func. to retrieve DB entries appropriate for Search view
|
||||
# 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 GetEntriesInSearchView( OPT ):
|
||||
search_term=OPT.orig_search_term
|
||||
if 'AI:' in OPT.orig_search_term:
|
||||
search_term = search_term.replace('AI:','')
|
||||
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:
|
||||
OPT.num_entries = eval( f"{join}.count()" )
|
||||
last_entry = eval( f"{join}.{OPT.last_order}.limit(1).first()" )
|
||||
if last_entry:
|
||||
OPT.last_eid = last_entry.id
|
||||
else:
|
||||
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 =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 =eval( f"{join}.{OPT.order}.offset({OPT.offset}).limit({OPT.how_many}).all()")
|
||||
|
||||
# remove any duplicates from combined data
|
||||
all_entries = []
|
||||
for f in file_data:
|
||||
all_entries.append(f)
|
||||
for d in dir_data:
|
||||
add_it=1
|
||||
for f in file_data:
|
||||
if d.name == f.name:
|
||||
add_it=0
|
||||
break
|
||||
if add_it:
|
||||
all_entries.append(d)
|
||||
for a in ai_data:
|
||||
add_it=1
|
||||
for f in file_data:
|
||||
if a.name == f.name:
|
||||
add_it=0
|
||||
break
|
||||
if add_it:
|
||||
all_entries.append(a)
|
||||
|
||||
# for all searches first_entry is worked out when first_eid not set yet & offset is 0 and we have some entries
|
||||
if OPT.first_eid == 0 and OPT.offset == 0 and len(all_entries):
|
||||
OPT.first_eid = all_entries[0].id
|
||||
if OPT.last_eid == 0:
|
||||
by_fname= f"select e.id from entry e where e.name ilike '%%{search_term}%%'"
|
||||
by_dirname=f"select e.id from entry e, entry_dir_link edl where edl.entry_id = e.id and edl.dir_eid in ( select d.eid from dir d where d.rel_path 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} ) "
|
||||
|
||||
#num_entries
|
||||
num_e_sql = f"select count(1) from ( {by_fname} union {by_dirname} union {by_ai} ) as foo"
|
||||
num_e_result = db.engine.execute( num_e_sql )
|
||||
for res in num_e_result:
|
||||
OPT.num_entries=res.count
|
||||
|
||||
last_entry_sql= f"{sel_no_order} order by {OPT.last_order_raw} limit 1"
|
||||
last_entry=db.engine.execute( last_entry_sql )
|
||||
# can only be 1 due to limit above
|
||||
for l in last_entry:
|
||||
OPT.last_eid = l.id
|
||||
# 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()
|
||||
UpdatePref( pref, OPT )
|
||||
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'):
|
||||
search_term=OPT.orig_search_term
|
||||
if 'AI:' in search_term:
|
||||
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()
|
||||
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()
|
||||
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()
|
||||
if len(last_entry):
|
||||
OPT.last_eid = last_entry[0].id
|
||||
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()
|
||||
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()
|
||||
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()
|
||||
|
||||
# remove any duplicates from combined data
|
||||
all_entries = []
|
||||
for f in file_data:
|
||||
all_entries.append(f)
|
||||
for d in dir_data:
|
||||
add_it=1
|
||||
for f in file_data:
|
||||
if d.name == f.name:
|
||||
add_it=0
|
||||
break
|
||||
if add_it:
|
||||
all_entries.append(d)
|
||||
for a in ai_data:
|
||||
add_it=1
|
||||
for f in file_data:
|
||||
if a.name == f.name:
|
||||
add_it=0
|
||||
break
|
||||
if add_it:
|
||||
all_entries.append(a)
|
||||
|
||||
# for all searches first_entry is worked out when first_eid not set yet & offset is 0 and we have some entries
|
||||
if OPT.first_eid == 0 and OPT.offset == 0 and len(all_entries):
|
||||
OPT.first_eid = all_entries[0].id
|
||||
if OPT.last_eid == 0:
|
||||
by_fname= f"select e.id from entry e where e.name ilike '%%{search_term}%%'"
|
||||
by_dirname=f"select e.id from entry e, entry_dir_link edl where edl.entry_id = e.id and edl.dir_eid in ( select d.eid from dir d where d.rel_path 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} ) "
|
||||
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_e_sql = f"select count(1) from ( {by_fname} union {by_dirname} union {by_ai} ) as foo"
|
||||
num_e_result = db.engine.execute( num_e_sql )
|
||||
for res in num_e_result:
|
||||
OPT.num_entries=res.count
|
||||
|
||||
last_entry_sql= f"{sel_no_order} order by {order_asc} limit 1"
|
||||
last_entry=db.engine.execute( last_entry_sql )
|
||||
# can only be 1 due to limit above
|
||||
for l in last_entry:
|
||||
OPT.last_eid = l.id
|
||||
# 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()
|
||||
UpdatePref( pref, OPT )
|
||||
|
||||
return all_entries
|
||||
return GetEntriesInSearchView( OPT )
|
||||
|
||||
# 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
|
||||
|
||||
@@ -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
|
||||
// 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
|
||||
|
||||
@@ -172,7 +172,7 @@ class States(PA):
|
||||
else:
|
||||
# is a search so...
|
||||
print( "For now, search defaults for noo / folders are hardcoded" )
|
||||
self.noo = 'Oldest'
|
||||
self.noo = 'Newest'
|
||||
self.folders=False
|
||||
|
||||
self.cwd=self.root
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
<span class="alert alert-primary p-2">Searched for: '{{search_term}}'</span>
|
||||
</div class="col my-auto">
|
||||
<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');
|
||||
</script>
|
||||
{% endif %}
|
||||
@@ -258,11 +257,11 @@
|
||||
<input type="hidden" name="cwd" id="cwd" value="{{OPT.cwd}}">
|
||||
<div class="row">
|
||||
<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>
|
||||
</button>
|
||||
<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>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user