Exemplo n.º 1
0
def tagfiles(albumdir, album, options):
    '''Rename and tag files using freedb information for
       the specified album.'''

    # XXX: doesn't really belong here
    missing = album.validate()
    if len(missing) > 0:
        if options.strict:
            amiss = ",".join(missing)
            raise TagIncompleteWarning(amiss)
        else:
            for miss in missing:
                print TagIncompleteWarning(miss)
            print
    album.ignoreMissing(True)

    localalbum = LocalAlbumInfo(albumdir)
    filelist = localalbum.getfilelist(options.sysencoding)
    
    a = len(album.tracks)
    b = len(filelist)
    if a != b:
        raise NamingMuseError('there are %d files, but %d metainfo tracks' % (b,a))

    namebinder = get_namebinder(options, filelist)
    
    tracks = namebinder(filelist, album, options.sysencoding)
    if not sortedcmp(tracks, album.tracks):
        options.dryrun = True
        print NamingMuseError("binding was not exact, forcing dry run")

    print "Tagging album: %s, %s - %s, %s.\n" % \
          (album.year, album.artist, album.title, album.genre)

    # Process files
    renamealbum = True

    renameTempDir = FilePath(albumdir, 'rename-tmp')

    if renameTempDir.exists():
        raise NamingMuseError('%s exists!' % renameTempDir)

    renameTempDir.mkdir()

    # a list of tuples (from, to)
    # we use temporary renames to avoid filename collision on filename swaps
    # this holds the list of final renames to be executed
    finalrenames = []

    # a list of tuples (from, to)
    # used to rollback renames in case of error
    rollback = []

    renamesign = "->"
    rollbacksign = '<-'
    if options.tagonly:
        renamesign = "-tag->"
    if options.dryrun:
        renamesign = "-dry->" 

    try:
        for i in range(0, len(filelist)):
            fpath = filelist[i]
            # XXX: move bug check to freedbalbuminfo parser

            #if album.isVarious:
            #    if not "/" in title and "-" in title:
            #        # workaround: this is a bug in the freedb entry
            #        # (according to submission guidelines)
            #        trackartist, title = title.split("-")
            #        print NamingMuseWarning("bugged database entry with - instead of /")
            #    else:
            #        trackartist, title = title.split("/")
            #    trackartist, title = trackartist.strip(), title.strip()
            #else:
            #    trackartist = albumartist
            track = tracks[i]

            tofile = policy.genfilename(filelist[i], album, track)
            tofile = tofile.encode(options.sysencoding)
            totmpfile = FilePath(renameTempDir, tofile, encoding=options.sysencoding)
            tofinalfile = FilePath(albumdir, tofile, encoding=options.sysencoding)
        
            # Tag and rename file
            print fpath.getName()
            print "\t", colorize(renamesign), tofinalfile.getName()

            if not options.dryrun:

                # Tag file

                #preserve stat
                fd = tempfile.NamedTemporaryFile()
                tmpfilename = fd.name
                shutil.copystat(str(fpath), tmpfilename)
                
                # tag the file
                tagfile(fpath, album, track, options)

                # restore filestat
                shutil.copystat(tmpfilename, str(fpath))

                # deletes tempfile
                fd.close()

                # Rename file to temporary name
                
                if not options.tagonly:
                    if totmpfile.exists():
                        raise NamingMuseError('tried to rename file over existing: %s' % str(totmpfile))
                    if fpath != totmpfile:
                        fpath.rename(totmpfile)
                        rollback.append((fpath, totmpfile))
                        finalrenames.append((totmpfile, tofinalfile))

    except Exception, e:
        print
        print colorize('Error: an error occurred. rolling back %d renames.' % len(rollback))
        for frompath, topath in reversed(rollback):
            print frompath.getName()
            print "\t", colorize(rollbacksign), topath.getName()
            topath.rename(frompath)
        renameTempDir.rmdir()
        raise
Exemplo n.º 2
0
def tagfiles(albumdir, album, options):
    '''Rename and tag files using freedb information for
       the specified album.'''

    # XXX: doesn't really belong here
    missing = album.validate()
    if len(missing) > 0:
        if options.strict:
            amiss = ",".join(missing)
            raise TagIncompleteWarning(amiss)
        else:
            for miss in missing:
                print TagIncompleteWarning(miss)
            print
    album.ignoreMissing(True)

    localalbum = LocalAlbumInfo(albumdir)
    filelist = localalbum.getfilelist(options.sysencoding)

    a = len(album.tracks)
    b = len(filelist)
    if a != b:
        raise NamingMuseError('there are %d files, but %d metainfo tracks' %
                              (b, a))

    namebinder = get_namebinder(options, filelist)

    tracks = namebinder(filelist, album, options.sysencoding)
    if not sortedcmp(tracks, album.tracks):
        options.dryrun = True
        print NamingMuseError("binding was not exact, forcing dry run")

    print "Tagging album: %s, %s - %s, %s.\n" % \
          (album.year, album.artist, album.title, album.genre)

    # Process files
    renamealbum = True

    renameTempDir = FilePath(albumdir, 'rename-tmp')

    if renameTempDir.exists():
        raise NamingMuseError('%s exists!' % renameTempDir)

    renameTempDir.mkdir()

    # a list of tuples (from, to)
    # we use temporary renames to avoid filename collision on filename swaps
    # this holds the list of final renames to be executed
    finalrenames = []

    # a list of tuples (from, to)
    # used to rollback renames in case of error
    rollback = []

    renamesign = "->"
    rollbacksign = '<-'
    if options.tagonly:
        renamesign = "-tag->"
    if options.dryrun:
        renamesign = "-dry->"

    try:
        for i in range(0, len(filelist)):
            fpath = filelist[i]
            # XXX: move bug check to freedbalbuminfo parser

            #if album.isVarious:
            #    if not "/" in title and "-" in title:
            #        # workaround: this is a bug in the freedb entry
            #        # (according to submission guidelines)
            #        trackartist, title = title.split("-")
            #        print NamingMuseWarning("bugged database entry with - instead of /")
            #    else:
            #        trackartist, title = title.split("/")
            #    trackartist, title = trackartist.strip(), title.strip()
            #else:
            #    trackartist = albumartist
            track = tracks[i]

            tofile = policy.genfilename(filelist[i], album, track)
            tofile = tofile.encode(options.sysencoding)
            totmpfile = FilePath(renameTempDir,
                                 tofile,
                                 encoding=options.sysencoding)
            tofinalfile = FilePath(albumdir,
                                   tofile,
                                   encoding=options.sysencoding)

            # Tag and rename file
            print fpath.getName()
            print "\t", colorize(renamesign), tofinalfile.getName()

            if not options.dryrun:

                # Tag file

                #preserve stat
                fd = tempfile.NamedTemporaryFile()
                tmpfilename = fd.name
                shutil.copystat(str(fpath), tmpfilename)

                # tag the file
                tagfile(fpath, album, track, options)

                # restore filestat
                shutil.copystat(tmpfilename, str(fpath))

                # deletes tempfile
                fd.close()

                # Rename file to temporary name

                if not options.tagonly:
                    if totmpfile.exists():
                        raise NamingMuseError(
                            'tried to rename file over existing: %s' %
                            str(totmpfile))
                    if fpath != totmpfile:
                        fpath.rename(totmpfile)
                        rollback.append((fpath, totmpfile))
                        finalrenames.append((totmpfile, tofinalfile))

    except Exception, e:
        print
        print colorize('Error: an error occurred. rolling back %d renames.' %
                       len(rollback))
        for frompath, topath in reversed(rollback):
            print frompath.getName()
            print "\t", colorize(rollbacksign), topath.getName()
            topath.rename(frompath)
        renameTempDir.rmdir()
        raise
Exemplo n.º 3
0
        renamesign = "-dry->"
    if not (options.dryrun or options.tagonly) and renamealbum \
        and str(albumdir) != str(newalbumdir):
        if newalbumdir.exists():
            raise NamingMuseWarning("Directory already exists (dup album?): " +
                  str(newalbumdir))
        try:
            albumdir.rename(newalbumdir)
        except OSError, err:
            raise NamingMuseWarning(str(err))

    # Print rename message
    print "\n", albumdir.getName()
    print "\t", colorize(renamesign),
    if needartistdirmove:
        print FilePath(album.artist.encode(options.sysencoding), newalbumdir.getName())
    else:
        print newalbumdir.getName()

def tagfile(fpath, album, track, options):
    """ Tag the file with metadata """

    if not hasattr(tagpy.FileRef, 'create'):
        print 'warning: using generic tagging. upgrade to tagpy 0.94.5 or later.'
        fileref = tagpy.FileRef(str(fpath))
        tag = fileref.tag()
        tag.year = album.year
        tag.genre = album.genre
        tag.artist = track.artist
        tag.album = album.title
        tag.title = track.title
Exemplo n.º 4
0
    if not (options.dryrun or options.tagonly) and renamealbum \
        and str(albumdir) != str(newalbumdir):
        if newalbumdir.exists():
            raise NamingMuseWarning("Directory already exists (dup album?): " +
                                    str(newalbumdir))
        try:
            albumdir.rename(newalbumdir)
        except OSError, err:
            raise NamingMuseWarning(str(err))

    # Print rename message
    print "\n", albumdir.getName()
    print "\t", colorize(renamesign),
    if needartistdirmove:
        print FilePath(album.artist.encode(options.sysencoding),
                       newalbumdir.getName())
    else:
        print newalbumdir.getName()


def tagfile(fpath, album, track, options):
    """ Tag the file with metadata """

    if not hasattr(tagpy.FileRef, 'create'):
        print 'warning: using generic tagging. upgrade to tagpy 0.94.5 or later.'
        fileref = tagpy.FileRef(str(fpath))
        tag = fileref.tag()
        tag.year = album.year
        tag.genre = album.genre
        tag.artist = track.artist
        tag.album = album.title