diff options
Diffstat (limited to 'bin/lastexport.py')
-rwxr-xr-x | bin/lastexport.py | 178 |
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) + |