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
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
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
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