去る3月11日、東北関東大地震が発生しました。現在もその影響を受けている地域が数あります。
被災者の方々には心からお見舞い申し上げます。
地震発生当初、都内にいた私は4時間かけて浦安市の自宅まで徒歩で帰りました。大地震が来た際には、そういうこともありえると考えたことはありましたが、まさか、現実になるとは。そして、浦安市内に入ると、そこには予想もしなかった光景がありました。
地盤の液状化です。
状況はこちらを参考にしていただければと思います。
地震・断水日誌の写真 3|M-Sea日誌
なんとか自宅までたどり着いた、翌朝、Twitterのタイムラインを見ていると、IT系、または、インターネットサービス業各社が被災地の支援を率先していることを知りました。
私にも何かできることはないか?
数日模索していました。
で、出た結論は、
プログラムを書くこと。
いろいろ考えましたが、やっぱりこれしかできないのです。
そこで、一番身近なところで、私も居住している地域のために何かしたいと考えました。浦安市には外国の方もたくさん居住されています。状況がなかなか把握できない方もいらっしゃいました。
プログラムは、浦安市公式Twitterアカウント@urayasu_kohoのツイートを英訳するボット、@urayasu_kohobotです(翻訳ばかりで能がないですが・・・)。
Google App Engine – Google Codeを利用しています(以降GAEとします)。GAEの開発環境には、
- Javaランタイム環境
- Pythonランタイム環境
があります。今回はPythonランタイム環境を使用しました。
開発には、こちらを参考にさせていただきました。
GAEでTwitter botを作った – すぎゃーんメモ
この環境に不慣れであること、急ぎで作ったこともあり、ちょっと雑なソースになっているかもしれませんが、ソースコードは以下の通りです。
・/bot/bot.py
import logging
import os
import oauth
import re
import urllib
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp import RequestHandler
from google.appengine.ext.webapp import WSGIApplication
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import urlfetch
from google.appengine.api import memcache
from django.utils import simplejson
class TwitterHandler(RequestHandler):
def __init__(self):
twit = TwitBot()
self.action = {
'timeline' :twit.timeline,
'update' :twit.update
}
def get(self):
action = self.action.get(self.request.get('action'))
if action:
logging.debug(action)
action()
template_values = {
'actions' :sorted(self.action.keys()),
'done' :self.request.get('action'),
'path' :self.request.path,
}
path = os.path.join(os.path.dirname(__file__), 'template.html')
self.response.out.write(template.render(path, template_values))
class TwitBot:
def __init__(self):
self.client = oauth.TwitterClient(
'********************************',
'***************************************',
None)
def timeline(self):
url = 'http://api.twitter.com/1/statuses/user_timeline.json'
params = {
'screen_name' :'urayasu_koho',
}
logging.debug(memcache.get('id'))
if memcache.get('id') != None :
params['since_id'] = memcache.get('id')
result = self.client.make_request(
url,
token = '************************************************************',
secret = '****************************************',
additional_params = params,
protected = True,
method = urlfetch.GET)
logging.debug(result.status_code)
if result.status_code == 200:
statuses = simplejson.loads(result.content)
statuses.reverse()
for status in statuses:
self.translate(status = re.sub('#urayasu', '', status['text']))
memcache.set('id', status['id'])
def update(self, status = None):
if status != None:
url = 'http://api.twitter.com/1/statuses/update.json'
if len(status) > 140:
status = status[0:139]
params = {
'status' : status.encode('utf-8'),
'count' :20
}
result = self.client.make_request(
url,
token = '************************************************************'',
secret = '****************************************'',
additional_params = params,
protected = True,
method = urlfetch.POST)
logging.debug(result.status_code)
logging.debug(result.content)
def translate(self, status = None):
if status != None:
logging.debug(status)
url = 'http://ajax.googleapis.com/ajax/services/language/translate'
opt = 'v=1.0&'+urllib.urlencode({'q':status.encode('utf-8')})+'&format=text&langpair=ja|en'
result = urllib.urlopen(url, opt)
translated = simplejson.loads(result.read())
if translated['responseStatus'] == 200:
self.update(status = translated['responseData']['translatedText'])
def main():
logging.getLogger().setLevel(logging.DEBUG)
application = WSGIApplication([
('/bot/', TwitterHandler),],
debug = False)
run_wsgi_app(application)
if __name__ == '__main__':
main()
・app.yaml
application: example.com version: 1 runtime: python api_version: 1 handlers: 〜中略〜 - url: /bot/.* script: bot/bot.py login: admin
・cron.yaml
cron: - description: update timeline url: /bot/?action=timeline schedule: every 1 minutes
説明不足で申し訳ありません。Google App Engineについての記事は、後日、何か書きたいと思います。
このボットについては、、、あまり、利用頻度も高くないとも思いますし、単なる自己満足かもしれません。ですが、少しでも何かの役に立てれば、という思いを込めて作成しました。
今、私にできること。
これが私の結論です。
urayasu_kohobot (urayasu_kohobot) on Twitter