from appscript import * from mactypes import * import os import getopt import sys import time import Growl notifier = Growl.GrowlNotifier("python", ["python"]) notifier.register() def display(msg): name = os.path.basename(sys.argv[0]).replace(".py","") notifier.notify("python",name , msg) def error(msg): print "ERROR: %s" % msg sys.exit(-1) def mkPlaylist(itunes,name): playlist_new = False playlists = itunes.playlists.get() for p in playlists: if p.name() == name: playlist_new = p if not playlist_new: playlist_new = itunes.make(new=k.user_playlist, with_properties={k.name: name}) return playlist_new def removeDuplicatesFromPlaylist(itunes,playlist): count = 0 foundIDs = [] tracks = playlist.tracks for id, track in zip(tracks.database_ID.get(), tracks.get()): if id in foundIDs: track.delete() count += 1 else: foundIDs.append(id) display("Removed %i duplicate tracks" % count) print "Removed %i duplicate tracks from '%s' " % ( count ,playlist.name()) def doJob(itunes,job): if job['playlist']: playlist = mkPlaylist(itunes,job['playlist']) display("Process Playlist %s" % job['playlist']) display("Add %i Files" % len(job['files'])) for idx,file in enumerate(job['files']): track = itunes.add(file, to=itunes.playlists['Library']) trial = 15 while trial: try: if job['artist']: track.artist.set(job['artist']) if job['album']: track.album.set(job['album']) break except: trial = trial - 1 time.sleep(1) try: print "Process '%s'" % file.path except: pass if playlist: itunes.add(file, to=playlist) if idx and idx%30==0: display("Processed %i Files" % idx) display("Remove Duplicates from Playlist %s" % job['playlist']) if playlist: removeDuplicatesFromPlaylist(itunes,playlist) def addSingleJob(jobs,do_album,do_artist,do_playlist,do_dir): job = { 'album' : do_album , 'artist' : do_artist, 'playlist' : do_playlist, 'files' : [] } d = os.listdir(do_dir) for file in d: if file.lower().find("mp3")>-1: file = do_dir + "/" + file try: job['files'].append(Alias(unicode(file))) except: print "Cannot add %s" % file jobs.append(job) return jobs def addMultiJob(jobs,do_dir): for root, dirs, files in os.walk(do_dir): job = { 'album' : None , 'artist' : None, 'playlist' : None, 'files' : [] } if not len(files): continue for name in files: file = os.path.join(root, name) try: if file.lower().find("mp3")>-1: job['files'].append(Alias(unicode(file))) except: print "Cannot add %s" % file data = root.split("/") if len(data)>1: job['artist'] = data[len(data)-2].replace("_"," ") job['album'] = data[len(data)-1].replace("_"," ") job['playlist'] = "%s - %s" % (job['artist'],job['album']) else: job['artist'] = data[0].replace("_"," ") job['playlist'] = "%s" % (job['artist']) if len(job['files']): jobs.append(job) print "Add Job %s" % (job['playlist']) return jobs def main(): try: opts, args = getopt.getopt(sys.argv[1:], "d:p:a:A:r", ["dir=", "playlist=",'artist','album','recursiv']) except: error("Parsing args") display("Start") do_artist = None do_album = None do_dir = None do_playlist = None do_recursiv = False for o,a in opts: if o in ('-d','dir'): do_dir = unicode(a,"utf-8") if o in ('-p','playlist'): do_playlist = unicode(a,'utf-8') if o in ('-a','artist'): do_artist = unicode(a,'utf-8') if o in ('-A','album'): do_album = unicode(a,'utf-8') if o in ('-r','recursiv'): do_recursiv = True if not do_dir: error("No dir set") jobs = [] if do_recursiv: jobs = addMultiJob(jobs,do_dir) else: jobs = addSingleJob(jobs,do_album,do_artist,do_playlist,do_dir) display("Process %i Jobs" % len(jobs)) itunes = app('iTunes') for job in jobs: doJob(itunes,job) display("Done") if __name__ == '__main__': main()