Simple Twitter poster written in Python (with CLI)

[ permalink ] [ download ]
#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib
import urllib2
import httplib
import feedparser
import getopt
import sys
import getpass
import signal

class TwitterRequest:

    def __init__(self, username=None, password=None):
        self._username = username
        self._password = password

    def doAuthRequest(self, url, data=None):
        try:
            password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
            password_mgr.add_password(None, "http://twitter.com/", self._username, self._password)
            handler = urllib2.HTTPBasicAuthHandler(password_mgr)
            opener = urllib2.build_opener(handler)
            opener.addheaders = [ ( 'User-agent', 'Mozilla/5.0' ) ]
            req = urllib2.Request(url, data)
            return opener.open(req)
        except urllib2.HTTPError, err:
            print str(err)
            sys.exit(1)

    def doRequest(self, url):
        try:
            opener = urllib2.build_opener()
            opener.addheaders = [ ( 'User-agent', 'Mozilla/5.0' ) ]
            req = urllib2.Request(url)
            return opener.open(req)
        except urllib2.HTTPError, err:
            print str(err)
            sys.exit(1)
 
############################################################################################################

class SimpleTwitter:

    def __init__(self, username, password):
        self._username = username
        self._password = password
        self.msglen = 140

    def _truncate(self, msg):
        if len(msg) > self.msglen:
            print "Message truncated. Maximum allowed message length is " + str(self.msglen) + " characters."
            return msg[:self.msglen]
        else:
            return msg
    
    def getUsername(self):
        return self._username

    def getPassword(self):
        return self._password

    def getFriendsTimeline(self):
        req = TwitterRequest(self.getUsername(), self.getPassword())
        f = req.doAuthRequest('http://twitter.com/statuses/friends_timeline.rss')
        d = feedparser.parse(f.read())

        for elem in reversed(d['entries']):
            print elem.updated + " -- " + elem.title

    def getUserTimeline(self):
        req = TwitterRequest(self.getUsername(), self.getPassword())
        data = urllib.urlencode({'id' : self.getUsername()})
        f = req.doAuthRequest('http://twitter.com/statuses/user_timeline.rss', data)
        d = feedparser.parse(f.read())

        for elem in reversed(d['entries']):
            print elem.updated + " -- " + elem.title

    def getPublicTimeline(self):
        req = TwitterRequest()
        f = req.doRequest('http://twitter.com/statuses/public_timeline.rss')
        d = feedparser.parse(f.read())

        for elem in reversed(d['entries']):
            print elem.updated + " -- " + elem.title

    def update(self, msg):
        data = urllib.urlencode({'status' : self._truncate(msg)})
        req = TwitterRequest(self.getUsername(), self.getPassword())
        f = req.doAuthRequest('http://twitter.com/statuses/update.xml', data)
        if f:
            print "Update OK!"
        else:
            print "Error updating..."

    def directMsg(self, user, msg):
        data = urllib.urlencode({'user' : str(user), 'text' : self._truncate(msg)})
        req = TwitterRequest(self.getUsername(), self.getPassword())
        f = req.doAuthRequest('http://twitter.com/direct_messages/new.xml', data)
        if f:
            print "Direct message sent OK!"
        else:
            print "Error sending Direct Message..."

    def follow(self, user):
        req = TwitterRequest(self.getUsername(), self.getPassword())
        f = req.doAuthRequest('http://twitter.com/friendships/create/'+str(user)+'.xml')
        if f:
            print "OK, now following user " + str(user)
        else:
            print "Error trying to follow user..."

############################################################################################################

def usage():
    print """
    SimpleTwitter usage:
    ===================

    ./twitter-cli.py
    
    Commands:
    >> post <message>               Post message.
    >> user                         Show user timeline.
    >> friends                      Show friends timeline.
    >> public                       Show public timeline.
    >> follow <username>            Follow user.
    >> direct <username> <message>  Send direct message to user.

    """

def get_user_data():
    user = raw_input("Enter your username: ")
    password = getpass.getpass("Enter your password: ")
    return SimpleTwitter(user, password)

def signal_handler(signal, frame):
            print '\nYou pressed Ctrl+C!\n'
            sys.exit(0)

def main():
    signal.signal(signal.SIGINT, signal_handler)
    twitt = get_user_data()

    while 1:
        comm = raw_input(">> ")
        c = comm.split()
        if len(c) > 0:
            if c[0] == 'quit':
                sys.exit(0)
            elif c[0] == 'post' and len(c) > 1:
                msg = " ".join(c[1:])
                print "\nPosting..."
                twitt.update(msg)
                continue
            elif c[0] == 'friends':
                print "\nGetting friends timeline... "
                twitt.getFriendsTimeline()
                continue
            elif c[0] == 'public':
                print "\nGetting public timeline... "
                twitt.getPublicTimeline()
                continue
            elif c[0] == 'user':
                print "\nGetting user timeline... "
                twitt.getUserTimeline()
                continue
            elif c[0] == 'follow' and len(c) == 2:
                print "\nRequest to follow user " + str(c[1])
                twitt.follow(str(c[1]))
                continue
            elif c[0] == "direct" and len(c) > 2:
                print "\nDirect message to user " + str(c[1])
                msg = " ".join(c[2:])
                twitt.directMsg(str(c[1]), str(msg))
                continue
            else:
                usage()


if __name__ == "__main__":
    main()
hits counter