haya14busa

haya14busa’s memo

PythonでTwitterのタイムラインをストリーミングで読み上げさせるfor Mac[tweepy]

作りま……パクりました

初心者ながらPythonでツイッターのタイムライン読み上げさせたら面白いなーと思って頑張ってました。最初は何も考えずpython-twitterで試行錯誤してたんだけど、tweepyはStreaming APIにも対応しててtweepy使った方が楽なことを発見。んでググってたらそのままターミナルにストリーミングでTL流すスクリプト見つけたので、そこにSayKotoeriコマンドをプラスしてちょっと変えただけのほぼ丸パクリです。頑張って自分で作ったのは別記事のリストを擬似ストリーミングで読み上げさせる方なので、ご了承ください。

リストバージョン -> PythonでツイッターのリストのTLを擬似ストリーミングで読み上げさせる[tweepy] « haya14busa

tweepyのインストール

pip install tweepyでおけ。記事執筆現在API1.1にも対応してます。pipならバージョンは2.0でgithubには2.1が上がってるっぽいです。でも現場2.0で良さそう。公式ドキュメントのバージョンが1.4で古かったりして大変なので、バージョンに気を付けてググったり、dir()コマンドとかソース読んで自分で見ていくとわかりやすいっぽいです。

読み上げコマンド

Saykotoeri & SayKana , or Saykotoeri2コマンドが必要です。リンク先からインストールしてください。デフォルトのsayコマンドでKyokoさんをインストールして使うのもいいけどKyokoさんは漢字全然読めないからお察し。英語を読ませる場合、sayコマンドの発音は凄いと思います。英語用リストではsayコマンド使ってます。

SayKotoeri2の方がいろいろコマンドのオプションがあって使いやすいんだけど、女性1、いわゆるゆっくり(れいむ)の声がSayKotoeriの方でしか使えなかったんでやむなくSayKotoeri使ってます。SayKotoeri2で同じ声使う方法知ってる方がいらしたら教えてほしい。

それとSayKotoeriは英語が全然読めないのでことえり辞書で教育するといいっぽいです。(例: 読み->ついったー, 単語:Twitter)
それ用の辞書入れたら良いのだろうけど無料でいいやつは現状ないかも。シェアウェアなら->NADのカタカナ英語辞書(シェア)

一応正規表現でツイートに埋め込まれてるURLを「URL」, RTを「Retweet」に置換などはしてますがもっと置換のパターン増やせばよりストレスなく聞き取れるかも。

コード

twAloud.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Timelineをストリーミングで読み上げさせる
# 
# Author:   haya14busa
# URL:      http://haya14busa.com
# require:  SayKotoeri, Saykana or SayKotoeri2
# OS:       for Mac Only
# Link:     [twitterをターミナル上で楽しむ(python)](http://www.nari64.com/?p=200)

import tweepy
from tweepy import  Stream, TweepError
import logging
import urllib
from subprocess import call
import re
import sys, codecs

sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
sys.stdin = codecs.getreader('utf_8')(sys.stdin)

def get_oauth():
    CONSUMER_KEY='**********'
    CONSUMER_SECRET='**********'
    ACCESS_TOKEN_KEY='**********'
    ACCESS_TOKEN_SECRET='**********'

    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN_KEY, ACCESS_TOKEN_SECRET)
    return auth

def str_replace(string):
    string = re.sub('&.+;', ' ', string)
    # remove URL
    string = re.sub('(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)', 'URL', string)
    # remove quote
    string = re.sub('"', ' ', string)
    string = re.sub("'", ' ', string)
    string = re.sub('\/', ' ', string)

    string = re.sub('RT', 'Retweet', string)
    return string

class CustomStreamListener(tweepy.StreamListener):

    def on_status(self, status):

        try:
            print u'---{name}/@{screen}---\n   {text}\nvia {src} {created}'.format(
                    name = status.author.name,
                    screen = status.author.screen_name,
                    text = status.text,
                    src = status.source,
                    created = status.created_at)
            read_text = str_replace(status.text.encode('utf-8'))
            call(['SayKotoeri -s "-s 120" "{text}" >/dev/null 2>&1'.format(text=read_text)], shell=True)

        except Exception, e:
            print >> sys.stderr, 'Encountered Exception:', e
            pass

    def on_error(self, status_code):
        print >> sys.stderr, 'Encountered error with status code:', status_code
        return True # Don't kill the stream

    def on_timeout(self):
        print >> sys.stderr, 'Timeout...'
        return True # Don't kill the stream


class UserStream(Stream):

    def user_stream(self, follow=None, track=None, async=False, locations=None):
        self.parameters = {"delimited": "length", }
        self.headers['Content-type'] = "application/x-www-form-urlencoded"

        if self.running:
            raise TweepError('Stream object already connected!')

        self.scheme = "https"
        self.host = 'userstream.twitter.com'
        self.url = '/2/user.json'

        if follow:
           self.parameters['follow'] = ','.join(map(str, follow))
        if track:
            self.parameters['track'] = ','.join(map(str, track))
        if locations and len(locations) > 0:
            assert len(locations) % 4 == 0
            self.parameters['locations'] = ','.join(['%.2f' % l for l in locations])

        self.body = urllib.urlencode(self.parameters)
        logging.debug("[ User Stream URL ]: %s://%s%s" % (self.scheme, self.host, self.url))
        logging.debug("[ Request Body ] :" + self.body)
        self._start(async)

def main():
    auth = get_oauth()
    stream = UserStream(auth, CustomStreamListener())
    stream.timeout = None
    stream.user_stream()

if __name__ == "__main__":
    main()

使い方

Twitter Developersに登録してCONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN_KEY, ACCESS_TOKEN_SECRETをそれぞれ取得してコードの該当位置に書き込んでください。PINコードで認証とかは気が向いたらまた考える。

読み上げコマンド含め好きなように編集して使ってください。デフォルトだと一般的なゆっくりの声です。もちろん読み上げなしにして授業中や会社でばれないようにツイッターするのもよし。

あとはターミナルでpython twaloud.py 終了はCtrl-Cで強制終了してください。

それとデフォルトのTerminal.appよりもiTerm2だとコマンドクリックでURL開けるのでタイムライン読むのに便利です。

参考リンク

ライブラリ

リストバージョン

コード

読み上げ関連

Comments