Managing mp3 Files with eyeD3

Oct 12, 2011 Python

I'm more than a little bit OCD when it comes to managing my music collection. It's huge, and I like to keep the files named with a certain pattern so that when I look at the archive I can see, at a glance, what I have without having to open some clumsy client to get a look at the metadata.

I also manage a music site that involves working with audio files on a daily basis, and this renaming scheme just makes them easier to manage. Whenever I have a new batch of purchases or downloads, I run this script against them.

This script uses a module called EyeD3 - possibly not the shiniest Python package for managing mp3 metadata, but it's simple and it works.


import os, sys, fileinput, string, datetime
import eyeD3

sourcefolder = "/sourcefolder/"

def processfile(sourcefile):
    """
    Rename an mp3 file using the artist and title in its metadata
    """
    tag = eyeD3.Tag()
    tag.link(sourcefile)

    artist = tag.getArtist()
    title = tag.getTitle()

    stripchars = [" ", ",", "(", ")", ".", "'", "_", "/"]
    for char in stripchars:
        artist = artist.replace(char, "")
        title = title.replace(char, "")
    artist = artist.replace("&", "and")
    title = title.replace("&", "and")

    # I snuck this in for cases where I want to give the file a 
    # specific date; otherwise it defaults to the current date.
    try:
        today = str(sys.argv[1])
    except IndexError:
        today = str(datetime.date.today()).replace("-", "")

    newfile = ('%s/%s_%s_%s.mp3') %(sourcefolder,today,artist,title)
    os.rename(sourcefile, newfile)

    return newfile

def identify():
    """
    Do a non-recursive walk of the source folder
    to identify files with the .mp3 extension
    """
    files = []
    for folder in os.listdir(sourcefolder):
        fullpathname = os.path.join(sourcefolder, folder)
        if os.path.isfile(fullpathname):
            x = len(sourcefolder)
            name = fullpathname[x+1:]
            if name[-3:] == 'mp3':
                print "Process this file: " + name
                files.append(fullpathname)
            else:
                print "Ignore this file: " + name
    return files

def main():
    files = identify()
    for file in files:
        p = processfile(file)
        print p

if __name__ == "__main__":
    main()