#! /usr/bin/python # Twitooth # # Sends information about nearby Bluetooth devices to Twitter # # @author Gareth Jones (http://blog.garethj.com) # # # Todo # ---- # # - Add ignore/include lists to limit devices # - Run server in different script so this one can be extended # - Listen for and react to direct messages (e.g. 'status gareth' returns time last seen) # # Change history # -------------- # # 0.4 # - # # 0.3 # - Added error handling so failure to connect doesn't kill the app # - Fixed bug where no devices reported incorrectly # # 0.2 # - Reduced number of tweets by sending single device list for each update # # 0.1 # - Alpha release import twitter, scanner, sys from scanner import * # Constants VERSION = "0.4a" # Output version number when loaded debug("Loading Twitooth version " + VERSION) # Main ToothTwit server application. Polls for nearby Bluetooth devices and # reports sightings to Twitter. class ToothTwit: # Creates a new instance of the server def __init__(self, twitterUsername, twitterPassword, excludeList=None): self.__username = twitterUsername self.__api = twitter.Api(twitterUsername, twitterPassword) self.__scanner = BluetoothDeviceScanner() self.__scanner.addListener(self) self.__excludeList = [excludeList] # Starts the application def start(self): debug("Starting ToothTwit") self.__scanner.start() debug("Exiting Twitooth") # The method called when the device list changes. Publishes all new and # missing devices to Twitter. def deviceListUpdated(self, currentDevices, newDevices, missingDevices): currentDevices = self.removeExcludedDevices(currentDevices) newDevices = self.removeExcludedDevices(newDevices) missingDevices = self.removeExcludedDevices(missingDevices) try: message = "Now I can see " if (currentDevices.getSize() > 0): for device in currentDevices.getDevices(): message += device.getName() for newDevice in newDevices.getDevices(): if (newDevice == device): message += "*" message += ", " message = message.rstrip(', ') else: message += "nobody :(" if (missingDevices.getSize() > 0): message += " ("; for missingDevice in missingDevices.getDevices(): message += missingDevice.getName() + ", " message = message.rstrip(', ') message += " disappeared)" debug("Posting to Twitter: '" + message + "'") self.__api.PostUpdate(message) except Exception, exception: debug(str(exception), "ERROR") def removeExcludedDevices(self, deviceList): if (self.__excludeList and len(self.__excludeList) > 0): for device in deviceList: for excludeDevice in excludeList: if (excludeDevice == device): deviceList.remove(device) return deviceList # Main script entry point; here's where we kick off the server if (len(sys.argv) > 2): username = sys.argv[1] password = sys.argv[2] if (len(sys.argv) > 3): excludeList = sys.argv[3] toothtwit = ToothTwit(username, password, excludeList) else: toothtwit = ToothTwit(username, password) else: print "Usage: " + sys.argv[0] + " twitter-username twitter-password" sys.exit(1) toothtwit.start()