Created
November 25, 2010 04:49
-
-
Save scoffey/714923 to your computer and use it in GitHub Desktop.
Sorts a given iTunes playlist according to the least played tracks in each album
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 characters
#!/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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment