Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Sort iTunes playlists by date and track number Apps
Do you have a recently-added playlist in iTunes with tracks all out of order because the playlist is sorted by date added? This script allows you to sort by date added (or whatever you want in iTunes), then album, then track number/name. It does require some Python/Terminal use, and installing appscript (via sudo easy_install appscript in 10.5 and later; more help on the appscript install page).

One warning: if you do, for some reason, choose a playlist that already exists as the target, this script will delete the songs in it. Here's the code:
#!/usr/bin/env python
# encoding: utf-8
"""
itunesMostRecentAlbums.py
version .1
Created by John Sheeley on 2009-11-10.
Do whatever in the world you want with this.
"""

import sys
import getopt
from appscript import *

help_message = '''
Use this script to create a new playlist in iTunes. 
It reads one playlist, orders tracks by album, then by track # or name.

Parameters (default values):
-v: Verbose output.
-h --help: This help message.
-m --maxAlbums: Maximum number of albums to process. 0 for all. (0)
-s --songsPerAlbum: Number of songs required to define an album. (5)
-p --playlist: Source playlist. ("Recently Added")
-n --newplaylist: Destination playlist. ("Sorted Recently Added")

This is useful when using with a source playlist sorted by date added. 
Essentially you will be sorting by date, album, track.

This does require appscript. If you do not have it, install it with this command:
sudo easy_install appscript
'''

iTunes = app('iTunes.app')
maxAlbums = 0
songsPerAlbum = 5
playlist = "Recently Added"
newPlaylist = "Sorted Recently Added"
verbose = False

class Usage(Exception):
	def __init__(self, msg):
		self.msg = msg

def main(argv=None):
	if argv is None:
		argv = sys.argv
	try:
		try:
			opts, args = getopt.getopt(argv[1:], "ho:v", ["help", "output="])
		except getopt.error, msg:
			raise Usage(msg)
	
		# option processing
		for option, value in opts:
			if option == "-v":
				verbose = True
			if option in ("-h", "--help"):
				raise Usage(help_message)
			if option == "--maxAlbums":
				maxAlbums = value
			if option in ("-s","--songsPerAlbum"):
				songsPerAlbum = value
			if option in ("-p", "--playlist"):
				playlist = value
			if option in ("-n", "--newplaylist"):
				newPlaylist = value
		
	except Usage, err:
		print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
		print >> sys.stderr, "\t for help use --help"
		return 2

def getItunesData(iTunes, playlist, verbose):
	#get songs in recently added playlist
	if iTunes.isrunning:
		#iTunes is running, begin grabbing data
		playlists = iTunes.user_playlists
		if not iTunes.exists(playlists[playlist]):
			#playlist doesn't exist
			print("The playlist you specified, '" + playlist + "', doesn't seem to exist.\nPlease check that it does, and that it is sorted by date.")
		else:
			#we have the playlist, select it
			currentPlaylist = playlists[playlist]
			#get albums 
			allTracks = currentPlaylist.tracks()
		return allTracks

def sortSongs(allTracks, songsPerAlbum, maxAlbums, verbose):
	songData = {}
	songNames = {}
	songCount = {}
	albumOrder = []
	for track in allTracks:
		albumTitle = track.album()
		if albumTitle != '':
			#album title isn't blank
			if albumTitle not in songData.keys():
				#make multi-dimensional dictionary for data
				songData[albumTitle] = {}
				albumOrder.append(albumTitle)
				songNames[albumTitle] = {}
				songCount[albumTitle] = 1
			else:
				songCount[albumTitle] += 1
			trackNumber = track.track_number()
			if trackNumber in songData[albumTitle]: #== 0:
				#if there aren't track numbers, sort by track names
				trackNumber = track.name()
			songData[albumTitle][trackNumber] = track
			songNames[albumTitle][trackNumber] = track.name()
	
	#remove albums
	toDelete = []
	for album in songData.keys():
		if songCount[album] < songsPerAlbum:
			#remove album from list if it doesn't have enough songs
			toDelete.append(album)
	omittedSongs = "Albums omitted (for having too few songs): "
	for album in toDelete:
		omittedSongs += "\nTracks:" + str(songCount[album]) + " - " + album
		omittedSongs += str(songNames[album])
		del songData[album]
		albumOrder.remove(album)
	if verbose:
		#for debug and such
		print omittedSongs
		
	if len(songData.keys()) <= maxAlbums or maxAlbums == 0:
		#show all albums
		length = len(songData.keys())
	else:
		#show only maxAlbums # albums
		length = maxAlbums
	
	sortedSongs = []
	for i in range(length):
		tracks = songData[albumOrder[i]].keys()
		tracks.sort()
		for track in tracks:
			sortedSongs.append(songData[albumOrder[i]][track])
	return sortedSongs
	
def makePlaylist(iTunes, songs, name, oldPlaylist, verbose):
	#make new playlist, or use existing, and insert songs
	playlists = iTunes.user_playlists
	if iTunes.exists(playlists[name]):
		#playlist exists, empty it and fill with new tracks
		playlistTracks = playlists[name].tracks()
		if len(playlistTracks) > 0:
			iTunes.delete(playlists[name].tracks)
	else:
		location = playlists[oldPlaylist].parent()
		iTunes.make(new=k.playlist, at=location, with_properties={k.name: name})
	
	playlist = playlists[name]
	tracks = []
	
	for track in songs:
		iTunes.duplicate(track, to=playlist)
	return True

#actually run stuff
allTracks = getItunesData(iTunes, playlist, verbose)
sortedSongs = sortSongs(allTracks, songsPerAlbum, maxAlbums, verbose)
finished = makePlaylist(iTunes, sortedSongs, newPlaylist, playlist, verbose)
if finished:
	print "Success!"
#iTunes.reveal(currentPlaylist)
if __name__ == "__main__":
	sys.exit(main())
[robg adds: Copy and paste the script into a Terminal text editor (or text-only GUI editor), save it, and then make it executable in Terminal (chmod a+x scriptname. Usage instructions are available by calling the program with the -h parameter. I haven't tested this one.]
    •    
  • Currently 2.44 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (16 votes cast)
 
[11,209 views]  

Sort iTunes playlists by date and track number | 4 comments | Create New Account
Click here to return to the 'Sort iTunes playlists by date and track number' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Sort iTunes playlists by date and track number
Authored by: auco on Dec 02, '09 03:36:30PM

um.. I don't understand: why don't you just click the sorting table header in your intelligent playlist that is auto-updated and contains your recently added tracks? :scratchhead:



[ Reply to This | # ]
Sort iTunes playlists by date and track number
Authored by: sheeley on Dec 02, '09 08:10:48PM

Because whatever you click will simply sort by that. I often add multiple albums to iTunes at the same time, and if you sort by date added, you get something like this:
Artist - Album 2 - Track 13
Arist 2 - Album 1 - Track 5
etc. - All out of order.
This script takes them, and orders by album as recently added, then track number/name, like so:
Newest - Album 2 - Track 1
Newest - Album 2 - Track 2
Newest - Album 2 - Track 3
Next Newest - Album 3 - Track 1
Next Newest - Album 3 - Track 2
Next Newest - Album 3 - Track 3

It's also useful if, instead of deciding how many songs you want to include in a playlist, you want to decide how many albums.



[ Reply to This | # ]
Sort iTunes playlists by date and track number
Authored by: yopyop on Dec 04, '09 05:23:40PM

I haven't been able to make this work - the terminal gives an error in 10.6 on installing appscript. I may come back later to troubleshoot according to the notes on installing appscript on the appscript website, but it looks kinda gnarly.

Also, how do you execute the script in the file (once you've made it executable according to the instructions above). I'm not Python certified. do you type 'sh' to execute it?

This would be an incredibly useful feature in iTunes, as I'm always adding songs to iTunes manually, then finding the first track (because it's out of order), clicking play, then sorting by Album, then APPLE-L to find the track (since it's gone off the screen since resorting).

If someone made a widget or plugin for iTunes that did this function I would kiss their feet.



[ Reply to This | # ]
Sort iTunes playlists by date and track number
Authored by: burgerga123 on Dec 07, '09 11:58:52AM
Hmmm... I'm not quite getting what I need to do to get this to work. I installed appscript fine. And I pasted the code in to text edit and saved it with a .py extension. Typed chmod a+x ~/RecentSort.py which seemed to work. Then when I execute the program in terminal it gives me some sort of error.

Traceback (most recent call last):
  File "/Users/garrisonburger/RecentSort.py", line 165, in <module>
    finished = makePlaylist(iTunes, sortedSongs, newPlaylist, playlist, verbose)
  File "/Users/garrisonburger/RecentSort.py", line 152, in makePlaylist
    location = playlists[oldPlaylist].parent()
  File "build/bdist.macosx-10.6-universal/egg/appscript/reference.py", line 648, in __call__
  File "build/bdist.macosx-10.6-universal/egg/appscript/reference.py", line 504, in __call__
appscript.reference.CommandError: Command failed:
		OSERROR: -1728
		MESSAGE: Can't get reference.
		COMMAND: app(u'/Applications/iTunes.app').user_playlists['Recently Added'].parent.get()

Not quite sure what I'm doing wrong. I tried running it with the -p and -n parameters but got the same error. Any help?

[ Reply to This | # ]