[Python]メモ帳Twitterを作る（タイムライン表示編）

[[Python]メモ帳Twitterを作る（ツイート編） - Qiita](https://qiita.com/higuratu/items/1cf5d54a8925f0860262)の続編です。

上記の記事を投稿して1年以上経ってしまいました。
前回はツイートするところまで出来たので、今回はタイムラインを表示してみたよという備忘録。

PythonでTkinterというGUI作れるライブラリ使ってメモ帳twitter作るよ！

#前回のを少し修正
前回はツイート時に認証を通していたが、何度も認証通すのが面倒くさいので起動時に認証通すようにしてしまいました。
あとは可変があるキーはあとから修正しやすいように別ファイルに隔離しました。
起動時に認証通すと放置でセッションが切れてしまうため、
```twitter = OAuth1Session(CK, CS, AT, ATS)```
に関しては各関数にて認証を通します。

```python:config.py
#twitterの認証に必要なキー一覧
CONSUMER_KEY = "XXXXXXXXXXXXXXX"
CONSUMER_SECRET = "XXXXXXXXXXXXXXX"
ACCESS_TOKEN = "XXXXXXXXXXXXXXX"
ACCESS_TOKEN_SECRET = "XXXXXXXXXXXXXXX"
```

```python:notepad.py
# -*- coding: Shift_JIS -*-
import tkinter
import tkinter.font as font
import json
import config #config.pyの読み込み
from requests_oauthlib import OAuth1Session #OAuthのライブラリの読み込み

def tweet():
	twitter = OAuth1Session(CK, CS, AT, ATS)
	tweet = text_widget.get('1.0','end -1c')
	params = {"status": tweet}
	twitter.post("https://api.twitter.com/1.1/statuses/update.json",params = params)


#認証部分を起動時に実行
#config.pyから各キーの取得
CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET


root = tkinter.Tk()
#以下前回と変わっていないため略
```

#タイムライン上のツイートを取得する
ここから本題です。

twitterのタイムラインを取得して表示していきます。
URLとパラメーター指定してtwitterからタイムラインの取得を行います。

詳しい内容は[公式ドキュメント](https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline)参照
[日本語翻訳されたのもあるよ](http://westplain.sakuraweb.com/translate/twitter/Documentation/REST-APIs/Public-API/GET-statuses-home_timeline.cgi)

URLは```https://api.twitter.com/1.1/statuses/home_timeline.json```らしい。

パラメータはひとまず取得するツイート数のみ指定

```python:Notepad.py
def getTimeLine():
	twitter = OAuth1Session(CK, CS, AT, ATS)
	url = "https://api.twitter.com/1.1/statuses/home_timeline.json"

	params ={'count' : 200} #取得ツイート数 
	req = twitter.get(url, params = params)
```

#取得したツイートを整形する
取得したツイートを良い感じに整形します。

Tkinterでは文字コードが基本多言語面?と呼ばれU+0000～U+FFFFの文字しか使えないらしい。
難しい文字とか使えないよーってやつですね。
なのでそれ以外の文字を出力しようとすると下記のようなエラーが表示される。
下記エラーは🤔(U+1f914)を表示しようとしてエラーが出ています。🤔🤔🤔🤔🤔

```
_tkinter.TclError: character U+1f914 is above the range (U+0000-U+FFFF) allowed by Tcl
```

twitterはで顔文字が使われるなんてざらにあるのでそいつらは除外しつつ表示していきます。

なお今回は、ツイート内容、ユーザー名、投稿日時のみを対象としていますが、他にもいろいろな情報を持っています。
詳しくは公式ドキュメントを参照


```python:Notepad.py
def getTimeLine():
#~略~
    #レスポンスステータスコードが200(成功)だった場合のみ実行
	if req.status_code == 200:
        #取得されたツイートを1つづつリストに格納
	    timeline = json.loads(req.text)
        #ツイート1つ1つを整形して出力
	    for tweet in timeline:
	        #tweetの対応外文字削除
            #一文字ずつ精査し文字コードがU-FFFF(65535)以下の文字をリストに入れる。（ここもっとスマートな方法あったら教えてください）
	        char_list = [tweet['text'][i] for i in range(len(tweet['text'])) if ord(tweet['text'][i]) in range(65535)]
	        tweetstr = ''
            #リストに入っている文字をくっつけて文字列に
	        for i in char_list:
	        	tweetstr=tweetstr+i
	        #usernameの対応外文字削除
            #usernameもツイート内容と同じく対応
	        char_list = [tweet['user']['name'][j] for j in range(len(tweet['user']['name'])) if ord(tweet['user']['name'][j]) in range(65535)]
	        name = ''
	        for j in char_list:
	        	name=name+j
     #レスポンスステータスコードが200(成功)以外の場合はステータスコードを表示
	else:
	    print("ERROR: %d" % req.status_code)
```

#ツイートを表示する
あとは内容をGUI上に表示するだけ、
前回作成したエディット上に表示させます。
表示にはinsertを使います
Tkinterのドキュメントより
https://docs.python.org/ja/3/library/tkinter.ttk.html
>insert(pos, child, **kw)
>指定された位置にペインを挿入します。
>
>pos は文字列の "end" か整数のインデックスか管理されている子ウィンドウの名前です。 child が既にノート>ブックの管理対象だった場合、指定された場所に移動させます。

ということらしいです。なるほど
基本的に一つ目の引数に'end'を入れておけばいいって感じだと思います。
ユーザー名とツイート内容、ツイート時間と見やすいように1ツイートごとに点線で区切ってます。
ここはいい感じに。

あと何回も実行する場合に備えてはじめてにテキストボックスをクリアしておきます。

```python:Notepad.py
def getTimeLine():
	# テキストボックスをクリア
	text_widget.delete(1.0,tkinter.END)
    #~略~
        	text_widget.insert('end',name + '\n' + tweetstr+'\n')
	        text_widget.insert('end',tweet['created_at']+'\n')
	        text_widget.insert('end','----------------------------------------------------\n')
```

これでタイムラインへの表示まで完了しました。

あとはコマンドの追加をして今回作成した関数を実行できるようにして終わりです。
今回は開く(O)ボタンでタイムライン表示することにします。

```python:Notepad.py
filemenu.add_command(label="開く(O)...", command=getTimeLine)
```

#実行結果
![VfZWvuCA6FjMS7u1579597828_1579597888.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121230/2d9b3f26-a0c5-32fc-2f26-c73089ef1d5e.png)


#今回作成したプログラム
[[Python]メモ帳Twitterを作る（ツイート編） - Qiita](https://qiita.com/higuratu/items/1cf5d54a8925f0860262)のを含め今回作成したプログラムを下記に置いています。
[higuratujino/NotepadTwitter - GitHub](https://github.com/higuratujino/NotepadTwitter)

#さいごに
なるだけメモ帳っぽさを保ちたいためできるだけ違和感の内容に実装していきたいです
（色々詰め込めない言い訳）

python初心者なので実装で至らない点等ありましたらアドバイスお願い致します。
今回の課題点はツイート時間がUTC時刻になっちゃってること。

次回はツイートにたいしてリプライを返せるようなサムシングができたらいいなと妄想しております。
それかファボ＆リツイート

#参考資料
[tkinter.ttk --- Tk のテーマ付きウィジェット](https://docs.python.org/ja/3/library/tkinter.ttk.html#module-tkinter.ttk)
[12. Tk.Text の使い方 - 紫藤のページ](https://www.shido.info/py/tkinter12.html)
[pythonでツイッターのタイムラインの取得 - Qiita](https://qiita.com/sugurunatsuno/items/2faa069b475bb45da552)
[Get Tweet timelines - TwitterDeveloper](https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-home_timeline)
[Twitter 開発者 ドキュメント日本語訳](http://westplain.sakuraweb.com/translate/twitter/Documentation/REST-APIs/Public-API/GET-statuses-home_timeline.cgi)