handling iTunes plist with 3,006 values for key in python 2 with plistlib

310 views Asked by At

I'm trying to handle iTunes plist with plistlib under Python 2.7 on a Mac OS El Capitan system. The problem is get('Tracks') returns 3,006 values that have apparently lost their sub-keys. How do I handle this if my goal is to locate and alter SPECIFIC tracks' data than write the plist back out?

As buried in the previous paragraph, what I need help with exactly is this: print tracks list all the sub-keys values, but not the sub-keys themselves. Given that not all keys are quarantined to be present, how do I retrieve the key values of a specific track?

Here' my test code:

import plistlib as pl

plist = pl.readPist('/Users/bryandunphy/Music/iTunes HQR/iTunes Library.xml')
tracks = pl.get('Tracks')
print tracks

Here is an example data record that I believe contains all possible sub-keys (keys are absent if they are empty strings, False or the numeral 0):

    <key>2655</key>
    <dict>
        <key>Track ID</key><integer>2655</integer>
        <key>Size</key><integer>8558199</integer>
        <key>Total Time</key><integer>210120</integer>
        <key>Disc Number</key><integer>1</integer>
        <key>Disc Count</key><integer>2</integer>
        <key>Track Number</key><integer>5</integer>
        <key>Track Count</key><integer>17</integer>
        <key>Date Modified</key><date>2016-12-15T02:13:07Z</date>
        <key>Date Added</key><date>2016-12-14T11:32:46Z</date>
        <key>Bit Rate</key><integer>320</integer>
        <key>Sample Rate</key><integer>44100</integer>
        <key>Persistent ID</key><string>7BD213A791587573</string>
        <key>Track Type</key><string>File</string>
        <key>File Type</key><integer>1295270176</integer>
        <key>File Folder Count</key><integer>5</integer>
        <key>Library Folder Count</key><integer>1</integer>
        <key>Name</key><string>Born To Be Wild</string>
        <key>Artist</key><string>Steppenwolf</string>
        <key>Album Artist</key><string>Steppenwolf</string>
        <key>Album</key><string>Born To Be Wild: A Retrospective</string>
        <key>Genre</key><string>Rock</string>
        <key>Kind</key><string>AAC audio file</string>
        <key>Sort Album Artist</key><string>Steppenwolf</string>
        <key>Location</key><string>file:///Users/bryandunphy/Music/iTunes%20HQR/iTunes%20Media/Music/Steppenwolf/Born%20To%20Be%20Wild_%20A%20Retrospective/1-05%20Born%20To%20Be%20Wild.m4a</string>
    </dict>

The top of the file above the records is :

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Major Version</key><integer>1</integer>
        <key>Minor Version</key><integer>1</integer>
        <key>Application Version</key><string>12.5.4.42</string>
        <key>Date</key><date>2017-01-02T02:41:51Z</date>
        <key>Features</key><integer>5</integer>
        <key>Show Content Ratings</key><true/>
        <key>Library Persistent ID</key><string>4FA8621533B66A9E</string>
        <key>Tracks</key>
    <dict>
1

There are 1 answers

1
YCFlame On BEST ANSWER

let's say your iTunes plist file is like this:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Major Version</key><integer>1</integer>
  <key>Minor Version</key><integer>1</integer>
  <key>Application Version</key><string>4.6</string>
  <key>Music Folder</key>
    <string>/Users/bryandunphy/Music/iTunes HQR/iTunes Library.xml</string>
  <key>Library Persistent ID</key><string>8E84CC790968E27F</string>
  <key>Tracks</key>
  <dict>
    <key>2655</key>
    <dict>
        <key>Track ID</key><integer>2655</integer>
        <key>Size</key><integer>8558199</integer>
        <key>Total Time</key><integer>210120</integer>
        <key>Disc Number</key><integer>1</integer>
        <key>Disc Count</key><integer>2</integer>
        <key>Track Number</key><integer>5</integer>
        <key>Track Count</key><integer>17</integer>
        <key>Date Modified</key><date>2016-12-15T02:13:07Z</date>
        <key>Date Added</key><date>2016-12-14T11:32:46Z</date>
        <key>Bit Rate</key><integer>320</integer>
        <key>Sample Rate</key><integer>44100</integer>
        <key>Persistent ID</key><string>7BD213A791587573</string>
        <key>Track Type</key><string>File</string>
        <key>File Type</key><integer>1295270176</integer>
        <key>File Folder Count</key><integer>5</integer>
        <key>Library Folder Count</key><integer>1</integer>
        <key>Name</key><string>Born To Be Wild</string>
        <key>Artist</key><string>Steppenwolf</string>
        <key>Album Artist</key><string>Steppenwolf</string>
        <key>Album</key><string>Born To Be Wild: A Retrospective</string>
        <key>Genre</key><string>Rock</string>
        <key>Kind</key><string>AAC audio file</string>
        <key>Sort Album Artist</key><string>Steppenwolf</string>
        <key>Location</key><string>file:///Users/bryandunphy/Music/iTunes%20HQR/iTunes%20Media/Music/Steppenwolf/Born%20To%20Be%20Wild_%20A%20Retrospective/1-05%20Born%20To%20Be%20Wild.m4a</string>
    </dict>
  </dict>
</dict>
</plist>

Your test code will output a dictionary like this:

{'2655': {'Album': 'Born To Be Wild: A Retrospective', 'Persistent ID': '7BD213A791587573', 'Track Number': 5, 'Album Artist': 'Steppenwolf', 'Track Type': 'File', 'File Folder Count': 5, 'Disc Number': 1, 'Total Time': 210120, 'Artist': 'Steppenwolf', 'Track Count': 17, 'Genre': 'Rock', 'Bit Rate': 320, 'Kind': 'AAC audio file', 'Name': 'Born To Be Wild', 'Sample Rate': 44100, 'Disc Count': 2, 'Sort Album Artist': 'Steppenwolf', 'File Type': 1295270176, 'Track ID': 2655, 'Location': 'file:///Users/bryandunphy/Music/iTunes%20HQR/iTunes%20Media/Music/Steppenwolf/Born%20To%20Be%20Wild_%20A%20Retrospective/1-05%20Born%20To%20Be%20Wild.m4a', 'Date Modified': datetime.datetime(2016, 12, 15, 2, 13, 7), 'Library Folder Count': 1, 'Date Added': datetime.datetime(2016, 12, 14, 11, 32, 46), 'Size': 8558199}}

If you want get sub-keys values of each track, you can code like this:

for id, track_info in tracks.items():
    print id, track_info.values()

The output is like:

2655 ['Born To Be Wild: A Retrospective', '7BD213A791587573', 5, 'Steppenwolf', 'File', 5, 1, 210120, 'Steppenwolf', 17, 'Rock', 320, 'AAC audio file', 'Born To Be Wild', 44100, 2, 'Steppenwolf', 1295270176, 2655, 'file:///Users/bryandunphy/Music/iTunes%20HQR/iTunes%20Media/Music/Steppenwolf/Born%20To%20Be%20Wild_%20A%20Retrospective/1-05%20Born%20To%20Be%20Wild.m4a', datetime.datetime(2016, 12, 15, 2, 13, 7), 1, datetime.datetime(2016, 12, 14, 11, 32, 46), 8558199]

You may use track_info.items() instead so that you can get key-value pairs like this:

2655 [('Album', 'Born To Be Wild: A Retrospective'), ('Persistent ID', '7BD213A791587573'), ('Track Number', 5), ('Album Artist', 'Steppenwolf'), ('Track Type', 'File'), ('File Folder Count', 5), ('Disc Number', 1), ('Total Time', 210120), ('Artist', 'Steppenwolf'), ('Track Count', 17), ('Genre', 'Rock'), ('Bit Rate', 320), ('Kind', 'AAC audio file'), ('Name', 'Born To Be Wild'), ('Sample Rate', 44100), ('Disc Count', 2), ('Sort Album Artist', 'Steppenwolf'), ('File Type', 1295270176), ('Track ID', 2655), ('Location', 'file:///Users/bryandunphy/Music/iTunes%20HQR/iTunes%20Media/Music/Steppenwolf/Born%20To%20Be%20Wild_%20A%20Retrospective/1-05%20Born%20To%20Be%20Wild.m4a'), ('Date Modified', datetime.datetime(2016, 12, 15, 2, 13, 7)), ('Library Folder Count', 1), ('Date Added', datetime.datetime(2016, 12, 14, 11, 32, 46)), ('Size', 8558199)]