PluginInterface.require_command("id3info")
from mx import DateTime

class MPEGAudioFile(PluginInterface.File):

	date = None
	sample_rate = None
	track_number = None
	bitrate = None
	title = None
	album = None
	genre = None
	artist = None
	# fixme implement comment and length extraction
# 	comment = None
# 	length = None

	MPEGAudioFile_catalogable = [
		"date","sample_rate","track_number","bitrate",
		"title","album","genre","artist","comment" ]

	def __init__(self,filename,mimetype,volume):
		PluginInterface.File.__init__(self,filename,mimetype,volume)
		metadata = id3info_extract(filename)
		for key,value in metadata.iteritems():
			if key == "TYER":
				self.date = DateTime.DateTime(value,1,1)
			elif key == "frequency":
				self.sample_rate = value
			elif key == "TRCK":
				self.track_number = value
			elif key == "TIT2":
				self.title = value
			elif key == "TALB":
				self.album =value
			elif key == "bitrate":
				self.bitrate = value
			elif key == "TCON":
				self.genre = value
			elif key == "COMM":
				self.comment = value
			elif key == "TPE1":
				self.artist = value

	def __str__(self):
		return "MP3 %s (%s - %s - %s)"%(self.get_filename(),self.artist,self.album,self.title)

def get_factory():
	return MPEGAudioFile

def get_mimetypes():
	return ["audio/mpeg","audio/x-mp3"]

def id3info_extract(filename):
	import commands
	output = commands.getoutput("LANG=en_US.iso-8859-1 id3info %s"%PluginInterface.shell_quote(filename))
	output = PluginInterface.transcode_to_platform_encoding(output,"iso-8859-1")
	lines = output.splitlines()
	tags = [ a[4:] for a in lines if a.startswith("===") ]
	t = {}
	for tag in tags:
		splitted = tag.split(":",1)
		key,value = splitted[0],splitted[1]
		key = key.strip().split(" ",1)[0].strip()
		value = value.strip()
		t[key] = value
	mp3info = [ a for a in lines if a.startswith("Bitrate") or a.startswith("Frequency") ]
	for a in mp3info:
		splitted = a.split(":",1)
		key,value = splitted[0],splitted[1]
		value = value.strip()
		if key == "Bitrate": t["bitrate"] = value
		if key == "Frequency": t["frequency"] = value
	
	key = "TYER"
	if t.has_key(key):
		try: t[key] = int(t[key])
		except:
			PluginInterface.log("id3lib-audio-mpeg").warning("Error decoding year (%s)",t[key],exc_info=True)
			del(t[key])
	key = "TRCK"
	if t.has_key(key):
		try: t[key] = int(t[key].split("/",1)[0])
		except:
			PluginInterface.log("id3lib-audio-mpeg").warning("Error decoding track (%s)",t[key],exc_info=True)
			del(t[key])
	key = "COMM"
	if t.has_key(key):
		if t[key].startswith("(ID3v1 Comment)["): t[key] = t[key][22:]
	key = "bitrate"
	if t.has_key(key):
		try: t[key] = int(t[key][:-4])*1000
		except: 
			PluginInterface.log("id3lib-audio-mpeg").warning("Error decoding bitrate (%s)",t[key],exc_info=True)
			del(t[key])
	key = "frequency"
	if t.has_key(key):
		try:
			val = int(t[key][:-3])
			if val == 44: t[key] = 44100
			elif val == 48: t[key] = 48000
			elif val == 24: t[key] = 24000
			elif val == 22: t[key] = 22050
			elif val == 11: t[key] = 11025
			elif val == 8: t[key] = 8000
			else: raise Exception, "Unknown bitrate value %s"%val
		except: 
			PluginInterface.log("id3lib-audio-mpeg").warning("Error decoding frequency (%s)",t[key],exc_info=True)
			del(t[key])
	
	def get_genre_from_int(genrenr):  # inner function with the tables
		assert type(genrenr) is int
		if not hasattr(get_genre_from_int,"genres"): get_genre_from_int.genres = id3_builtin_genres
		if get_genre_from_int.genres.has_key(genrenr): return get_genre_from_int.genres[genrenr]
	
	key = "TCON"
	if t.has_key(key):
		try:
			if t[key].startswith("(") and t[key].endswith(")"):
				genrenr = int (t[key][1:-1])
				genrename = get_genre_from_int(genrenr)
				if genrename is not None: t[key] = genrename
				else:
					PluginInterface.log("id3lib-audio-mpeg").warning("Error decoding genre (%s)",t[key],exc_info=True)
					del(t[key])
		except:
			PluginInterface.log("id3lib-audio-mpeg").warning("Error decoding genre (%s)",t[key],exc_info=True)
			del(t[key])
			
	return t

id3_builtin_genres = {
0 : "Blues", 
1 : "Classic Rock", 
2 : "Country", 
3 : "Dance", 
4 : "Disco", 
5 : "Funk", 
6 : "Grunge", 
7 : "Hip-Hop", 
8 : "Jazz", 
9 : "Metal", 
10 : "New Age", 
11 : "Oldies", 
12 : "Other", 
13 : "Pop", 
14 : "R&B", 
15 : "Rap", 
16 : "Reggae", 
17 : "Rock", 
18 : "Techno", 
19 : "Industrial", 
20 : "Alternative", 
21 : "Ska", 
22 : "Death Metal", 
23 : "Pranks", 
24 : "Soundtrack", 
25 : "Euro-Techno", 
26 : "Ambient", 
27 : "Trip-Hop", 
28 : "Vocal", 
29 : "Jazz+Funk", 
30 : "Fusion", 
31 : "Trance", 
32 : "Classical", 
33 : "Instrumental", 
34 : "Acid", 
35 : "House", 
36 : "Game", 
37 : "Sound Clip", 
38 : "Gospel", 
39 : "Noise", 
40 : "AlternRock", 
41 : "Bass", 
42 : "Soul", 
43 : "Punk", 
44 : "Space", 
45 : "Meditative", 
46 : "Instrumental Pop", 
47 : "Instrumental Rock", 
48 : "Ethnic", 
49 : "Gothic", 
50 : "Darkwave", 
51 : "Techno-Industrial", 
52 : "Electronic", 
53 : "Pop-Folk", 
54 : "Eurodance", 
55 : "Dream", 
56 : "Southern Rock", 
57 : "Comedy", 
58 : "Cult", 
59 : "Gangsta", 
60 : "Top 40", 
61 : "Christian Rap", 
62 : "Pop/Funk", 
63 : "Jungle", 
64 : "Native American", 
65 : "Cabaret", 
66 : "New Wave", 
67 : "Psychadelic", 
68 : "Rave", 
69 : "Showtunes", 
70 : "Trailer", 
71 : "Lo-Fi", 
72 : "Tribal", 
73 : "Acid Punk", 
74 : "Acid Jazz", 
75 : "Polka", 
76 : "Retro", 
77 : "Musical", 
78 : "Rock & Roll", 
79 : "Hard Rock", 
80 : "Folk", 
81 : "Folk-Rock", 
82 : "National Folk", 
83 : "Swing", 
84 : "Fast Fusion", 
85 : "Bebob", 
86 : "Latin", 
87 : "Revival", 
88 : "Celtic", 
89 : "Bluegrass", 
90 : "Avantgarde", 
91 : "Gothic Rock", 
92 : "Progressive Rock", 
93 : "Psychedelic Rock", 
94 : "Symphonic Rock", 
95 : "Slow Rock", 
96 : "Big Band", 
97 : "Chorus", 
98 : "Easy Listening", 
99 : "Acoustic", 
100 : "Humour", 
101 : "Speech", 
102 : "Chanson", 
103 : "Opera", 
104 : "Chamber Music", 
105 : "Sonata", 
106 : "Symphony", 
107 : "Booty Bass", 
108 : "Primus", 
109 : "Porn Groove", 
110 : "Satire", 
111 : "Slow Jam", 
112 : "Club", 
113 : "Tango", 
114 : "Samba", 
115 : "Folklore", 
116 : "Ballad", 
117 : "Power Ballad", 
118 : "Rhythmic Soul", 
119 : "Freestyle", 
120 : "Duet", 
121 : "Punk Rock", 
122 : "Drum Solo", 
123 : "A capella", 
124 : "Euro-House", 
125 : "Dance Hall", 
126 : "Goa", 
127 : "Drum & Bass", 
128 : "Club-House", 
129 : "Hardcore", 
130 : "Terror", 
131 : "Indie", 
132 : "Britpop", 
133 : "Negerpunk", 
134 : "Polsk Punk", 
135 : "Beat", 
136 : "Christian Gangsta Rap", 
137 : "Heavy Metal", 
138 : "Black Metal", 
139 : "Crossover", 
140 : "Contemporary Christian", 
141 : "Christian Rock ", 
142 : "Merengue", 
143 : "Salsa", 
144 : "Trash Metal", 
145 : "Anime", 
146 : "JPop", 
147 : "Synthpop",
}
