
""" regexp.py [options] regexp tracks*

regexp.py iterates over the tracks files supplied, applies the regular
expression to the file name, and extracts mp3 information as a result.

Your regular expression must follow python syntax, and should result in the
following groups:

    artist
    album
    title
    tracknumber
    year

An example might be: "(?P<artist>.*) - (?P<album>.*) - (?P<tracknumber>[0-9]*) - (?P<title>.*).mp3"
This would match something like
"Elvis Costello - My Aim is True - 01 - Working Week.mp3".

If you include --full-path, the regular expression will be matched
against the full path to the song; otherwise, it is only matched
against the file name.

All regular expressions are always matched from the start of the
string.  If you have some junk at the beginning you want to ignore,
you can always prefix the regular expression with".*?".

    -q          quiet mode (no progress updates)
    -d          debug regular expressions
    --full-path applies the regular expression to the full path, including
                any directories, rather than just the base path
    --dry-run   don't actually do anything
    -i file     also processes files taken from 'file'; this must have one
                filename per line, with no escaping
"""


import sys, getopt, re, os, os.path
import ID3

def usage (msg):
    print >> sys.stderr, __doc__
    print >> sys.stderr, msg
    sys.exit (1)
    pass

def main (arglist):

    try:
        opts,args = getopt.getopt (arglist[1:],
                                   "hqdi:",
                                   ["dry-run","full-path"])

        verbose = 1
        debugmode = 0
        dryrun = 0
        fullpath = 0
        filestoprocess = args[1:]
        
        for opt, optarg in opts:
            if opt == "-d": debugmode = 1
            if opt == "-q": quiet = 0
            elif opt == "--dry-run": dryrun = 1
            elif opt == "--full-path": fullpath = 1
            elif opt == "-h": usage ("")
            elif opt == "-i":
                filestoprocess += [x for x in
                                   open (optarg,'r').read().split ('\n')
                                   if x]
            pass

        if len (args) < 1: usage ("")
    except getopt.GetoptError, e:
        usage (str (e))
        return

    # Compile the regular expression.
    regexptxt = args[0]
    regexp = re.compile (regexptxt)

    # Make a dictionary with each possible key we expect to find
    # in the regexp
    keys = []
    for key in ('artist', 'album', 'title', 'tracknumber', 'year'):
        if ("?P<%s>" % key) in regexptxt:
            keys.append (key)

    sys.stderr.write ('Expecting %s\n' % ",".join (keys))

    counter = 0

    for filepath in filestoprocess:

        if fullpath: matchpath = os.path.realpath (filepath)
        else: matchpath = os.path.split (filepath)[1]

        if verbose:
            counter += 1
            if (counter % 10) == 0:
                percentage = 100 * counter // len (args) - 1
                sys.stdout.write ("%02d%% complete.\r" % percentage)
                sys.stdout.flush ()

        mo = regexp.match (matchpath)
        
        if not mo:
            sys.stderr.write ("Regexp did not match: '%s'\n" % matchpath)
            continue

        id3info = ID3.ID3 (filepath)
        
        for key in keys:
            if not mo.group (key):
                sys.stderr.write ("No %s found for: '%s'\n"
                                  % (key, matchpath))
                continue
            txt = mo.group (key)
            if not dryrun: id3info [ key.upper() ] = txt
            if debugmode:
                sys.stderr.write ("%s for '%s' is '%s'\n"
                                  % (key, matchpath, txt))

        # write changes back out (if any)
        id3info.write ()
        pass

    if verbose: sys.stdout.write ('100% processed.\n')
    return

if __name__ == "__main__":
    main (sys.argv)
    pass
