forked from esanbock/ITunesToRhythm
/
dumpitunes.py
129 lines (109 loc) · 4.5 KB
/
dumpitunes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python
#
#Copyright @ 2010 Douglas Esanbock
#iTunesToRhythm is free software; you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation; either version 3 of the License, or
#(at your option) any later version.
#
#iTunesToRhythm is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with iTunesToRhythm; if not, write to the Free Software Foundation, Inc.,
#51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import sys
import libxml2
import time
from songparser import BaseSong, BaseLibraryParser
class iTunesSong(BaseSong):
def __init__(self, songNode):
self.xmlNode = songNode
self.artist = self.xmlNode.xpathEval("string[preceding-sibling::* = 'Artist']")
self.album = self.xmlNode.xpathEval("string[preceding-sibling::* = 'Album']")
self.title = self.xmlNode.xpathEval("string[preceding-sibling::* = 'Name']")[0].content
self.size = self.xmlNode.xpathEval("integer[preceding-sibling::* = 'Size']")
self.rating = self.xmlNode.xpathEval("integer[preceding-sibling::* = 'Rating']")
self.playcount = self.xmlNode.xpathEval("integer[preceding-sibling::* = 'Play Count']")
self.filePath = self.xmlNode.xpathEval("string[preceding-sibling::* = 'Location']")[0].content
self.dateadded = self.xmlNode.xpathEval("date[preceding-sibling::* = 'Date Added']")
if len(self.artist) == 0:
self.artist = "Unknown"
else:
self.artist = self.artist[0].content
if len(self.album) == 0:
self.album = "Unknown"
else:
self.album = self.album[0].content
if len(self.size) == 0:
self.size = "Unknown"
else:
self.size = self.size[0].content
if len(self.rating) == 0:
self.rating = 0
else:
self.rating = int(self.rating[0].content)
if len(self.playcount) == 0:
self.playcount = 0
else:
self.playcount = int(self.playcount[0].content)
if len(self.dateadded) == 0:
self.dateadded = 0
else:
#http://www.epochconverter.com/
self.dateadded = int(time.mktime(time.strptime(self.dateadded[0].content, '%Y-%m-%dT%H:%M:%SZ')))
def setRating(self, rating):
ratingValueNodes = self.xmlNode.xpathEval("integer[preceding-sibling::* = 'Rating'][1]")
if len(ratingValueNodes) == 0:
newRatingKeyNode = libxml2.newNode("key")
self.xmlNode.addChild(newRatingKeyNode)
newRatingKeyNode.setContent("Rating")
ratingValueNode = libxml2.newNode("integer")
newRatingKeyNode.addSibling(ratingValueNode)
else:
ratingValueNode = ratingValueNodes[0]
ratingValueNode.setContent(str(rating))
def setPlaycount(self, playcount):
playcountValueNodes = self.xmlNode.xpathEval("integer[preceding-sibling::* = 'Play Count'][1]")
if len(playcountValueNodes) == 0:
newPlaycountKeyNode = libxml2.newNode("key")
self.xmlNode.addChild(newPlaycountKeyNode)
newPlaycountKeyNode.setContent("Play Count")
playcountValueNode = libxml2.newNode("integer")
newPlaycountKeyNode.addSibling(playcountValueNode)
else:
playcountValueNode = playcountValueNodes[0]
playcountValueNode.setContent(str(playcount))
def setDateAdded(self, dateadded):
dateaddedValueNodes = self.xmlNode.xpathEval("date[preceding-sibling::* = 'Date Added'][1]")
if len(dateaddedValueNodes) == 0:
newdateaddedKeyNode = libxml2.newNode("key")
self.xmlNode.addChild(newdateaddedKeyNode)
newdateaddedKeyNode.setContent("Date Added")
dateaddedValueNode = libxml2.newNode("first-seen")
newdateaddedKeyNode.addSibling(dateaddedValueNode)
else:
dateaddedValueNode = dateaddedValueNodes[0]
dateaddedValueNode.setContent(str(dateadded))
def main(argv):
location = argv[1]
print( "Reading iTunes library from " + location )
parser = iTunesLibraryParser(location)
allSongs = parser.getSongs()
for song in allSongs:
print( song.artist + " - " + song.album + " - " + song.title + " - " + song.size )
class iTunesLibraryParser(BaseLibraryParser):
def getSongs(self):
allSongNodes = self.xpathContext.xpathEval("/plist/dict/dict/dict/*/..")
return [iTunesSong(s) for s in allSongNodes]
def findSongBySize(self, size):
matches = self.xpathContext.xpathEval("/plist/dict/dict/dict[integer = '" + str(size) + "']")
matchingsongs = []
for match in matches:
song = iTunesSong(match)
matchingsongs.append(song)
return matchingsongs
if __name__ == "__main__":
main(sys.argv)