summaryrefslogtreecommitdiff
path: root/bin/lastexport.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/lastexport.py')
-rwxr-xr-xbin/lastexport.py178
1 files changed, 178 insertions, 0 deletions
diff --git a/bin/lastexport.py b/bin/lastexport.py
new file mode 100755
index 0000000..3e8c0d8
--- /dev/null
+++ b/bin/lastexport.py
@@ -0,0 +1,178 @@
+#!/usr/bin/env python2
+#-*- coding: utf-8 -*-
+
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""
+Script for exporting tracks through audioscrobbler API.
+Usage: lastexport.py -u USER [-o OUTFILE] [-p STARTPAGE] [-s SERVER]
+"""
+
+import urllib2, urllib, sys, time
+from xml.dom import minidom
+from optparse import OptionParser
+
+def get_options(parser):
+ """ Define command line options."""
+ parser.add_option("-u", "--user", dest="username", default=None,
+ help="User name.")
+ parser.add_option("-o", "--outfile", dest="outfile", default="exported_tracks.txt",
+ help="Output file, default is exported_tracks.txt")
+ parser.add_option("-p", "--page", dest="startpage", type="int", default="1",
+ help="Page to start fetching tracks from, default is 1")
+ parser.add_option("-s", "--server", dest="server", default="last.fm",
+ help="Server to fetch track info from, default is last.fm")
+ options, args = parser.parse_args()
+
+ if not options.username:
+ sys.exit("User name not specified, see --help")
+
+ return options.username, options.outfile, options.startpage, options.server
+
+def connect_server(username, startpage):
+ """ Connect to server and get a XML page."""
+ if server == "libre.fm":
+ baseurl = 'http://alpha.libre.fm/2.0/?'
+ urlvars = dict(method='user.getrecenttracks',
+ api_key='ohaiderthisisthelastexportscript',
+ user=username,
+ page=startpage,
+ limit=200)
+
+ elif server == "last.fm":
+ baseurl = 'http://ws.audioscrobbler.com/2.0/?'
+ urlvars = dict(method='user.getrecenttracks',
+ api_key='e38cc7822bd7476fe4083e36ee69748e',
+ user=username,
+ page=startpage,
+ limit=50)
+ else:
+ sys.exit("No config exist for this server, valid servers are: last.fm, libre.fm")
+
+
+ url = baseurl + urllib.urlencode(urlvars)
+ try:
+ f = urllib2.urlopen(url)
+ except:
+ print "Failed to open page %s" % urlvars['page']
+ response = None
+ return response
+
+ response = f.read()
+ f.close()
+ return response
+
+def get_pageinfo(response):
+ """Check how many pages of tracks the user have."""
+ xmlpage = minidom.parseString(response)
+ totalpages = xmlpage.getElementsByTagName('recenttracks')[0].attributes['totalPages'].value
+ return int(totalpages)
+
+def get_tracklist(response):
+ """Read XML page and get a list of tracks and their info."""
+ xmlpage = minidom.parseString(response)
+ tracklist = xmlpage.getElementsByTagName('track')
+ return tracklist
+
+def parse_track(tracklist, i):
+ """Extract info from every track entry and output to list."""
+ track = tracklist[i].getElementsByTagName
+ try:
+ artistname = track('artist')[0].childNodes[0].data
+ except:
+ artistname = ''
+ try:
+ artistmbid = track('artist')[0].attributes['mbid'].value
+ except:
+ artistmbid = ''
+ try:
+ trackname = track('name')[0].childNodes[0].data
+ except:
+ trackname = ''
+ try:
+ trackmbid = track('mbid')[0].childNodes[0].data
+ except:
+ trackmbid = ''
+ try:
+ albumname = track('album')[0].childNodes[0].data
+ except:
+ albumname = ''
+ try:
+ albummbid = track('album')[0].attributes['mbid'].value
+ except:
+ albummbid = ''
+ try:
+ date = track('date')[0].attributes['uts'].value
+ except:
+ date = ''
+
+ output = [date, trackname, artistname, albumname, trackmbid, artistmbid, albummbid]
+
+ return output
+
+def write_tracks(trackdict, outfile, startpage, page, totalpages):
+ """Write dictionary content with all tracks to file."""
+ #create a sorted list from track dictionary.
+ sortlist = []
+ for v in trackdict.values():
+ sortlist.append(v)
+ sortlist.sort(reverse=True)
+
+ #open output file and write tracks.
+ f = open(outfile, 'a')
+ for i in sortlist:
+ #sys.stdout.write(("\t".join(trackdict[i]) + "\n").encode('utf-8'))
+ f.write(("\t".join(i) + "\n").encode('utf-8'))
+ print "Wrote page %s-%s of %s to file %s, exiting." % (startpage, page, totalpages, outfile)
+ f.close()
+
+def main(username, startpage, outfile):
+ trackdict = dict()
+ page = startpage
+ response = connect_server(username, page)
+ totalpages = get_pageinfo(response)
+ #totalpages = 2
+
+ if startpage > totalpages:
+ sys.exit("First page (%s) is higher than total pages (%s), exiting." % (startpage, totalpages))
+
+ while page <= totalpages:
+ #Skip connect if on first page, already have that one stored.
+ if page > startpage:
+ response = connect_server(username, page)
+ #If empty response, something went wrong, write tracks to file and exit.
+ if not response:
+ write_tracks(trackdict, outfile, startpage, page-1, totalpages)
+ sys.exit()
+
+ tracklist = get_tracklist(response)
+ for i in range(len(tracklist)):
+ track = parse_track(tracklist, i)
+ trackdict.setdefault(track[0], track)
+
+ if (page % 10) == 0:
+ print "Getting page %s of %s.." % (page, totalpages)
+
+ page += 1
+ time.sleep(.5)
+
+
+ write_tracks(trackdict, outfile, startpage, page-1, totalpages)
+
+if __name__ == "__main__":
+ parser = OptionParser()
+ username, outfile, startpage, server = get_options(parser)
+ main(username, startpage, outfile)
+