#!/usr/bin/python helptext = """ Tool for encoding tags of mp3 files in the russian 1-byte charsets to unicode Usage: tag2utf [DIRECTORIES] (By default files will be searched in the current dirrectory) Modes: --toUtf : programm will try to recode tags --fixBroken : programm will try to --help, --version, --usage - view this text Version 0.12 Author: Kopats Andrei hlamer@tut.by This program is distributed under the terms of the GPL License. TODO: undo changes, Charsets will be in the config file or command line, for encoding not only from cp1251 and koi8-r GUI If you need to encode tags from different charset using this version, you can modify script, it's very easy to do. """ charsets = {'cp1251':'c','koi8-r':'k' } #modify it if you want decode tags from other encodings try: import eyeD3 except: print 'You need to install python-eyed3 package.' sys.exit() import os.path import re import os import sys mp3FileName = re.compile ('.*(mp3|MP3)$') def recodingNeed (strs): """recodint needed if tags had symbols with 255>ords >128 """ needed = False for string in strs: for i in range (len(string)): if ord (string[i])>255: return False #it's a unicode if 255>ord (string[i])>127: return True #nonunicode nonascii def passDir (rootdir): tags = [] songs = [] titles = [] artists = [] albums = [] for song in os.listdir(rootdir) : if ( os.path.isfile(os.path.join(rootdir,song)) and mp3FileName.match (song)): filename = os.path.join(rootdir,song) tag = eyeD3.Tag() try: if not tag.link(filename): continue #somthing wrong whith this file except: print '\n',filename,':error, may be tag is corrupted.\n ' continue if recodingNeed ([tag.getTitle(),tag.getArtist(),tag.getAlbum()]): if not os.access(filename,os.W_OK): print 'Warning! Have not access for writing file '\ ,filename , ' Sciped!' continue tags.append (tag) songs.append (song) titles.append (getTagStr (tag.getTitle())) artists.append (getTagStr (tag.getArtist())) albums.append (getTagStr (tag.getAlbum())) if len (tags) > 0: print len(tags),' file(s) finded in the ',rootdir askUser (tags,songs,titles,artists,albums) def getTagStr (tagUnicStr): #gets the 1byte 8bits string, as writed in the tag, from the unicode, returned by tag.get* ls = [] for i in range (0,tagUnicStr.__len__()): ls.append (chr (ord (tagUnicStr[i]))) Str8 = ''.join(ls) return Str8 def updateTags (tags,titles,artists,albums,charset): for i in range (len(tags)): tags[i].setVersion (eyeD3.ID3_V2_4) tags[i].setTextEncoding (eyeD3.UTF_8_ENCODING) tags[i].setArtist(artists[i].decode(charset)) tags[i].setAlbum (albums[i].decode(charset)) tags[i].setTitle (titles[i].decode(charset)) tags[i].update() def askUser (tags,songs, titles,artists,albums): charsetListStr = '' for charset in charsets.keys(): print '\n','If charset of tags is ', charset, '[',charsets[charset],']:' for i in range (len(songs)): print songs[i],' ',\ titles[i].decode(charset),' ',\ artists[i].decode(charset),' ',\ albums[i].decode(charset) charsetListStr = charsetListStr + " '"+charsets[charset]+"' - "+charset+'\n' print '\n',"Select charset:\n",charsetListStr, "'s' - skip this file(s)" if len(tags) >1: print "'m' - manual for every file" while 1: #get user choise end update the tags choise = raw_input() if choise in charsets.values(): charset = charsets.keys()[charsets.values().index(choise)] updateTags(tags,titles,artists,albums,charset) break elif choise == 's': return elif choise == 'm' and len(tags) >1: for i in range(len(tags)): askUser ([tags[i]],[songs[i]],[titles[i]],[artists[i]],[albums[i]]) return else: print 'What?' argsFailed = False ; if len (sys.argv) <2: #have no arguments rootdirs = [os.getcwd()] print 'Starting search in the ',os.getcwd() else: if ( sys.argv[1] == '--usage' or sys.argv[1] == '--help' or sys.argv[1] == '--version'): print helptext sys.exit() rootdirs = [] #have arguments for i in range(1,len(sys.argv)): if os.path.isdir(sys.argv[i]): rootdirs.append(sys.argv[i]) elif os.path.isdir (os.path.join (os.getcwd(),sys.argv[i])): rootdirs.append (os.path.join (os.getcwd(),sys.argv[i])) #this need because paths may have start in the working dir or in the root dir else: print "Not right argument '",sys.argv[i],"' It's not a directory.\n Try ",sys.argv[0], " --usage" argsFailed = True; if argsFailed: sys.exit() for rootdir in rootdirs: for root, dirs, files in os.walk(rootdir): passDir (root)