Commit 5adc54e5 authored by Jean-Francois Dockes's avatar Jean-Francois Dockes
Browse files

a bit of refactoring, implement pwd for search dir: filtering, fix stuff...

a bit of refactoring, implement pwd for search dir: filtering, fix stuff broken by shuffling code between files
parent 11e0f6c3
......@@ -38,7 +38,7 @@ dispatcher = cmdtalkplugin.Dispatch()
msgproc = cmdtalkplugin.Processor(dispatcher)
def uprcl_init():
global httphp, pathprefix, uprclhost, pathmap
global httphp, pathprefix, uprclhost, pathmap, rclconfdir
if "UPMPD_HTTPHOSTPORT" not in os.environ:
raise Exception("No UPMPD_HTTPHOSTPORT in environment")
......@@ -130,28 +130,9 @@ def search(a):
raise Exception("bad objid [%s]" % objid)
upnps = a['origsearch']
rcls = uprclsearch.upnpsearchtorecoll(upnps)
uplog("Search: recoll search: %s" % rcls)
rcldb = recoll.connect(confdir=rclconfdir)
rclq = rcldb.query()
rclq.execute(rcls)
uplog("Estimated query results: %d" % (rclq.rowcount))
entries = []
maxcnt = 0
totcnt = 0
while True:
docs = rclq.fetchmany()
for doc in docs:
id = g_myprefix + '$' + 'seeyoulater'
e = rcldoctoentry(id, objid, httphp, pathprefix, doc)
entries.append(e)
totcnt += 1
if (maxcnt > 0 and totcnt >= maxcnt) or len(docs) != rclq.arraysize:
break
uplog("Search retrieved %d docs" % (totcnt,))
entries = uprclsearch.search(rclconfdir, objid, upnps, g_myprefix, httphp, pathprefix)
encoded = json.dumps(entries)
return {"entries" : encoded}
......
......@@ -25,6 +25,14 @@ g_myprefix = '0$uprcl$folders'
# configuration. The entries are paths instead of simple names, and
# the doc index (j) is 0. The dir index points normally to a dirvec
# entry.
# Create new directory entry: insert in father and append dirvec slot (with ".." entry)
def _createdir(dirvec, fathidx, docidx, nm):
dirvec.append({})
dirvec[fathidx][nm] = (len(dirvec) - 1, docidx)
dirvec[-1][".."] = (fathidx, -1)
return len(dirvec) - 1
def _rcl2folders(docs, confdir):
global dirvec
dirvec = []
......@@ -33,12 +41,12 @@ def _rcl2folders(docs, confdir):
topdirs = [os.path.expanduser(d) for d in
shlex.split(rclconf.getConfParam('topdirs'))]
topidx = 0
dirvec.append({})
dirvec[0][".."] = (0, -1)
for d in topdirs:
topidx += 1
dirvec[0][d] = (topidx, -1)
dirvec.append({})
dirvec[0][d] = (len(dirvec)-1, -1)
dirvec[-1][".."] = (0, -1)
# Walk the doc list and update the directory tree according to the
# url (create intermediary directories if needed, create leaf
......@@ -89,17 +97,11 @@ def _rcl2folders(docs, confdir):
if idx != len(path) -1:
# This is an intermediate element. Create a
# Doc-less directory
topidx += 1
dirvec.append({})
dirvec[fathidx][elt] = (topidx, -1)
fathidx = topidx
fathidx = _createdir(dirvec, fathidx, -1, elt)
else:
# Last element. If directory, needs a dirvec entry
if doc.mtype == 'inode/directory':
topidx += 1
dirvec.append({})
dirvec[fathidx][elt] = (topidx, docidx)
fathidx = topidx
fathidx = _createdir(dirvec, fathidx, docidx, elt)
else:
dirvec[fathidx][elt] = (-1, docidx)
......@@ -176,35 +178,42 @@ def _cmpentries(e1, e2):
return int(a1) - int(a2)
# Browse method
# objid is like folders$index
# flag is meta or children.
def browse(pid, flag, httphp, pathprefix):
global g_alldocs, g_dirvec
def _objidtodiridx(pid):
if not pid.startswith(g_myprefix):
uplog("folders.browse: bad pid %s" % pid)
return []
raise Exception("folders.browse: bad pid %s" % pid)
if len(g_alldocs) == 0:
uplog("folders:browse: no docs")
return []
raise Exception("folders:browse: no docs")
diridx = pid[len(g_myprefix):]
if not diridx:
diridx = 0
else:
if diridx[1] != 'd':
raise Exception("folders:browse: called on non dir objid %s" % pid)
diridx = int(diridx[2:])
if diridx >= len(g_dirvec):
uplog("folders:browse: bad pid %s" % pid)
return []
raise Exception("folders:browse: bad pid %s" % pid)
return diridx
# Browse method
# objid is like folders$index
# flag is meta or children.
def browse(pid, flag, httphp, pathprefix):
diridx = _objidtodiridx(pid)
entries = []
# The basename call is just for diridx==0 (topdirs). Remove it if
# this proves a performance issue
for nm,ids in g_dirvec[diridx].iteritems():
#uplog("folders:browse: got nm %s" % nm.decode('utf-8'))
if nm == "..":
continue
thisdiridx = ids[0]
thisdocidx = ids[1]
if thisdiridx >= 0:
......@@ -221,5 +230,29 @@ def browse(pid, flag, httphp, pathprefix):
if e:
entries.append(e)
#return entries
return sorted(entries, cmp=_cmpentries)
# return path for objid, which has to be a container. This is good old pwd
def dirpath(objid):
diridx = _objidtodiridx(objid)
lpath = []
while True:
fathidx = g_dirvec[diridx][".."][0]
for nm, ids in g_dirvec[fathidx].iteritems():
if ids[0] == diridx:
lpath.append(nm)
break
diridx = fathidx
if diridx == 0:
break
if not lpath:
path = "/"
else:
path = ""
for elt in reversed(lpath):
path += elt + "/"
return path
#!/usr/bin/env python
from __future__ import print_function
import uprclfolders
from uprclutils import *
from recoll import recoll
def _getchar(s, i):
if i < len(s):
return i+1,s[i]
......@@ -39,6 +43,7 @@ def _readstring(s, i):
return len(s), str
def upnpsearchtorecoll(s):
uplog("upnpsearchtorecoll:in: <%s>" % s)
s = s.replace('\t', ' ')
s = s.replace('\n', ' ')
s = s.replace('\r', ' ')
......@@ -97,7 +102,7 @@ def upnpsearchtorecoll(s):
# Does not work because OR/AND priorities are reversed
# between recoll and upnp. This would be very
# difficult to correct, let's hope that the callers
# use parenthesese
# use parentheses
out.append('OR')
else:
if hadDerived:
......@@ -111,9 +116,48 @@ def upnpsearchtorecoll(s):
ostr = ""
for tok in out:
ostr += tok + " "
uplog("upnpsearchtorecoll:out: <%s>" % ostr)
return ostr
def search(rclconfdir, objid, upnps, idprefix, httphp, pathprefix):
rcls = upnpsearchtorecoll(upnps)
filterdir = uprclfolders.dirpath(objid)
rcls += " dir:\"" + filterdir + "\""
uplog("Search: recoll search: %s" % rcls)
rcldb = recoll.connect(confdir=rclconfdir)
try:
rclq = rcldb.query()
rclq.execute(rcls)
except Exception as e:
uplog("Search: recoll query raised: %s" % e)
return []
uplog("Estimated query results: %d" % (rclq.rowcount))
if rclq.rowcount == 0:
return []
entries = []
maxcnt = 0
totcnt = 0
while True:
docs = rclq.fetchmany()
for doc in docs:
id = idprefix + '$' + 'seeyoulater'
e = rcldoctoentry(id, objid, httphp, pathprefix, doc)
entries.append(e)
totcnt += 1
if (maxcnt > 0 and totcnt >= maxcnt) or len(docs) != rclq.arraysize:
break
uplog("Search retrieved %d docs" % (totcnt,))
return entries
if __name__ == '__main__':
s = '(upnp:artist derivedFrom "abc\\"def\\g") or (dc:title:xxx) '
print("INPUT: %s" % s)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment