Archive for February, 2009
Sneeky Facebook Hack
I hit a problem making my app that appears on the front page of someones profile update. I found a lot of people had had the same issue. Calling fb.profile.setFBML updates the profile of the widget on the users front page but only after the apps page has been visited e.g. http://apps.facebook.com/appname. This is Facebook caching the app. My cheat is once the update has been done, I call the page and then discard result to refresh the cache.
So I did the following in App Engine. This works for me testing the app locally but it needs a lot more testing and I’m certain there must be a better way but until I find it…
class FacebookUpdate(webapp.RequestHandler):
def get(self):
fb = getFacebookConnection();
fb.profile.setFBML('', 12345678, 'profile', '', 'mobile_profile', 'Happy Happy test 4')
self.response.out.write('complete')
urlfetch.fetch("http://apps.facebook.com/cassandra")
Debug mode in App Engine
Just a personal reminder about how to get App Engine into debug mode:
def main():
# Set the logging level in the main function
# See the section on Requests and App Caching for information on how
# App Engine reuses your request handlers when you specify a main function
logging.getLogger().setLevel(logging.DEBUG)
application = webapp.WSGIApplication([('/', MainPage),
('/sign', Guestbook)],
debug=True)
webapp.util.run_wsgi_app(application)
if __name__ = '__main__':
main()
Marking the Day
Thought I should mark this day somehow. Its my first time being made redundant. The project I was on no longer exists therefore I`m surplus to requirements. Nothing more, just felt like making a note.
Google Gears
Playing with Google Gears: Geo Location Example. You will need to install Google Gears.
App Engine and its Datastore
I`m sure this mentioned in its docs somewhere but it might handy: http://localhost:8080/_ah/admin/datastore Thats the web interface into your local datastore.
Sound and Firefox in Ubuntu
Its nasty I know but sometimes I lose sound normally after Firefox gets in a twist with a Flash video. To fix it and to check thats the problem run:
channam@tomservo:~$ sudo lsof | grep pcm
[sudo] password for channam:
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /home/channam/.gvfs
Output information may be incomplete.
pulseaudi 5727 channam mem CHR 116,8 12971 /dev/snd/pcmC0D0p
pulseaudi 5727 channam 39u CHR 116,8 12971 /dev/snd/pcmC0D0p
firefox 5917 channam mem REG 8,1 22052 670628 /usr/lib/alsa-lib/libasound_module_pcm_pulse.so
The last line above shows Firefox holding open some Alsa lib. At this point all Firefox windows are shut. We now know Firefox hasn’t closed correctly. So to make sure it dies:
channam@tomservo:~$ kill -9 5917
channam@tomservo:~$ sudo lsof | grep pcm
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /home/channam/.gvfs
Output information may be incomplete.
pulseaudi 5727 channam mem CHR 116,8 12971 /dev/snd/pcmC0D0p
pulseaudi 5727 channam 39u CHR 116,8 12971 /dev/snd/pcmC0D0p
Restart Firefox and should be well again until next time…
A little Ruby
I wrote a little ruby a while back to interpret the data from National Vulnerability Database
require 'net/http'
require 'rexml/document'
include REXML
#url = 'http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-recent.xml'
# get the XML data as a string
#xml_data = Net::HTTP.get_response(URI.parse(url)).body
# for download
#doc = REXML::Document.new(xml_data)
file = File.open("recent.xml")
doc = Document.new(file)
doc.elements.each('nvd/entry') do |entry|
print entry.elements["vuln:cve-id"].text
print " ==> "
if entry.elements["vuln:cwe"]
puts entry.elements["vuln:cwe"].attributes['id']
else
puts ""
end
end
Twitter Bot
While bored I wrote the following python twitter bot. It gets the rss feed from uk hot deals and then tweets the deals. Its pretty basic as it just checks the top item on the list instead of doing dates and times. It uses python-twitter-0.5.
The script is run by cron currently every minute.
#!/usr/bin/env python
import twitter
import urllib
from xml.dom import minidom
import simplejson
api = twitter.Api(username='username', password='passwd')
def shorten(param):
""" Using bit.ly to shorten the url """
url = param
request = "http://api.bit.ly/shorten?version=2.0.1&longUrl="
request += url
request += "&login=username&apiKey=APIKEY"
# fire off request for bit.ly
sock = urllib.urlopen(request)
json = sock.read()
sock.close()
# get the json
json = simplejson.loads(json)
return json['results'][url]['shortUrl']
# get the rss feed
sock = urllib.urlopen("http://www.hotukdeals.com/rss/hot")
rss = sock.read()
sock.close()
# parse the rss into ready xml
xmldoc = minidom.parseString(rss)
# eextract our results
items = xmldoc.getElementsByTagName('item')
result = items[0].getElementsByTagName('title')[0].childNodes[0].nodeValue
result += " " +shorten(items[0].getElementsByTagName('link')[0].childNodes[0].nodeValue)
# open the temp file and read in old value
f = open('/tmp/workfile', 'w+')
existing = f.read()
existing = existing.replace('\n', '')
unicode_result = unicode(result)
# if the new value from the top of the rss feed is different tweet and record it
if unicode_result.encode('utf-8') != existing:
unicode_string = unicode(result)
f.write(unicode_string.encode('utf-8'))
if len(result) > 0:
api.PostUpdate(result)
f.close()
Dbus and Banshee
A little old news but fun. Add a track to your play queue using python:
import dbus
bus = dbus.SessionBus()
player_queue = bus.get_object("org.bansheeproject.Banshee",
"/org/bansheeproject/Banshee/SourceManager/PlayQueue")
player_queue.EnqueueUri("/home/channam/Music/Jonathon Coulton/Code Monkey.mp3",True)
Twitter Bot using bit.ly
On the back of my App Engine bit.ly library I have created Deal Chimp. Hes a twitter bot that updates from UK Hot Deals RSS feed so that you can keep up with the bargains.

