Created
November 25, 2010 04:49
Revisions
-
scoffey created this gist
Nov 25, 2010 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,89 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ This script implements an algorithm for sorting a given iTunes playlist according to the least played tracks in each album. It aims to identify the tracks that were played the least and to show how many times they should be played in order to reach the same playcount as the most played track in the album they belong to. The program input is the name of the playlist where tracks should be taken from and the name of the new playlist to create or replace. The output, apart from the new iTunes playlist, is a table showing the candidate tracks and the playcount difference used for sorting them. """ __author__ = 'Santiago Coffey' __email__ = '[email protected]' __version__ = '0.1' __license__ = 'GNU General Public License 3' __docformat__ = 'restructuredtext en' import sys import appscript iTunes = appscript.app('itunes') def make_catalog(tracks): """ Makes a music catalog dict by artist+album with track playcounts """ catalog = dict() for track in tracks: artist = track.album_artist() or track.artist() album = track.album() album_list = catalog.get((artist, album), {}) album_list[track] = track.played_count() catalog[(artist, album)] = album_list return catalog def make_tracks_tuples(album_list, artist, album): """ Returns tuples with artist name, album name, track object and playcount difference """ max_playcount = max(album_list.values()) return [(artist, album, track, max_playcount - n) for track, n \ in album_list.iteritems() if n < max_playcount] def get_candidates(playlist): """ Returns candidate tracks data sorted by playcount difference """ candidates = [] catalog = make_catalog(playlist.file_tracks()) for artist_album, album_list in catalog.iteritems(): tuples = make_tracks_tuples(album_list, *artist_album) candidates.extend(tuples) candidates.sort(key=lambda x: x[3], reverse=True) return candidates def show_candidates(candidates): """ Prints candidate tracks data as a table """ template = '\t | '.join(['%s'] * 4) for artist, album, track, count in candidates: print template % (count, artist, album, track.name()) def replace_playlist(name, tracks): """ Creates or replaces an iTunes playlist with given tracks """ playlist = iTunes.user_playlists[name] if iTunes.exists(playlist): # empty existing playlist if len(playlist.tracks()): iTunes.delete(playlist.tracks) else: # create playlist iTunes.make(new=appscript.k.playlist, \ with_properties={appscript.k.name: name}) for track in tracks: iTunes.duplicate(track, to=playlist) def main(program, *args): """ Main program: Computes and creates new playlist according to input """ source = raw_input('Enter your source playlist name: ') playlist = iTunes.user_playlists[source] if iTunes.exists(playlist): destination = raw_input('Enter your destination playlist name: ') candidates = get_candidates(playlist) show_candidates(candidates) replace_playlist(destination, [i[2] for i in candidates]) else: print 'Error: No such iTunes playlist: %s' % source if __name__ == '__main__': main(*sys.argv)