def _tagsbrowseitems(self, pid, qpath, i, selwhere, values): stmt = 'SELECT docidx FROM tracks ' + selwhere c = self._conn.cursor() rows = c.execute(stmt, values) docids = [r[0] for r in rows] albids = self._subtreealbums(selwhere, values) entries = [] displaytracks = True if len(albids) == 1: # Only display '>> Complete album' if not all tracks # already there. If all tracks are there, we display # the album entry (with the same id value: show album) albid = albids[0] tlist = self._trackentriesforalbum(albid, pid) # Replace $items with $albums for the album entry id = pid.replace('$items', '$albums') + '$' + str(albid) + '$showca' if len(tlist) != len(docids): entries.append(rcldirentry(id, pid, '>> Complete Album')) else: displaytracks = False el = self._direntriesforalbums(pid, "WHERE album_id = %s" % albid) el[0]['id'] = id entries.append(el[0]) if displaytracks: rcldocs = uprclinit.g_trees['folders'].rcldocs() entries += [ rcldoctoentry(pid + '$i' + str(docid), pid, self._httphp, self._pprefix, rcldocs[docid]) for docid in docids ] return sorted(entries, key=cmpentries)
def _trackentriesforstmt(self, stmt, values, pid): rcldocs = uprclinit.g_trees['folders'].rcldocs() c = self._conn.cursor() c.execute(stmt, values) entries = [ rcldoctoentry(pid + '$i' + str(r[0]), pid, self._httphp, self._pprefix, rcldocs[r[0]]) for r in c ] return sorted(entries, key=cmpentries)
def browse(self, pid, flag): idx = self._objidtoidx(pid) entries = [] rcldocs = uprclinit.g_trees['folders'].rcldocs() if idx == 0: # Browsing root for i in range(len(self.utidx))[1:]: doc = rcldocs[self.utidx[i]] id = self._idprefix + '$u' + str(i) e = rcldoctoentry(id, pid, self._httphp, self._pprefix, doc) if e: entries.append(e) else: # Non root: only items in there. flag needs to be 'meta' doc = rcldocs[idx] id = self._idprefix + '$u' + str(idx) e = rcldoctoentry(id, pid, self._httphp, self._pprefix, doc) if e: entries.append(e) return sorted(entries, key=lambda entry: entry['tt'].lower())
def browse(pid, flag, httphp, pathprefix): idx = _objidtoidx(pid) entries = [] if idx == 0: # Browsing root for i in range(len(g_utidx))[1:]: doc = g_rcldocs[g_utidx[i]] id = untg_prefix + '$u' + str(i) e = rcldoctoentry(id, pid, httphp, pathprefix, doc) if e: entries.append(e) else: # Non root: only items in there. flag needs to be 'meta' doc = g_rcldocs[thisdocidx] id = untg_prefix + '$u' + str(idx) e = rcldoctoentry(id, pid, httphp, pathprefix, doc) if e: entries.append(e) return sorted(entries, cmp=cmpentries)
def browse(self, pid, flag): idx = self._objidtoidx(pid) folders = uprclinit.g_trees['folders'] rcldocs = folders.rcldocs() entries = [] if idx == 0: # Browsing root for i in range(len(self.utidx))[1:]: doc = rcldocs[self.utidx[i]] id = self._idprefix + '$p' + str(i) title = doc.title if doc.title else doc.filename e = rcldirentry(id, pid, title, upnpclass='object.container.playlistContainer') if e: entries.append(e) else: pldoc = rcldocs[self.utidx[idx]] plpath = uprclutils.docpath(pldoc) #uplog("playlists: plpath %s" % plpath) try: m3u = uprclutils.M3u(plpath) except Exception as ex: uplog("M3u open failed: %s %s" % (plpath, ex)) return entries cnt = 1 for url in m3u: doc = recoll.Doc() if m3u.urlRE.match(url): # Actual URL (usually http). Create bogus doc doc.setbinurl(bytearray(url)) elt = os.path.split(url)[1] doc.title = elt.decode('utf-8', errors='ignore') doc.mtype = "audio/mpeg" else: doc.setbinurl(bytearray(b'file://' + url)) fathidx, docidx = folders._stat(doc) if docidx < 0: uplog("playlists: can't stat %s" % doc.getbinurl()) continue doc = rcldocs[docidx] id = pid + '$e' + str(len(entries)) e = rcldoctoentry(id, pid, self._httphp, self._pprefix, doc) if e: entries.append(e) return sorted(entries, key=cmpentries)
def browse(pid, flag, httphp, pathprefix): diridx = _objidtodiridx(pid) # If there is only one entry in root, skip it. This means that 0 # and 1 point to the same dir, but this does not seem to be an # issue if diridx == 0 and len(dirvec[0]) == 2: diridx = 1 entries = [] # The basename call is just for diridx==0 (topdirs). Remove it if # this proves a performance issue for nm, ids in _dirvec[diridx].iteritems(): if nm == "..": continue thisdiridx = ids[0] thisdocidx = ids[1] if thisdocidx >= 0: doc = g_alldocs[thisdocidx] else: uplog("No doc for %s" % pid) doc = None if thisdiridx >= 0: # Skip empty directories if len(dirvec[thisdiridx]) == 1: continue id = _foldersIdPfx + '$' + 'd' + str(thisdiridx) if doc and doc.albumarturi: arturi = doc.albumarturi else: arturi = _arturifordir(thisdiridx) entries.append( rcldirentry(id, pid, os.path.basename(nm), arturi=arturi)) else: # Not a directory. docidx had better been set if thisdocidx == -1: uplog("folders:docidx -1 for non-dir entry %s" % nm) continue doc = g_alldocs[thisdocidx] id = _foldersIdPfx + '$i' + str(thisdocidx) e = rcldoctoentry(id, pid, httphp, pathprefix, doc) if e: entries.append(e) return sorted(entries, cmp=cmpentries)
def search(foldersobj, rclconfdir, objid, upnps, idprefix, httphp, pathprefix): rcls = _upnpsearchtorecoll(upnps) filterdir = foldersobj.dirpath(objid) if filterdir and filterdir != "/": 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 while True: docs = rclq.fetchmany() for doc in docs: arturi = uprclutils.docarturi(doc, httphp, pathprefix) if arturi: # The uri is quoted, so it's ascii and we can just store # it as a doc attribute doc.albumarturi = arturi id = foldersobj.objidfordoc(doc) e = uprclutils.rcldoctoentry(id, objid, httphp, pathprefix, doc) if e: entries.append(e) if (maxcnt > 0 and len(entries) >= maxcnt) or \ len(docs) != rclq.arraysize: break uplog("Search retrieved %d docs" % (len(entries),)) entries.sort(key=uprclutils.cmpentries) return entries
def search(rclconfdir, objid, upnps, idprefix, httphp, pathprefix): rcls = upnpsearchtorecoll(upnps) filterdir = uprclfolders.dirpath(objid) if filterdir and filterdir != "/": 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 while True: docs = rclq.fetchmany() for doc in docs: id = idprefix + '$' + 'seeyoulater' e = rcldoctoentry(id, objid, httphp, pathprefix, doc) if e: entries.append(e) if (maxcnt > 0 and len(entries) >= maxcnt) or \ len(docs) != rclq.arraysize: break uplog("Search retrieved %d docs" % (len(entries), )) return sorted(entries, cmp=cmpentries)
def browse(self, pid, flag): diridx,pthremain = self._objidtodiridx(pid) # If pthremain is set, this is pointing to 'Tag View'. Pass # the request along to the tags browser. if pthremain: if not pthremain.find('$tagview.0') == 0: raise Exception("uprclfolders: pid [%s]. bad pthremain"%pid) return uprclinit.g_trees['tags'].browseFolder(pid, flag, pthremain, self.dirpath(pid)) # If there is only one entry in root, skip it. This means that 0 # and 1 point to the same dir, but this does not seem to be an # issue if diridx == 0 and len(self._dirvec[0]) == 2: diridx = 1 #uplog("Folders browse: diridx %d content: [%s]" % # (diridx,self._dirvec[diridx])) entries = [] # The basename call is just for diridx==0 (topdirs). Remove it if # this proves a performance issue for nm,ids in self._dirvec[diridx].items(): if nm == ".." or nm == ".": continue thisdiridx = ids[0] thisdocidx = ids[1] if thisdocidx >= 0: doc = self._rcldocs[thisdocidx] else: # uplog("No doc for %s" % pid) doc = None if thisdiridx >= 0: # Skip empty directories if len(self._dirvec[thisdiridx]) == 1: continue id = self._idprefix + '$d' + str(thisdiridx) if doc and doc.albumarturi: arturi = doc.albumarturi else: arturi = self._arturifordir(thisdiridx) entries.append(rcldirentry(id, pid, os.path.basename(nm), arturi=arturi)) else: # Not a directory. docidx had better been set if thisdocidx == -1: uplog("folders:docidx -1 for non-dir entry %s"%nm) continue doc = self._rcldocs[thisdocidx] id = self._idprefix + '$i' + str(thisdocidx) e = rcldoctoentry(id, pid, self._httphp, self._pprefix, doc) if e: entries.append(e) entries.sort(key=cmpentries) # Add "Browse subtree by tags" entry if pid != self._idprefix and self._enabletags: id = pid + '$tagview.0' entries.insert(0, rcldirentry(id, pid, ">> Tag View")) return entries
def _tagsbrowse(self, pid, qpath, flag, path=''): uplog("tagsbrowse. pid %s qpath %s" % (pid, qpath)) # Walk the qpath, which was generated from the objid and # defines what tracks are selected and what we want to # display. E.g =Artist$21$=Date would display all distinct # dates for tracks by Artist #21. =Artist$21$=Date$48 the data # for date 48 (the numbers are indexes into the aux tables) qlen = len(qpath) selwhat = '' if path: selwhere = ' WHERE tracks.path LIKE ? ' values = [ path + '%', ] else: selwhere = '' values = [] i = 0 while i < qlen: elt = qpath[i] # Detect the special values: albums items etc. here. Their # presence changes how we process the rest (showing tracks and # albums and not dealing with other tags any more) if elt == 'albums': return self._tagsbrowsealbums(pid, qpath, i, selwhere, values) elif elt == 'items': return self._tagsbrowseitems(pid, qpath, i, selwhere, values) # '=colname'. Set the current column name, which will be used # in different ways depending if this is the last element or # not. if elt.startswith('='): col = g_tagtotable[elt[1:]] selwhere = selwhere + ' AND ' if selwhere else ' WHERE ' if i == qlen - 1: # We can only get here if the qpath ends with '=colname' # (otherwise the else branch below fetches the 2 last # elements and breaks the loop). We want to fetch all # unique values for the column inside the current selection. # e.g. artist.artist_id, artist.value selwhat = '%s.%s, %s.value' % (col, _clid(col), col) # e.g. tracks.artist_id = artist.artist_id selwhere += 'tracks.%s = %s.%s' % (_clid(col), col, _clid(col)) else: # Look at the value specified for the =xx column. The # selwhat value is only used as a flag selwhat = 'tracks.docidx' selwhere += 'tracks.%s = ?' % _clid(col) i += 1 values.append(int(qpath[i])) i += 1 entries = [] if selwhat == 'tracks.docidx': # We are displaying content for a given value of a given tag docids = self._docidsforsel(selwhere, values) albids = self._subtreealbums(selwhere, values) subqs = self._subtreetags(selwhere, values) displaytracks = True if len(albids) > 1: id = pid + '$albums' label = '%d albums' entries.append(rcldirentry(id, pid, label % len(albids))) elif len(albids) == 1 and not subqs: # Only display '>> Complete album' if not all tracks # already there. If all tracks are there, we display # the album entry (with the same id value: show album) albid = albids[0] tlist = self._trackentriesforalbum(albid, pid) id = pid + '$albums$' + str(albid) + '$showca' if len(tlist) != len(docids): entries.append(rcldirentry(id, pid, '>> Complete Album')) else: displaytracks = False el = self._direntriesforalbums( pid, "WHERE album_id = %s" % albid) el[0]['id'] = id entries.append(el[0]) if subqs: id = pid + '$items' label = '%d items' entries.append(rcldirentry(id, pid, label % len(docids))) for tt in subqs: id = pid + '$=' + tt entries.append(rcldirentry(id, pid, g_tagdisplaytag[tt])) elif displaytracks: rcldocs = uprclinit.g_trees['folders'].rcldocs() for docidx in docids: id = pid + '$*i' + str(docidx) entries.append( rcldoctoentry(id, pid, self._httphp, self._pprefix, rcldocs[docidx])) entries = sorted(entries, key=cmpentries) else: # SELECT col.col_id, col.value FROM tracks, col # WHERE tracks.col_id = col.col_id # GROUP BY tracks.col_id # ORDER BY col.value stmt = "SELECT " + selwhat + " FROM tracks, " + col + \ selwhere + \ " GROUP BY tracks." + _clid(col) + \ " ORDER BY value" uplog("tagsbrowse: executing <%s> values %s" % (stmt, values)) c = self._conn.cursor() c.execute(stmt, values) for r in c: id = pid + '$' + str(r[0]) entries.append(rcldirentry(id, pid, r[1])) return entries