import mutagen import mutagen.id3 from mutagen.easyid3 import EasyID3 def popms(id3): for k, v in id3.iteritems(): if k.startswith('POPM'): yield k, v def byte2rating(b): if b >= 224: return 5 if b >= 160: return 4 if b >= 96: return 3 if b >= 32: return 2 if b >= 1: return 1 return 0 def rating2byte(r): if r == 5: return 256 if r == 4: return 192 if r == 3: return 128 if r == 2: return 64 if r == 1: return 1 return 0 def rating_get(id3, key): try: rating = id3['TXXX:RATING'] except KeyError: try: _, popm = popms(id3).next() except StopIteration: return [] else: return [unicode(byte2rating(popm.rating))] else: return list(rating.text) def _canconv(r): try: if int(r) != str(int(r)): return False return int(r) >= 1 and int(r) <= 5 except (ValueError, TypeError): return False def rating_set(id3, key, val): rating_delete(id3, key) if _canconv(val): popm = mutagen.id3.POPM() popm.email = "Windows Media Player 9 Series" popm.count = 0 popm.rating = rating2byte(int(val)) id3.add(popm) else: if 'TXXX:RATING' in id3: del(id3['TXXX:RATING']) id3.add(mutagen.id3.TXXX(encoding=3, desc='RATING', text=unicode(val))) def rating_delete(id3, key): for k, v in popms(id3): del(id3[k]) if 'TXXX:RATING' in id3: del(id3['TXXX:RATING']) replaygain_tags = ('replaygain_album_gain', 'replaygain_album_peak', \ 'replaygain_track_gain', 'replaygain_track_peak') for tag in replaygain_tags: EasyID3.RegisterTXXXKey(tag, tag) extra_tags = ('sync', 'totaltracks', 'totaldiscs') for tag in extra_tags: EasyID3.RegisterTXXXKey(tag, tag.upper()) EasyID3.RegisterTextKey('albumartist', 'TPE2') EasyID3.RegisterKey('rating', rating_get, rating_set, rating_delete)