Skip to content

Instantly share code, notes, and snippets.

@jcsalterego
Created February 5, 2009 06:47
Show Gist options
  • Save jcsalterego/58581 to your computer and use it in GitHub Desktop.
Save jcsalterego/58581 to your computer and use it in GitHub Desktop.
# Fork of http://bazaar.launchpad.net/~mrooney/nutunes/trunk/annotate/head%3A/nutunes.py
# Fetch your top artists from Last.FM and show the most recent Waffles torrents.
# Depends: python >= 2.5, feedparser (python-feedparser in Ubuntu)
from xml.etree import ElementTree as ET
from cookielib import CookieJar, DefaultCookiePolicy
import urllib2, urllib, re, getpass, feedparser
def enable_cookies():
cj = CookieJar(DefaultCookiePolicy(rfc2965=True))
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)
def url_read(url, postVars=None):
try:
con = urllib2.urlopen(url, postVars)
except Exception:
result = None
else:
result = con.read()
return result
def Get(url):
return url_read(url)
def Post(url, varDict):
return url_read(url, urllib.urlencode(varDict))
class WafflesMusicSource:
SCHEMA = [("Username",), ("Password",)]
def __init__(self, username, password, quality="v0"):
self.UID = None
self.Passphrase = None
self.Quality = quality
self._Login(username, password)
def _Login(self, username, password):
enable_cookies()
result = Post("https://www.waffles.fm/takelogin.php",
{"username": username,
"password": password,
"restricttoip": "yes",
"encrypt": "yes",
"logout": "yes",
"submit": "Log in!"})
if not result:
raise Exception("Unable to post to Waffles login!")
elif "Welcome back" not in result:
raise Exception("Login failed!")
regex = 'news_feed.php\?uid=([0-9]+)&passkey=([0-9a-zA-Z]+)"'
userinfo = re.findall(regex, result)
if userinfo == []:
raise Exception("Unable to parse UID and Passphrase from Waffles!")
self.UID, self.Passphrase = userinfo[0]
def Fetch(self, artist):
if not self.UID or not self.Passphrase:
raise Exception("UID or Passphrase not set, call _Login first!")
artist = artist.replace(" ", "+")
feedURL = (('https://www.waffles.fm/browse.php?q=%s+%s&c=0&uid=%s'
'&passkey=%s&rss=1') %
(artist,
self.Quality,
self.UID,
self.Passphrase))
feedRaw = Get(feedURL)
if not feedRaw:
raise Exception("Unable to fetch feed for '%s'" % artist)
d = feedparser.parse(feedRaw)
for entry in d.entries:
yield entry.updated, entry.title, entry.link
class LastFMArtistSource:
SCHEMA = [("Username",)]
def __init__(self, username):
self.Username = username
def GetArtists(self):
xmlurl = "http://ws.audioscrobbler.com/2.0/user/%s/topartists.xml" % self.Username
xml = urllib2.urlopen(xmlurl).read()
tree = ET.fromstring(xml)
return [element.text for element in tree.findall("artist/name")]
def showNewest(artists, musicSource, top=10):
newThings = []
for artist in artists[:top]:
newThings.extend(list(musicSource.Fetch(artist)))
for newthing in reversed(sorted(newThings)):
print "%s: %s" % (newthing[0], newthing[1])
def main():
user1 = raw_input("Last.FM username: ")
user2 = raw_input("Waffles username: ")
wpass = getpass.getpass("Waffles password: ")
artists = LastFMArtistSource(user1).GetArtists()
musicSource = WafflesMusicSource(user2, wpass)
showNewest(artists, musicSource)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment