################################################ # Twitter Tool, by Eric Harrison (http://crawlicious.com) # Copyright 2009 Third Picket Properties, LLC # 11/14/09 16:09:39 Sat # # You may share this tool with others, use or modify it, but you must give credit to the author. ################################################ import sys import urllib2 import libxml2 MAX_BUFFER_COUNT = 200 class MyRequest(urllib2.Request): def __init__(self, url, method, params): urllib2.Request.__init__(self, url, params) self.method = method def get_method(self): if self.method != None: return self.method return urllib2.Request.get_method(self) class DirectMessageManager: def __init__(self, username, password): self.username = username self.password = password def authenticatedFetch(self, url, method, params): passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() passmgr.add_password(None, "http://twitter.com/", self.username, self.password) handler = urllib2.HTTPBasicAuthHandler(passmgr) opener = urllib2.build_opener(handler) opener.addheaders = [('User-agent', 'Mozilla/5.0')] req = MyRequest(url, method, params) return opener.open(req) def extractNodeValue(self, obj, key): values = obj.xpathEval(key) if len(values) > 0: return values[0].getContent() return None def listMessages(self, count, max_id=None): count = int(count) if count > MAX_BUFFER_COUNT: count = MAX_BUFFER_COUNT url = "http://twitter.com/direct_messages.xml?count=%d"%count if max_id: url = url + "&max_id=%s"%max_id fh = self.authenticatedFetch(url, None, None) messageText = fh.read() rss = libxml2.parseDoc(messageText) messageobjs = rss.xpathEval('/direct-messages/direct_message') messages = [] for o in messageobjs: sender_name = self.extractNodeValue(o, 'sender_screen_name') date = self.extractNodeValue(o, 'created_at') text = self.extractNodeValue(o, 'text') id = self.extractNodeValue(o, 'id') messages.append({'sender':sender_name, 'date':date, 'text':text, 'id':id}) return messages def deleteMessage(self, id): url = "http://twitter.com/direct_messages/destroy/%s.xml"%id fh = self.authenticatedFetch(url, "DELETE", None) messageText = fh.read() rss = libxml2.parseDoc(messageText) if str(type(rss)).find('instance'): return True return False def unfollowPerson(self, username): url = "http://twitter.com/friendships/destroy.xml?screen_name=%s" try: fh = self.authenticatedFetch(url%username, "DELETE", None) messageText = fh.read() rss = libxml2.parseDoc(messageText) if str(type(rss)).find('instance'): return True return False except urllib2.HTTPError: return False if __name__ == "__main__": if len(sys.argv) < 5 or sys.argv[1] not in ('list', 'delete', 'unfollow'): print "syntax: %s [list | delete ] twituser twitpass [maxmessages | all]"%(sys.argv[0]) print "syntax: %s unfollow twituser twitpass users_to_unfollow"%(sys.argv[0]) sys.exit(3) dm = DirectMessageManager(sys.argv[2], sys.argv[3]) if sys.argv[1] == 'list': count = sys.argv[4] if count == "all": messages = dm.listMessages(MAX_BUFFER_COUNT) while len(messages) > 0: for m in messages: print "from: %(sender)s date: %(date)s\n%(text)s"%m print "-----------------------------------------" messages = dm.listMessages(MAX_BUFFER_COUNT, max_id=(int(messages[-1]['id'])-1)) else: messages = dm.listMessages(count) for m in messages: print "from: %(sender)s date: %(date)s\n%(text)s"%m print "-----------------------------------------" elif sys.argv[1] == 'delete': count = sys.argv[4] if count == "all": messages = dm.listMessages(MAX_BUFFER_COUNT) while len(messages) > 0: for m in messages: print "deleting message %(id)s from %(sender)s"%m if not dm.deleteMessage(m['id']): print "error deleting message %(id)s"%m messages = dm.listMessages(MAX_BUFFER_COUNT) else: messages = dm.listMessages(count) for m in messages: print "deleting message %(id)s from %(sender)s"%m if not dm.deleteMessage(m['id']): print "error deleting message %(id)s"%m elif sys.argv[1] == "unfollow": for p in range(4, len(sys.argv)): r = dm.unfollowPerson(sys.argv[p]) if r: print "unfollowed %s"%sys.argv[p] else: print "error unfollowing %s"%sys.argv[p]