Created
February 5, 2009 06:47
-
-
Save jcsalterego/58581 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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