7 from optparse import OptionParser
10 from urllib import urlencode
11 from urllib2 import Request, urlopen, URLError, HTTPError
14 class ScrobbleException(Exception):
19 class ScrobbleServer(object):
21 def __init__(self, server_name, sk, api_key='thisisthelibreimport2pythonthing'):
22 if server_name[:7] != "http://":
23 server_name = "http://%s" % (server_name,)
24 self.api_key = api_key
25 self.name = server_name
28 self.submit_url = server_name + '/2.0/'
30 def submit(self, sleep_func=time.sleep):
31 if len(self.post_data) == 0:
35 for track in self.post_data:
36 data += track.get_tuples(i)
38 data += [('method', 'track.scrobble'),('sk', self.sk),('api_key', self.api_key),('format', 'json')]
40 for timeout in (1, 2, 4, 8, 16, 32):
42 req = Request(self.submit_url, urlencode(data))
43 response = urlopen(req)
44 except (URLError, HTTPError), e:
46 print 'Scrobbling error: %s, will retry in %ss' % (last_error, timeout)
48 jsonresponse = json.load(response)
50 if jsonresponse['scrobbles']: # we're just checking if key exists
53 last_error = 'Bad server response: %s' % response
54 print '%s, will retry in %ss' % (last_error, timeout)
57 raise ScrobbleException('Cannot scrobble after multiple retries. Last error: %s' % last_error)
62 def add_track(self, scrobble_track, sleep_func=time.sleep):
63 i = len(self.post_data)
65 self.submit(sleep_func)
67 self.post_data.append(scrobble_track)
70 class ScrobbleTrack(object):
72 def __init__(self, timestamp, trackname, artistname, albumname=None,
73 trackmbid=None, tracklength=None, tracknumber=None):
74 self.timestamp = timestamp
75 self.trackname = trackname
76 self.artistname = artistname
77 self.albumname = albumname
78 self.trackmbid = trackmbid
79 self.tracklength = tracklength
80 self.tracknumber = tracknumber
82 def get_tuples(self, i):
84 data += [('timestamp[%d]' % i, self.timestamp), ('track[%d]' % i, self.trackname),
85 ('artist[%d]' % i, self.artistname)]
86 if self.albumname is not None:
87 data.append(('album[%d]' % i, self.albumname))
88 if self.trackmbid is not None:
89 data.append(('mbid[%d]' % i, self.trackmbid))
90 if self.tracklength is not None:
91 data.append(('duration[%d]' % i, self.tracklength))
92 if self.tracknumber is not None:
93 data.append(('tracknumber[%d]' % i, self.tracknumber))
97 def get_parser(usage):
98 parser = OptionParser(usage=usage)
99 parser.add_option('-s', '--server',
100 help="Server to submit to. Defaults to"
102 parser.set_defaults(server='libre.fm')