職場のプロキシーがあれで、ブラウザからだとリロードしまくらないとちゃんと表示してくれないので、TwitTermベースでつくってみた。
urllib2でBasic認証のさせ方を覚えた。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
username = "user"
password = "password"
interval = 240
from datetime import datetime, timedelta
import os
import sys
import re
import time
import types
from threading import Thread
import urllib
import urllib2
import webbrowser
from xml.dom.minidom import parse
import thread
import warnings
warnings.filterwarnings("ignore")
try:
import readline
except ImportError:
sys.stderr.write('INFO: For better line editing capability, '
'install "readline" module.\n')
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, 'http://api.wassr.jp/', username, password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)
tagText = lambda node, tagName: \
node.getElementsByTagName(tagName)[0].firstChild.nodeValue
class TwitterReader(Thread):
target_url ='http://api.wassr.jp/statuses/friends_timeline.rss'
def __init__(self):
Thread.__init__(self)
self.last_id = 0
def run(self):
while not TwitterWriter.already_exit:
req = urllib2.Request(self.target_url)
req.add_data("since_id=" + str(self.last_id))
e = None
try:
e = parse(file=urllib2.urlopen(req))
except Exception, ex: # HTTPError or ExpatError
sys.stderr.write(str(ex) + " will retry after %s sec\n" % interval)
if type(e) != types.NoneType:
for status in reversed(e.getElementsByTagName("item")):
screen_name = tagText(status, "author")
text = tagText(status, "description")
print_status(screen_name, text,
time_created_at(tagText(status, "dcterms:modified")))
for i in range(interval):
if TwitterWriter.already_exit:
break
time.sleep(1)
def print_status(screen_name, text, (rel_time, created_at)):
print "[%s] %s (%s)" % (screen_name, text, rel_time)
plural = lambda n: n > 1 and "s" or ""
def time_created_at(s):
"""
recieving text element of 'created_at' in the response of Twitter API,
returns relative time string from now.
"""
try:
date = time.strptime(s, "%Y-%m-%dT%H:%M:%S+09:00")[:-2]
except ValueError:
return "", ""
created_at = datetime(*date)
d = datetime.now() - created_at
if d.days:
rel_time = "%s days ago" % d.days
elif d.seconds > 3600:
hours = d.seconds / 3600
rel_time = "%s hour%s ago" % (hours, plural(hours))
elif 60 <= d.seconds < 3600:
minutes = d.seconds / 60
rel_time = "%s minute%s ago" % (minutes, plural(minutes))
elif 30 < d.seconds < 60:
rel_time = "less than a minute ago"
else:
rel_time = "less than %s second%s ago" % (d.seconds, plural(d.seconds))
return rel_time, created_at.strftime("%H:%M:%S")
class TwitterWriter(Thread):
target_url = "http://twitter.com/statuses/update.xml"
already_exit = False
def __init__(self):
Thread.__init__(self)
def run(self):
while 1:
try:
update_text = raw_input().strip()
if hasattr(sys, "winver"):
update_text = update_text.decode("shift_jis", "replace").encode("utf-8")
except EOFError: # EOFError
TwitterWriter.already_exit = True
break
if len(update_text):
params = {}
params['status'] = update_text
up = urllib2.urlopen('http://api.wassr.jp/statuses/update.json', urllib.urlencode(params))
if up.code == 200:
print "(update) [%s] %s " % (username,update_text)
TwitterWriter.already_exit = True
def main():
if username == "" or password == "":
print "Error: Please specify your twitter account info in", sys.argv[0]
sys.exit(1)
print "Note: CTRL-D (or CTRL-C) to exit"
reader = TwitterReader()
writer = TwitterWriter()
reader.start()
writer.start()
reader.join()
writer.join()
if __name__ == '__main__':
main()
まだリプライとかできないけど快適だ。