gobble.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. try:
  2. import hashlib
  3. md5hash = hashlib.md5
  4. except ImportError:
  5. import md5
  6. md5hash = md5.new
  7. from optparse import OptionParser
  8. import time
  9. from urllib import urlencode
  10. from urllib2 import urlopen
  11. class GobbleException(Exception):
  12. pass
  13. class GobbleServer(object):
  14. def __init__(self, server_name, username, password, client_code='imp'):
  15. if server_name[:7] != "http://":
  16. server_name = "http://%s" % (server_name,)
  17. self.client_code = client_code
  18. self.name = server_name
  19. self.password = password
  20. self.post_data = []
  21. self.session_id = None
  22. self.submit_url = None
  23. self.username = username
  24. self._handshake()
  25. def _handshake(self):
  26. timestamp = int(time.time())
  27. token = (md5hash(md5hash(self.password).hexdigest()
  28. + str(timestamp)).hexdigest())
  29. auth_url = "%s/?hs=true&p=1.2&u=%s&t=%d&a=%s&c=%s" % (self.name,
  30. self.username,
  31. timestamp,
  32. token,
  33. self.client_code)
  34. response = urlopen(auth_url).read()
  35. lines = response.split("\n")
  36. if lines[0] != "OK":
  37. raise GobbleException("Server returned: %s" % (response,))
  38. self.session_id = lines[1]
  39. self.submit_url = lines[3]
  40. def submit(self):
  41. if len(self.post_data) == 0:
  42. return
  43. i = 0
  44. data = []
  45. for track in self.post_data:
  46. data += track.get_tuples(i)
  47. i += 1
  48. data += [('s', self.session_id)]
  49. response = urlopen(self.submit_url, urlencode(data)).read()
  50. if response != "OK\n":
  51. raise GobbleException("Server returned: %s" % (response,))
  52. self.post_data = []
  53. time.sleep(1)
  54. def add_track(self, gobble_track):
  55. i = len(self.post_data)
  56. if i > 49:
  57. self.submit()
  58. i = 0
  59. self.post_data.append(gobble_track)
  60. class GobbleTrack(object):
  61. def __init__(self, artist, track, timestamp, album=None, length=None,
  62. tracknumber=None, mbid=None):
  63. self.artist = artist
  64. self.track = track
  65. self.timestamp = timestamp
  66. self.album = album
  67. self.length = length
  68. self.tracknumber = tracknumber
  69. self.mbid = mbid
  70. def get_tuples(self, i):
  71. timestamp = str(int(time.mktime(self.timestamp.utctimetuple())))
  72. data = []
  73. data += [('a[%d]' % i, self.artist), ('t[%d]' % i, self.track),
  74. ('i[%d]' % i, timestamp)]
  75. if self.album is not None:
  76. data.append(('b[%d]' % i, self.album))
  77. if self.length is not None:
  78. data.append(('l[%d]' % i, self.length))
  79. if self.tracknumber is not None:
  80. data.append(('n[%d]' % i, self.tracknumber))
  81. if self.mbid is not None:
  82. data.append(('m[%d]' % i, self.mbid))
  83. return data
  84. def get_parser(usage):
  85. parser = OptionParser(usage=usage)
  86. parser.add_option('-s', '--server',
  87. help="Server to submit to. Defaults to"
  88. " 'turtle.libre.fm'.")
  89. parser.set_defaults(server='turtle.libre.fm')
  90. return parser