Twitter bot

Mar. 2nd, 2011 10:25 am
jodi: (Default)
[personal profile] jodi
I decided to start learning Python by creating a Twitter bot. I have an online diary, that I have been keeping for over a decade now, and I decided that I would output lines from it as tweets, so that I could keep in touch with my younger self. If you want to see it in action: Echochild.

Things I found odd to start with in Python:
No semi-colons at the end of lines
Layout actually matters
Having to put colons after if statements
Lists as opposed to arrays

I have been using Python as non-root. This has led me to much confusion about how to install packages. I tried installing virtual pythons, I tried easy install, and other things, and it just made me more and more muddled.

There are quite a few Python to Twitter packages, but in the end, I decided upon Tweepy.
I downloaded:

I then unpacked it:
tar -xvzf joshthecoder-tweepy-1.7.1-30-gfcaff74.tar.gz

I then created the following directories in my home directory:

I then put site-packages on my path:
export PYTHONPATH=myhomedir/tweepy/lib/python2.6/site-packages

The site-wide Python is at /usr/pkg/bin/python, so from the joshthecoder-tweepy-fcaff74 directory I then ran:
/usr/pkg/bin/python install --prefix=myhomedir/tweepy

I formatted the diary entries, using Vi, so that there is just one sentence per line.

I got the appropriate authorisation tokens from Twitter: consumer token, consumer secret, etc.

Due to access restrictions, I am unable to run cron jobs or leave things running in the background, so concluded that being able to tweet just by going to a web page would do. Not quite automatic, but still, will do for now.

I then created a CGI script in the joshthecoder-tweepy-fcaff74 directory.
import tweepy

#twitter authentication
auth = tweepy.OAuthHandler("consumer_token","consumer_secret")
auth.set_access_token("access token key","access token secret")
api = tweepy.API(auth)

diaryentries =[]

#mydiary.txt is the diary file. This is just opening the diary file, reading each line, and if it is the first line,
#and is less than 140 chars, writes it out to twitter.

f = open ('mydiary.txt','r')
for line in f:
     if fcount==0:
         if len(line)<140:
             api.update_status(line) #this line writes it to twitter
             diaryentries.append(line) #this line is just putting the diary entries back in the list
         fcount = fcount+1

# write all the diary entries back out to the file
f = open ('mydiary.txt','w')
f.writelines(diaryentries) #writing the list of diary entries back to the file

print "Content-Type: text/html" # HTML is following
print # blank line, end of headers
print "Echochild"

The next thing to do is make it actually reply to people!

on 2011-03-02 12:18 pm (UTC)
Posted by [identity profile]

The way we handle non-root deployment at work is using virtualenv ( You can run the package's directly if you don't have it installed, or just 'virtualenv' on the command line if you do.

For instance, you could create ~/virtualenvs/twitterbot/, and then make sure you use the binaries (python, easy_install) that were created in ~/virtualenvs/twitterbot/bin rather than the system's defaults. Then you can easy_install into there as non-root.

One thing I'd say about easy_install is that it's generally better to run it with the -Z switch, because zipped eggs can cause you some trouble later if you're trying to run an application as a user who doesn't have a home directory (such as www-data/apache), because it doesn't have anywhere to unzip too. Plus, I've noticed tracebacks tend to be a little odd when using zipped eggs.

You can put semicolons if you want :). I'm not sure why that's still a feature in Python, though...

Are lists that different to arrays?

The rest looks great, anyway. Quick shorthand: fcount += 1 instead of fcount = fcount + 1

on 2011-03-02 12:46 pm (UTC)
Posted by (Anonymous)
Yeah, python doesn't have a ++ operator; from the Zen of Python (import this on a console): "Special cases aren't special enough to break the rules." :)

You may have a bit of trouble getting the CGI script to use the right python version; if you can't get apache to use the virtualenv's own one (which magically sets up the correct site-packages, etc), although I suspect Apache makes that fairly easy to configure. If all else fails, check out the script that virtualenv installes into the virtualenv's bin/, which can set up the magic before you start importing anything.

on 2011-03-02 12:48 pm (UTC)
Posted by [identity profile]
Oops, that was from me. I should probably just get a dreamwidth account.

on 2011-03-02 01:46 pm (UTC)
damerell: (computers)
Posted by [personal profile] damerell
Presumably there is some crazy doublethink that makes missing '++' featureful.

on 2011-03-02 01:13 pm (UTC)
aquarion: (Default)
Posted by [personal profile] aquarion
For installing things with virtualenvs I've found "pip" to be better than easyinstalling things. You activate the virtual environment, and then type "pip install packagename" and it finds and downloads it. Or you can install directly from a github page, and stuff like that.

To run stuff automatically you can use something like which will fetch the web page every hour (or less) automatically for free.

April 2014


Most Popular Tags

Expand Cut Tags

No cut tags