Commit 2297eff4 authored by Jean-Francois Dockes's avatar Jean-Francois Dockes
Browse files

uprcl: create recoll documents for the albums (those do not actually exist in the file system)

parent 8f44d4a7
......@@ -101,7 +101,7 @@ import uprclinit
# store than by using an exclusion list, but it's a bit more difficult
# to manage.
#
# + possibly 'xdocid' if/when needed?
# + possibly 'xdocid' and/or 'rcludi' if/when needed?
#
_otherneededfields = [
'albumartist', 'allartists', 'comment', 'composer', 'conductor',
......@@ -220,15 +220,15 @@ class Folders(object):
def _pathbeyondtopdirs(self, doc):
url = uprclutils.docpath(doc).decode('utf-8', errors='replace')
# Determine the root entry (topdirs element). Special because
# its path is not a simple name.
fathidx = -1
# its path is not a simple name. Fathidx is its index in _dirvec
firstdiridx = -1
for rtpath,idx in self._dirvec[0].items():
#uplog("type(url) %s type(rtpath) %s rtpath %s url %s" %
# (type(url),type(rtpath),rtpath, url))
if url.startswith(rtpath):
fathidx = idx[0]
firstdiridx = idx[0]
break
if fathidx == -1:
if firstdiridx == -1:
# uplog("No parent in topdirs: %s" % url)
return None,None
......@@ -248,7 +248,7 @@ class Folders(object):
# Split path. The caller will walk the list (possibly creating
# directory entries as needed, or doing something else).
path = url1.split('/')[1:]
return fathidx, path
return firstdiridx, path
# Main folders build method: walk the recoll docs array and split
......@@ -299,7 +299,8 @@ class Folders(object):
# For linking item search results to the main
# array. Deactivated for now as it does not seem to be
# needed.
# needed (and we would need to add xdocid to the
# resultstore fields).
#self._xid2idx[doc["xdocid"]] = docidx
fathidx, path = self._pathbeyondtopdirs(doc)
......@@ -409,8 +410,7 @@ class Folders(object):
pathremain = ''
else:
if dirpth[0:2] != '$d':
raise Exception("folders:browse: called on non dir objid %s" %
pid)
raise Exception("folders:browse: called on non dir objid %s" % pid)
# Other $sign?
nextdol = dirpth.find("$", 1)
if nextdol > 0:
......@@ -573,15 +573,22 @@ class Folders(object):
return path
# Compute object id for doc out of recoll search. Not used at the moment.
# and _xid2idx is not built
# Compute object id for doc out of recoll search. Not used at the
# moment, and _xid2idx is not built.
def _objidforxdocid(self, doc):
if doc["xdocid"] not in self._xid2idx:
return None
return self._idprefix + '$i' + str(self._xid2idx[doc["xdocid"]])
# Given a doc, we walk its url down from the part in root to find
# its directory entry, and return the _dirvec and _rcldocs indices
# it holds, either of which can be -1
def _stat(self, doc):
# _pathbeyond... returns the _dirvec index of the root entry
# we start from (root is special), and the split rest of path.
# That is if the doc url has /av/mp3/classique/bach/ and the root entry is /av/mp3,
# we get the _dirvec entry index for /av/mp3 and [classique, bach]
fathidx, pathl = self._pathbeyondtopdirs(doc)
if not fathidx:
return -1,-1
......@@ -603,10 +610,13 @@ class Folders(object):
def objidfordoc(self, doc):
id=None
if doc["mtype"] == 'inode/directory':
id = self._objidforpath(doc)
else:
id = self._objidforxdocid(doc)
#else:
# # Note: not currently doing anything, see method comments
# id = self._objidforxdocid(doc)
if not id:
id = self._idprefix + '$' + 'seeyoulater'
return id
......@@ -22,6 +22,7 @@ from recoll import recoll
from upmplgutils import uplog
from conftree import stringToStrings
import uprclutils
import uprclinit
def _getchar(s, i):
if i < len(s):
......@@ -223,11 +224,12 @@ def _upnpsearchtorecoll(s):
return " ".join(out)
def search(foldersobj, rclconfdir, objid, upnps, idprefix, httphp, pathprefix):
# inobjid is for the container this search is run from.
def search(foldersobj, rclconfdir, inobjid, upnps, idprefix, httphp, pathprefix):
tags = uprclinit.getTree('tags')
rcls = _upnpsearchtorecoll(upnps)
filterdir = foldersobj.dirpath(objid)
filterdir = foldersobj.dirpath(inobjid)
if filterdir and filterdir != "/":
rcls += " dir:\"" + filterdir + "\""
......@@ -250,8 +252,24 @@ def search(foldersobj, rclconfdir, objid, upnps, idprefix, httphp, pathprefix):
while True:
docs = rclq.fetchmany()
for doc in docs:
# The doc is either an actual recollindex product from the
# FS or a synthetic one from uprcltags creating album
# entries. Different processing for either
e = None
if doc["rcludi"].find("albid") == 0:
albid = doc["rcludi"][5:]
uplog("rcludi %s albid %s" % (doc["rcludi"], albid))
e = tags.direntryforalbid(albid)
else:
# Objidfordoc uses the path from the url to walk the
# _dirvec and determine the right entry if doc is a
# container. If doc is an item, the returned id is bogus
# (0$uprcl$folders$seeyoulater), because it's not useful
# at the moment. Of course, this breaks the recommendation
# for the objids to be consistent and unchanging
id = foldersobj.objidfordoc(doc)
e = uprclutils.rcldoctoentry(id, objid, httphp, pathprefix, doc)
uplog("Search: id [%s] for doc udi [%s]\n" % (id, doc["rcludi"]))
e = uprclutils.rcldoctoentry(id, inobjid, httphp, pathprefix, doc)
if e:
entries.append(e)
if (maxcnt > 0 and len(entries) >= maxcnt) or \
......
......@@ -316,6 +316,23 @@ class Tagged(object):
upnpclass='object.container.album.musicAlbum'))
return entries
# Called when the search finds one of our synthetic album search
# results. Create a container entry for it
def direntryforalbid(self, albid):
intalbid = int(albid)
c = self._conn.cursor()
stmt = '''SELECT album_id, albtitle, albarturi, albdate, artist.value
FROM albums LEFT JOIN artist ON artist.artist_id = albums.artist_id
WHERE album_id = ? AND albtdisc is NULL ORDER BY albtitle'''
args = (intalbid,)
c.execute(stmt, args)
for r in c:
pid = uprclinit.getObjPrefix() + 'albums'
id = pid + '$' + albid
return rcldirentry(id, pid, r[1], arturi=r[2], date=r[3],artist=r[4],
upnpclass='object.container.album.musicAlbum')
return None
# This is called when an 'albums' element is encountered in the
# selection path. i is the index of the albums element. The tree under
......
......@@ -18,6 +18,7 @@
import os
import time
import re
from recoll import recoll
from timeit import default_timer as timer
from uprclutils import audiomtypes, docfolder, uplog
......@@ -353,6 +354,26 @@ def _setalbumartists(conn):
c1.execute('''UPDATE albums SET artist_id = ?
WHERE album_id = ?''', (r[1], r[0]))
# Update the recoll index for the albums
def _albumstorecoll(conn):
rcldb = recoll.connect(confdir=uprclinit.getRclConfdir(), writable=True)
c = conn.cursor()
# 0 1 2 3 4 5
stmt = '''SELECT album_id, albfolder, albtitle, albarturi, albdate, artist.value
FROM albums LEFT JOIN artist ON artist.artist_id = albums.artist_id
WHERE albtdisc is NULL'''
c.execute(stmt, ())
for r in c:
udi = "albid" + str(r[0])
doc = recoll.Doc()
doc["album"] = r[2]
doc["title"] = r[2]
doc["mtype"] = "inode/directory"
if r[5]:
doc["albumartist"] = r[5]
doc["url"] = "file://" + r[1]
uplog("_albumstorecoll: creating album for: %s" % doc["album"])
rcldb.addOrUpdate(udi, doc)
# Check that the numbers are sequential
def _checkseq(seq):
......@@ -544,4 +565,5 @@ def recolltosql(conn, rcldocs):
end = timer()
uplog("recolltosql: processed %d docs in %.2f Seconds" %
(totcnt, end-start))
_albumstorecoll(conn)
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