#!/usr/bin/env python
#coding: utf-8

######################################################################
##
## This program is called "Zine tagger", it's a seed to what I hope
## might become in the future a module to a larger prgoram I am
## developing. (The name of the file you are reading is probably
## "nagtag", but that doesn't mean the program is really called like
## this!)
##
## This programs performs the basic tasks I used to use lltag
## for. First you can make a textual query to tracktype.org looking
## for an album. (Tracktype is a modern-day "cddb" website that
## accepts textual queries...). The query answers are listed with an
## index number at the left. If you type the number of a record, it
## prints the track names and other data. The script uses urllib and
## minidom to fetch and parse the data.
##
## When you are satisfied with a certain album from the DB, you just
## make sure it was the last one you printed, and say 'OK'. The progam
## then moves to a second stage where it prints the names of the files
## you provided as arguments when you called the program, together
## with each track name taken from the DB.
##
## At this moment you should check if each file name corresponds to
## the track name we got. At this moment you should check out for
## example if there is a song missing in your files, or if they are in
## incorrect order, or if there are extra songs either in your files
## or in the tracktype record. Extra tracks at the end of the list in
## both cases do not matter, because we will tag the files until
## either of the lists are over, and the extra ones are _ignored_. The
## idea of the program is really just tagging albuns that have been
## correctly downloaded and that are correctly reistered in
## tracktype.org. Any problems you should find at this stage should
## unfortunately be taken care of outside of this script.
##
## Once you checked everything, say 'OK' again, and the tags will be
## recorded to the files using mutagen.
##
## I hope you can find this script useful. Any coments or advices,
## please write me at Nicolau Werneck <[email protected]>.
##
## Plase, buy stuff made by your favorite artists to support their
## work! And give some money to free software developers too! Dumb
## winners use smart drugs. Plant a tree today. Salve a Mata
## Atl�ntica. Use camisinha.
##
##    ++nicolau
##
######################################################################


import urllib
import sys
import string
import re

from xml.dom import minidom

from mutagen.mp3 import MP3
from mutagen.easyid3 import EasyID3
import mutagen.id3

def getChildText(root, tag):
   child = root.getElementsByTagName(tag)[0].childNodes
   if len(child)>0:
       return child[0].nodeValue
   else:
       return ''


def parse_cddb(root):
   disc = root.getElementsByTagName("disc")[0]
   artist, title, year = [getChildText(root, k) for k in ['artist', 'title', 'year']]
   faixas_xml = root.getElementsByTagName("track")
   faixas = [(int(getChildText(f, 'number')), getChildText(f, 'title')) for f in faixas_xml]
   return (artist, title, year, faixas)



def tracktype_search(aaa):
   cddb={'hello':'lltag',
         'proto':4,
         'cmd':'cddb album '+aaa}

   params = urllib.urlencode(cddb)
   f = urllib.urlopen("http://tracktype.org/~cddb/cddb.cgi", params)
   ans = f.readlines()

   return [tuple(string.strip(k).split(' ', 3)) for k in ans[1:-1]]



def tracktype_xml(cat, code):
   print "%s/%s"%(cat, code)

   f = urllib.urlopen("http://tracktype.org/xml/%s/%s"%(cat,code))
   return minidom.parse(f)


if __name__ =='__main__':

   print "Greetigs. This is the Zine tagger. Press the Enter key on an empty line to print the Commands list."
   search_results=[]
   while True:
       aaa = string.strip(sys.stdin.readline())
       if re.match(r'^$', aaa):
           print """
Zine tagger commands:
l - lists the results of the last query
s<string> - searches for <string> on tracktype.org
\d+ - selects album with \d+ index number from query and prints it tracks
OK - moves on with selected album to second stage
- blank line prints this commands list.
"""
       if re.match(r'^l$', aaa):
           if search_results==[]:
               print "No search results"
               continue
           z=0
           for data in search_results:
               print "[%02d] %s"%(z, data[3])
               z+=1

       if re.match(r'^\d+$', aaa):
           cat, code=search_results[int(aaa)][0:2]
           xml_stuff=tracktype_xml(cat, code)
           artist, title, year, tracks = parse_cddb(xml_stuff)
           print "Artist: %s\nAlbum: %s (%s)\n"%(artist, title, year)
           for k in tracks:
               print k[0], k[1]

       if re.match(r'^s.+$', aaa):
           search_results = tracktype_search(aaa[1:])
           z=0
           for data in search_results:
               print "[%02d] %s"%(z, data[3])
               z+=1

       if re.match(r'^OK+$', aaa):
           if tracks ==[]:
               print "NO ALBUM LOADED"
           else:
               print "SELECTED"
               break


   files = sys.argv[1:]

   if len(files) > len(tracks):
       print "ATTENTION: more files than tracks!"
   if len(files) < len(tracks):
       print "ATTENTION: more tracks than files!"

   numT = min(len(files), len(tracks))

   while True:
       aaa = string.strip(sys.stdin.readline())
       if re.match(r'^$', aaa):
           print """
Zine tagger second stage commands:
l - lists current file/tags association.
OK - records the tags on the files.
- blank line prints this commands list.
"""
       if re.match(r'^l$', aaa):
           print "Artist: %s\nTitle: %s\nYear:%s\n"%(artist, title, year)
           for i in range(numT):
               k = tracks[i]
               print "FILE: ", files[i]
               print "[%02d]%s"%(k[0], k[1])
               print "%s/%s(%s)"%(artist, title, year)
               print

       if re.match(r'^OK$', aaa):
           for i in range(numT):
               print "RECORDING FILE: ", files[i]
               k = tracks[i]
               print "[%02d]%s"%(k[0], k[1])
               print "%s/%s(%s)"%(artist, title, year)

               audio = EasyID3(files[i])
               audio['artist']=artist
               audio['album']=title
               audio['date']=year
               audio['tracknumber']="%d"%k[0]
               audio['title']=k[1]
               audio.save()
               #audio.pprint()

               print
           break