#!/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