Tweet はしないけど，tweepy は使ってみたい：ただコンソールに検索結果を表示するだけ

# 1.この記事で学べること・学べないこと

　学べること

- tweepyの基本的な利用方法の一部。
- tweepyを活用したプログラムの例。

　学べないこと

- Python のきれいな設計。
- tweepy のクリエイティブな利用方法。

# 2.実際のコード

```py3:twiiter.py
import tweepy
from collections import deque
from threading import Thread

# tweepy を使う前の必要最低限の準備
CONSUMER_KEY='XXXXXXX'
CONSUMER_SECRET='XXXXXXXX'
ACCESS_TOKEN='XXXXXXXX'
ACCESS_SECRET='XXXXXXXX'
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
# ここまで

class Format(object):
    """Class to provide with a variety of formats."""

    def __init__(self, tweet):
        """Store some data of tweets in a hash-table. """
        self.status = {
                'text': tweet.text,
                'author': tweet.author.screen_name,
                'reply_name': tweet.in_reply_to_screen_name,
                'created_at': tweet.created_at,
                }

class StreamingFormat(Format):

    def format(self):
        """Format tweet text readable with some information."""
        author     = self.status['author']
        created_at = self.status['created_at']
        string = '@\033[33m{}\033[0m:{}\n'.format(author, created_at)
        string += self.status['text']
        string += '\n'
        return string

class Memory(deque):
    """Class to have hashed tweet contents."""

    def __init__(self, capacity):
        """Define max capacity of self."""
        super().__init__()
        self.capacity = capacity

    def append(self, item):
        """Append unless over capacity."""
        if len(self) > self.capacity:
            self.popleft
        super().append(item)

class Producer(Thread):
    """Class to get tweets and avoid duplication. """

    def __init__(self, queue, api, query):
        """ Initialize memory to avoid duplication. """
        super().__init__(target=self.main)
        self.api = api
        self.queue = queue
        self.query = query
        self.memory = Memory(1000)
    
    def main(self):
        """ Thread to add tweets to queue. """
        while True:
            for tweet in self.twigen():
                if tweet is not None:
                    self.queue.put(tweet)
            """
            https://syncer.jp/what-is-twitter-api-limit
            上記サイトによると， Twitter には Tweet の取
            得制限があり，それ以上のアクセスをすると，
            制限がかかってしまうから，気をつける必要がある。
            全ての Tweet から検索するときには，15分間で
            180回までという制限があるので，5秒に一回の
            ペースが最大。ギリギリを攻める必要はないので，
            10秒おきぐらいに設定しておく。
            """
            time.sleep(10)

    def twigen(self):
        """Yield a tweet after hashing the tweet and memorizing it"""
        import hashlib

        tweets = self.api.search(q=self.query, count=100)
        for tweet in tweets:
            hashing = hashlib.md5(tweet.text.encode('utf-8'))
            hashed_tweet = hashing.hexdigest()
            if hashed_tweet in self.memory:
                yield None
            else:
                self.memory.append(hashed_tweet)
                yield tweet

class Consumer(Thread):

    def __init__(self, queue):
        super().__init__(target=self.main)
        self.queue = queue

    def main(self):
        """Take tweet from queue and print it."""
        while True:
            q = self.queue.get()
            f = StreamingFormat(q)
            print(f.format())
            time.sleep(1)

class TwitterStreamer(object):
    """Class to print formatted tweet data on console."""

    def __init__(self, api, query=None):
        from queue import Queue

        queue = Queue()
        Producer(queue, api, query).start()
        Consumer(queue).start()

if __name__ == '__main__':

    opts = {
            "api":tweepy.API(auth), 
            "query":'ラーテル' 
            }

    TwitterStreamer(**opts)

```

　`CONSUMER_KEY，CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_SECRET` の取得方法については割愛する。必ず必要なので用意する

```
@decimal1010:2016-04-02 10:36:36
ミツアナグマってラーテルのことか

@anaguma86:2016-04-02 09:53:06
バンドウイルカじゃなくハンドウイルカって表記にテンション上がるラーテル。

@kyuurin525:2016-04-02 09:28:04
なんか開いて5ページ目くらいでラーテルちゃんの虜になった

@tsube_kii:2016-04-02 08:05:31
ライオンガードでカイオンと一緒にいる動物の種類が全然わかんなかったんだけどラーテルって動物なのね……

```

実行するとこんな感じでコンソールに出力され続ける。