#!/usr/bin/env python # Twitnotify.py 0.1 # Copyright Zeth Green 2008 # See http://zeth.me.uk/python/ # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Send Notifications about Twitter updates. It assumes a GNOME based Linux/Unix system. The first time it may seem a bit crazy if you have a lot of old Twitter updates. Four steps to install: 1. Install the three dependencies: pynotify - available from your distribution. e.g. sudo apt-get install python-notify e.g. sudo emerge notify-python simplejson - available from the cheeseshop. e.g. sudo easy_install simplejson python-twitter - available from the cheeseshop. e.g. sudo easy_install python-twitter 2. Get a Twitter account. Add some friends (e.g. zeth0). 3. Set up the USERNAME and PASSWORD below. 4. Run the script and (optionally) background it. """ import pygtk pygtk.require('2.0') import pynotify import sys #import gtk import os import twitter import urllib import pickle import time ##################################### # Change these to match your system USERNAME = "zeth0" PASSWORD = "lenna" ##################################### # These should be fine for most users STORAGE_DIRECTORY = "~/.twitter" IMAGE_DIRECTORY = "~/.twitter/images" ##################################### class TwitterStatus(object): """Manages your history of Twitter status updates.""" def __init__(self): self.api = twitter.Api(username = USERNAME, password = PASSWORD) self.store = {} self.storage = os.path.expanduser(STORAGE_DIRECTORY) self.image_storage = os.path.expanduser(IMAGE_DIRECTORY) if not os.path.exists(self.image_storage): os.makedirs(self.image_storage) def save(self): """Save storage file to disk.""" filename = open(self.storage + "/twitter.pkl", 'w') pickle.dump(self.store, filename) filename.close() def load(self): """Load storage file from disk.""" try: filename = open(self.storage + "/twitter.pkl", 'r') self.store = pickle.load(filename) filename.close() except IOError: self.store = {} def check_status(self, status): """Check if a status update has already been stored. If not then store it and send a notification.""" if status.id not in self.store.keys(): # Deal with inconsistencies in the bindings try: username = status.user.name except AttributeError: username = status.sender_screen_name try: profile_image = status.user.profile_image_url except AttributeError: profile_image = self.api.GetUser(\ username).GetProfileImageUrl() # Find the image imagepath = self.cached_image(username) if not imagepath: imagepath = self.download_image(username, profile_image) # Markup Hyperlinks text = status.text if "http://" in text: for i in text.split(): if i.startswith("http://"): text = text.replace(i, \ '' + i + '') # Call notification send_note(username, text, imagepath ) # Add to dict self.store[status.id] = status def download_image(self, username, image_url): """Download new profile image.""" fileextension = image_url.rpartition('.')[-1] targetname = self.image_storage + "/" + username + "." + fileextension urllib.urlretrieve(image_url, targetname) return targetname def cached_image(self, username): """Check for already downloaded profile image.""" for i in os.listdir(self.image_storage): if i.startswith(username + "."): return i else: return None def send_note(user, message, imageurl): """Send the note to the desktop.""" if not pynotify.init("Twitter Notify"): sys.exit(1) note = pynotify.Notification(user, message, imageurl) if not note.show(): print "Failed to send notification" sys.exit(1) def check_updates(): """Check for Twitter Updates""" # Initiate twit = TwitterStatus() # Load stored entries twit.load() # Start with Friend Timeline for i in twit.api.GetFriendsTimeline(): twit.check_status(i) # Next lets do Replies for i in twit.api.GetReplies(): twit.check_status(i) # Personal Messages we have been sent for i in twit.api.GetDirectMessages(): twit.check_status(i) # Save stored entries twit.save() def main(): """When called directly, run and then repeat.""" check_updates() print "Initial update completed." print "It will now repeat every 10 mins." #Repeat every ten minutes while 1: try: time.sleep(600) check_updates() except KeyboardInterrupt: sys.exit(1) if __name__ == '__main__': main()