コード例 #1
0
ファイル: mutagenext.py プロジェクト: Unhelpful/audiomangler
def _format(self, filename=None, base=None, preadd=(), postadd=()):
    filename, base = from_config('filename', 'base')
    meta = NormMetaData(preadd)
    meta.update(self.meta.flat())
    meta.update(postadd)
    filename = FileFormat(filename)
    base = os.path.abspath(base)
    return os.path.join(base, filename.evaluate(meta))
コード例 #2
0
ファイル: scanner.py プロジェクト: Unhelpful/audiomangler
def scan(items, groupby = None, sortby = None, trackid = None):
    groupbytxt, sortbytxt, trackidtxt = from_config('groupby', 'sortby', 'trackid')
    groupby = Expr(groupby or groupbytxt)
    sortby = Expr(sortby or sortbytxt)
    trackid = Expr(trackid or trackidtxt)
    homedir = os.getenv('HOME')
    if homedir is not None:
        cachefile = os.path.join(homedir, '.audiomangler')
        try:
            os.mkdir(cachefile)
        except OSError:
            pass
        cachefile = os.path.join(cachefile, 'cache')
    else:
        cachefile = 'audiomangler.cache'
    dircache = {}
    if shelve:
        try:
            dircache = shelve.open(cachefile, protocol=2)
        except Exception:
            pass
    if dircache.get('//version', None) != db_version:
        dircache.clear()
        dircache['//version'] = db_version
    if isinstance(items, basestring):
        items = (items, )
    tracks = []
    scanned = set()
    newdircache = {}
    items = map(os.path.abspath, items)
    for item in items:
        if item in scanned:
            continue
        t = scan_track(item)
        if t is not None:
            tracks.append(t)
            scanned.add(item)
        else:
            dirs = [item]
            while dirs:
                path = dirs.pop(0)
                try:
                    dst = os.stat(path)
                except OSError:
                    print "unable to stat dir %s" % path
                    continue
                cached = dircache.get(path, None)
                if cached and cached['key'] == (dst.st_ino, dst.st_mtime):
                    newcached = cached
                    newtracks = []
                    newfiles = []
                    for track in cached['tracks']:
                        try:
                            fst = os.stat(track['path'])
                        except Exception:
                            continue
                        if track['key'] == (fst.st_ino, fst.st_size, fst.st_mtime):
                            newtracks.append(track)
                            t = track['obj']
                            t._meta_cache = (False, False)
                            t.relpath = t.filename.replace(item, '', 1).lstrip('/')
                            t.reldir = t.relpath.rsplit('/', 1)
                            if len(t.reldir) > 1:
                                t.reldir = t.reldir[0]
                            else:
                                t.reldir = ''
                            tracks.append(t)
                        else:
                            t = scan_track(track['path'])
                            if t is not None:
                                tracks.append(t)
                                newtracks.append({'path':track['path'], 'obj':t, 'key':(fst.st_ino, fst.st_size, fst.st_mtime)})
                    for file_ in cached['files']:
                        try:
                            fst = os.stat(file_['path'])
                        except Exception:
                            continue
                        if file_['key'] == (fst.st_ino, fst.st_size, fst.st_mtime):
                            newfiles.append(file_)
                        else:
                            t = scan_track(file_['path'])
                            if t is not None:
                                tracks.append(t)
                                newtracks.append({'path':file_['path'], 'obj':t, 'key':(fst.st_ino, fst.st_size, fst.st_mtime)})
                            else:
                                newfiles.append({'path':file_['path'], 'key':(fst.st_ino, fst.st_size, fst.st_mtime)})
                    newcached['tracks'] = newtracks
                    newcached['files'] = newfiles
                else:
                    newcached = {'tracks':[], 'dirs':[], 'files':[]}
                    newcached['key'] = (dst.st_ino, dst.st_mtime)
                    try:
                        paths = (os.path.join(path, f) for f in sorted(os.listdir(path)))
                    except OSError:
                        continue
                    for filename in paths:
                        if filename in scanned:
                            continue
                        else:
                            scanned.add(filename)
                        if os.path.isdir(filename):
                            newcached['dirs'].append(filename)
                        elif os.path.isfile(filename):
                            try:
                                fst = os.stat(filename)
                            except Exception:
                                continue
                            t = scan_track(filename)
                            if t is not None:
                                tracks.append(t)
                                newcached['tracks'].append({'path':filename, 'obj':t, 'key':(fst.st_ino, fst.st_size, fst.st_mtime)})
                            else:
                                newcached['files'].append({'path':filename, 'key':(fst.st_ino, fst.st_size, fst.st_mtime)})
                        else:
                            continue
                dirs.extend(newcached['dirs'])
                newdircache[path] = newcached
    for item in items:
        for key in dircache.keys():
            if key.startswith(item):
                del dircache[key]
    dircache.update(newdircache)
    if hasattr(dircache, 'close'):
        dircache.close()
    albums = {}
    dirs = {}
    trackids = {}
    for t in tracks:
        t.sortkey = t.meta.evaluate(sortby)
        albums.setdefault(t.meta.evaluate(groupby), []).append(t)
        dirs.setdefault(os.path.split(t.filename)[0], []).append(t)
        t.tid = t.meta.evaluate(trackid)
        if t.tid in trackids:
            print "trackid collision"
            print t.filename
            print trackids[t.tid].filename
        trackids[t.tid] = t
    #trying not to evaluate sort expressions for every comparison. don't modify
    #metadata during sort. ;)
    for v in albums.itervalues():
        v.sort(lambda x, y: cmp(x.sortkey, y.sortkey))
    for v in dirs.itervalues():
        v.sort(lambda x, y: cmp(x.sortkey, y.sortkey))
    return albums, dirs, trackids