Skip to content

Instantly share code, notes, and snippets.

@Gipetto
Created October 31, 2017 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gipetto/7663193a9cfee71779a4a6bf4cf66a33 to your computer and use it in GitHub Desktop.
Save Gipetto/7663193a9cfee71779a4a6bf4cf66a33 to your computer and use it in GitHub Desktop.
Get a list of purchased tracks from your iTunes library that includes the purchaser. Not accurate for newer iTunes files (I couldn't find the purchaser with mutagen code)
#!/usr/bin/env python3
from plistlib import *
import mutagen as m
import urllib.parse
import pprint
import sys
import csv
import os
library_file = '/path/to/Music/iTunes/iTunes Library.xml'
export_file = 'purchased.csv'
###########################
pp = pprint.PrettyPrinter()
META_KEY_APPID = 'apID'
META_KEY_RATING = 'rtng'
KEY_ALBUM = 'Album'
KEY_ARTIST = 'Artist'
KEY_DATE_ADDED = 'Date Added'
KEY_KIND = 'Kind'
KEY_LOCATION = 'Location'
KEY_NAME = 'Name'
KEY_OWNER = 'Owner'
KEY_PROTECTED = 'Protected'
KEY_RATING = 'Rating'
KEY_TRACK_ID = 'Track ID'
KEY_TRACKS = 'Tracks'
KEY_TYPE = 'Track Type'
TYPE_REMOTE = 'Remote'
KIND_PROTECTED = 'Protected AAC audio file'
KIND_PURCHASED = 'Purchased AAC audio file'
kinds = [KIND_PROTECTED, KIND_PURCHASED]
interesting_keys = [
KEY_TRACK_ID,
KEY_KIND,
KEY_PROTECTED,
KEY_ARTIST,
KEY_ALBUM,
KEY_NAME,
KEY_RATING,
KEY_OWNER,
KEY_DATE_ADDED,
KEY_LOCATION
]
def get_file(location):
path = os.path.realpath(urllib.parse.unquote(location).replace('file://', ''))
return m.File(path)
def get_file_key(file, key):
try:
return file.tags[key][0]
except KeyError:
return '-'
def main():
with open(library_file, 'rb') as fp:
print('loading library')
library = load(fp)
with open(export_file, 'w') as f:
writer = csv.writer(f)
writer.writerow(interesting_keys)
for id, track in library[KEY_TRACKS].items():
if (track[KEY_TYPE] != TYPE_REMOTE) and (track[KEY_KIND] in kinds):
try:
file = get_file(track[KEY_LOCATION])
if KEY_ALBUM not in track:
track[KEY_ALBUM] = '-'
if KEY_PROTECTED not in track:
track[KEY_PROTECTED] = '-'
track[KEY_OWNER] = get_file_key(file, META_KEY_APPID)
track[KEY_RATING] = get_file_key(file, META_KEY_RATING)
writer.writerow([track[key] for key in interesting_keys])
print('.', end='', flush=True)
except Exception as e:
pp.pprint(track)
pp.pprint(e)
print('done')
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment