#!/usr/local/bin/python

# twexpire 0.2 by Andrew Gerrand (nf@wh3rd.net) 2009

import urllib2
import time
import cjson
import codecs

period = 7*24*60*60 # delete any tweets older than 7 days
twitter_user = 'your_twitter_username'
twitter_password = 'your_twitter_password'
log_location = "/path/to/backups/%s" # back up tweets to this directory

twitter_url = "http://twitter.com/statuses/user_timeline.json?page=%d"
twitter_destroy = "http://twitter.com/statuses/destroy/%d.json"
twitter_dm_url = "http://twitter.com/direct_messages.json?page=%d"
twitter_dm_sent_url = "http://twitter.com/direct_messages/sent.json?page=%d"
twitter_dm_destroy = "http://twitter.com/direct_messages/destroy/%d.json"

class twexpire:
	
	def __init__(self, username, password, tw_url, tw_dest_url, logfile):
		self.username = username
		self.opener = self.get_opener(username, password)
		self.url = tw_url
		self.destroy_url = tw_dest_url
		self.logfile = logfile

	def get_opener(self, username, password):
		pwmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
		pwmgr.add_password(None, 'twitter.com', username, password)
		auth = urllib2.HTTPBasicAuthHandler(pwmgr)
		return urllib2.build_opener(auth)

	def get_timeline(self, page=1):
		tweets = cjson.decode(self.opener.open(self.url % page).read())
		out = []
		for tweet in tweets:
			tweet_ts = time.mktime(time.strptime( 
				tweet['created_at'], 
				"%a %b %d %H:%M:%S +0000 %Y"
			)) 
			user = ''
			# normal posts
			if 'user' in tweet:
				user = tweet['user']['screen_name']
			# for dm's
			if 'sender' in tweet:
				user = tweet['sender']['screen_name']
				if user == self.username:
					user = "to:%s" % tweet['recipient']['screen_name']
			out.append({
				'user': user,
				'fid': tweet['id'],
				'body': tweet['text'],
				'ts': tweet_ts
			})
		return out

	def get_old(self, period):
		page = 1
		threshold = time.time() - period
		old = []
		tweets = [1]
		while len(tweets) > 0:
			tweets = self.get_timeline(page)
			for t in tweets:
				if t['ts'] < threshold:
					old.append(t)
			page = page + 1
		return old

	def delete_tweet(self, twid):
		try:
			url = self.opener.open(self.destroy_url % twid, "id=%d" % twid)
			result = cjson.decode(url.read())
			return True
		except urllib2.HTTPError:
			return False

	def log_tweet(self, t):
		log = codecs.open(self.logfile, "a", "utf-8")
		log.write("%d %d %s %s\n" % (t['fid'], t['ts'], t['user'], t['body']))
		log.close()

	def prune(self, period):
		old = self.get_old(period)
		deleted = 0
		for t in old:
			self.log_tweet(t)
			if self.delete_tweet(t['fid']):
				deleted = deleted + 1
		return deleted

tw = twexpire(twitter_user, twitter_password, twitter_url, twitter_destroy, log_location % 'tweets.log')
dm = twexpire(twitter_user, twitter_password, twitter_dm_url, twitter_dm_destroy, log_location % 'dm.log')
dm_sent = twexpire(twitter_user, twitter_password, twitter_dm_sent_url, twitter_dm_destroy, log_location % 'dm.log')

a, b, c = tw.prune(period), dm.prune(period), dm_sent.prune(period)

print "twexpire: deleted %d tweets, %d received DMs, %d sent DMs." % (a, b, c)

