[Python] TwitterAPIを使用しGUI(tkinter)アプリをexe化するまでにつまずいた事をメモ代わりに

↓作成物→グラブルTwitter救援検索アプリ(クリップボードにコピー+通知音+python環境無しでも動くwindows用GUIアプリ)
https://github.com/EnableAX/gbf-search-app.git

プログラミングを始め2か月弱で何か作ってみるといいと言われ作った際の詰まったポイントを簡易的に書いていきます。
作った物はTwitterAPIを利用しグランブルーファンタジーの救援IDをクリップボードにコピーするまでのアプリ
をpyスプリクトではなくPython環境が入っていないwindowsのパソコンでも使用できるものを作りたかった。
きっかけとなったpyスプリクトは下記URLにて配布されております。
https://github.com/bookii/gbf-rapid-search


環境=win10(64bit), Python 3.7.4, VScode 1.4
exe化時=Python 3.4.4, py2exe=0.9.2.2

####tkinterのRadiobuttonから二つの変数を読み込みたい
Radiobuttonを使用し救援に参加する際に敵のLvと正式名称を二つの変数を取得しようとしたときに
valueに挿入する変数をリストや辞書にして試したのだが自身の書き方がよくなかったのかうまく拾えず最終的には
文字列としてファイルに書き出し検索開始時にそのファイルから文字列をリストに変換し変数を割り当てて解決した。
以下はコード例です。
まず初めに文字列をファイルに書き出す

```
def maguna():
    enemy_s = StringVar()
    #OKボタン用コマンド ここでテキストファイルに書き出す
    def enemy_set():
        Enemy = enemy_s.get()
        with open(enemy_n, mode="w") as f:
            f.write(Enemy)
        sub_win.destroy()
    tiamat50 = ttk.Radiobutton(
            frame1,
            padding=5,
            text='Lv50 ティアマト・マグナ',
            value=("50\nティアマト・マグナ"), #変数に入れる文字列のリストとして分けたい部分に改行(\n)を入れる
            variable=enemy_s)
    tiamat50.grid(row=0, sticky=W)
```

その文字列の入ったファイルを読み込む際にリストに変換し変数に割り当てる

```
#敵情報読み込み
with open(enemy_n) as fe:
    Enemy = [s.strip() for s in fe.readlines()] 
```

上記以外は調べれば出てくるページを参考に記述できたので
exe前までに参考にしたサイトを乗せておきます。
ファイル関連↓
https://qiita.com/tortuepin/items/4a0669d8f275e966229e
http://hk29.hatenablog.jp/entry/2018/05/01/112953
json→https://note.nkmk.me/python-json-load-dump/
tkinter↓
分かりやすい機能説明→https://python.keicode.com/advanced/tkinter.php
配置→https://www.shido.info/py/tkinter2.html
サブメニュー→https://codeday.me/jp/qa/20190822/1499460.html
TwitterAPI↓
https://qiita.com/snofra/items/3189bb0a9605ea8e4ce6

###tkinterでmain.loop時にメインフレームがフリーズする
一通りコードが書けデバックスタートし敵を選択、APIキーを入れStartボタンを押した瞬間にフリーズ・・・
何故だと調べたらmain.loop時にStartボタン等によりループが始まるとメインスレッドが止まるらしい。
勝手にマルチスレッド処理になるものだと思っていたので
メインフレームのみフリーズしていたわけだ(クリップボードへのコピーは行われていた為)
調べてみたら通常はシングルスレッドで稼働していて別の関数によるループが始まると
使っていたスレッドがそちらに使われるのでメインがフリーズすると個人的には解釈した。
そのフリーズを防ぐのに`threading`を使用する。

下記URLに注意点や使い方が説明してあるので参考にした。
https://www.haya-programming.com/entry/2019/01/20/012926
join()を例外や停止フラグのbreakの下に置くとエラー等が出ずちゃんと動くようになったので解決。

###exe化の選択肢＝pyinstaller か py2exe
とりあえず簡潔にpyinstallerはダメでした。
exeがそもそも起動しない。かなり調べていろいろオプションも設定したができなかったのでヤメ

py2exeがpython3.4までなので公式からDLしてインストール
初めにsetup.pyを書くのだが探せばすぐ見つかるのだがbundle_filesが大半2になっていて
起動しないので下記参考に
https://shrkw.hatenablog.com/entry/20080825/py2exe_with_tkinter
ターミナル上で別バージョンのpythonを実行する際

```
py -3.4 -m #ベース
py -3.4 -m pip install #モジュール名

py2exeを使用する際
py -3.4 -m setup_py2.py py2exe ← ×
py -3.4 -m setup_py2 py2exe　← ○
.pyをつけてて何回No nameって出た事か・・・
-m このオプションのおかげらしい
```

それでも起動しなかった・・・ファイルの読み込み場所のpath処理がpy2exeを使う際に
色々変えないといけないらしいので調べ解決。参考サイトは下記
https://note.nkmk.me/python-script-file-path/
しかしpy2exeは`__file__`が使えないので`sys.argv[0]`に変えること。
例(同じディレクトリ内にあるtoken_list.jsonを読み込む場合)

```
token_list = os.path.join(os.path.dirname(sys.argv[0]), "token_list.json")
token_check = os.path.isfile(token_list)
```

これだけやってmissing modulesが21個も出てたがtkinterの起動と敵、APIキーの設定までは出来た。
あとはスタートとストップができれば完成だがスタートを押した瞬間に
エラーログが出てくる＆何も変化しない(フリーズはしてない)

そこでエラーログ内を見てみると
[OSError: Could not find a suitable TLS CA certificate bundle, invalid path]

と出ている・・・調べ、どうやらrequests処理中のcertifiが読み込めない？zipファイル？らしいが
exeになっていて解凍もできないしそもそもなんだこれはということで調べたらssl認証らしい。
つなぐ先はTwitterだし安全だと判断し認証をしない事にする。
requests処理の後に`verify = False`を追加。参考サイトは下記
https://dev.classmethod.jp/server-side/python/how-to-manage-ca-root-certs-for-requets-library/

再びexeを書き出し実行しちゃんと動いた事を確認したが終了時にエラーログが出ている・・・

[InsecureRequestWarning]

ssl証明書のチェックを無視しているためにでるエラーらしいので下記参考にしエラーを表示しない事に
※Twitter相手であり安全であると判断し無視しています
http://73spica.tech/blog/requests-insecurerequestwarning-disable/

再び書き出し無事エラーも出なくなり別PCでも動いたので完成しました。

####後書き
urllibのモジュール読み込みエラーが出ているからcertifiがうまくいかないのかな?
そのうち調べますかね