Posting to the Twitter API on an admin change
For context, I've been working on a project that involves submitted messages going through a manual review process - once they've been approved in the admin, each message should be posted to Twitter. My Twitter API script is over here, for reference.
I had originally thought I'd set up a cron job to run the posting script, and I still might go back to that if the manual review from the admin starts to take too much time. Doug Hellman suggested using signals, but after some consideration I realized that Django signals would probably be overkill - it's a little disappointing because I've never actually gotten signals working in a project. I need a use case to make me figure it out, and I thought this would be it.
Instead I was browsing some old code and realized that, oh yeah, I can put a save method in my admin class ... honestly, I'm embarrassed that I didn't think of it first - it's a no-brainer.
I just wrapped all the script code in a method:
#!/usr/bin/python
import MySQLdb as Database
import base64, urllib, urllib2
def main():
db = Database.connect("myhost", "myuser", "mypasswd", "mydbname")
cursor = db.cursor(Database.cursors.DictCursor)
sql = """SELECT * FROM twitter_message WHERE approved=1 AND posted=0"""
cursor.execute(sql)
data = cursor.fetchall()
username = "twitter_username"
password = "twitter_password"
for record in data:
message = record["message"]
message = message.replace(',', '')
post_data = {'status': message}
request = urllib2.Request('http://twitter.com/statuses/update.json')
request.headers['Authorization'] = 'Basic %s' % ( base64.b64encode(username + ':' + password),)
request.data = urllib.urlencode({'status': message})
response = urllib2.urlopen(request) # The Response
""" the most painful part is hacking up the response to get at the status id """
a = response.read()
b = a.split(',') ## convert the whole thing to a list
c = b[30] ## hope the id is always the 30th item in the list
d = int(c[5:]) ## strip off first part of string, leave behind the number
if response.code == 200 and type(d) == int:
record_id = record["id"]
sql = """UPDATE twitter_message posted=1, post_date=NOW(), status_id=%s WHERE id=%s""" %(d, record_id)
cursor.execute(sql)
cursor.close()
db.close()
if __name__ == "__main__":
main()
Then imported it as a module and called it from the relevant admin.py:
import twitterpost
class TweetAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.save()
if obj.approved: twitterpost.main()
list_filter = ('approved',)
Note that the script is called after the obj.save() - the script only acts on records that have already been marked 'approved'.
That's it. Three extra lines of code (six if you count what I added to the script).
Katie Cunningham - 2009-04-07 10:09:54
This is incredibly helpful! We recently had someone speak up about a need for something like this, and this should do the trick!
If we do end up using it, I'll let you know. Then you can put NASA on your resume!
lifewithryan - 2009-04-07 13:37:42
I was trying to tweet this from my blackberry the other day when I read your post, but it wasn't working, so I gave up and never got to reply back -- but overriding the save method was going to be my suggestion...*honest*
Ash Christopher - 2009-04-07 16:09:49
I used Python Twitter Tools (http://mike.verdone.ca/twitter/) for twitter integration. It is simple to use, forward compatible (so long as Twitter continues to use REST) and it has all sorts of other goodies in addition to the library. IRC bot, console client, etc.
Barbara - 2009-04-07 18:22:49
For everyone suggesting python-twitter: I agree that it's a great set of tools, but I mentioned in my earlier post that I decided to write my own because I don't need that much functionality - for my own project, I'm only doing posts, so I didn't want all the code overhead.
mksoft - 2009-04-17 23:58:25
Since you already have the object from save_model, it seems inefficient to you execute another connection/query do the db (and coupling it with mysql) instead of passing obj to the function (plus main is not a very good name - a descriptive one would be better).
fashion - 2010-07-16 21:35:52
php is the best language for me to use in api
<A href="http://www.timberland6inch.com/">mens tim - 2010-07-21 03:42:10
There were timberland 6 inch sensitivity and a beauty to her that have nothing to do with timberland 6 inch boots looks. She was one to be listened to, whose words were so easy to take to timberland boots sale heart.I used to find notes left in the collection basket, beautiful timberland boots outlet notes about my homilies and about the writer's black timberland boots thoughts on the daily scriptural readings. The person who penned the notes mens timberland boots would add reflections to my thoughts and would always include some timberland pro boots quotes from poets and mystics he or she had white timberland boots read and remembered and loved. The notes fascinated black timberland shoes uk me. Here was someone immersed in a search for truth and beauty. Words had been cheap timberland boots treasured, words that were beautiful. And I felt as if the words timberland waterproof boots somehow delighted in being discovered, for they were obviously very generous to the as yet anonymous timberland work boots writer of the notes. And now this person was in turn learning the secret of sharing them. Beauty so shines when given away. The only truth that exists timberland hiking boots is, in that sense, free. http://www.timberland6inch.com/






Ronny - 2009-04-07 06:39:11
I've used python-twitter (http://code.google.com/p/python-twitter/) in one of my Django projects and I'm very happy with it.