Twitter Spitter

A friend and I are working on a Twitter project (http://twitter.com/elijahfromafar). This project is the Twitter account of a fictional character living in a war-torn town, in a  war-torn country far away. We’re writing all of the tweets from the perspective of this person, and we’d like to develop a plot-line, so we’ve created a Google Document with all of the Tweets in the order we want them to be posted. The issue is that we don’t want to spend the rest of our otherwise busy lives (we’re both post-secondary students) posting tweets for our fictional character. So how did we solve the problem? Python, of course!

In a few hours I hacked up a script that parsed a csv file with times and dates of each post, then used the Twitter API to post them (using python-twitter). Here’s the code (sorry for the cruddy formatting):

'''
Created on Jul 9, 2009

@author: Peter Davoust

Spits out tweets according to a csv file. The file should be formatted thusly:

year,month,day,hour,minute,tweet

Commas in the tweet don't matter; anything after the minute field will be read as a tweet anyway.
'''

import twitter
import sys
import datetime
import time

class TwitterSpitter:
 username="someuser"
 password="betyoucantguessthis82"
 admin = "worldgnat"  #The account that can send the END command

 continuing=True
 tweets = dict()
 api = twitter.Api()

 '''
 Log into the Twitter account, load tweets from file, begin posting updates.
 '''
 def __init__(self,file):
 print 'Logging in to Twitter account.'

 self.api = twitter.Api(self.username, self.password)
 #print 'Would be logging in now'

 print 'Loading updates from file %s.' % file
 self.load_updates(file)

 print 'Loaded. Posting updates.'
 self.main()

 '''
 Load tweets from provided file.
 '''
 def load_updates(self,file):
 f=open(file,'r')
 for line in f:
 print line
 field = line.split(",")
 print field

 #create the dictionary key from the date, and time fields
 key=datetime.datetime(int(field[0]),int(field[1]),int(field[2]),int(field[3]),int(field[4]))

 #tweet should be in field[6] through field[n]
 tweet = field[5]

 #if there are more parts to the tweet, then add them to the current part
 if len(field) >= 7:
 for i in range(6,len(field)-1):
 tweet+=","+field[i]

 self.tweets[key]=tweet

 def current_time(self):
 return datetime.time(time.localtime()[3],time.localtime()[4], time.localtime()[5])

 def current_date(self):
 return datetime.date.today()

 def current_datetime(self):
 return datetime.datetime(self.current_date().year, self.current_date().month, self.current_date().day, self.current_time().hour, self.current_time().minute)

 def update(self):
 now = self.current_datetime() #We can'd use datetime.now() because that includes milliseconds etc.
 if self.tweets.has_key(now):
 if self.tweets[now] == "END":
 print 'Reached the end of updates to be posted. Exiting.'
 sys.exit(0)

 #If we aren't finished, try to post an update
 self.api.PostUpdate(self.tweets[now])
 print 'Just posted: ' + self.tweets[now]

 def main(self):
 while(self.continuing):
 statuses = self.api.GetUserTimeline(self.admin)
 if (statuses[0].text == "END"):
 print 'Stopping by admin request.'
 sys.exit(0)
 self.update()
 time.sleep(60)
 sys.exit(0)

running = TwitterSpitter(sys.argv[1])

In order to use it you’ll need to install python-twitter and simple-json. If I were really efficient I would probably have it determine the time between the current post and the next, but I’m still a little unfamiliar with the datetime module, and I don’t think there is any great sacrifice of processor power by running this code every minute. In the future I may hack something up.

There is a second problem created by this script, however. Since we’re using Google Docs, it’s pretty easy to convert the document to rich text, remove all the formatting using OpenOffice, then convert to text, but the problem is inserting all of those dates and making it a csv file. It’s not a big deal, but it can be tedious with a few hundred posts. Python to the rescue again! I created an even tinier script that parses a flat text file and puts it in csv format, using the current time and date as the first few fields. Here’s the code:

'''
Created on Jul 20, 2009

@author: Peter Davoust

Converts a flat file of tweets into a csv file readable by twitterspitter.py
'''
import sys
import datetime

now = datetime.datetime.now();

input = open(sys.argv[1], 'r')
output = open(sys.argv[2], 'w')

for line in input:
 output.write("%(year)i, %(month)i, %(day)i, %(hour)i, %(minute)i, %(tweet)s" % {"year": now.year, "month": now.month, "day": now.day, "hour": now.hour, "minute": now.minute, "tweet": line})

input.close()
output.close()

So that’s about it. One problem this creates, is that since there is no way to differentiate between a comma in a sentence and a comma used to separate two fields, any sentence with a comma will get split up when you open it with a spreadsheet program. However, while this might be annoying if you want to go in and edit your sentences in the spreadsheet, it will get written out the same way it was read in, and since my script interprets anything after the minute field as part of the tweet, the comma will be tweeted along with the entire sentence. Note: If you’re using OpenOffice (or NeoOffice), you need to Save As, and check the box that says “Edit filter settings.” Then remove everything in the “Text Delimiter” drop-box, or else all your tweets will have quotes around them.
If you use this program, please drop me a line so I know it helped someone! If you want to post more than one tweet per minute you’ll need to do a little editing, but it should be too hard. If anyone wants to play with that, let me know in the comments or in an e-mail and I’ll be happy to help you.

Finally, please follow @elijahfromafar on Twitter! It’s going to be a fun project, and I hope you can watch it unfold!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s