October 24, 2012

青空文庫の書き出しをつぶやくTwitter Bot


青空文庫を「ほんのまくら」みたいにでも使った青空文庫の書き出したちをつぶやくTwitter Botを作ってみた.
http://twitter.com/aozoramakura

1時間毎に
[書き出し] [カードへのリンク] #aozoramakura
ってつぶやく.


Google App EngineでBot


もうPythonのマイクロフレームワーク「Flask」でもApp EngineのTwitter Botは15行じゃ書けない -を参考にして以下を使う.


TwitterにOAuth認証して投稿する.Google APIで統計情報の取れるURL短縮を行う.


Flask


GoogleAppEngineLauncherでNew Applicationをつくったらgigq/flasktodoからダウンロードしたのをそのまま突っ込んでapplication.py, app.yaml, cron.yamlを編集.app.yamlでアプリ名を変えるのを忘れずに…

編集後のapplication.pyは以下.

# -*- coding: utf-8 -*-
from django.utils import simplejson as json
from random import choice
from flask import Flask, request
import tweepy
import httplib2
from apiclient.discovery import build
from google.appengine.api import memcache
from oauth2client.appengine import AppAssertionCredentials
import datetime
from google.appengine.ext import db
app = Flask(__name__)
# OAuth for Twitter API
CONSUMER_KEY = 'xxxxxxxx'
CONSUMER_SECRET = 'xxxxxxxx'
ACCESS_TOKEN = 'xxxxxxxx'
ACCESS_TOKEN_SECRET = 'xxxxxxxx'
# OAuth for Google API
credentials = AppAssertionCredentials(
scope='https://www.googleapis.com/auth/urlshortener')
http = credentials.authorize(httplib2.Http(memcache))
service = build('urlshortener', 'v1', http=http)
# store shortend url
class Shortened(db.Model):
short_url = db.StringProperty()
long_url = db.StringProperty()
date = db.DateTimeProperty(auto_now_add=True)
@app.route('/post_update')
def post_update():
# choice data
source = json.loads(open("makura.json").read())
data = choice(source)
# set text
if len(data['text']) > 100:
text = data['text'][:100] + '...'
else:
text = data['text'][:100]
# get shortened url
long_url = 'http://www.aozora.gr.jp/cards/%s/card%s.html' % (data['jinbutsu'], data['sakuhin'])
credentials.refresh(http)
short_url = service.url().insert(body={"longUrl": long_url}).execute()['id']
# put to datastore
s = Shortened()
s.long_url = long_url
s.short_url = short_url
s.put()
# post to twitter
post = '%s %s #aozoramakura' % (text, short_url)
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
api = tweepy.API(auth_handler=auth)
api.update_status(post)
return post
if __name__ == '__main__':
app.run()
view raw application.py hosted with ❤ by GitHub



Tweepy


Tweepyはtweepy/tweepyからダウンロード.tweepyフォルダをアプリのトップにコピーするだけ.インストール必要はない.


書き出しのデータ


makura.jsonをアプリのフォルダのトップに置く.青空文庫から抜き出した.辞書のリスト.
[{u'ebk': u'',
u'html': u'http://www.aozora.gr.jp/cards/001235/files/49858_41918.html',
u'jinbutsu': u'001235',
u'sakuhin': u'49858',
u'text': u'\u3042\u308b\u4eba\u3073\u3068\u306f\u3001\u300c\u30aa\u30c9\u30e9\u30c7\u30af\u300d\u3068\u3044\u3046\u8a00\u8449\u306f\u30b9\u30e9\u30f4\u8a9e\u304b\u3089\u51fa\u3066\u3044\u308b\u3001\u3068\u3044\u3063\u3066\u3001\u305d\u308c\u3092\u6839\u62e0\u306b\u3057\u3066\u3053\u306e\u8a00\u8449\u306e\u6210\u7acb\u3092\u8a3c\u660e\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u308b\u3002'}, ...]


字数制限


Twitterには140字という制限があるから,100字を超えてる書き出しは101字以降を省略省略.URLは自動的にt.coに.t.coの文字数はGET help/configuration | Twitter Developersにある通り.https://api.twitter.com/1/help/configuration.jsonにアクセスすれば確認できる.確認は1日1回までにしてね,とのこと.今だとhttpで20字,httpsで21字.


Twitter APIでOAuth認証


Create an application | Twitter Developersで新しいアプリをつくる

投稿したいのでSettingsからRead and Writeにする


DetailsからAccess tokenを生成


OAuth ToolsからConsumer key, Cunsumer secret, Access token, Access token secretを取得



Google APIでURL短縮


OAuth認証してGoogle URL Shortenerで短縮します.OAuthを通すと独自の短縮URLが手に入ります.App EngineでGoogle APIを使うためにアプリのディレクトリで

$ enable-app-engine-project .

とすれば必要なファイルがアプリのディレクトリにコピーされる.

URL Shortener API…
Getting Started - URL Shortener API — Google Developers
api-python-client-doc.appspot.com/urlshortener_v1.html

Google APIをPythonで使う…
Getting Started - Google APIs Client Library for Python — Google Developers

Google APIをApp Engineで使うには…
Using Google App Engine - Google APIs Client Library for Python — Google Developers

サンプル…
/ - google-api-python-client - Google APIs Client Library for Python - Google Project Hosting


TweetしたURLをデータストアに保存


元urlと短縮urlと発行した日時.

データストアの使用 - Google App Engine — Google Developers


cronで1時間ごとに投稿


cron.yamlの設定.

Python 用クローンを使用したスケジュールされたタスク - Google App Engine — Google Developers

cron:
- description: post update to twitter
url: /post_update
schedule: every 60 minutes synchronized
timezone: Asia/Tokyo
view raw cron.yaml hosted with ❤ by GitHub



管理者のみ投稿可能に


app.yamlの設定.管理者のみアクセス可能でもcronは走る.cronのみに反応させる時は以下のHTTPヘッダを確認.
X-AppEngine-Cron: true

Python 用クローンを使用したスケジュールされたタスク - Google App Engine — Google Developers

application: aozoramakura
version: 1
runtime: python
api_version: 1
handlers:
- url: /post_update
script: app.py
login: admin
view raw app.yaml hosted with ❤ by GitHub



App Engineの設定


App Engineのダッシュボードで,Administration > Application Settings > PerformanceでMax Idle Instanceを1に設定



Billing Status


4時間走らせて

Frontend Instance Hours 4% 1.01 of 28.00 Instance Hours
Code and Static File Storage 1% 0.01 of 1.00 GBytes

これら以外0


アイコン


ほったらかし温泉で撮った空

October 19, 2012

青空文庫を「ほんのまくら」みたいに

青空文庫の作品の書き出しを抜き出して夏に紀伊国屋でやってた「ほんのまくら」フェアっぽくしてみました.「ほんのまくら」の書籍一覧はこちら


あおぞらまくら

  • 取得できた書き出しの数は8969件です.適当にやったのでうまく抜き出せてないのも結構あると思います
  • 12秒にひとつずつ新しい書き出しが追加されます
  • ヘッダ部分をクリックすると新しい書き出しが追加されます
  • ランダムで表示させているので放っておくとずっと伸びていきます
  • 書き出しをクリックすると青空文庫の該当作品のページに飛べるようにしたつもりです
  • 元データはhttps://github.com/aozorabunko/aozorabunkoからクローンしたものです

表示には凄まじくレスポンシブ!!とちょっと話題になっていたNHKスタジオパークでも使われてるjQuery Masonryを使いました.なんでもPinterestっぽく仕上がります.Masonry /méɪsnri/.