20200227のGitに関する記事は11件です。

【初心者】Heroku、Flask、Python、Gitでアップロードする方法(その④)

Heroku、Flask、Pythonについて、Progateやドットインストール、Qiita等でひととおり学習したので、まとめてみる

(1)作業ディレクトリを作成
(2)仮想環境を設定
(3)必要なフレームワークとWEBサーバーをインストール
(4)FlaskファイルをPythonで作成
(5)Flaskファイルを実行してみる

(6)Herokuにデプロイする
  ①Herokuにアカウント登録する
  ②HomebrewでHerokuをインストールする
  ③Gitを用意する
  ④Herokuにアプリを作成する
  ⑤ローカルアプリとHerokuアプリを紐つける

  ⑥Herokuへのデプロイに必要なファイルを作成する
  ⑦Herokuへデプロイする

(7)エラー対応
  ①heroku ps:scale web=1で正常になるケース
  ②heroku ps:scale web=1で正常にならないケース
(8)ファイルを更新する

(7)エラー対応

以下を入力し、デプロイすると、ブラウザに以下のようなエラーメッセージが表示された。

heroku open

スクリーンショット 2020-02-27 21.07.56.png

ターミナルに以下を入力し、ログを確認する。

heroku logs --tail

すると、

heroku[router]: at=error code=H14 desc="No web processes running" 

というメッセージ。

①heroku ps:scale web=1で正常になるケース

code=14をググると、以下のサイトに詳細が書かれている
https://github.com/herokaijp/devcenter/wiki/error-codes

heroku ps:scale web=1

として、

heroku open

とすると、
スクリーンショット 2020-02-26 22.38.02.png

無事、正常にデプロイできた。

②heroku ps:scale web=1で正常にならないケース

code=14をググると、以下のサイトに詳細が書かれているが、改善しなかった。

もう一度、デプロイに必要なファイルを確認すると、Procfileにタイポを発見。
(誤)web:gunicorn hello:app --log-file -

(正)web: gunicorn hello:app --log-file -
:の後ろに空白がなかった。

修正し、再度以下の通り進める。

git status

以下のように更新したファイルが表示された。

modified:   Procfile

今度は、'the-second'として入力。

git commit -m'the-second'
git push heroku master
heroku open

無事、ブラウザに以下のように表示され、正常にデプロイできた。
スクリーンショット 2020-02-26 22.38.02.png

(8)ファイルを更新する

基本的に(7)の②の要領でファイルを追加、または修正したものをHerokuにデプロイすればOK。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者】Heroku、Flask、Python、Gitでアップロードする方法(その③)

Heroku、Flask、Pythonについて、Progateやドットインストール、Qiita等でひととおり学習したので、まとめてみる

(1)作業ディレクトリを作成
(2)仮想環境を設定
(3)必要なフレームワークとWEBサーバーをインストール
(4)FlaskファイルをPythonで作成
(5)Flaskファイルを実行してみる

(6)Herokuにデプロイする
  ①Herokuにアカウント登録する
  ②HomebrewでHerokuをインストールする
  ③Gitを用意する
  ④Herokuにアプリを作成する
  ⑤ローカルアプリとHerokuアプリを紐つける

  ⑥Herokuへのデプロイに必要なファイルを作成する
  ⑦Herokuへデプロイする
(7)エラー対応
  ①heroku ps:scale web=1で正常になるケース
  ②heroku ps:scale web=1で正常にならないケース
(8)ファイルを更新する

⑥Herokuへのデプロイに必要なファイルを作成する

デプロイに必要なファイルを2つ作成する。

まず、Herokuでアプリを動かすために、どんなライブラリが必要かを伝えるファイルとして、requirements.txtを作成する。
my-projet内で以下を入力する。

pip freeze > requirements.txt

requirements.txtには、今までインストールしたライブラリ一覧が表示されたファイルが作成される。

次に、Herokuでアプリを起動した際に最初に実行されるコマンドを記載したファイルとして、Procfileを作成する(拡張子の指定はしない)。

touch Profile

作成したProcfileを開き、以下を入力して保存する。

web: gunicorn hello:app --log-file -

hello.pyの中の、appというサーバーを開くという意味になる。
webの後ろは、必ずスペースを付けないと、後々Herokuにデプロイした際にエラーとなるので注意が必要。

⑦Herokuへデプロイする

まず、以下をターミナルに入力し、今のmy-project内のファイルの状態を表します。

git status

次に、どのファイルをHerokuにデプロイするのかを指定します。
全てのファイルを指定することとし、以下を入力。

git add .

その後に以下のように入力し、再度ステータスを確認すると、ファイルをデプロイするための準備が整った状態を確認できる。

git status

次に、これらのファイルはどういう内容が更新されたのか、何が変更されたのかを説明する必要を記載する必要がある。今回は'the-first'として、以下のように入力。

git commit -m'the-first'

再度ステータスを確認すると、

git status

全てのファイルをデプロイできる状態にした(コミットした)と表示される。

On branch master
nothing to commit, working tree clean

これでHerokuにファイルをpushする(デプロイする)準備が整った。
以下を入力し、Herokuにpush(デプロイ)する。

git push heroku master

最後に以下を入力してデプロイを確認する。

heroku open

ブラウザが開き、以下のように表示されれば成功。
スクリーンショット 2020-02-26 22.38.02.png

【超初心者】Heroku、Flask、Python、Gitでアップロードする方法(その④)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者】Heroku、Flask、Python、Gitでアップロードする方法(その②)

Heroku、Flask、Pythonについて、Progateやドットインストール、Qiita等でひととおり学習したので、まとめてみる

(1)作業ディレクトリを作成
(2)仮想環境を設定
(3)必要なフレームワークとWEBサーバーをインストール
(4)FlaskファイルをPythonで作成
(5)Flaskファイルを実行してみる

(6)Herokuにデプロイする
  ①Herokuにアカウント登録する
  ②HomebrewでHerokuをインストールする
  ③Gitを用意する
  ④Herokuにアプリを作成する
  ⑤ローカルアプリとHerokuアプリを紐つける
  ⑥Herokuへのデプロイに必要なファイルを作成する
  ⑦Herokuへデプロイする

(7)エラー対応
  ①heroku ps:scale web=1で正常になるケース
  ②heroku ps:scale web=1で正常にならないケース
(8)ファイルを更新する

(6)Herokuにデプロイする

①Herokuにアカウント登録する

以下のHerokuページにアクセスして、Herokuのアカウント登録をする。
https://www.heroku.com/

②HomebrewでHerokuをインストールする

まずはHomebrewというパッケージマネージャーをインストールする。
以下のHomebrewページにアクセスして、表示されているスクリプトをターミナルに貼り付けて実行する。
https://brew.sh/index_ja

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

その後、以下をターミナルに入力してHerokuをインストールする。

brew install heroku/brew/heroku

先ほど作成したアカウントでログインする。
スクリーンショット 2020-02-26 20.59.04.png

③Gitを用意する

Gitについての詳細は以下のページを参考にした。
https://backlog.com/ja/git-tutorial/
https://prog-8.com/languages/git

Gitのバージョンを確認してみる。

git version

Gitがインストールされていれば、以下の通りとなる。

git version 2.20.1 (Apple Git-117)

初期設定の確認として、以下をそれぞれ入力する。

git config user.name
git config user.email

何も反応なければ、以下の例のように名前やemailを登録する。
(登録しなければ、Gitが正常に動かない)

git config user.name "hogehoge"
git config user.email "example@gmial.com"

④Herokuにアプリを作成する

ローカルで作成したhello.pyアプリを、Heroku(リモート)を結びつける必要がある。
まずは、以下のようにHerokuにログインする。

heroku login

以下のように表示されたら、q以外の任意の文字を入力するとHerokuページが表示される。

Press any key to open up the browser to login or q to exit:

ログインすると以下のような画面となる
スクリーンショット 2020-02-26 20.59.04.png

その後ターミナルで、Herokuに、例として、sample-noonnoon というアプリを作成することとし、以下のように入力する。

 heroku create sample-noonnoon

これでHerokuにアプリが作成された。Herokuページにログインし、ダッシュボードを確認すると、以下のようにsample-noonnoonが確認できる。
スクリーンショット 2020-02-27 19.10.03.png

⑤ローカルアプリとHerokuアプリを紐つける

ローカルで作成したアプリと、Herokuで作成したアプリを紐つける。
まずは、my-project内で、Gitを初期化する。

git init

本当に初期化されたかどうか以下を入力し確認する。(.gitが表示されていればOK)

ls -a

Gitを初期化することで、ディレクトリmy-projedt内の変更履歴を管理できるようになった。
次にGitとHerokuを紐つける。

heroku git:remote -a sample-noonnoon

こうすることでローカル上のアプリとHerokuのアプリが紐つく。

set git remote heroku to https://git.heroku.com/sample-noonnoon.git

【超初心者】Heroku、Flask、Python、Gitでアップロードする方法(その③)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者】Heroku、Flask、Python、Gitでアップロードする方法(その①)

Heroku、Flask、Pythonについて、Progateやドットインストール、Qiita等でひととおり学習したので、まとめてみる

(1)作業ディレクトリを作成
(2)仮想環境を設定
(3)必要なフレームワークとWEBサーバーをインストール
(4)FlaskファイルをPythonで作成
(5)Flaskファイルを実行してみる
(6)Herokuにデプロイする
  ①Herokuにアカウント登録する
  ②HomebrewでHerokuをインストールする
  ③Gitを用意する
  ④Herokuにアプリを作成する
  ⑤ローカルアプリとHerokuアプリを紐つける

  ⑥Herokuへのデプロイに必要なファイルを作成する
  ⑦Herokuへデプロイする

(7)エラー対応
  ①heroku ps:scale web=1で正常になるケース
  ②heroku ps:scale web=1で正常にならないケース
(8)ファイルを更新する

(1)作業ディレクトリを作成

デスクトップ上でいつも作業してるので、今回もデスクトップ上にディレクトリを設置した。
まず、Macのターミナルを起動して、cd desktop と入力、次にmkdir myprojectと入力、これで、デスクトップ上に、ディレクトリmy-projectを作成。

(2)仮想環境を設定

次に ターミナルで、cd myproject とし、ディレクトリmy-project内に移動。
Pythonのvenvという仮想環境を提供する機能を使ってローカルに開発環境を設定する。
仮想環境は、python -m venv ●●●と設定。●●●は任意の名称で良いが、任意のサブディレクトリが作成され、サブディレクトリ内に仮想環境ファイルが作成される。ただし今回は、python -m venv . としてmyproject直下に仮想環境ファイルを作成した。サブディレクトリ下に仮想環境ファイルを作成すると、後述するHerokuへのデプロイ時になぜかエラーが発生したため、直下に作成した。

python3 -m venv .

その後、仮想環境を有効化するために以下のように入力する。

source bin/activate

ちなみに仮想環境を無効化する場合は、以下のように入力する。

deactivate

(3)必要なフレームワークとWEBサーバーをインストール

次に、フレームワークをインストールする。

pip install flask

それと、WEBサーバーをインストールする。

pip install gnicorn

(4)FlaskファイルをPythonで作成

有効化した仮想環境上で、以下のように入力してmy-project内に実行ファイルを作成。今回はhello.pyというファイルを作成。

touch hello.py

次にhello.pyを開き、以下のように入力する。
なお、app.run()はこのままだとapp.run(debug=false)となり、デバックモードはオフの状態。本番環境ではdebug=trueとすると危険ぽいのでデフォルトのままとした。
詳しくは以下を参考にした。
https://www.subarunari.com/entry/2018/03/10/いまさらながら_Flask_についてまとめる_〜Debugger〜

hello.py
# -*- coding: utf-8 -*-
# 日本語を使う場合にコメントアウトでも必要

# flaskなどの必要なライブラリをインポート
from flask import Flask

# 自分の名称を app という名前でインスタンス化
app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World!'

#app.run()はデフォルトではfalseが設定されている
if __name__ == '__main__':
    app.run()

(5)Flaskファイルを実行してみる

再びターミナルで操作する。
作成したhello.pyがちゃんと動くかどうかローカル環境で試してみる。
ターミナルで以下を入力。

python3 hello.py flask run

すると、以下のように表示される。

* Serving Flask app "hello" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - 

ブラウザで、上記の部分の http://127.0.0.1:5000/ にアクセスすると、以下のように表示される。スクリーンショット 2020-02-26 22.38.02.png

これでローカル環境では正常に動くことが確認できた。
control + c でターミナル入力モードに戻る。

【超初心者】Heroku、Flask、Python、Gitでアップロードする方法(その②)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

プログラミング初学者のためのGithub用語解説⭐︎

プログラミング必須タスク!Githubについて解説

  • 基本的な用語解説

プログラミング初学者の多くが学ぶ Github について解説していきます!!

分かりづらい点があればコメントください!


リポジトリ(Repository)

VSコードなどの変更内容履歴などが格納されている場所 (貯蔵庫のようなもの)

リモートリポジトリ(Remoterepository)

サーバー上にあるリポジトリ。ユーザー間で共有できる

ローカルリポシトリ(Localrepository)

自分のPCにあるリポジトリ。

ブランチ(Branch)

履歴管理を枝分かれさせたもの。各ユーザが自由に作成できるのようなもの

コミット(Commit)

ローカルリポジトリに変更内容を保存すること。

プル(Pull)

ローカルリポジトリの変更をリモートリポジトリに反映させること。

フェッチ(Fetch)

リモートリポジトリの内容をローカルリポジトリに反映させること。

コンフリクト(Conflict)

衝突。ユーザーが同じファイルの変更を反映させた時などに起こるアクシデントのようなもの。

クローン(Clone)

リモートリポジトリをコピーしてローカルリポジトリを作成すること git clone

プルリクエスト(Pullrequest)

編集リクエスト。ローカルリポジトリで変更した内容をユーザーにレビューしてもらう時に使う。


簡単な用語ではこれぐらい!これからプログラミングを始める方は必ず覚えておいて損はない用語なのでぜひ覚えておきましょう!!

以上!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Progateのコラム「Gitの環境構築をしよう!」でGithubへのプッシュがうまくいかなかった件

Progateのコラム「Gitの環境構築をしよう!」をやっている際に最後にGithubへプッシュがうまくできなかったのでシェアします(問題解決までの時間:2時間半)。

初めてのターミナルでのgit操作ということもあり、何も考えずにコラムに書いてあるコードをコピペしていきました。

最後にGithubを更新すると、コラムに書かれている通りならファイルが作成されているはずでした。

しかし、Githubを何度更新してもファイルは作成されず、どこか間違えたかと思いもう一度コラムを繰り返してみました。けれどだめでした。

よくよくGithubの画面を見てみると、
スクリーンショット 2020-02-27 17.18.27.png
左下のほうに「import code」と書いてあるのを見つけて

git push origin master
Username for 'https://github.com':

ターミナルの最後の行にある「https://github.com」をインポートしてみましたがだめでした。

英語が読めなかったので、「…or create a new repository on the command line」の下の、

echo "# mystic" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/yamadataro0221/mysite.git
git push -u origin master

と「…or push an existing repository from the command line」の、

git remote add origin https://github.com/yamadataro0221/mysite.git
git push -u origin master

をコピペしてGithubの画面を更新するもうまくいかず。

とりあえずもう一度新しいリポジトリを作って再度コラムに書いてある通りやるもうまくいきませんでした。

解決方法

記事を書くほどのことでもないでのですが、

git push origin master
Username for 'https://github.com':

プッシュのあとの最後の一文をググるとgithubでユーザー名とパスワードを毎回聞かれる問題解消という記事が出てきて初めて、今Githubのユーザー名を求められていることに気づきました。

そこからはGithubのパスワードも入れて、Githubを更新するとプッシュされていました。

得たこと

  • とりあえずつまったときは最後のコードをググる

最後に

他にググれば記事が出てくるのでわざわざ書かなくてもよかったかもですが、「progate Git プッシュ」でググっても出てこなかったので、この先同じところでつまる人のために書きました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHubで過去にリリースしたタグ名を変更したいとき

大前提

  • Tag(タグ)
    • Gitの機能。コミットにつけられる。
  • Release(リリース)
    • GitHubの機能。タグにコメントや添付ファイルをつけて公開できる。

TL;DR

git tag new-tag old-tag

old-tagからnew-tagに変更したいときは、上記コマンドでnew-tagを作ってから、GitHub上のReleaseのEdit画面でタグ名をnew-tagに変更する。

やりたいこと

1.01.12.0というリリースがあるが、よくよく見たらリリース1.1のタグ名が間違っていた。
リリース1.1のタグを正しいものに直したい。

最初にやってみたこと

GitHub上のReleaseのEdit画面で、素直にタグ名を編集してみた。
ら、そのブランチの最新コミット(ここではリリース2.0時点のコミット)でタグが作られてしまった。失敗。

やるべきこと

GitHub上では操作できないので、Gitコマンドで。

git tag new-tag old-tag

これでold-tagのコミットにnew-tagというタグが新しく作られる。
まずはこれをプッシュ。

git push origin new-tag

これでリモートにnew-tagが反映される。

次に、GitHub上でタグ名を変更したいReleaseのEdit画面を開く。
タグ名をさっき作ったnew-tagに変更してUpdateする。
これでやりたいことができた。

あとは修正前のタグ(old-tag)はもう不要なので、それを削除する。
リモートからの削除。

git push --delete origin old-tag

ローカルからの削除。

git tag -d old-tag

以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git Clone時に「error: filename in tree entry contains backslash:」

Git Errorは突然に

ちょっと環境が特殊かもしれませんが、、
Sambaで共有しているLinuxの作業ディレクトリ上に
WindowsのGitクライアントから git clone すると、下記のようなエラーが出ました。

error: filename in tree entry contains backslash:

調べると、、

ドキュメンテーションより

core.protectNTFSがtrueに設定されている場合、
NTFSファイルシステムで問題を引き起こす可能性のあるパスのチェックアウトを許可しません。
Windowsではデフォルトはtrue、それ以外ではfalseです。

設定変更

git config --global core.protectNTFS false

うちの環境が特殊ですよね。。:sob:

参考

https://github.com/civetweb/civetweb/issues/812
https://git-scm.com/docs/git-config/en

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【LINE bot】おいら、だじゃレンジャー!

はじめに

前回のLINE botの記事でオウムがえしのLINE botを作成したぞ!
ちびっこのみんなに好かれたくお題を与えるとそのお題にまつわる
だじゃれを返すLINE botを作成することにしたんだ?
LINE botの登録、作成、Herokuへのデプロイ等は
前回のLINE botの記事を参考にしてくれ?

完成品

できあがりはこんな感じなんやで!
ぜひとも友達登録してくれよな?
image.png

準備

  • Procfile (Herokuで実行するコマンド)
  • requirements.txt (main.pyを動かす上で必要なパッケージ)
  • runtime.txt (使用する言語とバージョン)
  • main.py (LINE botのmainの部分)
  • dajaregen.py (だじゃれを生成する部分)
Procfile
web: python3 main.py
requirements.txt
Flask==1.1.1                
line-bot-sdk==1.15.0
requests==2.22.0
beautifulsoup4==4.8.2 
urllib3==1.25.8
runtime.txt
python-3.6.8
main.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os
import dajaregen as dj

app = Flask(__name__)

#環境変数取得
# not should be chnged chracters.
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]


line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    word = event.message.text
    dajare_text = dj.dajare_search(word)
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=dajare_text))


if __name__ == "__main__":
#    app.run()
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)
dajaregen.py
import requests
from bs4 import BeautifulSoup
import urllib
import random

def dajare_search(query):
    q_quote = urllib.parse.quote(query)
    r = requests.get(f'https://dajare.jp/keyword/{q_quote}/')
    bs = BeautifulSoup(r.text, features="html.parser")
    dajare = []
    for x in bs.find_all('tr'):
        da = x.find("td", class_='ListWorkBody')
        if not da:
            continue
        score = x.find("td", class_="ListWorkScore")
        dajare.append({'text': da.text, 'score': float(score.text.split(' (')[0])})
    dajare_text = []
    for x in sorted(dajare, key=lambda x: x['score'], reverse=True):
        dajare_text.append(x['text'])
    #result = '\n'.join(dajare_text)
    result = random.choice(dajare_text)
    return result

main.pyについて

これが、LINE botのメインとなるぞ。
ほとんど、line-bot-sdk-pythonのお手本と変わらないけれど、注目してほしいのは、この部分?

利用者がbotへ向けて送ったメッセージ(だじゃれのお題)を取得して、dajaregen.pyのdajare_searchの引数として入力することで、だじゃれを返す。

word = event.message.text
dajare_text = dj.dajare_search(word)

だじゃれは、この部分から利用者へ返すぞ!

line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=dajare_text))

dajaregen.pyについて

ここで、選りすぐりのだじゃれを考えているぞ。
だじゃれのネタはDajareStationを参考にしているんだ。
(僕もまだまだ未熟なのさ...)
そこから、htmlからお題にまつわるだじゃれを取り出し、
ランダムにひとつだけ返す作りになっているだ〜。
コードはこちらを参考にさせてもらったよ!
僕の生みの親同然です!!ありがとう!

実行

実行するとこんな感じだよ!
同じお題でも違うだじゃれを返してみせるよ?
image.png

まとめ

お題を与えることでだじゃれを返すLINE botを作った。
他にも楽しめそうなことがあったらコメントで教えてくれ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

おいら、だじゃレンジャー!

はじめに

前回のLINE botの記事でオウムがえしのLINE botを作成したぞ!
ちびっこのみんなに好かれたくお題を与えるとそのお題にまつわる
だじゃれを返すLINE botを作成することにしたんだ?
LINE botの登録、作成、Herokuへのデプロイ等は
前回のLINE botの記事を参考にしてくれ?

完成品

できあがりはこんな感じなんやで!
ぜひとも友達登録してくれよな?
image.png

準備

  • Procfile (Herokuで実行するコマンド)
  • requirements.txt (main.pyを動かす上で必要なパッケージ)
  • runtime.txt (使用する言語とバージョン)
  • main.py (LINE botのmainの部分)
  • dajaregen.py (だじゃれを生成する部分)
Procfile
web: python3 main.py
requirements.txt
Flask==1.1.1                
line-bot-sdk==1.15.0
requests==2.22.0
beautifulsoup4==4.8.2 
urllib3==1.25.8
runtime.txt
python-3.6.8
main.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import os
import dajaregen as dj

app = Flask(__name__)

#環境変数取得
# not should be chnged chracters.
YOUR_CHANNEL_ACCESS_TOKEN = os.environ["YOUR_CHANNEL_ACCESS_TOKEN"]
YOUR_CHANNEL_SECRET = os.environ["YOUR_CHANNEL_SECRET"]


line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    word = event.message.text
    dajare_text = dj.dajare_search(word)
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=dajare_text))


if __name__ == "__main__":
#    app.run()
    port = int(os.getenv("PORT", 5000))
    app.run(host="0.0.0.0", port=port)
dajaregen.py
import requests
from bs4 import BeautifulSoup
import urllib
import random

def dajare_search(query):
    q_quote = urllib.parse.quote(query)
    r = requests.get(f'https://dajare.jp/keyword/{q_quote}/')
    bs = BeautifulSoup(r.text, features="html.parser")
    dajare = []
    for x in bs.find_all('tr'):
        da = x.find("td", class_='ListWorkBody')
        if not da:
            continue
        score = x.find("td", class_="ListWorkScore")
        dajare.append({'text': da.text, 'score': float(score.text.split(' (')[0])})
    dajare_text = []
    for x in sorted(dajare, key=lambda x: x['score'], reverse=True):
        dajare_text.append(x['text'])
    #result = '\n'.join(dajare_text)
    result = random.choice(dajare_text)
    return result

main.pyについて

これが、LINE botのメインとなるぞ。
ほとんど、line-bot-sdk-pythonのお手本と変わらないけれど、注目してほしいのは、この部分?

利用者がbotへ向けて送ったメッセージ(だじゃれのお題)を取得して、dajaregen.pyのdajare_searchの引数として入力することで、だじゃれを返す。

word = event.message.text
dajare_text = dj.dajare_search(word)

だじゃれは、この部分から利用者へ返すぞ!

line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text=dajare_text))

dajaregen.pyについて

ここで、選りすぐりのだじゃれを考えているぞ。
だじゃれのネタはDajareStationを参考にしているんだ。
(僕もまだまだ未熟なのさ...)
そこから、htmlからお題にまつわるだじゃれを取り出し、
ランダムにひとつだけ返す作りになっているだ〜。
コードはこちらを参考にさせてもらったよ!
僕の生みの親同然です!!ありがとう!

実行

実行するとこんな感じだよ!
同じお題でも違うだじゃれを返してみせるよ?
image.png

まとめ

お題を与えることでだじゃれを返すLINE botを作った。
他にも楽しめそうなことがあったらコメントで教えてくれ!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Github謹製Gitリポジトリサイズ問題解析ツール「git-sizer」

こちらは、Gitリポジトリのさまざまなサイズメトリックを集計し、問題を引き起こす可能性のある箇所を解析する Github製のツールgit-sizerのREADME.mdの翻訳(ほとんどGoogle翻訳)です。

このREADME.mdは解析ツールの利用方法だけではなく、巨大Gitリポジトリを避けるための手法やベストプラクティスが詰まっているので、ついつい大きいリポジトリを作ってしまいがちな人は必見です。


幸せなGitリポジトリはすべて似ています。 不幸なGitリポジトリはすべて、それ自体が不幸です。 —Linus Tolstoy

git-sizer

あなたのGitリポジトリは溢れんばかりのサイズでしょうか?

git-sizer は、ローカルGitリポジトリのさまざまなサイズメトリックを計算し、問題や不便を引き起こす可能性があるものにフラグを立てます。 例えば:

  • リポジトリが全体的に大きすぎませんか? 理想的には、Gitリポジトリは1 GiB未満である必要があり、(特別な処理なしで)5 GiBを超えると扱いにくくなります。 大きなリポジトリでは、クローン作成とリパックに時間がかかり、多くのディスク容量が必要になります。 提案:

    • 生成されたファイル(コンパイラ出力、JARファイルなど)をGitに保存しないでください。 必要に応じてそれらを再生成するか、パッケージレジストリまたはファイルサーバーに保存することをお勧めします。
    • 大きなメディア資産をGitに保存しないでください。 Git-LFS または git-annex を調べてください。 実際にリポジトリの外部に保存しながら、Gitでメディアアセットをバージョン管理します。
    • 特に圧縮されている場合は、Gitにファイルアーカイブ(ZIPファイル、tarballなど)を保存しないでください。 そのようなファイルの異なるバージョンは、互いに十分に差分をとらないため、Gitはそれらを効率的に保存できません。 個々のファイルをリポジトリに保存するか、アーカイブを他の場所に保存することをお勧めします。
  • リポジトリの参照(ブランチやタグ)が多すぎませんか? たとえクローンが最新であっても、フェッチするたびにすべてクライアントに転送する必要があります。 せいぜい数万に制限してください。 提案:

    • 不要なタグとブランチを削除します。
    • 「リモートトラッキング」ブランチを共有リポジトリにプッシュしないでください。
    • タグではなく "git notes" を使用して、コミットに補助情報(たとえば、CIビルド結果)を添付することを検討してください。
    • まれに必要なタグとブランチの一部を、通常の開発者から取得されないリポジトリの別のフォークに保存することもできます。
  • リポジトリに含まれるオブジェクトが多すぎませんか? オブジェクトが多いほど、Gitがリポジトリの履歴をたどるのにかかる時間は長くなります(ガベージコレクションなど)。 提案:

    • いくつかの大きなファイルに簡単に収集できる非常に多くの小さなファイルを保存しているかどうかを考えてください。
    • プロジェクトを複数のサブプロジェクトに分割することを検討してください。
  • リポジトリには巨大なblob(ファイル)が含まれていますか? Gitは、中小規模のファイルで最適に機能します。 メガバイトの範囲でいくつかのファイルを作成しても問題ありませんが、通常は例外です。 提案:

    • Git-LFS を使用して、大きなファイル、特に便利に差分やマージを行わないファイル(メディアアセットなど)を保存することを検討してください。
    • 「リポジトリが全体的に大きすぎませんか?」のセクションも参照してください。
  • リポジトリには、大きなテキストファイルの多くの多くのバージョンが含まれており、それぞれが以前のものからわずかに変更されていますか? このようなファイルの差分は非常に良好であるため、リポジトリが驚くほど大きくなることはありません。 しかし、Gitが完全なファイルを再構築し、それらを差分化するのは高価です。これは多くの操作のために内部で行う必要があります。 提案:

    • ログファイルとデータベースダンプをGitに保存しないでください。
    • 特に頻繁に変更される場合は、Gitに巨大なデータファイル(巨大なXMLファイルなど)を保存しないでください。 代わりにデータベースの使用を検討してください。
  • リポジトリには巨大なツリー(ディレクトリ)が含まれていますか? ファイルが変更されるたびに、Gitはファイルに至るすべてのツリー(パス内のすべてのディレクトリ)の新しいコピーを作成する必要があります。 巨大な木はこれを高価にします。 さらに、たとえば「git blame」のように、巨大なツリーを含む履歴を走査するのは非常に高価です。 提案:

    • それぞれ数千エントリ以上のディレクトリを作成しないでください。
    • 非常に多くのファイルを保存する必要がある場合は、複数の小さなディレクトリの階層に分割することをお勧めします。
  • リポジトリーには、同じ(または非常に類似した)ファイルが1回のコミットで異なるパスで繰り返し繰り返されますか? その場合、リポジトリの全体的なサイズは妥当かもしれませんが、チェックアウトすると、膨大な作業コピーになります。 (極端に言えば、これは「git bomb」と呼ばれます。以下を参照してください。)提案:

    • おそらく、タグとブランチまたはビルド時の構成システムを使用することで、目標をより効果的に達成できます。
  • リポジトリにとてつもなく長いパス名が含まれていますか? それはおそらく他のツールではうまく機能しないでしょう。 Javaを作成している場合でも、100文字または200文字で十分です。

  • リポジトリには他にも奇妙で疑わしいものがありますか?

    • 長いチェーンで互いに指し示す注釈付きタグ?
    • Octopus mergesで数十の親を持つ?
    • 巨大なログメッセージでコミットする?

git-sizer は、リポジトリに関する多くのサイズ関連の統計を計算します。これは、上記のすべての問題を明らかにするのに役立ちます。 これらのプラクティス自体は間違っていませんが、Gitをそのスイートスポットを超えて伸ばすほど、Gitの伝説的なスピードとパフォーマンスを楽しむことができなくなります。 特に、Gitリポジトリの統計がプロジェクトのサイズに比例していないように思われる場合は、Gitの使用方法を調整することで、作業を楽にすることができる場合があります。

Getting started

  1. Gitコマンドラインクライアントがインストールされていることを確認してください、 version >= 2.6。 Note: git-sizerは、リポジトリの内容を調べるためにgitコマンドを呼び出します。そのため、git-sizerを実行するときは、gitコマンドが$PATH` に存在する必要があります。

  2. git-sizerのインストール. いずれか:

    a. git-sizerのリリースバージョンをインストールします(推奨):

    1. releases page に移動し、プラットフォームに対応するZIPファイルをダウンロードします。
    2. ファイルをunzipします。
    3. 実行可能ファイル(git-sizerまたはgit-sizer.exe)を $PATHに移動します。

    b. ソースからビルドしてインストールします。 docs/BUILDING.mdの手順を参照してください。

  3. 分析するGitリポジトリの完全なclone(non-shallow)を含むディレクトリに移動して次を実行する:

    git-sizer [<option>...]
    

    オプションは不要です。利用可能なオプションについては、git-sizer -hで学ぶ、もしくは読んでください。

Pro tip: $PATHgit-sizerを追加した場合、git-sizerまたはgit sizerと入力して実行できます。後者の場合、Gitによって検出されて実行され、2つの単語の間にgit -C /path/to/my/repo sizerのような追加のGitオプションを追加できます。 PATHgit-sizerを追加しない場合、もちろん実行するためにフルパスとファイル名を入力する必要があります。例: /path/to/bin/git-sizer。どちらの場合も、git実行可能ファイルは$PATHある必要があります

Usage

デフォルトでは、 git-sizerは結果を表形式で出力します。たとえば、すべての統計が出力されるように --verboseオプションを使用して、the Linux repository を分析するためにそれを使用してみましょう:

$ git-sizer --verbose
Processing blobs: 1652370
Processing trees: 3396199
Processing commits: 722647
Matching commits to trees: 722647
Processing annotated tags: 534
Processing references: 539
| Name                         | Value     | Level of concern               |
| ---------------------------- | --------- | ------------------------------ |
| Overall repository size      |           |                                |
| * Commits                    |           |                                |
|   * Count                    |   723 k   | *                              |
|   * Total size               |   525 MiB | **                             |
| * Trees                      |           |                                |
|   * Count                    |  3.40 M   | **                             |
|   * Total size               |  9.00 GiB | ****                           |
|   * Total tree entries       |   264 M   | *****                          |
| * Blobs                      |           |                                |
|   * Count                    |  1.65 M   | *                              |
|   * Total size               |  55.8 GiB | *****                          |
| * Annotated tags             |           |                                |
|   * Count                    |   534     |                                |
| * References                 |           |                                |
|   * Count                    |   539     |                                |
|                              |           |                                |
| Biggest objects              |           |                                |
| * Commits                    |           |                                |
|   * Maximum size         [1] |  72.7 KiB | *                              |
|   * Maximum parents      [2] |    66     | ******                         |
| * Trees                      |           |                                |
|   * Maximum entries      [3] |  1.68 k   | *                              |
| * Blobs                      |           |                                |
|   * Maximum size         [4] |  13.5 MiB | *                              |
|                              |           |                                |
| History structure            |           |                                |
| * Maximum history depth      |   136 k   |                                |
| * Maximum tag depth      [5] |     1     |                                |
|                              |           |                                |
| Biggest checkouts            |           |                                |
| * Number of directories  [6] |  4.38 k   | **                             |
| * Maximum path depth     [7] |    13     | *                              |
| * Maximum path length    [8] |   134 B   | *                              |
| * Number of files        [9] |  62.3 k   | *                              |
| * Total size of files    [9] |   747 MiB |                                |
| * Number of symlinks    [10] |    40     |                                |
| * Number of submodules       |     0     |                                |

[1]  91cc53b0c78596a73fa708cceb7313e7168bb146
[2]  2cde51fbd0f310c8a2c5f977e665c0ac3945b46d
[3]  4f86eed5893207aca2c2da86b35b38f2e1ec1fc8 (refs/heads/master:arch/arm/boot/dts)
[4]  a02b6794337286bc12c907c33d5d75537c240bd0 (refs/heads/master:drivers/gpu/drm/amd/include/asic_reg/vega10/NBIO/nbio_6_1_sh_mask.h)
[5]  5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c (refs/tags/v2.6.11)
[6]  1459754b9d9acc2ffac8525bed6691e15913c6e2 (589b754df3f37ca0a1f96fccde7f91c59266f38a^{tree})
[7]  78a269635e76ed927e17d7883f2d90313570fdbc (dae09011115133666e47c35673c0564b0a702db7^{tree})
[8]  ce5f2e31d3bdc1186041fdfd27a5ac96e728f2c5 (refs/heads/master^{tree})
[9]  532bdadc08402b7a72a4b45a2e02e5c710b7d626 (e9ef1fe312b533592e39cddc1327463c30b0ed8d^{tree})
[10] f29a5ea76884ac37e1197bef1941f62fda3f7b99 (f5308d1b83eba20e69df5e0926ba7257c8dd9074^{tree})

出力は、測定されたもの、その数値、および懸念の原因となる可能性のある値の大まかな指示を示す表です。すべての場合において、参照から到達可能なオブジェクトのみが含まれます(つまり、到達不能なオブジェクトや、reflogからのみ到達可能なオブジェクトではありません)。。

"Overall repository size"セクションには、繰り返しを含まない、個別のオブジェクトに関するリポジトリ全体の統計が含まれます。 "Total size"は、非圧縮形式の対応するオブジェクトのサイズの合計で、バイト単位で測定されます。
すべてのオブジェクトの全体的な非圧縮サイズは、 git gc --aggressive(およびgit repack [-f|-F]git pack-objects --no-reuse-deltaなどのコマンドがどれだけ高価かを示しています。 )、 git fsck、およびgit log [-G|-S]になります。圧縮されていないツリーとコミットのサイズは、クローンとフェッチ、git gcを含む、到達可能性のトラバースがどれほど高価になるかを示しています。

"Biggest objects" セクションでは、履歴のどこにいても、各タイプの最大の単一オブジェクトに関する情報を提供します。
"History structure"セクションでは、"maximum history depth"は履歴内のコミットの最長チェーンであり、"maximum tag depth"は他の注釈付きタグを指す注釈付きタグの最長チェーンを報告します。

"Biggest checkouts"セクションは、作業コピーにチェックアウトされたコミットのサイズに関するものです。 "Maximum path depth"は作業コピー内のファイルのパスコンポーネントの最大数であり、"maximum path length"はバイト単位の最長パスです。 "Total size of files"は、同じファイルが複数回出現する場合の多重度を含む、単一の最大コミットのすべてのファイルサイズの合計です。

"Value"列には、単位「k」(キロ)、「M」(メガ)、「G」(ギガ)などを使用してカウントが表示され、単位「B」(バイト)、「KiB」(1024バイト)、 "MiB"(1024 KiB)など。値がカウンターをオーバーフローする場合(これは悪意のあるリポジトリでのみ発生します)、対応する値は表形式で として表示されるか、2³²-1に切り捨てられます。またはJSONモードの2⁶⁴-1(カウンターのサイズに応じて)。

"Level of concern"列では、アスタリスク(*)を使用して、"典型的な"Gitリポジトリと比較して高いと思われる値を示しています。アスタリスクが多いほど、リポジトリのこの側面が引き起こすと予想される不便さが大きくなります。感嘆符(!)は、非常に高い値(つまり、30を超えるアスタリスク(*)に相当)を示します。

脚注には、テーブルで参照される"biggest"オブジェクトのSHA-1と、そのオブジェクトがリポジトリの履歴のどこにあるかについてのより人間が読める <commit>:<path>の説明がリストされています。ラージオブジェクトの名前を指定すると、たとえば次のように入力できます

git cat-file -p <commit>:<path>

コマンドラインで、オブジェクトの内容を表示します。 (これらの脚注を省略したい場合は、--names=noneを使用してください。)

デフォルトでは、懸念の最小レベルを超える統計のみが報告されます。 (上記のように)--verboseを使用して、すべての統計の出力を要求します。--threshold=<value>を使用して、指定された懸念レベルを下回る統計のレポートを抑制します。 (<value>はアスタリスク(*)の数に対応する数値として解釈されます。)--criticalを使用して、重大な懸念レベルの統計のみをレポートします(--threshold=30に相当)。

正確な数値を含む機械可読形式の出力が必要な場合は、 --jsonオプションを使用します。 --json-version=1または--json-version=2を使用して、古いスタイルと新しいスタイルのJSON出力を選択できます。

他のオプションのリストを取得するには以下を実行します

git-sizer -h

Linuxリポジトリは大きいリポジトリの標準です。ご覧のとおり、Gitの制限の一部を押し上げています。実際、LinuxリポジトリでのGitの操作(たとえば、git fsck, git gc)には時間がかかります。しかし、その健全な構造のために、その次元のいずれもコードベースのサイズに大きく比例していないため、カーネルプロジェクトはGitを使用して正常に管理されます。

以下は、有名な"git bomb"リポジトリの非冗長出力です:

$ git-sizer
[...]
| Name                         | Value     | Level of concern               |
| ---------------------------- | --------- | ------------------------------ |
| Biggest checkouts            |           |                                |
| * Number of directories  [1] |  1.11 G   | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| * Maximum path depth     [1] |    11     | *                              |
| * Number of files        [1] |     ∞     | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| * Total size of files    [2] |  83.8 GiB | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |

[1]  c1971b07ce6888558e2178a121804774c4201b17 (refs/heads/master^{tree})
[2]  d9513477b01825130c48c4bebed114c4b2d50401 (18ed56cbc5012117e24a603e7c072cf65d36d469^{tree})

このリポジトリは、同じディレクトリが繰り返し繰り返される病理学的なツリー構造を持つように、いたずらに構築されています。その結果、リポジトリ全体のサイズは20 kb未満ですが、チェックアウトすると、100億を超えるファイルを含む10億を超えるディレクトリに爆発します。 (git-sizerはblobカウントにを出力します。これは、そのフィールドに使用される32ビットカウンターが真の数でオーバーフローしたためです。)

Contributing

git-sizerは常用されており、現在も活発に開発されています。手伝いたい場合は、CONTRIBUTING.mdをご覧ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む