Beispiel #1
0
 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)
Beispiel #2
0
 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)
Beispiel #3
0
    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())
Beispiel #4
0
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)
Beispiel #5
0
    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)
Beispiel #6
0
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)
Beispiel #7
0
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
Beispiel #8
0
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)
Beispiel #9
0
    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
Beispiel #10
0
    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