The FriendFeed API has a Python client library, so I thought I'd try it out with App Engine. It took a few tweaks to friendfeed.py, but it was pretty easy to get everything working.
First, I had to change the import line for simplejson:
#import simplejson
from django.utils import simplejson
Second, I needed to switch to using App Engine's URL Fetch API for the HTTP requests:
from google.appengine.api import urlfetch
This required a few adjustments to the FriendFeed class' _fetch() method. I moved the auth check to the top because it flowed a bit better and changed one line in that clause:
headers = {}
if self.auth_nickname and self.auth_key:
pair = "%s:%s" % (self.auth_nickname, self.auth_key)
token = base64.b64encode(pair)
#request.add_header("Authorization", "Basic %s" % token)
headers['Authorization'] = 'Basic %s' % token
Then I changed the post_args lines:
if post_args is not None:
#request = urllib2.Request(url, urllib.urlencode(post_args))
headers['Content-Type'] = 'application/x-www-form-urlencoded'
result = urlfetch.fetch(url, urllib.urlencode(post_args),
urlfetch.POST, headers)
else:
#request = urllib2.Request(url)
result = urlfetch.fetch(url, headers=headers)
And then one last change to fetch the data:
#stream = urllib2.urlopen(request)
#data = stream.read()
data = result.content
#stream.close()
return parse_json(data)
With those changes in place, everything seems to work fine. I haven't done any real testing, but it worked for reading public and private feeds, as well as posting a new entry.
I used the API to pull in FriendFeed likes and comments for each blog post. I did this by searching for the post's title and getting back the ID if the post URLs match:
service = friendfeed.FriendFeed()
feed = service.search('who:tom service:blog %s' % title)
for entry in feed['entries']:
if entry['link'] == 'http://www.tomstocky.com/blog/%s' % slug:
ffid = entry['id']
With that ID, I can then pull in the likes and comments for the post:
feed = service._fetch_feed('/api/feed/entry/' + ffid)
entry = feed['entries'][0]
likes = entry['likes']
comments = entry['comments']
When those are passed to my template, the end result is what now appear below each post on the homepage: