Lenovo-G570で交換可能なCPUについて

先日Lenovo-G580のCPUを適当に選択して交換して、今使えてるのですが、G570も持ってて、今アマゾンで新品で購入可能なCore iシリーズは使えるのか気になって調べてみました。

第二世代(Sandy Bridge)のマシンのようです、G570

CPUのソケットの形が第二世代と第三世代(Ivy Bridge)で同じらしく、全部使えるのか、一部なのかよくわかりませんでした。

G570のチップセットを調べてみると([Lenovo G570 チップセット]でネット検索)

https://www.lenovo.com/medias/g570-rt-0809.pdf?context=bWFzdGVyfGltYWdlc3wxNzIwMzd8YXBwbGljYXRpb24vcGRmfGltYWdlcy9oNDQvaDMwLzkzMzM5Mzk5NjE4ODYucGRmfDU1MWRjOTM5MmU1ODMxYTM3NzIyZDE5YThiZTRiNjViMDdmZTE0ZmQwYjI0ZWU0MDQ4M2E0OWFhOTczZDg5NTQ

モバイル インテル® HM65 Express チップセット を使っていると確認できました

このチップセットに対応しているCPUの確認方法はここのURLの左下の対応している製品をクリックすると見れます。(直接リンクはるURL不明)

他の部品の相性とかで動かない可能性もあるので、動作確認が取れてるCPUにした方が安全だとはおもいますが(動作確認の取れているCPUの情報は、「G570 CPU交換」等でネット検索かけると調べれます。

過去のG570のシリーズで使用されているCPUなら安全度高いかも(マザーボードのバージョン等で動かないものあるかもしれないけど)

メインマシン(Lenovo-G580)のCPUを交換しました

Celeron(一番安いタイプ)を購入しており、tensorflowのバイナリがavx命令を使うバイナリで、コンパイルに24時間程度必用なため、新しいPC購入しようかと考えたのですが、CPUの交換でもいけるか調べると、1万からずCPU交換して、avx命令に対応可能だったので、そっちにしました。

Amazonで Intel(R) Core(TM) i5-3230M CPU を購入し、

Lenovo-G580 CPU交換

でネット検索かけて、出てきた動画をみながら、CPU交換しました。

ほぼほぼ、全分解に近い分解しないと、CPUと対面不可能で、しかも交換後のテスト起動で画面がでてこず、CPUの選定あやまったかな?っと思いましたが、CPUの締め付けのネジを180度まわさず100度くらいで固くなったのでやめてたのを、180度になるまでガンと締め付けて、再度テストしたら上手く動作し、画面も出て、メモリテストを動作させてもエラーがでない状態になりました。

一時は、元のCPUに戻さないといけないかもって思ったけど。本当に良かった

後で調べ直してみると、i7のivy bridge(第三世代)でも良かったみたいで、どうせ交換するならi7系にすべきだったかもって、ちょっと後悔した

第二世代のSandy Bridge とCPUソケットの形は同じっていうことらしく、G570も持ってて、そっちは第二世代らしい。
G570に第三世代のCPUをいれてみた猛者の情報を探したけど、みつからなかった。

全分解しないといけないので、また外すの面倒、外さないなら、もう1個買う必用が…。
どうしよかな?って考えてます。(G570の方のCPU交換)

ということで

  • Lenovo-G580のCPU交換は大変、ほぼほぼ全分解しないとCPU交換出来ない
  • Intel(R) Core(TM) i5-3230M がG580で正常動作した
  • CPU締め付けのネジは180度まわしきりましょう!

追記)ハードウェアマニュアルが存在し、それをみながら交換した方が良い(後で気づきました。)

CPU交換に関係ないけど、マニュアルはここみたい。

Git超簡単入門

Git超簡単入門

1 Git概要

  • バージョン管理ソフト
  • 昔のバージョンからの変更内容とか、昔のバージョンへの巻き戻し等が可能

2 Gitのインストール

sudo apt install git

3 Gitの初期設定

  • ユーザー名、メールアドレスは適切なもので
git config --global user.name "ユーザー名"
git config --global user.email "メールアドレス"

4 超基本操作

4.1 gitで管理するための最初の呪文(init)

  • 管理したいディレクトリで以下のコマンドを実行
git init
  • これにより、gitで管理する情報の保管先(.gitディレクトリが掘られ、その中に管理情報をいれてく)

4.2 現状の状態をセーブ(commit)

  • コメント文書には変更のメモを書く、logみた時に何を変更した状態かわかりやすくなるように
git add -A
git commit -m "コメント文書" 

4.3 今までのセーブ(commit)状態を確認(log)

git log

4.4 現在の状態確認(status)

git status

4.5 最後のcommitからの変更内容確認(diff)

git diff
  • 特定のファイルの変更だけ表示する場合は
git diff ファイル名

4.6 修正したファイルを最後にcommitした時の状態に戻す

git checkout ファイル名

4.7 以前commitした状態にする

  • git log でログを確認して、戻したい状態のid(英数の長い文字列)を確認
git reset --hard  戻したい状態のid

4.7.1 これを間違って行ってしまった時に戻す方法

  • 以下のコマンドでみえなくなったlogを確認
git reflog
  • 戻すべきHEAD@{数字}を確認するか、idを確認し、以下のコマンドを実行
git reset --hard 確認した識別子

4.8 超基本操作を使ってみる操作例

4.8.1 上の説明と例の操作を行っている動画


4.8.2 練習操作例その1

  • 説明読むと、色々出来ることが多く、内容複雑で理解するのに効率悪い
  • 実際に使ってみて、説明を読み、また使ってみるのループがお勧め、効率良くなる
  • 練習用のディレクトリを作成しそこにはいる
  • 初期化するコマンドを入れる
git init
  • 適当な内容でファイルを作成
  • 状態確認してみる
git status
  • 下を実行するが初期設定を行っていないため怒られる
git add -A
git commit -m "最初のバージョン" 
  • メールアドレス”you@example.com”、ユーザー名を “Your Name”で登録してますが、実際やるときはちゃんとした内容で
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
  • 初期設定を行ったので再度
git commit -m "最初のバージョン" 
  • ログ確認
git log
  • ファイルに追加
  • 差分を確認
git diff
  • 修正後をセーブ(commit)
git add -A
git commit -m "ファイル内容追加"
  • ログ確認
git log
  • 新しいファイル2を追加
  • 修正をセーブ
git add -A
git commit -m "ファイル内容追加"
  • ログ確認
git log
  • 状態確認
git status
  • ファイルを修正し、最後のセーブ状態に戻す
git checkout 2
  • 最初のバージョンに戻す
  • まずログを確認
git log
  • 巻き戻す
git reset --hard 確認したid
  • 2ファイルがないこと、最初のファイルの内容が元に戻っていることを確認
  • ログ確認
git log
  • 最後の巻き戻し前に戻る
git reflog
  • 上のコマンドで確認したidを利用して戻す
git reset --hard 確認したidその2

5 今後

  • 今後も文書追加していきます。

6 この文書のチェンジログ

  • 2020/01/07 初版

著者: NM Max

Created: 2020-01-07 火 20:09

Validate

Freeciv 勝ち方

Freecivでの勝ち方

1 Freeciv概要

  • シミュレーションゲーム
  • 文明を進化させて他の勢力を倒すか、勝利条件の宇宙入植を行うことで勝利に(デフォルトルール)
  • 初心者で適当にやるとコンピューターにほぼほぼ負けちゃう

2 Freecivインストール

sudo apt install freeciv freeciv-client-gtk3 freeciv-client-extras
  • UbuntuやDebianで音楽パッケージも追加するなら以下
sudo apt install freeciv-sound-standard 

3 Freeciv勝ち方1

3.1 世界の不思議と言われる特殊建築物を他の勢力より先に建築し手に入れる

  • 早いもの勝ちなので、他の勢力より先に重要な世界の不思議を建築すべし
  • 超重要なのは、アレクサンドリア図書館、ミケランジェロの協会、J.S.バッハの大聖堂

3.2 最も重要な世界の不思議

  • アレクサンドリア図書館(「識字」まで研究が進むと建築可能になる)
  • 他の勢力2つが手に入れた研究を自国でもゲット出来る脅威のアイテム、初心者はこれをゲット出来なければ、再度やり直すべきレベル

3.2.1 アレクサンドリア図書館手に入れるまでの解説動画


3.3 研究の進め方のお勧め案(アレクサンドリア図書館を取れていた場合)

  • 「陶器」、目標「兵法」
  • 「兵法」の開発に入ったら、目標を「共和制」に
  • 「共和制」の開発に入ったら、目標を「哲学」に
  • 「哲学」の開発に入ったら、目標を「一神教」に
  • 「一神教」の開発に入ったら、目標を「神学」に
  • 「神学」の開発に入ったら、目標を「鉄道」に
  • 「鉄道」の開発に入ったら、目標を「爆薬」に
  • 「爆薬」の開発に入ったら、目標を「小型化」に
  • 最後の方は欲しいもの優先で変更してもあまり大差ないかも

3.4 作るべき戦闘ユニット

  • 弓兵(兵舎を建ててから作成するとより有能なユニットに)
  • マスケット兵(兵舎が新しいタイプになるので立て直し必用)
  • 機械化歩兵(最強防御力地上ユニット、最後はこれがお勧め)
  • その他のユニットも作成可能になったら作っていこう!

3.5 防御(初期)

  • 初心者のころはCPUに攻められて負けることが多い、防御重要
  • 城壁を都市に作りましょう、弓兵がいて、城壁があれば、最初のうちは都市まず落ちない
  • 沿岸防衛も作れるようになったら、はやめに作りましょう、他の勢力の海軍が強くなる前に!

3.6 攻める時に便利なユニット(中盤、後半)

  • スパイ(「偵察」が必用お金がかかるが、損耗少なく都市をゲットできる、私はスパイができるまで基本他の都市攻めない)
  • 榴弾砲 (「ロボット工学」が必用 城壁無視で攻撃可能)

4 最初のお勧め操作手順

  • 文明→研究で研究タブを開いて、研究対象を「陶器」目標を「兵法」にセット
  • 周囲の地形を調べて、収入が多そうな所に都市を建築
  • 労働者は道を作り、次の都市の作成までの時間を短縮

5 世界の不思議の建築速度上昇作戦

  • 他の都市でユニットを作成し、世界の不思議を作成している都市に移動させて解散させると、ユニット作成コストの半分が不思議建築に利用可能
  • キャラバン、貨物輸送車なら、全コスト分世界の不思議建築に流用可能
  • お金をつかって買うを行い、数ターン完成をはやめれることも

6 世界の不思議概要

  • 早いもの勝ちなので、他の勢力より先に重要な世界の不思議を建築すべし

6.1 必ず取るべき最重要世界の不思議

  • アレクサンドリア図書館(「識字」まで研究が進むと建築可能になる)

6.2 不満を下げることができる重要な世界の不思議

  • この2つか、どちらか一つは必ずゲットしたい
    • J.S.バッハの大聖堂 (「神学」が必用)
    • ミケランジェロの協会 (「一神教」が必用)
  • 他にも取っておくと便利
    • シェークスピアの劇場 (効果は建てた都市のみ「医術」が必用)
  • 取れたら取る感じで
    • 空中庭園 (「陶器」が必用 アレクサンドリア図書館を優先すべき)
    • 癌の治療 (「遺伝子工学」が必用)

6.3 支出を抑えたり、収入を増やす効果のある世界の不思議

  • ピラミッド(食料の損失軽減「石工所」が必用)
  • リチャード一世の十字軍遠征 (生産ポイントアップ 「工学」が)必用)
  • フーバーダム (水力発電所がある状態に(「電子工学」が必用)
  • マゼランの航海 (水上ユニットの移動力+2 「航海術」が必用)

7 今後

  • 今後も文書追加していきます。

8 この文書のチェンジログ

  • 2020/01/06 初版

著者: NM Max

Created: 2020-01-06 月 09:07

Validate

UbuntuでYaneuraOuコンパイル

UbuntuでYaneuraOuコンパイル

1 概要

  • Ubuntu(Debianでもほぼ同じと予想される)でYaneuraOuコンパイル

2 リンク

3 YaneuraOu をコンパイル

  • ソースファイル群から実行ファイルを作成

3.1 以下の操作を行っている動画


3.2 事前準備

  • コンパイラとしてclangをインストール
sudo apt install clang

3.3 作業用のディレクトリ作成

mkdir YaneuraOu
cd YaneuraOu/

3.4 YaneuraOuのソースゲット

git clone https://github.com/yaneurao/YaneuraOu.git

3.4.1 ソースのバックアップ

  • バックアップファイルをYaneuraOu.20191009.tgzで保存
tar cvzf YaneuraOu.20191009.tgz YaneuraOu/

3.5 CPUの命令セットの確認

  • 以下のコマンドを実行し、/proc/cpuinfoに含まれる命令セットに、使いたい命令セットが含まれているか確認。含まれているなら、希望の文字列が含まれた行が表示されるはずなので、出力を確認して、希望の命令セットが含まれるか確認。
  • avx5系かどうか?
grep -i avx5 /proc/cpuinfo
  • avx2系かどうか?
grep -i avx2 /proc/cpuinfo
  • sse42系かどうか?
grep -i sse4 /proc/cpuinfo

3.6 ソースディレクトリに移動

cd YaneuraOu/source/

3.7 必用ならMakefileを変更

  • 私のCPUセットはsse42なので、TARGET_CPU = SSE42 をコメントアウトして、CPUの命令セットを SSE42にした。使うマシンのCPUによっては変更の必用無い場合もある。
vi Makefile 

3.8 ビルド

  • 以下の命令で上手くエラーなくコンパイル出来ればOK
  • YaneuraOu-by-gcc というファイルが Makefileのあるフォルダに作成される。これが実行ファイル
  • YaneuraOu-by-gcc は将棋用のプロトコルと標準入力や出力でやりとりするソフトなので、これ単体で将棋を楽しむのはしんどいので、人間と将棋エンジンとの間をとりもってくれるソフトを利用して使う。
make

4 今後

  • 今後も文書追加していきます。

5 この文書のチェンジログ

  • 2019/12/12 初版

I

著者: NM Max

Created: 2019-12-12 木 12:05

Validate

Docker入門

Docker入門

目次

1 概要

  • 環境構築ツール
  • 基本Linuxベース
  • Windowsバージョンは互換性が低い?

3 インストール

3.1 Ubuntu

sudo apt install docker.io
  • 以下のコマンドで、dockerを使いたいユーザーをdockerグループに追加し、マシンを再起動
sudo adduser ユーザー名 docker

3.2 Windows

  • 公式サイト配布のものもある(互換性に問題あり?)
  • 公式サイトのものも結局エミュレーター等でLinuxを動作させているので、より互換性の高い仮想マシンにLinuxをインストールし、その環境でDocker使った方が良いかも
  • Qemuを利用しUbuntuをインストールする動画アップしてます。この環境にdocker.ioをインストールしても良いかも

4 カスタマイズしたDocker imageを作成(nginx)

  • 結構問題あるimageもあるらしいので、独自のimageを比較的信用できる配布元が配布しているimageを利用して作成
  • 今回はUbuntuのbase imageを利用

4.1 以下の操作を行っている動画


4.2 Dockerfileを作成

  • 以下の内容のファイルを、作業ディレクトリを用意して作成
  • FROM でベースとなるイメージを指定
  • RUNでimegeを作成するのに必用なコマンドを記述
  • ENVで環境変数を設定
  • EXPOSE で公開するポート番号指定
  • ENTRYPOINT でimageを起動した時に実行する命令を記述
FROM ubuntu:18.04 
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install locales \
    && apt -y install nginx \    
    && locale-gen ja_JP.UTF-8 
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
EXPOSE 80 
ENTRYPOINT /etc/init.d/nginx start && bash

4.3 image作成

  • 以下のコマンドで mynginx という名前でDocker imageを作成
docker build -t mynginx . 

4.4 Docker image一覧確認

  • 以下の内容のファイルを、作業ディレクトリを用意して作成
docker images

4.5 作成したimageを動かす

  • 以下のコマンドで8000番ポートとDockerコンテナの80番ポートをつなげる
docker run -it -p 8000:80 mynginx

5 作成されたコンテナの削除

docker rm $(docker ps -a -q)

5.1 関係しそうなコマンド

  • すべてのコンテナ一覧表示
docker ps -a
  • すべてのコンテナ一覧のID表示
docker ps -a -q

6 作成したイメージ全部消す

docker rmi $(docker images -q)

7 django向けにカスタマイズしたDocker imageを作成(django+mysql+nginx+uwsgi)

  • 今回もUbuntuのbase imageを利用

7.1 以下の操作を行っている動画


7.2 Dockerfileを作成

  • 以下の内容のファイルを、作業ディレクトリを用意して作成
  • 1000は現在利用してるuserのuidにしてください。( grep ユーザー名 /etc/passwd や id コマンド等で調べれます)
FROM ubuntu:18.04
MAINTAINER NM Max
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install mysql-client mysql-server libmysqlclient-dev libssl-dev \
    && apt -y install python3-pip python3 ipython3 \
    && apt -y install vim w3m wget diffutils sqlite3 nkf less diffutils patch sudo \
    && apt -y install nginx uwsgi-plugin-python3 \
    && apt -y install locales \
    && locale-gen ja_JP.UTF-8 \
    && pip3 install Django \
    && pip3 install mysqlclient
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
WORKDIR /work
COPY ./myinit.sh /work/myinit.sh
RUN chmod +x /work/myinit.sh
# RUN useradd -m --uid 1000 django -p1234 -s/bin/bash  
RUN echo "\n\n\n\n\n\n\n" | adduser --uid 1000 --disabled-password django 
RUN echo "django ALL=NOPASSWD: ALL" >> /etc/sudoers && chown django.django /work
RUN mkdir -p /home/django/C && chown  django.django /home/django/C 
# VOLUME /work /home/django/C 
EXPOSE 22 80 8000 8001
ENTRYPOINT /work/myinit.sh
  • バージョン指定したい場合は以下のようにpip3の部分にバージョン指定のオプションを追加
  • djangoのバージョン(3.0)と、mysqlclinent(1.4.6)のバージョンを指定
.... 省略
    && pip3 install Django==3.0 \
    && pip3 install mysqlclient==1.4.6
.... 省略

7.3 myinit.shを準備

  • 以下の内容にする。nginxとmysqlのサーバーを起動し、bashを動かす内容にしておく
  • 作成したdjangoのプロジェクトを含める場合は、それを起動するスクリプトも追加
#!/bin/sh
/etc/init.d/nginx start
/etc/init.d/mysql start
# /bin/bash
su - django

7.4 image作成

  • 以下のコマンドで mydjango という名前でDocker imageを作成
docker build -t mydjango . 

7.5 共有ディレクトリの作成

  • /workのディレクトリの所有権をuser.userにする場合
  • 利用しているユーザー名にuserは変更してください。(例えば、xxxなら chownxxx.xxx /work)
  • 共有ディレクトリを別にしたい場合は、/work をそのディレクトリ名に(例えば /home/user/C 等)
sudo mkdir /work
chown user.user /work

7.6 作成したimageを動かす

  • 以下のコマンドで80,8000,8001番ポートとDockerコンテナの80,8000,8001番ポートをつなげる
  • /workディレクトリを、コンテナの/home/django/Cと共有
  • ‘-i’オプションで、入力を流し込み
  • ‘-t’オプションで、ttyの出力をホスト側に流す
  • ‘–rm’オプションで、終了時にコンテナ削除
  • ‘-p’オプションで、ホストのポート番号とコンテナのポート番号を結合
  • ‘-v’オプションで、ホストのディレクトリとコンテナ内のディレクトリ共有
docker run -it --rm -p 80:80 -p 8000:8000 -p 8001:8001 -v /work:/home/django/C mydjango

7.7 テスト

  • 以下を行いdjangoユーザーになり、/home/django/Cディレクトリに移動しプロジェクト作成し、サーバー起動
su - django
cd C/
django-admin startproject mytest000
cd mytest000
python3 manage.py runserver 0:8000
  • ホスト側http://localhost:8000にて接続確認
  • ホスト側http://localhostにてnginxの接続も確認
  • ホスト側で以下のコマンドを実行し/workディレクトリが共有されファイル群が作成されていることを確認
tree /work

7.8 この章のまとめ

  • djangoを動かすとか、本番環境テストに必用なパッケージをパックしたDockerイメージを作成してみた。
  • ディレクトリ共有も行ってみた。

8 Docker imageのsave load

8.1 以下の操作を行っている動画


8.2 Docker imageのsave

docker save saveしたいimage名 > 保存したいファイル名
あるいは
docker save saveしたいimage名 -o 保存したいファイル名
docker save mydjango > mydjango.tar

8.3 Docker imageのload

docker load < 保存したファイル名
あるいは
docker load -i 保存したファイル名
docker load > mydjango.tar
docker load -o mydjango.tar
docker load -i mydjango.tar

9 django向けDocker composeを作成(django+mysql)

9.1 以下の操作を行っている動画


9.2 準備作業

9.2.1 作業用ディレクトリ生成

mkdir myDjango3.0_MySQL
cd myDjango3.0_MySQL

9.2.2 共有ディレクトリ生成

  • mkdir 命令で作成していますが、別のツールでディレクトリ作成してもOK
mkdir -p docker/mysql-docker-entrypoint-initdb.d/
mkdir -p docker/postgres-docker-entrypoint-initdb.d/
mkdir -p docker/mysql_data/
mkdir -p docker/postgres_data/
  • 作成したディレクトリツリーは以下に
.
└── docker
    ├── mysql-docker-entrypoint-initdb.d
    ├── mysql_data
    ├── postgres-docker-entrypoint-initdb.d
    └── postgres_data

9.2.3 Docker関係のファイルを準備

  1. Python(web)用
    • 以下の内容でDockerfile作成
    FROM python:3.8.1
    ENV PYTHONUNBUFFERED 1
    RUN mkdir /code
    RUN apt -y update \
        && apt -y upgrade \
        && apt -y install locales \
        && apt -y clean \
        && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
        && locale-gen \
        && locale-gen ja_JP.UTF-8 
    ENV LC_ALL ja_JP.UTF-8
    ENV LANG ja_JP.UTF-8
    ENV LANGUAGE ja_JP:ja
    RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
    WORKDIR /code
    ADD requirements.txt /code/
    RUN pip install -r requirements.txt
    ADD . /code/
    
    • 以下の内容でrequirements.txtを作成
    • ==以下はバージョン指定
    • ==以下をけずると、最新バージョンがインストールされます。
    • mysqlclientはMySQL用
    • psycopg2はPostgreSQL用
    Django==3.0
    psycopg2==2.8.4
    mysqlclient==1.4.6
    
  2. MySQL(db)用
    • 以下の内容でDockerfile.mysqljp を作成
    • Docker公式mysqlパッケージに日本語関係の設定を行う内容
    FROM mysql:8.0.18
    MAINTAINER NM Max
    RUN apt -y update \
        && apt -y upgrade \
        && apt -y install locales \
        && apt -y clean \
        && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
        && locale-gen \
        && locale-gen ja_JP.UTF-8 
    ENV LC_ALL ja_JP.UTF-8
    ENV LANG ja_JP.UTF-8
    ENV LANGUAGE ja_JP:ja
    RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
    
  3. docker-compose用ファイル作成
    • 以下の内容で docker-compose.yml を作成
    version: '3'
    services:
      db:
        image: mysqljp
        build:
          context: ./
          dockerfile: Dockerfile.mysqljp
        ports:
          - 3306:3306
        container_name: mysql_container
        environment:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: djangodb
          MYSQL_USER: django
          MYSQL_PASSWORD: django
          TZ: 'Asia/Tokyo'
        command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
        volumes:
          - ./docker/mysql_data:/var/lib/mysql
          - ./docker/mysql-docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
        restart: always
      web:
        image: mydjango3.0
        build:
          context: ./
          dockerfile: Dockerfile
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
          - .:/code
        ports:
          - "8000:8000"
        depends_on:
          - db
    

9.3 Docker image 作成(mysqljp, mydjango3.0)

  • docker/mysql_data/ docker/postgres_data/ ディレクトリ以下のファイルが存在してるとエラーになることあるので、エラーになったら消すか、移動
  • 以下のコマンドで、mysqljpとmydjango3.0 イメージが作成されます。
docker-compose build
  • 以下のコマンドで成功してるかみれます。
  • 以下のコマンドでmysqljpとmydjango3.0が作成されてたら成功
docker images

9.4 ファイルのバックアップ作成

  • 以下の手順だと、上のファイルやディレクトリを含んだmyDjango3.0_mysql.000.tgz が作成されます。
  • 好みのツールでzip圧縮でもOK
  • 次に行うテストプロジェクトで汚染される前の状態をどこか他のディレクトリにコピーでもOK
  • 後でこれらのファイルやディレクトリ群をコピーしやすくしておく
tar cvzf myDjango3.0_mysql.000.tgz *

9.5 テスト

9.5.1 テスト用のプロジェクト作成

  • 以下のコマンドを実行すると、dockertest001ディレクトリが作成され、内部に必用ファイルが作成されます。
  • docker-compose down で今起動したものを停止しておく
docker-compose run web django-admin startproject dockertest001
docker-compose down

9.5.2 作成されたファイル群の所有者を変更(Linuxの場合必用、windowsは不要かも)

  • Linuxの場合、作成されたものの所有者がroot.rootになっている場合、今作業しているユーザーに所有者を変更
sudo chown ユーザー名.ユーザー名 -R dockertest001
  • 例)現在作業しているユーザー名がuserなら以下
sudo chown user.user -R dockertest001
  • 以下のコマンドで今のユーザー名を確認可能
whoami

9.5.3 プロジェクト内に必用ファイル、ディレクトリをコピー

  • 先の手順で myDjango3.0_mysql.000.tgz を作成していたら、以下の手順でOK
  • zip圧縮や他の場所にコピーしてあれば、それをコピーしてくる
cd  dockertest001
tar xvzf ../myDjango3.0_mysql.000.tgz
docker-compose build

9.5.4 プロジェクト内のsetting.pyを修正

  • mysqlを利用するように設定変更
  • dockertest001/settings.pyをDATABASESのところを修正
... 省略
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'djangodb',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'db',
        'PORT': 3306,
    }
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
}
... 省略

9.5.5 makemigrations の実行

  • エラーが出ずに以下を実行出来たら成功(サーバーが立ち上がるまで時間がかかるので、何度かトライする方が良い)
docker-compose up db &
docker-compose run web python manage.py makemigrations

9.5.6 migrate の実行

docker-compose run web python manage.py migrate
  • エラーが出ずに以下の様な出力が出て、データベースの内容の変更が出来たら成功
Starting mysql_container ... done
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

9.5.7 mysqldumpによるデータベースのバックアップ

  • 以下のコマンドで現状のデータベースをバックアップ
docker-compose run db mysqldump -udjango -pdjango djangodb --host db > backup.sql
  • 1行目にゴミがはいるので、エディタで1行目を消すか、sedが使えるなら以下で1行目を削除したbackup.sqlを作成出来る。
docker-compose run db mysqldump -udjango -pdjango djangodb --host db |sed '1d' > backup.sql

9.5.8 サービスの起動

  • 以下のコマンドで mydjango3.0 イメージが起動し、http://localhost:8000/をブラウザで確認すると、djangoの招待ページが表示されます。
docker-compose up

9.5.9 サービスの停止

  • 画面に出ている停止方法にしたがって、止めます。
  • Linuxなら Ctrl と C ボタンの同時押し
  • その後以下のコマンドを入力して、動いているdockerを停止
docker-compose down

9.6 この章のまとめ

  • 以前はUbuntuベースでdjango用のDocker imageを作成しましたが、今回は公式のpythonと、mysqlイメージと、docker-composeを利用して作ってみました。

10 django向けDocker composeを作成(django+postgresql)

10.1 以下の操作を行っている動画


10.2 準備作業

10.2.1 作業用ディレクトリ生成

mkdir myDjango3.0_PostgreSQL
cd myDjango3.0_PostgreSQL

10.2.2 共有ディレクトリ生成

  • mkdir 命令で作成していますが、別のツールでディレクトリ作成してもOK
mkdir -p docker/mysql-docker-entrypoint-initdb.d/
mkdir -p docker/postgres-docker-entrypoint-initdb.d/
mkdir -p docker/mysql_data/
mkdir -p docker/postgres_data/
  • 作成したディレクトリツリーは以下に
.
└── docker
    ├── mysql-docker-entrypoint-initdb.d
    ├── mysql_data
    ├── postgres-docker-entrypoint-initdb.d
    └── postgres_data

10.2.3 Docker関係のファイルを準備

  1. Python(web)用
    • 以下の内容でDockerfile作成
    FROM python:3.8.1
    ENV PYTHONUNBUFFERED 1
    RUN mkdir /code
    RUN apt -y update \
        && apt -y upgrade \
        && apt -y install locales \
        && apt -y clean \
        && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
        && locale-gen \
        && locale-gen ja_JP.UTF-8 
    ENV LC_ALL ja_JP.UTF-8
    ENV LANG ja_JP.UTF-8
    ENV LANGUAGE ja_JP:ja
    RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
    WORKDIR /code
    ADD requirements.txt /code/
    RUN pip install -r requirements.txt
    ADD . /code/
    
    • 以下の内容でrequirements.txtを作成
    • ==以下はバージョン指定
    • ==以下をけずると、最新バージョンがインストールされます。
    • mysqlclientはMySQL用
    • psycopg2はPostgreSQL用
    Django==3.0
    psycopg2==2.8.4
    mysqlclient==1.4.6
    
  2. PostgreSQL(db)用
    • 以下の内容でDockerfile.postgresql作成
    FROM postgres:12.1
    MAINTAINER NM Max
    RUN apt -y update \
        && apt -y upgrade \
        && apt -y install locales \
        && apt -y clean \
        && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
        && locale-gen \
        && locale-gen ja_JP.UTF-8 
    ENV LC_ALL ja_JP.UTF-8
    ENV LANG ja_JP.UTF-8
    ENV LANGUAGE ja_JP:ja
    RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
    
  3. docker-compose用ファイル作成
    • 以下の内容で docker-compose.yml を作成
    version: '3'
    services:
      db:
        image: postgresjp
        build:
          context: ./
          dockerfile: Dockerfile.postgresql
        container_name: postgres_container
        environment:
          POSTGRES_DB: djangodb
          POSTGRES_USER: django
          POSTGRES_PASSWORD: django
          TZ: 'Asia/Tokyo'
          POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=ja_JP.UTF-8"
          LC_ALL: ja_JP.UTF-8
          LANG: ja_JP.UTF-8
          LANGUAGE: ja_JP:ja
        restart: always
        volumes:
          - ./docker/postgres_data/:/var/lib/postgresql/data/
          - ./docker/postgres-docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
      web:
        image: mydjango3.0
        build:
          context: ./
          dockerfile: Dockerfile
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
          - .:/code
        ports:
          - "8000:8000"
        depends_on:
          - db
    

10.3 Docker image 作成(postgresjp, mydjango3.0)

  • docker/mysql_data/ docker/postgres_data/ ディレクトリ以下のファイルが存在してるとエラーになることあるので、エラーになったら消すか、移動
  • 以下のコマンドで、postgresjpとmydjango3.0 イメージが作成されます。
docker-compose build
  • 以下のコマンドで成功してるかみれます。
  • 以下のコマンドでmydjango3.0が作成されてたら成功
docker images

10.4 ファイルのバックアップ作成

  • 以下の手順だと、上のファイルやディレクトリを含んだmyDjango3.0_postgresql.000.tgz が作成されます。
  • 好みのツールでzip圧縮でもOK
  • 次に行うテストプロジェクトで汚染される前の状態をどこか他のディレクトリにコピーでもOK
  • 後でこれらのファイルやディレクトリ群をコピーしやすくしておく
tar cvzf myDjango3.0_postgresql.000.tgz *

10.5 テスト

10.5.1 テスト用のプロジェクト作成

  • 以下のコマンドを実行すると、dockertest002ディレクトリが作成され、内部に必用ファイルが作成されます。
  • docker-compose down で今起動したものを停止しておく
docker-compose run web django-admin startproject dockertest002
docker-compose down

10.5.2 作成されたファイル群の所有者を変更(Linuxの場合必用、windowsは不要かも)

  • Linuxの場合、作成されたものの所有者がroot.rootになっている場合、今作業しているユーザーに所有者を変更
sudo chown ユーザー名.ユーザー名 -R dockertest002
  • 例)現在作業しているユーザー名がuserなら以下
sudo chown user.user -R dockertest002
  • 以下のコマンドで今のユーザー名を確認可能
whoami

10.5.3 プロジェクト内に必用ファイル、ディレクトリをコピー

  • 先の手順で myDjango3.0_postgresql.000.tgz を作成していたら、以下の手順でOK
  • zip圧縮や他の場所にコピーしてあれば、それをコピーしてくる
cd  dockertest002
tar xvzf ../myDjango3.0_postgresql.000.tgz
docker-compose build

10.5.4 プロジェクト内のsetting.pyを修正

  • mysqlを利用するように設定変更
  • dockertest002/settings.pyをDATABASESのところを修正
... 省略
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'djangodb',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'db',
        'PORT': 5432,
    }
#    'default': {
#        'ENGINE': 'django.db.backends.mysql',
#        'NAME': 'djangodb',
#        'USER': 'django',
#        'PASSWORD': 'django',
#        'HOST': 'db',
#        'PORT': 3306,
#    }
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
}
... 省略

10.5.5 makemigrations の実行

  • エラーが出ずに以下を実行出来たら成功(サーバーが立ち上がるまで時間がかかるので、何度かトライする方が良い)
docker-compose up db &
docker-compose run web python manage.py makemigrations

10.5.6 migrate の実行

docker-compose run web python manage.py migrate
  • エラーが出ずに以下の様な出力が出て、データベースの内容の変更が出来たら成功
Starting mysql_container ... done
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

10.5.7 サービスの起動

  • 以下のコマンドで mydjango3.0 イメージが起動し、http://localhost:8000/をブラウザで確認すると、djangoの招待ページが表示されます。
docker-compose up

10.5.8 サービスの停止

  • 画面に出ている停止方法にしたがって、止めます。
  • Linuxなら Ctrl と C ボタンの同時押し
  • その後以下のコマンドを入力して、動いているdockerを停止
docker-compose down

10.6 この章のまとめ

  • 公式のpythonと、postgresqlイメージと、docker-composeを利用してdjango向け環境を作ってみました。

11 django向けDocker composeを作成(django+sqlite3)

11.1 以下の操作を行っている動画


11.2 準備作業

11.2.1 Docker関係のファイルを準備

  • 作業用ディレクトリ作成し、その中にはいる
  • 好きなツールを使ってOK
mkdir myDjango3.0_Sqlite3
cd myDjango3.0_Sqlite3/

11.2.2 Docker関係のファイルを準備

  1. Python(web)用
    • 以下の内容でDockerfile作成
    FROM python:3.8.1
    ENV PYTHONUNBUFFERED 1
    RUN mkdir /code
    RUN apt -y update \
        && apt -y upgrade \
        && apt -y install locales \
        && apt -y clean \
        && echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen \
        && locale-gen \
        && locale-gen ja_JP.UTF-8 
    ENV LC_ALL ja_JP.UTF-8
    ENV LANG ja_JP.UTF-8
    ENV LANGUAGE ja_JP:ja
    RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
    WORKDIR /code
    ADD requirements.txt /code/
    RUN pip install -r requirements.txt
    ADD . /code/
    
    • 以下の内容でrequirements.txtを作成
    • ==以下はバージョン指定
    • ==以下をけずると、最新バージョンがインストールされます。
    • mysqlclientはMySQL用
    • psycopg2はPostgreSQL用
    Django==3.0
    psycopg2==2.8.4
    mysqlclient==1.4.6
    
  2. docker-compose用ファイル作成
    • 以下の内容で docker-compose.yml を作成
    version: '3'
    services:
      web:
        image: mydjango3.0
        build:
          context: ./
          dockerfile: Dockerfile
        command: python manage.py runserver 0.0.0.0:8000
        volumes:
          - .:/code
        ports:
          - "8000:8000"
    

11.3 Docker image 作成( mydjango3.0)

  • docker/mysql_data/ docker/postgres_data/ ディレクトリ以下のファイルが存在してるとエラーになることあるので、エラーになったら消すか、移動
  • 以下のコマンドで、mysqljpとmydjango3.0 イメージが作成されます。
docker-compose build
  • 以下のコマンドで成功してるかみれます。
  • 以下のコマンドでmydjango3.0が作成されてたら成功
docker images

11.4 ファイルのバックアップ作成

  • 以下の手順だと、上のファイルやディレクトリを含んだmyDjango3.0_postgresql.000.tgz が作成されます。
  • 好みのツールでzip圧縮でもOK
  • 次に行うテストプロジェクトで汚染される前の状態をどこか他のディレクトリにコピーでもOK
  • 後でこれらのファイルやディレクトリ群をコピーしやすくしておく
tar cvzf myDjango3.0_sqlite3.000.tgz *

11.5 テスト

11.5.1 テスト用のプロジェクト作成

  • 以下のコマンドを実行すると、dockertest003ディレクトリが作成され、内部に必用ファイルが作成されます。
  • docker-compose down で今起動したものを停止しておく
docker-compose run web django-admin startproject dockertest003
docker-compose down

11.5.2 作成されたファイル群の所有者を変更(Linuxの場合必用、windowsは不要かも)

  • Linuxの場合、作成されたものの所有者がroot.rootになっている場合、今作業しているユーザーに所有者を変更
sudo chown ユーザー名.ユーザー名 -R dockertest003
  • 例)現在作業しているユーザー名がuserなら以下
sudo chown user.user -R dockertest003
  • 以下のコマンドで今のユーザー名を確認可能
whoami

11.5.3 プロジェクト内に必用ファイル、ディレクトリをコピー

  • 先の手順で myDjango3.0_sqlite3.000.tgz を作成していたら、以下の手順でOK
  • zip圧縮や他の場所にコピーしてあれば、それをコピーしてくる
cd  dockertest003
tar xvzf ../myDjango3.0_sqlite3.000.tgz
docker-compose build

11.5.4 makemigrations の実行

  • エラーが出ずに以下を実行出来たら成功(サーバーが立ち上がるまで時間がかかるので、何度かトライする方が良い)
docker-compose run web python manage.py makemigrations

11.5.5 migrate の実行

docker-compose run web python manage.py migrate
  • エラーが出ずに以下の様な出力が出て、データベースの内容の変更が出来たら成功
Starting mysql_container ... done
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

11.5.6 サービスの起動

  • 以下のコマンドで mydjango3.0 イメージが起動し、http://localhost:8000/をブラウザで確認すると、djangoの招待ページが表示されます。
docker-compose up

11.5.7 サービスの停止

  • 画面に出ている停止方法にしたがって、止めます。
  • Linuxなら Ctrl と C ボタンの同時押し
  • その後以下のコマンドを入力して、動いているdockerを停止
docker-compose down

11.6 この章のまとめ

  • 公式のpythonlイメージを利用してdjango向け環境を作ってみました。

12 docker cp (コンテナ←→ホスト間でのファイルのコピー

12.1 以下の操作を行っている動画


12.2

12.2.1 Ubuntuのイメージをプル

docker pull ubuntu

12.2.2 Ubuntuのイメージを起動

docker run  -it --rm  ubuntu

12.2.3 内部で適当にファイルを作成

  • /test.txtにの”docker cp test”を入れる
echo "docker cp test" > /test.txt
  • 以下のコマンドで内容確認
cat /test.txt

12.2.4 docker cpコマンドで /test.txt をホスト側にコピー

  1. コンテナのidを確認
    docker ps -a
    
  2. ファイルのコピー(コンテナからホストへ)
    • 確認したidを利用して以下のコマンドでコピー
    docker cp 確認したコテナのID:/test.txt ./test.txt
    
    • あるいは
    docker cp 確認したコテナのID:/test.txt .
    
    • 取り出したファイルの中身の確認
    • cat コマンドで行うなら以下のコマンド、好きなテキストエディタで確認でもOK
    cat ./test.txt
    

12.2.5 docker cpコマンドで ホスト側のファイルをコンテナ側にコピー

  1. 転送するファイルの作成
    • cat コマンドで行うなら以下、適当な内容で test2.txt ファイルを作成してください
    echo "docker cp test2" > ./test2.txt
    
  2. コンテナのidを確認
    docker ps -a
    
  3. ファイルのコピー(ホストからコンテナへ)
    docker cp ./test2.txt 確認したコテナのID:/
    
  4. コンテナ側で確認
    cat test2.txt
    

12.3 この章のまとめ

  • docker cp コマンドを利用して、ホストとコンテナ間でファイルの転送を行ってみました。

13 一般ユーザー追加したUbuntuベースのPython用パッケージ作成

  • dockercomposeで利用したdjango向けのDockerfileをPython向けにし、一般ユーザーを追加
  • djangoも必用ならdjangoもインストールするように改造してください。

13.1 このイメージ作成の目的

  • tensorflowの最新バージョンはCPUにAVX命令が必用になってて、私の安物PCはAVX命令の無いCPUのため動かず、これをAVX無しのコンパイル用に使おうとしている
  • Ubuntu 19.10ベースで色々やったけど、回避が大変なエラーが出た為( 1.15ベース、最新ベース両方 回避が大変そうなエラーで断念)、Ubuntu 18.04ベースで今コンパイル中
  • 2020/01/13 20時時点でtensorflowをコンパイル中、まだ成功してない。成功したらコンパイル手順をアップします。
  • tensorflow 1.5 だとavx命令無しでも動く、しかしPython2系のものしかpipで簡単にインストール出来ない
  • tensorflowのDockerイメージがDocker hubにあるので、avx命令が使えるCPUを持っておられる方は、それをpullするのがお勧め
  • 私も今回のコンパイルに大変時間がかかるので、avxが使える現状使ってるPCに使えるCPUを購入しました。

13.2 以下の操作を行っている動画


13.3 Dockerfileの作成

FROM ubuntu:18.04
MAINTAINER NM Max
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install python3-pip python3 ipython3 python3-dev \
    && apt -y install python-pip python ipython python-dev  \
    && apt -y install vim w3m wget diffutils sqlite3 nkf less diffutils patch sudo git clang curl pkg-config zip g++ zlib1g-dev unzip \ 
    && apt -y install openssh-client openssh-server \
    && apt -y install locales \
    && locale-gen ja_JP.UTF-8 
# RUN pip install tensorflow 
# RUN pip install tensorflow==1.5 
# RUN pip3 install tensorflow 
# RUN pip3 install Django==3.0 psycopg2==2.8.4 mysqlclient==1.4.6
# RUN pip3 install Django psycopg2 mysqlclient
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
WORKDIR /work
COPY ./myinit.sh /work/myinit.sh
RUN chmod +x /work/myinit.sh
RUN echo "\n\n\n\n\n\n\n" | adduser --uid 1000 --disabled-password user 
RUN echo "user ALL=NOPASSWD: ALL" >> /etc/sudoers && chown user.user /work
RUN mkdir -p /home/user/C && chown  user.user /home/user/C 
EXPOSE 22 80 8000 8001
ENTRYPOINT /work/myinit.sh

13.4 myinit.shの作成

#!/bin/sh
su - user

13.5 makeDocker.shの作成

- これを実行するか、中のdocker命令を実行するとimageを作成できます。
#!/bin/sh
docker build -t mypython . 
  • 実行権限を与える
chmod +x ./makeDocker.sh

13.6 Start.shの作成

  • 起動には下のdockerから始まる命令を実行すると開始できます。
  • コンテナの/home/user/Cを、ホストの/work/mypythonに共有してます。共有ディレクトリを変更する場合は、/work/mypythonをそれに変更してください。
#!/bin/sh
docker run --rm -it -p 22:22 -p 8000:8000 -p 8001:8001 -v /work/mypython:/home/user/C mypython
  • 実行権限を与える
chmod +x ./Start.sh

13.7 囲碁用でtensorflowを利用するものを実行してみる

13.7.1 手順

  • 先程作成したイメージ起動
  • 先程作成したStart.shを動かすか、あるいは以下のコマンド実行
  • 以下のコマンドでは/work/mypythonに共有ディレクトリをリンクしてますので、他の場所を希望の場合、そこを変更してください。
docker run --rm -it -p 22:22 -p 8000:8000 -p 8001:8001 -v /work/mypython:/home/user/C mypython
  1. tensorflow インストール
    • avx命令が使えない方は以下でversion1.5(古いバージョンインストール)
    pip install tensorflow==1.5
    
    • avx命令が使えるCPUの方は以下で比較的新しいバージョンインストール
    pip install tensorflow
    
  2. Pyaq ソースゲット
    
    
  3. 用意されてるモデルを利用
    cp Pyaq/pre_train/model.ckpt Pyaq/
    
  4. 起動
    cd Pyaq
    ./pyaq.py --self --random
    

13.8 この章では

  • djangoをdockercomposeで動かす用のDockerに一般ユーザーを追加するコードを追加し修正したDockerfileを作成
  • tensorflowを利用して動く囲碁ソフトをそのイメージ内で動かしてみた

14 tensorflowをavx無しモードでコンパイル(v1.15.0-rc3)

14.1 関係リンク等、色々

--cxxopt=-std=c++11

14.2 以下の操作を行っている動画


14.3 実際に行った手順をhistoryからまとめたもの

cd C
sudo apt-get install pkg-config zip g++ zlib1g-dev unzip python
wget https://github.com/bazelbuild/bazel/releases/download/0.26.1/bazel-0.26.1-installer-linux-x86_64.sh
chmod +x bazel-0.26.1-installer-linux-x86_64.sh
./bazel-0.26.1-installer-linux-x86_64.sh --user
source /home/user/.bazel/bin/bazel-complete.bash
export PATH=$PATH:$HOME/bin
vi ~/.bashrc
git clone https://github.com/tensorflow/tensorflow.git -b v1.15.0-rc3
cd tensorflow/
pip3 install pip six numpy wheel setuptools mock future  keras_applications keras_preprocessing
./configure
date ; bazel build --cxxopt=-std=c++11 --config=opt //tensorflow/tools/pip_package:build_pip_package ; date
sudo tar cvzf /home_user.tgz /home/user/
sudo mv -i /home_user.tgz C/
cd tensorflow/
./bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/C/tensorflow_pkg
sudo python3 -m pip install  tensorflow_pkg/tensorflow-1.15.0rc3-cp36-cp36m-linux_x86_64.whl
python3 -m pip list | grep tensor

14.4 手順解説

14.4.1 dokcerイメージ起動

  • 前章で作ったmypythonを利用,mypythonイメージの作成方法は前章を参照してください。
docker run --rm -it -p 22:22 -p 8000:8000 -p 8001:8001 -v /work/mypython:/home/user/C mypython
  • 起動したら、ホストと共有しているディレクトリに移動
cd C

14.4.2 bazelのインストール

  • 最後の vi ~/.bashrc では ~/.bashrc に source home/user.bazel/bin/bazel-complete.bash を追加
sudo apt-get install pkg-config zip g++ zlib1g-dev unzip python
wget https://github.com/bazelbuild/bazel/releases/download/0.26.1/bazel-0.26.1-installer-linux-x86_64.sh
chmod +x bazel-0.26.1-installer-linux-x86_64.sh
./bazel-0.26.1-installer-linux-x86_64.sh --user
source /home/user/.bazel/bin/bazel-complete.bash
export PATH=$PATH:$HOME/bin
vi ~/.bashrc

14.4.3 tensorflow v1.15.0-rc3 のソースをダウンロードしてtensorflowディレクトリにはいる

git clone https://github.com/tensorflow/tensorflow.git -b v1.15.0-rc3
cd tensorflow/

14.4.4 必用パッケージインストール

pip3 install pip six numpy wheel setuptools mock future  keras_applications keras_preprocessing

14.4.5 ./configure 実行

./configure
  • 以下のように設定した
./configure
Extracting Bazel installation...
WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
You have bazel 1.2.1 installed.
Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python3


Found possible Python library paths:
  /usr/local/lib/python3.7/dist-packages
  /usr/lib/python3/dist-packages
Please input the desired Python library path to use.  Default is [/usr/local/lib/python3.7/dist-packages]

Do you wish to build TensorFlow with XLA JIT support? [Y/n]:
XLA JIT support will be enabled for TensorFlow.

Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]:
No OpenCL SYCL support will be enabled for TensorFlow.

Do you wish to build TensorFlow with ROCm support? [y/N]:
No ROCm support will be enabled for TensorFlow.

Do you wish to build TensorFlow with CUDA support? [y/N]:
No CUDA support will be enabled for TensorFlow.

Do you wish to download a fresh release of clang? (Experimental) [y/N]:
Clang will not be downloaded.

Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native -Wno-sign-compare]:


Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]:
Not configuring the WORKSPACE for Android builds.

Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
  --config=mkl          # Build with MKL support.
  --config=monolithic   # Config for mostly static monolithic build.
  --config=ngraph       # Build with Intel nGraph support.
  --config=numa         # Build with NUMA support.
  --config=dynamic_kernels  # (Experimental) Build kernels into separate shared objects.
  --config=v2           # Build TensorFlow 2.x instead of 1.x.
Preconfigured Bazel build configs to DISABLE default on features:
  --config=noaws        # Disable AWS S3 filesystem support.
  --config=nogcp        # Disable GCP support.
  --config=nohdfs       # Disable HDFS support.
  --config=nonccl       # Disable NVIDIA NCCL support.
Configuration finished

14.4.6 コンパイル

date ; bazel build --cxxopt=-std=c++11 --config=opt //tensorflow/tools/pip_package:build_pip_package ; date
  • 開始時のdateの出力が以下
2020年  1月 13日 月曜日 00:49:21 UTC
  • コンパイル成功した直後の出力が以下(ほぼほぼ24時間かかってる)
..... 省略
s: 1 operators, 3 arrays (0 quantized)
2020-01-13 23:46:35.875563: I tensorflow/lite/toco/allocate_transient_arrays.cc:345] Total transient array allocated size: 0 bytes, theoretical optimal value: 0 bytes.
2020-01-13 23:46:35.875595: I tensorflow/lite/toco/toco_tooling.cc:439] Estimated count of arithmetic ops: 0 ops, equivalently 0 MACs
2020-01-13 23:46:35.875616: I tensorflow/lite/toco/toco_tooling.cc:454] Number of parameters: 0
INFO: From ProtoCompile tensorflow/contrib/rpc/python/kernel_tests/test_example.pb.h:
bazel-out/k8-opt/bin/external/com_google_protobuf/src: warning: directory does not exist.
Target //tensorflow/tools/pip_package:build_pip_package up-to-date:
  bazel-bin/tensorflow/tools/pip_package/build_pip_package
INFO: Elapsed time: 82738.966s, Critical Path: 363.36s
INFO: 19514 processes: 19514 local.
INFO: Build completed successfully, 20531 total actions
2020年  1月 13日 月曜日 23:48:21 UTC

14.4.7 バックアップ

  • コンパイルに鬼のように時間かかるので現状をバックアップ
sudo tar cvzf /home_user.tgz /home/user/
sudo mv -i /home_user.tgz ~/C/

14.4.8 pip向けパッケージ作成

cd ~/C/tensorflow/
./bazel-bin/tensorflow/tools/pip_package/build_pip_package ~/C/tensorflow_pkg

14.4.9 作成したpip向けパッケージをインストール

sudo python3 -m pip install  tensorflow_pkg/tensorflow-1.15.0rc3-cp36-cp36m-linux_x86_64.whl

14.4.10 インストール確認

python3 -m pip list | grep tensor

14.4.11 インポートしてもcore dumpしないか確認

  • ipython3を起動
ipython3
  • 以下でtensorflowをimport
import tensorflow

14.5 この章でのまとめ

  • tensorflow v1.15.0-rc3 を cpuがavx拡張命令セットが使えないものでも動作するようにコンパイル
  • コンパイルに24時間程度必用になるため、ハードをavx対応にした方が良い
  • 公式文書のとうりではUbuntu 19.10ベースだとコンパイル中に色々エラーが発生、bazel関係のエラーが出たため断念し、Ubuntu 18.04ベースでコンパイル
  • tensorflow v1.15.0-rc3 では成功したが、gitoの最新masterや、v1.14.0-rc1はまだ成功出来てない、コンパイルに時間がかかりすぎるため、購入している交換cpuが届くまでこれで行く予定
  • 現状tensorflowを多用するなら、cpuはavx拡張命令対応のハードを使った方が良さげ

15 話題のAI関係のライブラリTensorflowをDockerで提供されているイメージを使って動かしてみる

15.1 以下の操作を行っている動画


15.2 イメージのゲット

docker pull tensorflow/tensorflow

15.3 Jupyter notebook serverをうごかしてみる

  • ディレクトリを掘る(ほってなくても自動で生成されるようだ、ただしroot権限で)
mkdir -p ~/notebooks
  • 以下のコマンドで起動
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 tensorflow/tensorflow:latest-py3-jupyter
  • 表示されるlocalhostのurlにアクセス

15.4 tensorflowのバージョン確認

  • 新しいノートを作成して以下のコマンドを実行
import tensorflow as tf
tf.__version__

15.5 この章のまとめ

  • Docker hubで提供されているtensorflow/tensorflowイメージを利用して、tensorflowを試してみた
  • Jupyter notebook使い勝手良いかも

16 Docker Hubのtensorflow/tensorflowを拡張、その1

  • 関係文書 https://hub.docker.com/r/tensorflow/tensorflow/
  • CPUがavx命令サポートしてないと動かないバイナリです。(avx拡張命令のないCPUの場合、コンパイルしなおす必用あり)
  • その2の予定はまだないけど、多分また拡張したくなりそうなので、拡張その1としてます。

16.1 以下の操作を行っている動画


16.2 mytensorflowイメージの作成手順

16.2.1 Docker ファイルを用意

  • 一般ユーザー(user,uidを1000)を追加
  • Python パッケージで使いそうなのを追加, tensorflow_hub,pillow,dlib等
  • その他色々てんこもりで追加(python-opencvや、tensorflow-model-server等)
FROM tensorflow/tensorflow:latest-py3-jupyter 
MAINTAINER NM Max
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install python3-pip python3 ipython3 python3-dev \
    && apt -y install python-pip python ipython python-dev  \
    && apt -y install vim w3m wget diffutils sqlite3 nkf less diffutils patch sudo git clang curl pkg-config zip g++ zlib1g-dev unzip \ 
    && apt -y install openssh-client openssh-server \
    && apt -y install build-essential cmake pkg-config \
    && apt -y install libatlas-base-dev  libboost-python-dev  \
    && apt -y install python3-dev python3-pip \
    && pip3 install --upgrade pip \
    && pip3 install tensorflow_hub \
    && pip3 install pillow \
    && pip3 install dlib --verbose \
    && apt install fonts-liberation \
    && apt -y install locales \
    && locale-gen ja_JP.UTF-8 
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
ENV TZ=Asia/Tokyo
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
RUN echo "\n\n\n\n\n\n\n" | adduser --uid 1000 --disabled-password user 
RUN echo "user ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN mkdir -p /home/user/C && chown  user.user /home/user/C 
ENV DEBIAN_FRONTEND=noninteractive
RUN apt -y install tzdata \
    && apt -y install python3-opencv python3-willow python3-skimage
RUN echo "deb [arch=amd64] http://storage.googleapis.com/tensorflow-serving-apt stable tensorflow-model-server tensorflow-model-server-universal" | tee /etc/apt/sources.list.d/tensorflow-serving.list \
    && curl https://storage.googleapis.com/tensorflow-serving-apt/tensorflow-serving.release.pub.gpg | sudo apt-key add - \
    && apt-get update && apt-get install tensorflow-model-server

16.2.2 Start.shファイルを用意

  • 起動用のファイルを作成
#!/bin/sh
#docker run --rm -it -p 22:22 -p 8000:8000 -p 8001:8001 -v /work/mypython:/home/user/C mypython
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow
  • 以下のコマンドで実行権限を与える(Linuxの場合)
chmod +x Start.sh
  • スクリプトファイルを利用出来ない環境の場合は以下で、直接起動スクリプトが実行している命令を実行してください。
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow

16.2.3 makeDocker.shファイルを用意

  • Dockerファイルを利用して、Dockerのイメージを作成する用のスクリプトファイルを作成。
#!/bin/sh
docker build -t mytensorflow . 
  • 実行権限を与える
chmod +x makeDocker.sh

16.2.4 イメージの作成

  • スクリプトファイルを利用できる環境の場合、上で作成したmakeDocker.shスクリプトを実行
./makeDocker.sh
  • スクリプトファイルを利用出来ない環境の場合は、以下
docker build -t mytensorflow . 

16.3 mytensorflowイメージの利用手順

16.3.1 mytensorflow起動1

  • スクリプトファイルを利用できる環境の場合、上で作成したStart.shスクリプトを実行
./Start.sh
  • スクリプトファイルを利用出来ない環境の場合は、以下
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow

16.3.2 mytensorflow起動2

  • 起動したら、メッセージが表示されます。最後の http://127.0.0.1/.. 省略 の部分をコピーして、ブラウザでそのURLを開く
  • ブラウザでterminalを起動したら、最初にbashを実行するとより使いやすくなる。

16.4 この章のまとめ

  • 既存のTensorflow Hubにあるイメージの拡張を行いました。
  • まだまだ、色々よく使うパッケージやソフトがあると思うので、拡張その2も作るかも。
  • 一般ユーザーを追加したので、より使いやすい。
  • 今のところ便利にこのイメージ利用してます。ベースがUbuntu 18.04なので、TensorFlow以外の用途にも使ってます。自分の環境を汚さずに色々試せて良い感じ。

17 Docker Hubのtensorflow/tensorflowを拡張、その2

  • 前章のDocker Hubのtensorflow/tensorflowをさらに拡張
  • ソースを読みやすくするGNU Globalを追加(pygmentを追加してpythonのソースにも対応させる)

17.1 以下の操作を行っている動画


17.2 mytensorflowイメージの作成手順

17.2.1 Docker ファイルを用意

  • GNU Globalを追加
FROM tensorflow/tensorflow:latest-py3-jupyter 
MAINTAINER NM Max
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install python3-pip python3 ipython3 python3-dev \
    && apt -y install python-pip python ipython python-dev  \
    && apt -y install vim w3m wget diffutils sqlite3 nkf less diffutils patch sudo git clang curl pkg-config zip g++ zlib1g-dev unzip \ 
    && apt -y install openssh-client openssh-server \
    && apt -y install build-essential cmake pkg-config \
    && apt -y install libatlas-base-dev  libboost-python-dev  \
    && apt -y install python3-dev python3-pip \
    && pip3 install --upgrade pip \
    && pip3 install tensorflow_hub \
    && pip3 install pillow \
    && pip3 install dlib --verbose \
    && apt install fonts-liberation \
    && apt -y install locales \
    && locale-gen ja_JP.UTF-8 
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
ENV TZ=Asia/Tokyo
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
RUN echo "\n\n\n\n\n\n\n" | adduser --uid 1000 --disabled-password user 
RUN echo "user ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN mkdir -p /home/user/C && chown  user.user /home/user/C 
ENV DEBIAN_FRONTEND=noninteractive
RUN apt -y install tzdata \
    && apt -y install python3-opencv python3-willow python3-skimage
RUN echo "deb [arch=amd64] http://storage.googleapis.com/tensorflow-serving-apt stable tensorflow-model-server tensorflow-model-server-universal" | tee /etc/apt/sources.list.d/tensorflow-serving.list \
    && curl https://storage.googleapis.com/tensorflow-serving-apt/tensorflow-serving.release.pub.gpg | sudo apt-key add - \
    && apt-get update && apt-get install tensorflow-model-server \
    && apt -y install global id-utils python-pygments exuberant-ctags python-pygments python3-pygments
COPY gtags.conf /etc/gtags.conf

17.2.2 gtags.confファイルを用意

#
# Copyright (c) 1998, 1999, 2000, 2001, 2002, 2003, 2010, 2011, 2013,
#       2015, 2016, 2017
#       Tama Communications Corporation
#
# This file is part of GNU GLOBAL.
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# *
# Configuration file for GNU GLOBAL source code tagging system.
#
# Basically, GLOBAL doesn't need this configuration file ('gtags.conf'),
# because it has default values in itself. If you have this file as
# '/etc/gtags.conf' or "$HOME/.globalrc" then GLOBAL overwrite the default
# values with values in the file.
# Configuration file is also necessary to use plug-in parsers.
#
# The format is similar to termcap(5). You can specify a target with
# GTAGSLABEL environment variable. Default target is 'default'.
#
# If you want to have default values for yourself, it is recommended to
# use the following method:
#
# default:\
#       :tc=default@~/.globalrc:\       <= includes default values from ~/.globalrc.
#       :tc=native:
#
# Please refer to gtags.conf(5) for details.
#
default:\
        :tc=native:
native:\
        :tc=gtags:tc=htags:
user:\
        :tc=user-custom:tc=htags:
ctags:\
        :tc=exuberant-ctags:tc=htags:
new-ctags:\
        :tc=universal-ctags:tc=htags:
pygments:\
        :tc=pygments-parser:tc=htags:
#
# [How to merge two or more parsers?]
#
# Rule: The first matched langmap is adopted.
#
# ":tc=builtin-parser:tc=pygments-parser:" means:
#       If built-in parser exists for the target, it is used.
#       Else if pygments parser exists it is used.
#
native-pygments:\
        :tc=builtin-parser:tc=pygments-parser:tc=htags:
#---------------------------------------------------------------------
# Configuration for gtags(1)
# See gtags(1).
#---------------------------------------------------------------------
common:\
        :skip=HTML/,HTML.pub/,tags,TAGS,ID,y.tab.c,y.tab.h,gtags.files,cscope.files,cscope.out,cscope.po.out,cscope.in.out,SCCS/,RCS/,CVS/,CVSROOT/,{arch}/,autom4te.cache/,*.orig,*.rej,*.bak,*~,#*#,*.swp,*.tmp,*_flymake.*,*_flymake,*.o,*.a,*.so,*.lo,*.zip,*.gz,*.bz2,*.xz,*.lzh,*.Z,*.tgz,*.min.js,*min.css:
#
# Built-in parsers.
#
gtags:\
        :tc=common:\
        :tc=builtin-parser:
builtin-parser:\
        :langmap=c\:.c.h,yacc\:.y,asm\:.s.S,java\:.java,cpp\:.c++.cc.hh.cpp.cxx.hxx.hpp.C.H,php\:.php.php3.phtml:
#
# skeleton for user's custom parser.
#
user-custom|User custom plugin parser:\
        :tc=common:\
        :langmap=c\:.c.h:\
        :gtags_parser=c\:$libdir/gtags/user-custom.la:
#
# Plug-in parser to use Exuberant Ctags.
#
# Most of the following definitions were automatically generated by this command line:
# $ perl maps2conf.pl /user/local/bin/ctags '$libdir/gtags/exuberant-ctags.la'
# ('/user/local/bin/ctags' should be replaced with the path of Exuberant Ctags.)
#
exuberant-ctags|plugin-example|setting to use Exuberant Ctags plug-in parser:\
        :tc=common:\
        :ctagscom=/usr/bin/ctags:\
        :ctagslib=$libdir/gtags/exuberant-ctags.la:\
        :langmap=Ant\:(*.build.xml):\
        :langmap=Asm\:.asm.ASM.s.S.A51(*.29[kK])(*.[68][68][kKsSxX])(*.[xX][68][68]):\
        :langmap=Asp\:.asp.asa:\
        :langmap=Awk\:.awk.gawk.mawk:\
        :langmap=Basic\:.bas.bi.bb.pb:\
        :langmap=BETA\:.bet:\
        :langmap=C\:.c:\
        :langmap=C++\:.c++.cc.cp.cpp.cxx.h.h++.hh.hp.hpp.hxx.C.H:\
        :langmap=C#\:.cs:\
        :langmap=Cobol\:.cbl.cob.CBL.COB:\
        :langmap=DosBatch\:.bat.cmd:\
        :langmap=Eiffel\:.e:\
        :langmap=Erlang\:.erl.ERL.hrl.HRL:\
        :langmap=Flex\:.as.mxml:\
        :langmap=Fortran\:.f.for.ftn.f77.f90.f95.F.FOR.FTN.F77.F90.F95:\
        :langmap=HTML\:.htm.html:\
        :langmap=Java\:.java:\
        :langmap=JavaScript\:.js:\
        :langmap=Lisp\:.cl.clisp.el.l.lisp.lsp:\
        :langmap=Lua\:.lua:\
        :langmap=Make\:.mak.mk([Mm]akefile)(GNUmakefile):\
        :langmap=MatLab\:.m:\
        :langmap=OCaml\:.ml.mli:\
        :langmap=Pascal\:.p.pas:\
        :langmap=Perl\:.pl.pm.plx.perl:\
        :langmap=PHP\:.php.php3.phtml:\
        :langmap=Python\:.py.pyx.pxd.pxi.scons:\
        :langmap=REXX\:.cmd.rexx.rx:\
        :langmap=Ruby\:.rb.ruby:\
        :langmap=Scheme\:.SCM.SM.sch.scheme.scm.sm:\
        :langmap=Sh\:.sh.SH.bsh.bash.ksh.zsh:\
        :langmap=SLang\:.sl:\
        :langmap=SML\:.sml.sig:\
        :langmap=SQL\:.sql:\
        :langmap=Tcl\:.tcl.tk.wish.itcl:\
        :langmap=Tex\:.tex:\
        :langmap=Vera\:.vr.vri.vrh:\
        :langmap=Verilog\:.v:\
        :langmap=VHDL\:.vhdl.vhd:\
        :langmap=Vim\:.vim:\
        :langmap=YACC\:.y:\
        :gtags_parser=Ant\:$ctagslib:\
        :gtags_parser=Asm\:$ctagslib:\
        :gtags_parser=Asp\:$ctagslib:\
        :gtags_parser=Awk\:$ctagslib:\
        :gtags_parser=Basic\:$ctagslib:\
        :gtags_parser=BETA\:$ctagslib:\
        :gtags_parser=C\:$ctagslib:\
        :gtags_parser=C++\:$ctagslib:\
        :gtags_parser=C#\:$ctagslib:\
        :gtags_parser=Cobol\:$ctagslib:\
        :gtags_parser=DosBatch\:$ctagslib:\
        :gtags_parser=Eiffel\:$ctagslib:\
        :gtags_parser=Erlang\:$ctagslib:\
        :gtags_parser=Flex\:$ctagslib:\
        :gtags_parser=Fortran\:$ctagslib:\
        :gtags_parser=HTML\:$ctagslib:\
        :gtags_parser=Java\:$ctagslib:\
        :gtags_parser=JavaScript\:$ctagslib:\
        :gtags_parser=Lisp\:$ctagslib:\
        :gtags_parser=Lua\:$ctagslib:\
        :gtags_parser=Make\:$ctagslib:\
        :gtags_parser=MatLab\:$ctagslib:\
        :gtags_parser=OCaml\:$ctagslib:\
        :gtags_parser=Pascal\:$ctagslib:\
        :gtags_parser=Perl\:$ctagslib:\
        :gtags_parser=PHP\:$ctagslib:\
        :gtags_parser=Python\:$ctagslib:\
        :gtags_parser=REXX\:$ctagslib:\
        :gtags_parser=Ruby\:$ctagslib:\
        :gtags_parser=Scheme\:$ctagslib:\
        :gtags_parser=Sh\:$ctagslib:\
        :gtags_parser=SLang\:$ctagslib:\
        :gtags_parser=SML\:$ctagslib:\
        :gtags_parser=SQL\:$ctagslib:\
        :gtags_parser=Tcl\:$ctagslib:\
        :gtags_parser=Tex\:$ctagslib:\
        :gtags_parser=Vera\:$ctagslib:\
        :gtags_parser=Verilog\:$ctagslib:\
        :gtags_parser=VHDL\:$ctagslib:\
        :gtags_parser=Vim\:$ctagslib:\
        :gtags_parser=YACC\:$ctagslib:
#
# Plug-in parser to use Universal Ctags.
#
# Most of the following definitions were automatically generated by this command line:
# $ perl maps2conf.pl /usr/local/bin/ctags '$libdir/gtags/universal-ctags.la'
# ('/user/local/bin/ctags' should be replaced with the path of Universal Ctags.)
#
universal-ctags|setting to use Universal Ctags plug-in parser:\
        :tc=common:\
        :ctagscom=:\
        :ctagslib=$libdir/gtags/universal-ctags.la:\
        :langmap=Ada\:.adb.ads.Ada:\
        :langmap=Ant\:(build.xml)(*.build.xml).ant.xml:\
        :langmap=Asm\:.A51(*.29[kK])(*.[68][68][kKsSxX])(*.[xX][68][68]).asm.ASM.s.S:\
        :langmap=Asp\:.asp.asa:\
        :langmap=Autoconf\:(configure.in).ac:\
        :langmap=Automake\:(Makefile.am).am:\
        :langmap=Awk\:.awk.gawk.mawk:\
        :langmap=Basic\:.bas.bi.bb.pb:\
        :langmap=BETA\:.bet:\
        :langmap=Clojure\:.clj.cljs.cljc:\
        :langmap=C\:.c:\
        :langmap=C++\:.c++.cc.cp.cpp.cxx.h.h++.hh.hp.hpp.hxx.inl:\
        :langmap=CSS\:.css:\
        :langmap=C#\:.cs:\
        :langmap=ctags\:.ctags:\
        :langmap=Cobol\:.cbl.cob.CBL.COB:\
        :langmap=CUDA\:.cu.cuh:\
        :langmap=D\:.d.di:\
        :langmap=Diff\:.diff.patch:\
        :langmap=DTD\:.dtd.mod:\
        :langmap=DTS\:.dts.dtsi:\
        :langmap=DosBatch\:.bat.cmd:\
        :langmap=Eiffel\:.e:\
        :langmap=elm\:.elm:\
        :langmap=Erlang\:.erl.ERL.hrl.HRL:\
        :langmap=Falcon\:.fal.ftd:\
        :langmap=Flex\:.as.mxml:\
        :langmap=Fortran\:.f.for.ftn.f77.f90.f95.f03.f08.f15:\
        :langmap=gdbinit\:(.gdbinit).gdb:\
        :langmap=Go\:.go:\
        :langmap=HTML\:.htm.html:\
        :langmap=Iniconf\:.ini.conf:\
        :langmap=ITcl\:.itcl:\
        :langmap=Java\:.java:\
        :langmap=JavaProperties\:.properties:\
        :langmap=JavaScript\:.js.jsx:\
        :langmap=JSON\:.json:\
        :langmap=LdScript\:(*.lds.S)(ld.*).lds.scr.ld:\
        :langmap=Lisp\:.cl.clisp.el.l.lisp.lsp:\
        :langmap=Lua\:.lua:\
        :langmap=M4\:.m4.spt:\
        :langmap=man\:.1.2.3.4.5.6.7.8.9:\
        :langmap=Make\:([Mm]akefile)(GNUmakefile).mak.mk:\
        :langmap=MatLab\:.m:\
        :langmap=Myrddin\:.myr:\
        :langmap=ObjectiveC\:.mm.m.h:\
        :langmap=OldC++\:.c++.cc.cp.cpp.cxx.h.h++.hh.hp.hpp.hxx.inl:\
        :langmap=OldC\:.c:\
        :langmap=OCaml\:.ml.mli.aug:\
        :langmap=passwd\:(passwd):\
        :langmap=Pascal\:.p.pas:\
        :langmap=Perl\:.pl.pm.ph.plx.perl:\
        :langmap=Perl6\:.p6.pm6.pm.pl6:\
        :langmap=PHP\:.php.php3.php4.php5.php7.phtml:\
        :langmap=pod\:.pod:\
        :langmap=Protobuf\:.proto:\
        :langmap=puppetManifest\:.pp:\
        :langmap=Python\:.py.pyx.pxd.pxi.scons:\
        :langmap=QemuHX\:.hx:\
        :langmap=R\:.r.R.s.q:\
        :langmap=REXX\:.cmd.rexx.rx:\
        :langmap=Robot\:.robot:\
        :langmap=RpmSpec\:.spec:\
        :langmap=reStructuredText\:.rest.reST.rst:\
        :langmap=Ruby\:.rb.ruby:\
        :langmap=Rust\:.rs:\
        :langmap=Scheme\:.SCM.SM.sch.scheme.scm.sm:\
        :langmap=Sh\:.sh.SH.bsh.bash.ksh.zsh.ash:\
        :langmap=SLang\:.sl:\
        :langmap=SML\:.sml.sig:\
        :langmap=SQL\:.sql:\
        :langmap=SystemdUnit\:.unit.service.socket.device.mount.automount.swap.target.path.timer.snapshot.scope.slice.time:\
        :langmap=Tcl\:.tcl.tk.wish.exp:\
        :langmap=Tex\:.tex:\
        :langmap=TTCN\:.ttcn.ttcn3:\
        :langmap=Vera\:.vr.vri.vrh:\
        :langmap=Verilog\:.v:\
        :langmap=SystemVerilog\:.sv.svh.svi:\
        :langmap=VHDL\:.vhdl.vhd:\
        :langmap=Vim\:(vimrc)([._]vimrc)(gvimrc)([._]gvimrc).vim.vba:\
        :langmap=WindRes\:.rc:\
        :langmap=YACC\:.y:\
        :langmap=YumRepo\:.repo:\
        :langmap=Zephir\:.zep:\
        :langmap=DBusIntrospect\:.xml:\
        :langmap=Glade\:.glade:\
        :langmap=Maven2\:(pom.xml).pom.xml:\
        :langmap=PlistXML\:.plist:\
        :langmap=RelaxNG\:.rng:\
        :langmap=SVG\:.svg:\
        :langmap=XSLT\:.xsl.xslt:\
        :gtags_parser=Ada\:$ctagslib:\
        :gtags_parser=Ant\:$ctagslib:\
        :gtags_parser=Asm\:$ctagslib:\
        :gtags_parser=Asp\:$ctagslib:\
        :gtags_parser=Autoconf\:$ctagslib:\
        :gtags_parser=Automake\:$ctagslib:\
        :gtags_parser=Awk\:$ctagslib:\
        :gtags_parser=Basic\:$ctagslib:\
        :gtags_parser=BETA\:$ctagslib:\
        :gtags_parser=Clojure\:$ctagslib:\
        :gtags_parser=C\:$ctagslib:\
        :gtags_parser=C++\:$ctagslib:\
        :gtags_parser=CSS\:$ctagslib:\
        :gtags_parser=C#\:$ctagslib:\
        :gtags_parser=ctags\:$ctagslib:\
        :gtags_parser=Cobol\:$ctagslib:\
        :gtags_parser=CUDA\:$ctagslib:\
        :gtags_parser=D\:$ctagslib:\
        :gtags_parser=Diff\:$ctagslib:\
        :gtags_parser=DTD\:$ctagslib:\
        :gtags_parser=DTS\:$ctagslib:\
        :gtags_parser=DosBatch\:$ctagslib:\
        :gtags_parser=Eiffel\:$ctagslib:\
        :gtags_parser=elm\:$ctagslib:\
        :gtags_parser=Erlang\:$ctagslib:\
        :gtags_parser=Falcon\:$ctagslib:\
        :gtags_parser=Flex\:$ctagslib:\
        :gtags_parser=Fortran\:$ctagslib:\
        :gtags_parser=gdbinit\:$ctagslib:\
        :gtags_parser=Go\:$ctagslib:\
        :gtags_parser=HTML\:$ctagslib:\
        :gtags_parser=Iniconf\:$ctagslib:\
        :gtags_parser=ITcl\:$ctagslib:\
        :gtags_parser=Java\:$ctagslib:\
        :gtags_parser=JavaProperties\:$ctagslib:\
        :gtags_parser=JavaScript\:$ctagslib:\
        :gtags_parser=JSON\:$ctagslib:\
        :gtags_parser=LdScript\:$ctagslib:\
        :gtags_parser=Lisp\:$ctagslib:\
        :gtags_parser=Lua\:$ctagslib:\
        :gtags_parser=M4\:$ctagslib:\
        :gtags_parser=man\:$ctagslib:\
        :gtags_parser=Make\:$ctagslib:\
        :gtags_parser=MatLab\:$ctagslib:\
        :gtags_parser=Myrddin\:$ctagslib:\
        :gtags_parser=ObjectiveC\:$ctagslib:\
        :gtags_parser=OldC++\:$ctagslib:\
        :gtags_parser=OldC\:$ctagslib:\
        :gtags_parser=OCaml\:$ctagslib:\
        :gtags_parser=passwd\:$ctagslib:\
        :gtags_parser=Pascal\:$ctagslib:\
        :gtags_parser=Perl\:$ctagslib:\
        :gtags_parser=Perl6\:$ctagslib:\
        :gtags_parser=PHP\:$ctagslib:\
        :gtags_parser=pod\:$ctagslib:\
        :gtags_parser=Protobuf\:$ctagslib:\
        :gtags_parser=puppetManifest\:$ctagslib:\
        :gtags_parser=Python\:$ctagslib:\
        :gtags_parser=QemuHX\:$ctagslib:\
        :gtags_parser=R\:$ctagslib:\
        :gtags_parser=REXX\:$ctagslib:\
        :gtags_parser=Robot\:$ctagslib:\
        :gtags_parser=RpmSpec\:$ctagslib:\
        :gtags_parser=reStructuredText\:$ctagslib:\
        :gtags_parser=Ruby\:$ctagslib:\
        :gtags_parser=Rust\:$ctagslib:\
        :gtags_parser=Scheme\:$ctagslib:\
        :gtags_parser=Sh\:$ctagslib:\
        :gtags_parser=SLang\:$ctagslib:\
        :gtags_parser=SML\:$ctagslib:\
        :gtags_parser=SQL\:$ctagslib:\
        :gtags_parser=SystemdUnit\:$ctagslib:\
        :gtags_parser=Tcl\:$ctagslib:\
        :gtags_parser=Tex\:$ctagslib:\
        :gtags_parser=TTCN\:$ctagslib:\
        :gtags_parser=Vera\:$ctagslib:\
        :gtags_parser=Verilog\:$ctagslib:\
        :gtags_parser=SystemVerilog\:$ctagslib:\
        :gtags_parser=VHDL\:$ctagslib:\
        :gtags_parser=Vim\:$ctagslib:\
        :gtags_parser=WindRes\:$ctagslib:\
        :gtags_parser=YACC\:$ctagslib:\
        :gtags_parser=YumRepo\:$ctagslib:\
        :gtags_parser=Zephir\:$ctagslib:\
        :gtags_parser=DBusIntrospect\:$ctagslib:\
        :gtags_parser=Glade\:$ctagslib:\
        :gtags_parser=Maven2\:$ctagslib:\
        :gtags_parser=PlistXML\:$ctagslib:\
        :gtags_parser=RelaxNG\:$ctagslib:\
        :gtags_parser=SVG\:$ctagslib:\
        :gtags_parser=XSLT\:$ctagslib:
#
# Plug-in parser to use Pygments.
#
pygments-parser|Pygments plug-in parser:\
        :tc=common:\
        :ctagscom=/usr/bin/ctags:\
        :pygmentslib=$libdir/gtags/pygments-parser.la:\
        :langmap=ABAP\:.abap:\
        :langmap=ANTLR\:.G.g:\
        :langmap=ActionScript3\:.as:\
        :langmap=Ada\:.adb.ads.ada:\
        :langmap=AppleScript\:.applescript:\
        :langmap=AspectJ\:.aj:\
        :langmap=Aspx-cs\:.aspx.asax.ascx.ashx.asmx.axd:\
        :langmap=Asymptote\:.asy:\
        :langmap=AutoIt\:.au3:\
        :langmap=Awk\:.awk.gawk.mawk:\
        :langmap=BUGS\:.bug:\
        :langmap=Bash\:.sh.ksh.bash.ebuild.eclass:\
        :langmap=Bat\:.bat.cmd:\
        :langmap=BlitzMax\:.bmx:\
        :langmap=Boo\:.boo:\
        :langmap=Bro\:.bro:\
        :langmap=C#\:.cs:\
        :langmap=C++\:.c++.cc.cp.cpp.cxx.h.h++.hh.hp.hpp.hxx.C.H:\
        :langmap=COBOLFree\:.cbl.CBL:\
        :langmap=COBOL\:.cob.COB.cpy.CPY:\
        :langmap=CUDA\:.cu.cuh:\
        :langmap=C\:.c.h:\
        :langmap=Ceylon\:.ceylon:\
        :langmap=Cfm\:.cfm.cfml.cfc:\
        :langmap=Clojure\:.clj:\
        :langmap=CoffeeScript\:.coffee:\
        :langmap=Common-Lisp\:.cl.lisp.el:\
        :langmap=Coq\:.v:\
        :langmap=Croc\:.croc:\
        :langmap=Csh\:.tcsh.csh:\
        :langmap=Cython\:.pyx.pxd.pxi:\
        :langmap=Dart\:.dart:\
        :langmap=Dg\:.dg:\
        :langmap=Duel\:.duel.jbst:\
        :langmap=Dylan\:.dylan.dyl.intr:\
        :langmap=ECL\:.ecl:\
        :langmap=EC\:.ec.eh:\
        :langmap=ERB\:.erb:\
        :langmap=Elixir\:.ex.exs:\
        :langmap=Erlang\:.erl.hrl.es.escript:\
        :langmap=Evoque\:.evoque:\
        :langmap=FSharp\:.fs.fsi:\
        :langmap=Factor\:.factor:\
        :langmap=Fancy\:.fy.fancypack:\
        :langmap=Fantom\:.fan:\
        :langmap=Felix\:.flx.flxh:\
        :langmap=Fortran\:.f.f90.F.F90:\
        :langmap=GAS\:.s.S:\
        :langmap=GLSL\:.vert.frag.geo:\
        :langmap=Genshi\:.kid:\
        :langmap=Gherkin\:.feature:\
        :langmap=Gnuplot\:.plot.plt:\
        :langmap=Go\:.go:\
        :langmap=GoodData-CL\:.gdc:\
        :langmap=Gosu\:.gs.gsx.gsp.vark:\
        :langmap=Groovy\:.groovy:\
        :langmap=Gst\:.gst:\
        :langmap=HaXe\:.hx:\
        :langmap=Haml\:.haml:\
        :langmap=Haskell\:.hs:\
        :langmap=Hxml\:.hxml:\
        :langmap=Hybris\:.hy.hyb:\
        :langmap=IDL\:.pro:\
        :langmap=Io\:.io:\
        :langmap=Ioke\:.ik:\
        :langmap=JAGS\:.jag.bug:\
        :langmap=Jade\:.jade:\
        :langmap=JavaScript\:.js:\
        :langmap=Java\:.java:\
        :langmap=Jsp\:.jsp:\
        :langmap=Julia\:.jl:\
        :langmap=Koka\:.kk.kki:\
        :langmap=Kotlin\:.kt:\
        :langmap=LLVM\:.ll:\
        :langmap=Lasso\:.lasso:\
        :langmap=Literate-Haskell\:.lhs:\
        :langmap=LiveScript\:.ls:\
        :langmap=Logos\:.x.xi.xm.xmi:\
        :langmap=Logtalk\:.lgt:\
        :langmap=Lua\:.lua.wlua:\
        :langmap=MOOCode\:.moo:\
        :langmap=MXML\:.mxml:\
        :langmap=Mako\:.mao:\
        :langmap=Mason\:.m.mhtml.mc.mi:\
        :langmap=Matlab\:.m:\
        :langmap=Modelica\:.mo:\
        :langmap=Modula2\:.mod:\
        :langmap=Monkey\:.monkey:\
        :langmap=MoonScript\:.moon:\
        :langmap=MuPAD\:.mu:\
        :langmap=Myghty\:.myt:\
        :langmap=NASM\:.asm.ASM:\
        :langmap=NSIS\:.nsi.nsh:\
        :langmap=Nemerle\:.n:\
        :langmap=NewLisp\:.lsp.nl:\
        :langmap=Newspeak\:.ns2:\
        :langmap=Nimrod\:.nim.nimrod:\
        :langmap=OCaml\:.ml.mli.mll.mly:\
        :langmap=Objective-C++\:.mm.hh:\
        :langmap=Objective-C\:.m.h:\
        :langmap=Objective-J\:.j:\
        :langmap=Octave\:.m:\
        :langmap=Ooc\:.ooc:\
        :langmap=Opa\:.opa:\
        :langmap=OpenEdge\:.p.cls:\
        :langmap=PHP\:.php.php3.phtml:\
        :langmap=Pascal\:.pas:\
        :langmap=Perl\:.pl.pm:\
        :langmap=PostScript\:.ps.eps:\
        :langmap=PowerShell\:.ps1:\
        :langmap=Prolog\:.prolog.pro.pl:\
        :langmap=Python\:.py.pyw.sc.tac.sage:\
        :langmap=QML\:.qml:\
        :langmap=REBOL\:.r.r3:\
        :langmap=RHTML\:.rhtml:\
        :langmap=Racket\:.rkt.rktl:\
        :langmap=Ragel\:.rl:\
        :langmap=Redcode\:.cw:\
        :langmap=RobotFramework\:.robot:\
        :langmap=Ruby\:.rb.rbw.rake.gemspec.rbx.duby:\
        :langmap=Rust\:.rs.rc:\
        :langmap=S\:.S.R:\
        :langmap=Scala\:.scala:\
        :langmap=Scaml\:.scaml:\
        :langmap=Scheme\:.scm.ss:\
        :langmap=Scilab\:.sci.sce.tst:\
        :langmap=Smalltalk\:.st:\
        :langmap=Smarty\:.tpl:\
        :langmap=Sml\:.sml.sig.fun:\
        :langmap=Snobol\:.snobol:\
        :langmap=SourcePawn\:.sp:\
        :langmap=Spitfire\:.spt:\
        :langmap=Ssp\:.ssp:\
        :langmap=Stan\:.stan:\
        :langmap=SystemVerilog\:.sv.svh:\
        :langmap=Tcl\:.tcl:\
        :langmap=TeX\:.tex.aux.toc:\
        :langmap=Tea\:.tea:\
        :langmap=Treetop\:.treetop.tt:\
        :langmap=TypeScript\:.ts:\
        :langmap=UrbiScript\:.u:\
        :langmap=VB.net\:.vb.bas:\
        :langmap=VGL\:.rpf:\
        :langmap=Vala\:.vala.vapi:\
        :langmap=Velocity\:.vm.fhtml:\
        :langmap=Verilog\:.v:\
        :langmap=Vhdl\:.vhdl.vhd:\
        :langmap=Vim\:.vim:\
        :langmap=XBase\:.PRG.prg:\
        :langmap=XQuery\:.xqy.xquery.xq.xql.xqm:\
        :langmap=XSLT\:.xsl.xslt.xpl:\
        :langmap=Xtend\:.xtend:\
        :gtags_parser=ABAP\:$pygmentslib:\
        :gtags_parser=ANTLR\:$pygmentslib:\
        :gtags_parser=ActionScript3\:$pygmentslib:\
        :gtags_parser=Ada\:$pygmentslib:\
        :gtags_parser=AppleScript\:$pygmentslib:\
        :gtags_parser=AspectJ\:$pygmentslib:\
        :gtags_parser=Aspx-cs\:$pygmentslib:\
        :gtags_parser=Asymptote\:$pygmentslib:\
        :gtags_parser=AutoIt\:$pygmentslib:\
        :gtags_parser=Awk\:$pygmentslib:\
        :gtags_parser=BUGS\:$pygmentslib:\
        :gtags_parser=Bash\:$pygmentslib:\
        :gtags_parser=Bat\:$pygmentslib:\
        :gtags_parser=BlitzMax\:$pygmentslib:\
        :gtags_parser=Boo\:$pygmentslib:\
        :gtags_parser=Bro\:$pygmentslib:\
        :gtags_parser=C#\:$pygmentslib:\
        :gtags_parser=C++\:$pygmentslib:\
        :gtags_parser=COBOLFree\:$pygmentslib:\
        :gtags_parser=COBOL\:$pygmentslib:\
        :gtags_parser=CUDA\:$pygmentslib:\
        :gtags_parser=C\:$pygmentslib:\
        :gtags_parser=Ceylon\:$pygmentslib:\
        :gtags_parser=Cfm\:$pygmentslib:\
        :gtags_parser=Clojure\:$pygmentslib:\
        :gtags_parser=CoffeeScript\:$pygmentslib:\
        :gtags_parser=Common-Lisp\:$pygmentslib:\
        :gtags_parser=Coq\:$pygmentslib:\
        :gtags_parser=Croc\:$pygmentslib:\
        :gtags_parser=Csh\:$pygmentslib:\
        :gtags_parser=Cython\:$pygmentslib:\
        :gtags_parser=Dart\:$pygmentslib:\
        :gtags_parser=Dg\:$pygmentslib:\
        :gtags_parser=Duel\:$pygmentslib:\
        :gtags_parser=Dylan\:$pygmentslib:\
        :gtags_parser=ECL\:$pygmentslib:\
        :gtags_parser=EC\:$pygmentslib:\
        :gtags_parser=ERB\:$pygmentslib:\
        :gtags_parser=Elixir\:$pygmentslib:\
        :gtags_parser=Erlang\:$pygmentslib:\
        :gtags_parser=Evoque\:$pygmentslib:\
        :gtags_parser=FSharp\:$pygmentslib:\
        :gtags_parser=Factor\:$pygmentslib:\
        :gtags_parser=Fancy\:$pygmentslib:\
        :gtags_parser=Fantom\:$pygmentslib:\
        :gtags_parser=Felix\:$pygmentslib:\
        :gtags_parser=Fortran\:$pygmentslib:\
        :gtags_parser=GAS\:$pygmentslib:\
        :gtags_parser=GLSL\:$pygmentslib:\
        :gtags_parser=Genshi\:$pygmentslib:\
        :gtags_parser=Gherkin\:$pygmentslib:\
        :gtags_parser=Gnuplot\:$pygmentslib:\
        :gtags_parser=Go\:$pygmentslib:\
        :gtags_parser=GoodData-CL\:$pygmentslib:\
        :gtags_parser=Gosu\:$pygmentslib:\
        :gtags_parser=Groovy\:$pygmentslib:\
        :gtags_parser=Gst\:$pygmentslib:\
        :gtags_parser=HaXe\:$pygmentslib:\
        :gtags_parser=Haml\:$pygmentslib:\
        :gtags_parser=Haskell\:$pygmentslib:\
        :gtags_parser=Hxml\:$pygmentslib:\
        :gtags_parser=Hybris\:$pygmentslib:\
        :gtags_parser=IDL\:$pygmentslib:\
        :gtags_parser=Io\:$pygmentslib:\
        :gtags_parser=Ioke\:$pygmentslib:\
        :gtags_parser=JAGS\:$pygmentslib:\
        :gtags_parser=Jade\:$pygmentslib:\
        :gtags_parser=JavaScript\:$pygmentslib:\
        :gtags_parser=Java\:$pygmentslib:\
        :gtags_parser=Jsp\:$pygmentslib:\
        :gtags_parser=Julia\:$pygmentslib:\
        :gtags_parser=Koka\:$pygmentslib:\
        :gtags_parser=Kotlin\:$pygmentslib:\
        :gtags_parser=LLVM\:$pygmentslib:\
        :gtags_parser=Lasso\:$pygmentslib:\
        :gtags_parser=Literate-Haskell\:$pygmentslib:\
        :gtags_parser=LiveScript\:$pygmentslib:\
        :gtags_parser=Logos\:$pygmentslib:\
        :gtags_parser=Logtalk\:$pygmentslib:\
        :gtags_parser=Lua\:$pygmentslib:\
        :gtags_parser=MAQL\:$pygmentslib:\
        :gtags_parser=MOOCode\:$pygmentslib:\
        :gtags_parser=MXML\:$pygmentslib:\
        :gtags_parser=Mako\:$pygmentslib:\
        :gtags_parser=Mason\:$pygmentslib:\
        :gtags_parser=Matlab\:$pygmentslib:\
        :gtags_parser=MiniD\:$pygmentslib:\
        :gtags_parser=Modelica\:$pygmentslib:\
        :gtags_parser=Modula2\:$pygmentslib:\
        :gtags_parser=Monkey\:$pygmentslib:\
        :gtags_parser=MoonScript\:$pygmentslib:\
        :gtags_parser=MuPAD\:$pygmentslib:\
        :gtags_parser=Myghty\:$pygmentslib:\
        :gtags_parser=NASM\:$pygmentslib:\
        :gtags_parser=NSIS\:$pygmentslib:\
        :gtags_parser=Nemerle\:$pygmentslib:\
        :gtags_parser=NewLisp\:$pygmentslib:\
        :gtags_parser=Newspeak\:$pygmentslib:\
        :gtags_parser=Nimrod\:$pygmentslib:\
        :gtags_parser=OCaml\:$pygmentslib:\
        :gtags_parser=Objective-C++\:$pygmentslib:\
        :gtags_parser=Objective-C\:$pygmentslib:\
        :gtags_parser=Objective-J\:$pygmentslib:\
        :gtags_parser=Octave\:$pygmentslib:\
        :gtags_parser=Ooc\:$pygmentslib:\
        :gtags_parser=Opa\:$pygmentslib:\
        :gtags_parser=OpenEdge\:$pygmentslib:\
        :gtags_parser=PHP\:$pygmentslib:\
        :gtags_parser=Pascal\:$pygmentslib:\
        :gtags_parser=Perl\:$pygmentslib:\
        :gtags_parser=PostScript\:$pygmentslib:\
        :gtags_parser=PowerShell\:$pygmentslib:\
        :gtags_parser=Prolog\:$pygmentslib:\
        :gtags_parser=Python\:$pygmentslib:\
        :gtags_parser=QML\:$pygmentslib:\
        :gtags_parser=REBOL\:$pygmentslib:\
        :gtags_parser=RHTML\:$pygmentslib:\
        :gtags_parser=Racket\:$pygmentslib:\
        :gtags_parser=Ragel\:$pygmentslib:\
        :gtags_parser=Redcode\:$pygmentslib:\
        :gtags_parser=RobotFramework\:$pygmentslib:\
        :gtags_parser=Ruby\:$pygmentslib:\
        :gtags_parser=Rust\:$pygmentslib:\
        :gtags_parser=S\:$pygmentslib:\
        :gtags_parser=Scala\:$pygmentslib:\
        :gtags_parser=Scaml\:$pygmentslib:\
        :gtags_parser=Scheme\:$pygmentslib:\
        :gtags_parser=Scilab\:$pygmentslib:\
        :gtags_parser=Smalltalk\:$pygmentslib:\
        :gtags_parser=Smarty\:$pygmentslib:\
        :gtags_parser=Sml\:$pygmentslib:\
        :gtags_parser=Snobol\:$pygmentslib:\
        :gtags_parser=SourcePawn\:$pygmentslib:\
        :gtags_parser=Spitfire\:$pygmentslib:\
        :gtags_parser=Ssp\:$pygmentslib:\
        :gtags_parser=Stan\:$pygmentslib:\
        :gtags_parser=SystemVerilog\:$pygmentslib:\
        :gtags_parser=Tcl\:$pygmentslib:\
        :gtags_parser=TeX\:$pygmentslib:\
        :gtags_parser=Tea\:$pygmentslib:\
        :gtags_parser=Treetop\:$pygmentslib:\
        :gtags_parser=TypeScript\:$pygmentslib:\
        :gtags_parser=UrbiScript\:$pygmentslib:\
        :gtags_parser=VB.net\:$pygmentslib:\
        :gtags_parser=VGL\:$pygmentslib:\
        :gtags_parser=Vala\:$pygmentslib:\
        :gtags_parser=Velocity\:$pygmentslib:\
        :gtags_parser=Verilog\:$pygmentslib:\
        :gtags_parser=Vhdl\:$pygmentslib:\
        :gtags_parser=Vim\:$pygmentslib:\
        :gtags_parser=XBase\:$pygmentslib:\
        :gtags_parser=XQuery\:$pygmentslib:\
        :gtags_parser=XSLT\:$pygmentslib:\
        :gtags_parser=Xtend\:$pygmentslib:
#
# Drupal configuration.
#
drupal|Drupal content management platform:\
        :tc=common:\
        :langmap=php\:.php.module.inc.profile.install.test:
#---------------------------------------------------------------------
# Configuration for htags(1)
#---------------------------------------------------------------------
htags:\
        ::

17.2.3 Start.shファイルを用意

  • 起動用のファイルを作成
#!/bin/sh
#docker run --rm -it -p 22:22 -p 8000:8000 -p 8001:8001 -v /work/mypython:/home/user/C mypython
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow
  • 以下のコマンドで実行権限を与える(Linuxの場合)
chmod +x Start.sh
  • スクリプトファイルを利用出来ない環境の場合は以下で、直接起動スクリプトが実行している命令を実行してください。
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow

17.2.4 makeDocker.shファイルを用意

  • Dockerファイルを利用して、Dockerのイメージを作成する用のスクリプトファイルを作成。
#!/bin/sh
docker build -t mytensorflow . 
  • 実行権限を与える
chmod +x makeDocker.sh

17.2.5 イメージの作成

  • スクリプトファイルを利用できる環境の場合、上で作成したmakeDocker.shスクリプトを実行
./makeDocker.sh
  • スクリプトファイルを利用出来ない環境の場合は、以下
docker build -t mytensorflow . 

17.3 mytensorflowイメージの利用手順

17.3.1 mytensorflow起動1

  • スクリプトファイルを利用できる環境の場合、上で作成したStart.shスクリプトを実行
./Start.sh
  • スクリプトファイルを利用出来ない環境の場合は、以下
docker run -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 mytensorflow

17.3.2 mytensorflow起動2

  • 起動したら、メッセージが表示されます。最後の http://127.0.0.1/.. 省略 の部分をコピーして、ブラウザでそのURLを開く
  • ブラウザでterminalを起動したら、最初にbashを実行するとより使いやすくなる。

17.4 この章のまとめ

  • 既存のTensorflow Hubにあるイメージの拡張その2を行いました。(GNU GlobalでPythonにも対応できるものを追加)

18 Rails6向けDockerイメージの作成

18.1 以下の操作を行っている動画


18.2 手順

18.2.1 Dockerfileを作成

  • rubyのバージョンはDocker Hubのrubyのimageのバージョンで指定
  • rails, ユーザーネーム, ユーザーID, nodejsのメジャーバージョン, PostgreSQLのクライアントのメジャーバージョン, yarnのバージョンの設定を可能としてます。
  • 起動後は一般ユーザーで起動するようにしてある
FROM ruby:2.6.5
MAINTAINER NM Max
ENV rails_v=6.0.2.1
ENV user_n=user
ENV user_id=1000
ENV node_v=12
ENV postgresql_v=11
ENV yarn_v=1.21.1-1
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install vim w3m wget diffutils sqlite3 nkf less diffutils patch sudo git clang curl pkg-config zip g++ zlib1g-dev unzip \ 
    && apt -y install openssh-client openssh-server \
    && apt -y install locales locales-all\
    && apt -y install -y gcc g++ make clang \
    && apt -y install -y libssl-dev libreadline-dev zlib1g-dev 
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen && \
    update-locale
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
RUN echo "\n\n\n\n\n\n\n" | adduser --uid ${user_id} --disabled-password ${user_n}
RUN echo "${user_n} ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN mkdir -p /home/${user_n}/C && chown  ${user_n}.${user_n} /home/${user_n}/C 
ENV DEBIAN_FRONTEND=noninteractive
RUN apt -y install libsqlite3-dev && apt -y install tzdata 
RUN gem install rails -v ${rails_v} 
RUN curl -sL https://deb.nodesource.com/setup_${node_v}.x | bash -
RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main '${postgresql_v} >> /etc/apt/sources.list.d/pgdg.list && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list 
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade \
  && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
    build-essential \
    postgresql-client-${postgresql_v} \
    nodejs \
    yarn=${yarn_v} \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 
EXPOSE 22 80 3000 8000 8001
RUN echo 'export GEM_HOME=/usr/local/bundle' >> /root/.bashrc ; echo 'export BUNDLE_SILENCE_ROOT_WARNING=1' >> /root/.bashrc ; echo 'export BUNDLE_APP_CONFIG="$GEM_HOME"' >>  /root/.bashrc ; echo 'export PATH="$GEM_HOME/bin:$PATH"' >>  /root/.bashrc
RUN echo 'export GEM_HOME=/usr/local/bundle' >> /home/${user_n}/.bashrc ; echo 'export BUNDLE_SILENCE_ROOT_WARNING=1' >> /home/${user_n}/.bashrc ; echo 'export BUNDLE_APP_CONFIG="$GEM_HOME"' >>  /home/${user_n}/.bashrc ; echo 'export PATH="$GEM_HOME/bin:$PATH"' >>  /home/${user_n}/.bashrc
ENTRYPOINT sudo su - ${user_n}

18.2.2 makeDocker.sh を作成

#!/bin/sh
docker build -t myrails . 
  • 以下で実行権限を与える
chmod +x ./makeDocker.sh
  • makeDockerを実行してイメージ作成、スクリプトファイルが使えない環境なら以下を実行
docker build -t myrails . 

18.2.3 Start.shを作成

#!/bin/sh
docker run -it --rm -p 22:22 -p 3000:3000 -v /work/myrails:/home/user/C myrails
  • 以下で実行権限を与える
chmod +x ./Start.sh
  • スクリプトファイルが使えない環境なら以下を実行
docker run -it --rm -p 22:22 -p 3000:3000 -v /work/myrails:/home/user/C myrails

18.2.4 起動後

  • 一般ユーザーのuserで起動します
  • プロジェクトを作成して、作ったプロジェクトを起動
rails new testapp 
cd testapp
rails s -b 0.0.0.0

18.3 この章のまとめ

  • 最新のRails6を動かす、Dockerイメージを作成し、動かしてみた
  • 一般ユーザーも追加し、日本語ロケール設定も行った

19 Rails6向けDockerイメージの作成2(改良バージョン)

  • 前章のイメージの改良バージョン
  • プロジェクト作成に必用になるgemをバージョン指定で入れてある
  • ホームディレクトリにtest000というプロジェクトファイルを生成済みで含めてある

19.1 以下の操作を行っている動画


19.2 手順

19.2.1 Dockerfileを作成

  • rubyのバージョンはDocker Hubのrubyのimageのバージョンで指定
  • rails, ユーザーネーム, ユーザーID, nodejsのメジャーバージョン, PostgreSQLのクライアントのメジャーバージョン, yarnのバージョンの設定を可能としてます。
  • 起動後は一般ユーザーで起動するようにしてある
FROM ruby:2.6.5
MAINTAINER NM Max
ENV rails_v=6.0.2.1
ENV user_n=user
ENV user_id=1000
ENV node_v=12
ENV postgresql_v=11
ENV yarn_v=1.22.0-1
RUN apt -y update \
    && apt -y upgrade \
    && apt -y install vim w3m wget diffutils sqlite3 nkf less diffutils patch sudo git clang curl pkg-config zip g++ zlib1g-dev unzip nmap tree \ 
    && apt -y install openssh-client openssh-server \
    && apt -y install locales locales-all\
    && apt -y install -y gcc g++ make clang \
    && apt -y install -y libssl-dev libreadline-dev zlib1g-dev 
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
    locale-gen && \
    update-locale
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
RUN echo "\n\n\n\n\n\n\n" | adduser --uid ${user_id} --disabled-password ${user_n}
RUN echo "${user_n} ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN mkdir -p /home/${user_n}/C && chown  ${user_n}.${user_n} /home/${user_n}/C 
ENV DEBIAN_FRONTEND=noninteractive
RUN apt -y install libsqlite3-dev && apt -y install tzdata 
RUN gem install rails -v ${rails_v} 
RUN curl -sL https://deb.nodesource.com/setup_${node_v}.x | bash -
RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main '${postgresql_v} >> /etc/apt/sources.list.d/pgdg.list && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list 
RUN apt-get update \
  && DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade \
  && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \
    build-essential \
    postgresql-client-${postgresql_v} \
    postgresql-${postgresql_v} \
    nodejs \
    yarn=${yarn_v} \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 
EXPOSE 22 80 3000 8000 8001
RUN echo 'export GEM_HOME=/usr/local/bundle' >> /root/.bashrc ; echo 'export BUNDLE_SILENCE_ROOT_WARNING=1' >> /root/.bashrc ; echo 'export BUNDLE_APP_CONFIG="$GEM_HOME"' >>  /root/.bashrc ; echo 'export PATH="$GEM_HOME/bin:$PATH"' >>  /root/.bashrc
RUN echo 'export GEM_HOME=/usr/local/bundle' >> /home/${user_n}/.bashrc ; echo 'export BUNDLE_SILENCE_ROOT_WARNING=1' >> /home/${user_n}/.bashrc ; echo 'export BUNDLE_APP_CONFIG="$GEM_HOME"' >>  /home/${user_n}/.bashrc ; echo 'export PATH="$GEM_HOME/bin:$PATH"' >>  /home/${user_n}/.bashrc
RUN gem install rake -v "13.0.1" && \
    gem install minitest -v "5.14.0" && \
    gem install public_suffix -v "4.0.3" && \
    gem install addressable -v "2.7.0" && \
    gem install bindex -v "0.8.1" && \
    gem install msgpack -v "1.3.3" && \
    gem install bootsnap -v "1.4.6" && \
    gem install byebug -v "11.1.1" && \
    gem install regexp_parser -v "1.7.0" && \
    gem install xpath -v "3.2.0" && \
    gem install capybara -v "3.31.0" && \
    gem install childprocess -v "3.0.0" && \
    gem install ffi -v "1.12.2" && \
    gem install jbuilder -v "2.10.0" && \
    gem install rb-fsevent -v "0.10.3" && \
    gem install rb-inotify -v "0.10.1" && \
    gem install ruby_dep -v "1.5.0" && \
    gem install listen -v "3.1.5" && \
    gem install puma -v "4.3.3" && \
    gem install rack-proxy -v "0.6.5" && \
    gem install rubyzip -v "2.2.0" && \
    gem install sassc -v "2.2.1" && \
    gem install tilt -v "2.0.10" && \
    gem install sassc-rails -v "2.1.2" && \
    gem install sass-rails -v "6.0.0" && \
    gem install selenium-webdriver -v "3.142.7" && \
    gem install spring -v "2.1.0" && \
    gem install spring-watcher-listen -v "2.0.1" && \
    gem install sqlite3 -v "1.4.2" && \
    gem install turbolinks-source -v "5.2.0" && \
    gem install turbolinks -v "5.2.1" && \
    gem install web-console -v "4.0.1" && \
    gem install webdrivers -v "4.2.0" && \
    gem install webpacker -v "4.2.2" 
# RUN apt purge -y libmariadb-dev libmariadb-dev-compat libmariadb3 mariadb-common
RUN echo ' export GEM_HOME=/usr/local/bundle ; export BUNDLE_SILENCE_ROOT_WARNING=1 ; export BUNDLE_APP_CONFIG="$GEM_HOME" ; export PATH="$GEM_HOME/bin:$PATH" ; rails new test000 --webpack=vue && cd test000 && rails action_text:install && rails db:migrate ' | sudo su - ${user_n}
ENTRYPOINT sudo su - ${user_n}

19.2.2 makeDocker.sh を作成

#!/bin/sh
docker build -t myrails3 . 
  • 以下で実行権限を与える
chmod +x ./makeDocker.sh
  • makeDockerを実行してイメージ作成、スクリプトファイルが使えない環境なら以下を実行
docker build -t myrails3 . 

19.2.3 Start.shを作成

#!/bin/sh
docker run -it --rm -p 22:22 -p 3000:3000 -v /work/myrails:/home/user/C myrails3
  • 以下で実行権限を与える
chmod +x ./Start.sh
  • スクリプトファイルが使えない環境なら以下を実行
docker run -it --rm -p 22:22 -p 3000:3000 -v /work/myrails:/home/user/C myrails3

19.2.4 起動後

  • 一般ユーザーのuserで起動します
  • プロジェクトを作成して、作ったプロジェクトを起動
cd test000 
rails s -b 0.0.0.0

19.3 後でGemfileを変更して必用なパッケージが増えた時

  • Gemfileを変更(例えば以下を追加)
gem "devise"
  • bundle install をして必用なパッケージをインストール
bundle install
  • 以下をDockerイメージ内で実行して追加されたパッケージを確認
ls -lFtr /usr/local/bundle/gems/ 
  • こんな感じになる。時間がずれてるところで、最後の方が追加されたパッケージ
....省略
drwxr-xr-x 7 root root 4096  3月  1 13:37 webpacker-4.2.2/
drwxr-xr-x 5 root root 4096  3月  1 14:16 bcrypt-3.1.13/
drwxr-xr-x 5 root root 4096  3月  1 14:16 orm_adapter-0.5.0/
drwxr-xr-x 3 root root 4096  3月  1 14:16 responders-3.0.0/
drwxr-xr-x 3 root root 4096  3月  1 14:16 warden-1.2.8/
drwxr-xr-x 5 root root 4096  3月  1 14:16 devise-4.7.1/
  • 新しく追加されたパッケージの部分をコピペ。今回だと以下に
drwxr-xr-x 5 root root 4096  3月  1 14:16 bcrypt-3.1.13/
drwxr-xr-x 5 root root 4096  3月  1 14:16 orm_adapter-0.5.0/
drwxr-xr-x 3 root root 4096  3月  1 14:16 responders-3.0.0/
drwxr-xr-x 3 root root 4096  3月  1 14:16 warden-1.2.8/
drwxr-xr-x 5 root root 4096  3月  1 14:16 devise-4.7.1/
  • ディレクトリ名以外は邪魔なので矩形指定で消す( Vimなら ctrl-v 押してから、矢印キーで範囲指定し、xで削除)
bcrypt-3.1.13/
orm_adapter-0.5.0/
responders-3.0.0/
warden-1.2.8/
devise-4.7.1/
  • これらの行をvimなら Ctrl+Shift+vを同時押しして、矢印で範囲指定し、 :キーを押してコマンド入力モードに
:'<,'>
  • が表示されてるので、この後に以下を入れエンター、これで最初にgem install が追加される
s/^/gem install /
  • 以下の感じに
gem install bcrypt-3.1.13/
gem install orm_adapter-0.5.0/
gem install responders-3.0.0/
gem install warden-1.2.8/
gem install devise-4.7.1/
  • これらの行をvimなら Ctrl+Shift+vを同時押しして、矢印で範囲指定し、 :キーを押してコマンド入力モードに
:'<,'>
  • が表示されてるので、この後に以下を入れエンター、これでおしりの部分が変形される
s/-\([0-9.]*\)\/$/ -v "\1" \&\& \\/
  • こんな感じに
gem install bcrypt -v "3.1.13" && \
gem install orm_adapter -v "0.5.0" && \
gem install responders -v "3.0.0" && \
gem install warden -v "1.2.8" && \
gem install devise -v "4.7.1" && \
  • 最後の行のおしりを消して、最初にRUN を追加し、インデントをvimなら Ctrl+Shift+vしてから矢印キーで選択後,シフト+>キーでインデントを揃えると以下に
RUN gem install bcrypt -v "3.1.13" && \
    gem install orm_adapter -v "0.5.0" && \
    gem install responders -v "3.0.0" && \
    gem install warden -v "1.2.8" && \
    gem install devise -v "4.7.1"
  • これをDockerの最後の方に追加

19.4 この章のまとめ

  • 前章のRails6向けDockerイメージの改良
  • 元々必用なGemもバージョン指定してDockerイメージに取り込み
  • デフォルトでtest000プロジェクトを生成したものもイメージに入れておいた(手軽に試せる)

20 色々な工夫(2021/05/18バージョン)

  • 今までのだと、DockerImage内の時計が日本時間とズレる(これの修正)
  • 同じapt updateが含まれる行のDockerfileを時間差をもって実行するとキャッシュが使われて、最新のパッケージリストじゃなく、かつてapt updateした時のパッケージリストがキャッシュから利用されてしまい、追加パッケージをダウンロード出来ないエラーで途中で止まってしまう事があった(キャッシュ無視でDocker Imageの作成をした方が良いケースあり)

20.1 以下の操作を行っている動画


20.2 色々な工夫2021/05/18バージョン手順

20.2.1 今までのだと、DockerImage内の時計が日本時間とズレる(これの修正) 対策方法(Ubuntuの場合)

  • Dockerfile で ENV DEBIAN_FRONTEND=noninteractive を使ってたら、コメントアウト(行頭に#を追加)
  • apt -y update && apt -y upgrade した後に echo “6\n79\n” | apt -y install tzdataを行う。これはtzdataを入れる時にタイムゾーンを聞かれるので、日本の東京を選択するのに必要な6のあと79を入れるようにした命令
FROM ubuntu:20.04
... 省略
#ENV DEBIAN_FRONTEND=noninteractive
... 省略
RUN apt -y update && apt -y upgrade 
RUN echo "6\n79\n" | apt -y install tzdata
... 省略

20.2.2 同じ(apt updateが含まれる行のDockerfileを時間差をもって実行するとキャッシュが使われて、最新のパッケージリストじゃなく、かつてapt updateした時のパッケージリストがキャッシュから利用されてしまい、追加パッケージをダウンロード出来ないエラーで途中で止まってしまう事があった(キャッシュ無視でDocker Imageの作成をした方が良いケースあり)時用の対策方法

  • docker build 刷る時に –no-cache オプションを追加して、キャッシュを利用しないようにする
  • 例えば mybuildozer のイメージ作成するには以下のコマンド
docker build --no-cache  -t mybuildozer .

20.3 この章のまとめ

  • 最近DockerでUbuntuベースでDocker Imageつくる時に追加してる工夫をまとめてみました。

21 PythonでAndroidアプリ作る用のDocker Imageの作成(2021/05/18バージョン)

  • 昔一度作ろうとしたが、Dockerfile内の命令で、GoogleのAndroid SDK NDKを入れる時のライセンスの認証入力の自動化がうまくいかず放置してた
  • ホスト側のAndroid SDKやNDKをディレクトリ共有でやったらいけそうな気して、作ってみた
  • YaneuraOuさんの将棋エンジン、詰将棋エンジンのAndroidクロスコンパイルをやるのにも使いたくて、文書化、動画化しようとしてる

21.1 以下の操作を行っている動画


21.2 PythonでAndroidアプリ作る用のDocker Imageの作成(2021/05/18バージョン) の手順

21.2.1 事前準備

  • 前準備として、Android SDK NDKをインストールする必要があります。https://youtu.be/3U5_330aySk
  • /work/Android に mount –bindして以下は行なっています。違うディレクトリにインストールしている場合は、そのディレクトリに置き換えてください。

21.2.2 Dockerfileを作成

  • 起動後は一般ユーザーで起動するようにしてある
  • Pythonパッケージでもっと入れた方が良いのあるけど、最小構成
  • Buldozerにもパッチ当てた方が良いとこあるけど、そこは現在は行わないDockerfile
    • ホストとの共有ディレクトリ内にvirtualenvを作成して、そこでBuldozerの修正行なった方が良いかも
  • YaneuraOuさんの将棋エンジンや、詰将棋エンジンのクロスコンパイルにも利用予定
  • Android SDKやNDKはホスト側に用意して、利用する方針
    • イメージにこれらも組み込む場合は、ホスト側で用意してから、COPYでDocker Imageに入れると良い
    • イメージのサイズが相当大きくなりそうだから、ホスト側においといて、起動時にディレクトリ共有する手順にするつもり
FROM ubuntu:20.04
MAINTAINER NM Max
#ENV DEBIAN_FRONTEND=noninteractive
ENV user_n=user
ENV user_id=1000
RUN apt -y update && apt -y upgrade 
RUN echo "6\n79\n" | apt -y install tzdata
RUN apt -y install python3-dev python3-pip vim git g++ clang cmake make w3m less python3-ipython ipython3 nkf less diffutils patch sudo zlib1g-dev unzip locales python3-virtualenv openjdk-8-jdk adb \
    && locale-gen ja_JP.UTF-8 \
    && pip3 install pybind11 \
    && pip3 install buildozer 
RUN echo 'LANG="ja_JP.UTF-8"' >> /etc/default/locale
ENV LC_ALL ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE LANGUAGE=ja_JP:ja
RUN echo "${user_n} ALL=NOPASSWD: ALL" >> /etc/sudoers
WORKDIR /work
RUN echo "\n\n\n\n\n\n\n" | adduser --uid ${user_id} --disabled-password ${user_n}
RUN echo "user ALL=NOPASSWD: ALL" >> /etc/sudoers && chown user.user /work
RUN mkdir -p /home/${user_n}/C && chown  ${user_n}.${user_n} /home/${user_n}/C
RUN mkdir -p /home/${user_n}/Android && chown  ${user_n}.${user_n} /home/${user_n}/Android
COPY set.sh /home/${user_n}/
RUN echo ". /home/${user_n}/set.sh" >> /home/${user_n}/.bashrc
ENTRYPOINT sudo su - ${user_n}

21.2.3 Android SDKやNDKを利用する時用の環境変数をセットするスクリプトファイルset.shを用意

export NDK_PATH=${HOME}/Android/SDK/ndk-bundle
export PATH=${HOME}/Android/SDK/cmake/3.10.2.4988404/bin:${HOME}/Android/SDK/cmdline-tools/latest/bin:${NDK_PATH}:$PATH
export ANDROID_SDK_ROOT=${HOME}/Android/SDK
export SDK_PATH=${ANDROID_SDK_ROOT}

21.2.4 Docker Image作成

docker build -t mybuildozer .
  • もし、apt install 時にパッケージがないとかエラーでるなら、古いキャッシュを利用しているのが原因かも、その場合は以下でイメージ作成を行う(キャッシュを利用しないようにして)
docker build --no-cache -t mybuildozer .

21.2.5 動作確認

  • ホストの /work/Android と ドッカーの/home/user/Android ディレクトリの共有 を行うようにオプション指定してあります。違うディレクトリと共有したい場合は /work/Android をそのディレクトリに変更
  • ホストの /work/mybuildozer と ドッカーの/home/user/C ディレクトリの共有 。 違うディレクトリと共有したい場合は /work/Android をそのディレクトリに変更
docker run -it --rm -v /work/Android:/home/user/Android -v /work/mybuildozer:/home/user/C mybuildozer

21.2.6 その他

  • Androidアプリや実行ファイルは上のDockerfileと上記の起動方法で可能だが、端末へのインストール転送は、ホスト側のadbコマンドで行う仕様(現在は)

21.3 この章のまとめ

  • YaneuraOuさんの将棋エンジンをAndroid用にクロスコンパイル可能で、PythonでAndroidアプリ作成出来るDocker Imageを作成してみた

22 今後

  • こんぱ今後も文書追加していきます。

23 この文書のチェンジログ

  • 2019/12/10 初版
  • 2019/12/12 django向けカスタマイズイメージ作成章追加
  • 2019/12/12 Docker imageのsave loadの章追加
  • 2019/12/28 docker-composeを利用し、django向け環境3つ(MySQL,PostgreSQL,SQLite3)を作成する3つの章追加
  • 2019/12/28 docker-composeを利用し、django向け(MySQL)のPython用Dockerfile修正
  • 2020/01/12 docker cpのの解説の章追加
  • 2020/01/13 一般ユーザー追加したUbuntuベースのPython用パッケージ作成 の章を追加
  • 2020/01/14 tensorflow v1.15.0-rc3 コンパイルの章追加
  • 2020/01/22 DockerHubのtensorflowイメージ利用の章追加
  • 2020/02/03 DockerHubのtensorflowイメージ拡張その1の章を追加
  • 2020/02/04 DockerHubのtensorflowイメージ拡張その2の章を追加
  • 2020/02/06 Rails6を動かすDockerイメージの作成
  • 2020/03/01 Rails6を動かすDockerイメージの作成2 の章を追加
  • 2021/05/18 色々な工夫(2021/05/18バージョン) の章の追加
  • 2021/05/18 PythonでAndroidアプリ作る用のDocker Imageの作成(2021/05/18バージョン) の章の追加

著者: NM Max

Created: 2021-05-18 火 23:47

Validate

django入門

django入門

目次

1 概要

1.1 djangoの概要

  • djangoは2019/11でPythonで最もユーザー数が多いとされているWebアプリケーションフレームワーク
  • 最新のdjangoはpython3系をサポートらしい

1.2 この文書の概要

  • django関係の入門者用文書
  • Ubuntu19系をを利用して最新のdjangoを使って確認してますが、他のOSでもほぼ同じ手順で作成可能
  • 実際の作業部分を真似しやすいように作成
  • 学習手順として、実際やってみてから、修正したり調べた方が効率良いケースが多い為
  • ベースはdjangoの本家の文書なので、この文書のライセンスもdjangoの本家と同じとします。

2 リンク

2.1 本家

Django ドキュメント (version 2.2)
https://docs.djangoproject.com/ja/2.2/
入門文書(version 2.2)
https://docs.djangoproject.com/ja/2.2/intro/
本家ドキュメント目次
https://docs.djangoproject.com/ja/2.2/contents/
本家ドキュメント索引
https://docs.djangoproject.com/ja/2.2/genindex/
モジュール索引
https://docs.djangoproject.com/ja/2.2/py-modindex/

3 インストール

  • 2019/10月頃、Ubuntuのパッケージのdjangoは1系統であるため、Ubuntuのパッケージによるインストールはお勧めしません。
  • WindowsやMacの場合、Ubuntuの仮想環境や模擬環境であれば、同じ操作で可能だと思います。

3.1 以下の操作を行っている動画


3.2 pipによるローカルへのインストール手順

3.2.1 必要パッケージのインストール

sudo apt install pip3

3.2.2 ローカルディレクトリへのインストール

  • ホームディレクトリの python3/dist-packages ディレクトリにインストールする場合
  • 下のコマンドを実行しパッケージ関係のファイルをインストール
pip3 install Django -t ~/python3/dist-packages
  • インストールしたファイルを検索パスで検索できるように以下の設定を ~/.bashrcに追加し、再起動するか、端末を開きなおし、設定を読み込んだ状態にする
export PYTHONPATH="$HOME/python3/dist-packages:$PYTHONPATH"
export PATH="$HOME/python3/dist-packages/bin:$PATH"
alias python=python3

4 ローカルディレクトリへのインストールしたものを最新のバージョンにアップグレード

4.1 以下の操作を行っている動画


4.2 アップグレードするコマンド

pip3 install --upgrade Django -t ~/python3/dist-packages

5 最初のdjangoアプリ

5.1 以下の操作を行っている動画


5.2 現状のdjangoのバージョン確認

python -m django --version
  • 2019/11/10現在で 2.2.7 の出力が得られています

5.3 python自体のバージョン確認

python --version
  • 2019/11/10現在で Python 3.7.5rc1 の出力が得られています

5.4 プロジェクトの作成

  • 以下のコマンドで mysite という名前のプロジェクトを作成できます。
  • mysiteというディレクトリが作成され、その中にディレクトリや各種ファイルが生成されます
  • プロジェクト名は mysite である必用はなく別の名前でもOK
django-admin startproject mysite

5.5 生成した空プロジェクトを動かしてブラウザで確認する方法

  • 以下のコマンドでプロジェクトのルートにカレントディレクトリを移動
cd mysite
  • 以下のコマンドでサーバーを起動
  • デフォルトで http://127.0.0.1:8000/ で動きます
  • ポート番号とかはオプションで変更可能
  • http://127.0.0.1:8000/ をブラウザで開くとデフォルト画面が表示されます。
python manage.py runserver

6 djangoアプリ2(Hello World)

  • https://docs.djangoproject.com/ja/2.2/intro/ がお勧め
  • 上の本家の文書の手順をベースとして簡略化し、多少アレンジした内容になってます。
  • 指定のurlにアクセスすると、指定の文字が表示されるものを作ります

6.1 以下の操作を行っている動画


6.2 指定のurlで指定の文字が表示されるウェッブアプリを作成する手順

6.2.1 mytest001というアプリを作成し、その中にmypageというアプリケーションを作成

django-admin startproject mytest001
cd mytest001
python manage.py startapp mypage

6.2.2 mypage/views.py を以下に変更します。

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world!")

6.2.3 mypage/urls.py には以下を記述します

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

6.2.4 mytest001/urls.py に 以下の変更を行う

from django.contrib import admin
from django.urls import include, path

from django.views.generic.base import RedirectView

urlpatterns = [
    path('mypage/', include('mypage.urls')),
    path('', RedirectView.as_view(url='/mypage/')),
    path('admin/', admin.site.urls),
]

6.2.5 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

7 djangoアプリ3(テンプレートの利用)

7.1 以下の操作を行っている動画


7.2 テンプレートファイルを利用して表示させるための手順

7.2.1 テンプレートファイルを入れるディレクトリの準備

  • プロジェクトのルート(manage.py があるディレクトリにあるmypageディレクトリ)に templates/mypage ディレクトリを作成します。
  • 以下のコマンド実行前に プロジェクトのルート(manage.py があるディレクトリ)に移動してから実行
mkdir -p mypage/templates/mypage

7.2.2 プロジェクトのセッティング修正

  • INSTALLED_APPS 以外の部分は変更しないでください。
  • mytest001/settings.py の INSTALLED_APPS に ‘mypage.apps.MypageConfig’, を追加
  • これを行うことで、テンプレートファイルの検索パスにmypageが含まれるようになります。
... 省略
# Application definition

INSTALLED_APPS = [
    'mypage.apps.MypageConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
... 省略

7.2.3 テンプレートファイル用意

  • 今回はemacsのorgモードを利用して自動生成したhtmlをベースに改造して以下を作成しました。
  • 以下の内容をmypage/templates/mypage/index.html として保存します。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>djangoの始め方</title>
</head>
<body>
<h1 class="title">djangoの始め方</h1>
</body>
</html>

7.2.4 表示部分の改造

  • mypage/views.py を以下の内容に変更します
from django.http import HttpResponse
from django.template import loader

def index(request):
    template = loader.get_template('mypage/index.html')
    context = {}
    return HttpResponse(template.render(context, request))

7.2.5 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

7.3 この章まとめ

  • テンプレートファイルを利用して表示できる手順を説明

8 djangoアプリ4(計算アプリ)

8.1 以下の操作を行っている動画


8.2 djangoアプリ4(計算アプリ)作成手順

8.2.1 プロジェクトとmycalcアプリのベース作成

  • 今回はmytest002という名前で新規に作っていきます。
django-admin startproject mytest002
cd mytest002
python manage.py startapp mycalc

8.2.2 プロジェクトのセッティング修正

  • INSTALLED_APPS 以外の部分は変更しないでください。
  • mytest002/settings.py の INSTALLED_APPS に ‘mycalc.apps.MypageConfig’, を追加
  • これを行うことで、テンプレートファイルの検索パスにmycalcが含まれるようになります。
... 省略
# Application definition

INSTALLED_APPS = [
    'mycalc.apps.MycalcConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
... 省略

8.2.3 テンプレートファイルを入れるディレクトリの準備

mkdir -p mycalc/templates/mycalc

8.2.4 テンプレートファイル用意

  • 以下の内容をmycalc/templates/mycalc/index.html として保存します。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>計算アプリ</title>
</head>
<body>
<form action="" method="POST">
  <table>
    {{ form.as_table }}
  </table>
  {% csrf_token %}
  <button type="submit">計算</button>
</form>
{% if ans != "" %}
  {{ ans }} </br>
{% endif %}
</body>
</html>

8.2.5 mycalc/form.py を作成

from django import forms

class numForm(forms.Form):
  num1 = forms.DecimalField(label='num1', initial=2, required=True)
  num2 = forms.DecimalField(label='num2', initial=1, required=True)

8.2.6 mycalc/views.py を以下に変更します。

from django.shortcuts import render
from .form import numForm

def index(request):
  if request.method == 'POST':
    form = numForm(request.POST)
    if form.is_valid():
      # print(request.POST)
      # print(form.cleaned_data['num1'])
      # print(form.cleaned_data['num2'])
      # return HttpResponseRedirect('/answer/')
      # print([form.cleaned_data['num1'],form.cleaned_data['num2']])
      n1=int(form.cleaned_data['num1'])
      n2=int(form.cleaned_data['num2'])
      ans=str(n1)+" + "+str(n2)+" = "+str(n1+n2)
      # print(ans)
  else:
    form=numForm()
    ans=""
  return render(request,'mycalc/index.html',{'form':form, 'ans' : ans})

8.2.7 mycalc/urls.py には以下を記述します

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

8.2.8 mytest002/urls.py に 以下の変更を行う

from django.contrib import admin
from django.urls import include, path

from django.views.generic.base import RedirectView

urlpatterns = [
    path('mycalc/', include('mycalc.urls')),
    path('', RedirectView.as_view(url='/mycalc/')),
    path('admin/', admin.site.urls),
]

8.2.9 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

8.3 この章まとめ

  • 整数を2つ入力して、足し算結果を返すアプリの作成(JavaScriptで作った方が楽っぽいけど)
  • formの使い方の基礎を確認

9 djangoアプリ5(ファイルアップロード)

9.1 以下の操作を行っている動画



9.2 djangoアプリ5(ファイルアップロード)作成手順

9.2.1 プロジェクトとmyfile_uploadアプリのベース作成

  • 今回はmytest003という名前で新規に作っていきます。
django-admin startproject mytest003
cd mytest003
python manage.py startapp myfile_upload

9.2.2 プロジェクトのセッティング修正

  • INSTALLED_APPS 以外の部分は変更しないでください。
  • mytest003/settings.py の INSTALLED_APPS に ‘myfileUpload.apps.MypageConfig’, を追加
  • これを行うことで、テンプレートファイルの検索パスにmyfile_uploadが含まれるようになります。
... 省略
# Application definition

INSTALLED_APPS = [
    'myfile_upload.apps.MyfileUploadConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
... 省略

9.2.3 myfile_upload/urls.py には以下を記述します

from django.urls import path

from . import views

urlpatterns = [
    path('', views.upload_file, name='index'),
]

9.2.4 mytest003/urls.py に 以下の変更を行う

from django.contrib import admin
from django.urls import include, path

from django.views.generic.base import RedirectView

import myfile_upload.views as myfile_upload

urlpatterns = [
    path('success/url/',myfile_upload.success),
    path('myfile_upload/', include('myfile_upload.urls')),
    path('', RedirectView.as_view(url='/myfile_upload/')),
    path('admin/', admin.site.urls),
]

9.2.5 テンプレートファイルを入れるディレクトリの準備

mkdir -p myfile_upload/templates/myfile_upload

9.2.6 テンプレートファイル1用意

  • 以下の内容をmyfile_upload/templates/myfile_upload/index.html として保存します。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>ファイルアップロードアプリ</title>
</head>
<body>
<form action="" method="POST" enctype="multipart/form-data">
  <table>
    {{ form.as_table }}
  </table>
  {% csrf_token %}
  <button type="submit">ファイルアップロード実行</button>
</form>
</body>
</html>

9.2.7 テンプレートファイル2(成功時用)用意

  • 以下の内容をmyfile_upload/templates/myfile_upload/success.html として保存します。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>ファイルアップロードアプリ</title>
</head>
<body>
<h1>ファイルのアップロードに成功しました!</h1>
</body>
</html>

9.2.8 myfile_upload/forms.py を作成

from django import forms

class UploadFileForm(forms.Form):
    # title = forms.CharField(max_length=50)
    file = forms.FileField()

9.2.9 myfile_upload/views.py を以下に変更します。

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm

# Imaginary function to handle an uploaded file.
# from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES['file'])
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'myfile_upload/index.html', {'form': form})

def handle_uploaded_file(f):
    fname='files/'+f.name
    print("fname:"+fname)
    with open(fname, 'wb+') as destination:
        for chunk in f.chunks():
            destination.write(chunk)

def success(request):
    return render(request, 'myfile_upload/success.html', {})

9.2.10 ファイル保管用のディレクトリ作成

mkdir -p files

9.2.11 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

9.3 この章まとめ

  • ファイルのアップロードを行う方法を確認

10 urlでのパラメータ渡し

10.1 以下の操作を行っている動画


10.2 djangoアプリ4(計算アプリ)の改造手順

10.2.1 mycalc/urls.py を以下に修正

  • <int: だとマイナスの数値にマッチしてくれないため、re_pathで正規表現マッチを利用 (?P<name>pattern)
from django.urls import path, re_path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    # ex: /mycalc/5/6/results/
    # path('<int:num1>/<int:num2>/results/', views.results, name='results'),
    # ex: /mycalc/5/-1/4/results/
    re_path(r'^(?P<num1>-?\d+)/(?P<num2>-?\d+)/(?P<num3>-?\d+)/results/$', views.results, name='results'),
]

10.2.2 mycalc/views.py を以下に変更します。

from django.shortcuts import render, redirect
from .form import numForm
from django.views.generic.base import RedirectView

def index(request):
  if request.method == 'POST':
    form = numForm(request.POST)
    if form.is_valid():
      n1=int(form.cleaned_data['num1'])
      n2=int(form.cleaned_data['num2'])
      return redirect(str(n1)+'/'+str(n2)+'/'+str(n1+n2)+'/results/')
  else:
    form=numForm()
  return render(request,'mycalc/index.html',{'form':form})

def results(request, num1, num2, num3):
  return render(request,'mycalc/results.html',{'num1':num1, 'num2':num2, 'num3':num3})

10.2.3 元のテンプレートファイルを修正

  • mycalc/templates/mycalc/index.html を以下に修正
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>計算アプリ</title>
</head>
<body>
<form action="" method="POST">
  <table>
    {{ form.as_table }}
  </table>
  {% csrf_token %}
  <button type="submit">計算</button>
</form>
</body>
</html>

10.2.4 結果表示用のテンプレートファイル作成

  • mycalc/templates/mycalc/results.html を以下の内容で作る
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>計算アプリ 計算結果</title>
</head>
<body>
    {{ num1 }} + {{ num2 }} = {{ num3 }} </br>
    {{ num1 }} + {{ num2 }} = {{ num1|add:num2 }} </br>
<a href="/mycalc/">計算設定画面へ</a>
</form>
</body>
</html>

10.2.5 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

10.3 この章まとめ

  • urlでのパラメーター渡し
  • 正規表現を利用したマッチも利用
  • 組み込みタグとフィルタの活用

11 カスタムフィルタ

11.1 以下の操作を行っている動画


11.2 カスタムフィルタの作成手順

11.2.1 カスタムフィルタ保存用のフォルダ作成

mkdir -p mycalc/templatetags

11.2.2 カスタムフィルタ用ファイルの作成

  • touchコマンドで空の__init__.pyを作成してます。エディタで空の__init__.pyを作成してもOK
touch mycalc/templatetags/__init__.py
  • mycalc/templatetags/mysub.py を以下の内容で作成
from django import template

register = template.Library()

@register.filter("mysub")
def mysub(value, arg):
    return int(value)-int(arg)

@register.filter("mymul")
def mymul(value, arg):
    return int(value)*int(arg)

@register.filter("mydiv")
def mydiv(value, arg):
    return int(value)/int(arg)

@register.filter("mymod")
def mymod(value, arg):
    return int(value)%int(arg)

11.2.3 結果表示用のテンプレートファイル修正

  • mycalc/templates/mycalc/results.html を以下の内容で作る
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>計算アプリ 計算結果</title>
</head>
<body>
    {{ num1 }} + {{ num2 }} = {{ num3 }} </br>
    {{ num1 }} + {{ num2 }} = {{ num1|add:num2 }} </br>
    {% load mysub %}
    {{ num1 }} - {{ num2 }} = {{ num1|mysub:num2 }} </br>
    {{ num1 }} * {{ num2 }} = {{ num1|mymul:num2 }} </br>
    {{ num1 }} / {{ num2 }} = {{ num1|mydiv:num2 }} </br>
    {{ num1 }} % {{ num2 }} = {{ num1|mymod:num2 }} </br>
<a href="/mycalc/">計算設定画面へ</a>
</form>
</body>
</html>

11.2.4 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

11.3 この章まとめ

  • カスタムフィルタを作成し利用してみた

12 セッション(session)関係の機能を試してみる

12.1 以下の操作を行っている動画


12.2 djangoアプリ5(ファイルアップロード mytest003)の改造手順

12.2.1 マイグレートを行う

  • セッション機能を利用するのに必用(デフォルトのセッションの設定の場合、データベースを利用するため)
python manage.py migrate

12.2.2 テンプレートファイル2(成功時用)を改造

  • myfile_upload/templates/myfile_upload/success.html を以下の内容に変更
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>ファイルアップロードアプリ</title>
</head>
<body>
<h1>ファイル {{ orgfilename }} を {{ dfilename }} として、アップロードすることに成功しました!</h1>
</body>
</html>

12.2.3 myfile_upload/views.py を以下に変更します。

  • テンポラリファイルを利用するように変更
  • success画面で、セッションに保存したファイル名を利用する様に変更
  • セッションでの値の保存は request.session[‘名前’]=値
  • 保存していたセッションでの値の取り出し request.session[‘名前’]
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
import tempfile

# Imaginary function to handle an uploaded file.
# from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            tfname=handle_uploaded_file(request.FILES['file'])
            request.session['org_fname']=request.FILES['file'].name
            request.session['tmp_fname']=tfname
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'myfile_upload/index.html', {'form': form})

def handle_uploaded_file(f):
    # fname='files/'+f.name
    tfname=""
    # print("fname:"+fname)
    # with open(fname, 'wb+') as destination:
    with tempfile.NamedTemporaryFile(mode='wb+',delete=False) as destination:
        tfname=destination.name
        print(tfname)
        for chunk in f.chunks():
            destination.write(chunk)
    return tfname

def success(request):
    return render(request, 'myfile_upload/success.html', {'orgfilename':request.session['org_fname'], 'dfilename':request.session['tmp_fname']})

12.2.4 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver

12.3 この章まとめ

  • セッション関係の機能を利用
  • 一時ファイル(tempfile)を利用

13 カスタムユーザーの作成(AbstractUserを継承タイプ)

13.1 以下の操作を行っている動画


13.2 カスタムユーザー設定(AbstractUserを継承タイプ)を行ってプロジェクトを始める手順

13.2.1 mytest004というアプリを作成し、その中にmyuserというアプリケーションを作成

django-admin startproject mytest004
cd mytest004
python manage.py startapp myuser

13.2.2 mytest004/settings.py 修正

  • INSTALLED_APPS に ‘myuser’, を追加
  • AUTH_USER_MODEL = ‘myuser.User’ を追加
... 省略
# Application definition

INSTALLED_APPS = [
    'mypage.apps.MypageConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myuser',
]

AUTH_USER_MODEL = 'myuser.User'
... 省略

13.2.3 myuser/models.py 修正

  • 「pass はヌル操作 (null operation) です — pass が実行されても、何も起きません。 pass は、構文法的には文が必要だが、コードとしては何も実行したくない場合のプレースホルダとして有用です。」 https://docs.python.org/ja/3/reference/simple_stmts.html#pass から引用
  • 後でUserを修正してカスタマイズ出来ます
# from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass

13.2.4 myuser/admin.py 修正

rom django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

13.2.5 migration作成、適用

python manage.py makemigrations
python manage.py migrate

13.2.6 superuserを作成

python manage.py createsuperuser
  • 以下の感じで、ユーザーネーム、メールアドレスを入れて(ここでメールアドレスは適当なもにしてます、わたしのメールアドレスではありません)
Username: admin
Email address: xxx@xxx.xxx
Password: 
Password (again): 
  • パスワードが簡単すぎると以下のようなメッセージが表示されます、以下の例では強引にそれを認めさせてます
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
  • パスワード2つ入力したものが異なると以下のメッセージが出ます。そのときは再度2回同じパスワードを入れてください
Error: Your passwords didn't match.

13.2.7 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver
  • http://localhost:8000/admin/ にアクセスして、設定した管理者権限のユーザー名とパスワードでログインします

13.3 この章まとめ

  • プロジェクト開始時にカスタムユーザー作成

14 カスタムユーザーの作成2(AbstractBaseUserを継承タイプ)

  • 前章はAbstractUserを継承していましたが、今回はより自由度が高くなるAbstractBaseUserを継承
  • myuser/models.py 修正する箇所が異なるのみで、他はほぼ一緒
  • 本家で関係する文書 は前章と同じになります。
  • 関係するインストールしたpythonファイル (ローカルの~/python3/にインストールした場合) ~/python3/dist-packages/django/contrib/auth/models.py

14.1 以下の操作を行っている動画


14.2 カスタムユーザー設定(AbstractBaseUserを継承タイプ)を行ってプロジェクトを始める手順

14.2.1 mytest005というアプリを作成し、その中にmyuserというアプリケーションを作成

django-admin startproject mytest005
cd mytest005
python manage.py startapp myuser

14.2.2 mytest005/settings.py 修正

  • INSTALLED_APPS に ‘myuser’, を追加
  • AUTH_USER_MODEL = ‘myuser.User’ を追加
... 省略
# Application definition

INSTALLED_APPS = [
    'myuser',
    'mypage.apps.MypageConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

AUTH_USER_MODEL = 'myuser.User'
... 省略

14.2.3 mytest005/settings.py 修正2

  • ローカライズの修正も行います。(今回特に必用ないけど)
  • LANGUAGE_CODE を ‘en-us’ から ‘ja’に変更
  • TIME_ZONE を ‘UTC’ から ‘Asia/Tokyo’ に変更
... 省略
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
... 省略

14.2.4 myuser/models.py 修正

  • 関係するインストールしたpythonファイル (ローカルの~/python3/にインストールした場合) ~/python3/dist-packages/django/contrib/auth/models.py をベースに削って作成。修正内容は以下の感じ
    • 関係しそうなimportのみを残す
    • from django.contrib.auth.models import PermissionsMixin, UserManager を追加(オリジナルの PermissionsMixin, UserManagerを利用するため)
    • from django.contrib.auth.validators import UnicodeUsernameValidator を追加
    • AbstractUser 部分をコピペ
      • クラス名をUserに変更
      • abstract = True をコメントアウト
  • 後で修正してカスタマイズ可能
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.core.mail import send_mail
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from django.contrib.auth.models import PermissionsMixin, UserManager

from django.contrib.auth.validators import UnicodeUsernameValidator


class User(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    """
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        # abstract = True

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        """Send an email to this user."""
        send_mail(subject, message, from_email, [self.email], **kwargs)

14.2.5 myuser/admin.py 修正

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)

14.2.6 migration作成、適用

python manage.py makemigrations
python manage.py migrate

14.2.7 superuserを作成

  • 質問に答えていって、作成
  • 実際の途中の様子は前章参照
python manage.py createsuperuser

14.2.8 サーバーを起動しブラウザで確認

  • 以下でサーバー起動
python manage.py runserver
  • http://localhost:8000/admin/ にアクセスして、設定した管理者権限のユーザー名とパスワードでログインします

14.3 この章まとめ

  • プロジェクト開始時にカスタムユーザー作成

15 郵便番号検索アプリの作成

15.1 以下の操作を行っている動画


15.2 郵便番号csvデータの取得と準備

15.2.1 データの取得が面倒な方は ken_all_utf_wh.json として以下を保存

  • 3つのデータのみ入っているデータ
[
  {
    "model": "zipcodes.zipcode",
    "pk": 1,
    "fields": {
      "jisx": "01101",
      "zipold": "060  ",
      "zip": "0600000",
      "prefecture": "ホッカイドウ",
      "city": "サッポロシチュウオウク",
      "street": "イカニケイサイガナイバアイ",
      "kprefecture": "北海道",
      "kcity": "札幌市中央区",
      "kstreet": "以下に掲載がない場合",
      "c1": "0",
      "c2": "0",
      "c3": "0",
      "c4": "0",
      "c5": "0",
      "c6": "0"
    }
  },
  {
    "model": "zipcodes.zipcode",
    "pk": 79393,
    "fields": {
      "jisx": "26104",
      "zipold": "604  ",
      "zip": "6048182",
      "prefecture": "キョウトフ",
      "city": "キョウトシナカギョウク",
      "street": "オオサカザイモクチョウ",
      "kprefecture": "京都府",
      "kcity": "京都市中京区",
      "kstreet": "大阪材木町",
      "c1": "0",
      "c2": "0",
      "c3": "0",
      "c4": "0",
      "c5": "0",
      "c6": "0"
    }
  },
  {
    "model": "zipcodes.zipcode",
    "pk": 124340,
    "fields": {
      "jisx": "47382",
      "zipold": "90718",
      "zip": "9071801",
      "prefecture": "オキナワケン",
      "city": "ヤエヤマグンヨナグニチョウ",
      "street": "ヨナグニ",
      "kprefecture": "沖縄県",
      "kcity": "八重山郡与那国町",
      "kstreet": "与那国",
      "c1": "0",
      "c2": "0",
      "c3": "0",
      "c4": "0",
      "c5": "0",
      "c6": "0"
    }
  }
]

15.2.2 データの取得

  • 郵便番号と住所のデータの準備が面倒な方は上のken_all_utf_wh.jsonを準備してスキップ可
  1. ブラウザでダウンロードしに行く場合
  2. wgetを利用してのダウンロードする場合
    • データと、データの説明ページをダウンロードしてます
    wget "https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip"
    wget "https://www.post.japanpost.jp/zipcode/dl/readme.html"
    
  3. unarを利用してzipファイルを解凍する場合
    • unar以外のツールでzipを解凍してもOK
    • KEN_ALL.CSV を取り出せます
    unar ken_all.zip
    
  4. 文字コードをユニコードに変換(nkfを利用する場合)
    • 複数の文字コードを変換できるエディタや、ツールを利用してもOK
    • ここではnkfコマンドでやってみます。
    • 環境がユニコードなら以下でOK
    • 作成したファイル名は ken_all_utf.csv
    nkf KEN_ALL.CSV > ken_all_utf.csv
    

    **

  5. 1行目に各列のデータ名をつける
    jisx,zipold,zip,prefecture,city,street,kprefecture,kcity,kstreet,c1,c2,c3,c4,c5,c6
    
    • echo と cat コマンドで行うと以下の感じ、普通のエディタで上の1行をデータの頭に入れてもOK
    echo "jisx,zipold,zip,prefecture,city,street,kprefecture,kcity,kstreet,c1,c2,c3,c4,c5,c6" > ken_all_head.csv
    cat ken_all_head.csv ken_all_utf.csv > ken_all_utf_wh.csv
    
  6. csvをjsonデータに変換
    • 他のツールを使ってもOK
    • 以下の内容のpythonファイルを作成し、convert.pyという名前で保存
    import csv
    import json
    
    with open('ken_all_utf_wh.csv', 'r') as f:
      r = csv.DictReader(f)
      c = 1
      a=[]
      for row in r:
        a.append({"model" : "zipcodes.zipcode", "pk" : c, 'fields' : row })
        c=c+1
      print(json.dumps(a, ensure_ascii=False, indent=2))
    
    • 以下を実行すると ken_all_utf_wh.csv(ヘッダー追加してユニコードにしたcsvファイル)をjson形式に変換し ken_all_utf_wh.json として保存
    python convert.py > ken_all_utf_wh.json
    

15.3 郵便番号検索アプリの作成手順

15.3.1 myzipcodes というアプリを作成し、その中にmyappというアプリケーションを作成

  • カスタムユーザーを最初に追加した方が後々カスタムユーザーを使う時に便利になりますが、説明上カスタムユーザーを追加せずに作って行きます。(前章を参考にカスタムユーザーを作っておく方が良い。)
django-admin startproject myzipcodes
cd myzipcodes
python manage.py startapp zipcodes

15.3.2 myzipcodes/settings.py 修正

  • INSTALLED_APPS に ‘zipcodes.apps.ZipcodesConfig’, を追加
... 省略
# Application definition

INSTALLED_APPS = [
    'zipcodes.apps.ZipcodesConfig',
    'mypage.apps.MypageConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

... 省略

15.3.3 myzipcodes/settings.py 修正2

  • ローカライズの修正も行います。(今回特に必用ないけど)
  • LANGUAGE_CODE を ‘en-us’ から ‘ja’に変更
  • TIME_ZONE を ‘UTC’ から ‘Asia/Tokyo’ に変更
... 省略
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
... 省略

15.3.4 zipcodes/models.py 修正

from django.db import models

class Zipcode(models.Model):
    jisx = models.CharField(max_length=20)
    zipold = models.CharField(max_length=10)
    zip = models.CharField(max_length=10)
    prefecture = models.CharField(max_length=200)
    city = models.CharField(max_length=200)
    street = models.CharField(max_length=200)
    kprefecture = models.CharField(max_length=200)
    kcity = models.CharField(max_length=200)
    kstreet = models.CharField(max_length=200)
    c1 = models.CharField(max_length=10)
    c2 = models.CharField(max_length=10)
    c3 = models.CharField(max_length=10)
    c4 = models.CharField(max_length=10)
    c5 = models.CharField(max_length=10)
    c6 = models.CharField(max_length=10)

15.3.5 zipcodes/admin.py 修正

  • Zipcodeを管理サイトに登録(これで管理メニューでzipcodeをいじれます)
from django.contrib import admin

from .models import Zipcode

admin.site.register(Zipcode)

15.3.6 migration作成、適用

python manage.py makemigrations
python manage.py migrate

15.3.7 郵便局から得たcsvファイルを前節で加工して生成した ken_all_utf_wh.json ファイルをデータベースに読み込み

python manage.py loaddata ../ken_all_utf_wh.json

15.3.8 zipcodes/views.py を以下に修正

from django.shortcuts import render, get_object_or_404, get_list_or_404
from .models import Zipcode
from django.db.models import Q

def getAddress(request,zipcode):
  d=get_list_or_404(Zipcode, zip__regex=zipcode)
  return render(request, 'zipcodes/getAddress.html', {'zipcode':zipcode, 'd':d})

def getZipcodesStreet(request,s):
  d=get_list_or_404(Zipcode, kstreet__regex=s)
  return render(request, 'zipcodes/getZipcodes.html', {'s':s, 'x':"町域名", 'd':d})

def getZipcodesCity(request,s):
  d=get_list_or_404(Zipcode, kcity__regex=s)
  return render(request, 'zipcodes/getZipcodes.html', {'s':s, 'x':"市区町村名", 'd':d})

def getZipcodesPrefecture(request,s):
  d=get_list_or_404(Zipcode, kprefecture__regex=s)
  return render(request, 'zipcodes/getZipcodes.html', {'s':s, 'x':"都道府県名", 'd':d})

def getZipcodesOr(request,s):
  d=get_list_or_404(Zipcode, Q(kprefecture__regex=s)|Q(kcity__regex=s)|Q(kstreet__regex=s))
  return render(request, 'zipcodes/getZipcodes.html', {'s':s, 'x':"都道>府県名あるいは市区町村名あるいは町域名", 'd':d})

15.3.9 zipcodes/templates/zipcodes/getAddress.html を作成

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>郵便番号{{zipcode}}を含む住所</title>
</head>
<body>
<h1>郵便番号{{zipcode}}を含む住所</h1>
{% for a in d %}
    <li>{{ a.zip }} {{ a.kprefecture}} {{ a.kcity }} {{ a.kstreet }}</a></li>
{% endfor %}
</body>
</html>

15.3.10 zipcodes/templates/zipcodes/getZipcodes.html を作成

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>"{{s}}"を"{{x}}"に含む住所</title>
</head>
<body>
<h1>"{{s}}"を"{{x}}"に含む住所</h1>
{% for a in d %}
    <li>{{ a.zip }} {{ a.kprefecture}} {{ a.kcity }} {{ a.kstreet }}</a></li>
{% endfor %}
</body>
</html>

15.3.11 myzipcodes/urls.py を以下に修正

from django.contrib import admin
from django.urls import path, re_path
from zipcodes import views as zviews

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^zip/(?P<zipcode>\d{1,7})$', zviews.getAddress, name="getAddress"),
    re_path(r'^street/(?P<s>.+)$', zviews.getZipcodesStreet, name="getZipcodesStreet"),
    re_path(r'^city/(?P<s>.+)$', zviews.getZipcodesCity, name="getZipcodesCity"),
    re_path(r'^prefecture/(?P<s>.+)$', zviews.getZipcodesPrefecture, name="getZipcodesPrefecture"),
    re_path(r'^address/(?P<s>.+)$', zviews.getZipcodesOr, name="getZipcodesPrefecture"),
]

15.4 この章でのまとめ

  • データベースとの連携機能の利用
  • データベースへのデータのインポート
  • 今までの章でやってきたテクの利用

16 djangoのshellの活用

16.1 以下の操作を行っている動画


16.2 動画で出てくる操作

  • 操作は一つ前の章で使った郵便番号検索アプリで行ってます

16.2.1 dangoのシェルの起動

  • 郵便番号アプリのプロジェクトのベースディレクトリ(manage.pyがあるディレクトリ)にはいってから
python manage.py shell
  • 現状やると以下の画面に
$ python manage.py shell
Python 3.7.5 (default, Nov 20 2019, 09:21:52) 
Type "copyright", "credits" or "license" for more information.

IPython 5.8.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: 

16.2.2 モデルクラスのimport

  • 郵便番号検索アプリの場合は Zipcode クラスをimport
  • import のfromの部分は、アプリ名とmodelsを . で結合し、郵便番号アプリのZipcodeの場合は zipcodes.models になる
from zipcodes.models import Zipcode

16.2.3 モデルクラスで検索

  1. 全部のデータを取得し、個数を表示
    • dに検索結果を入れる
    d=Zipcode.objects.all()
    len(d)
    
  2. pk=1のデータっを取得し、zipcodeや色々なデータを表示
    • dに検索結果を入れる
    d=Zipcode.objects.filter(pk=1)
    print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kstreet])
    
  3. 県名が”大阪府”で、市名が”大阪市”のデータを取得し数を数え、一番最初のデータの表示
    • And条件
    d=Zipcode.objects.filter(kprefecture="大阪府",kcity__startswith="大阪市")
    print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kstreet])
    
  4. Qオブジェクトを利用してORとかAnd
    • Q()で条件をくるんで
    • ANDは&で結合
    • ORは|で結合
    • “府”で終わる都道府県名で、市区町村名に”区”が含まれる And条件だと
    from django.db.models import Q
    d=Zipcode.objects.filter(Q(kprefecture__endswith="府")&Q(kcity__contains="区"))
    print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kstreet])
    
    • Qオブジェクトを利用しないANDケースだと
    d=Zipcode.objects.filter(kprefecture__endswith="府",kcity__contains="区")
    print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kstreet])
    
    • “府”で終わる都道府県名か、市区町村名に”区”が含まれる OR条件だと
    d=Zipcode.objects.filter(Q(kprefecture__endswith="府")|Q(kcity__contains="区"))
    print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kstreet])
    

16.2.4 ここまでの操作の画面のコピー

$ python manage.py shell
Python 3.7.5 (default, Nov 20 2019, 09:21:52) 
Type "copyright", "credits" or "license" for more information.

IPython 5.8.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from zipcodes.models import Zipcode
   ...: 

In [2]: d=Zipcode.objects.all()
   ...: len(d)
   ...: 
Out[2]: 124340

In [3]: d=Zipcode.objects.filter(pk=1)
   ...: print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kst
   ...: reet])
   ...: 
[1, '0600000', '北海道', '札幌市中央区', '以下に掲載がない場合']

In [4]: d=Zipcode.objects.filter(kprefecture="大阪府",kcity__startswith=
   ...: "大阪市")
   ...: print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kst
   ...: reet])
   ...: 
[966, '5340000', '大阪府', '大阪市都島区', '以下に掲載がない場合']

In [5]: from django.db.models import Q
   ...: d=Zipcode.objects.filter(Q(kprefecture__endswith="府")&Q(kcity__
   ...: contains="区"))
   ...: print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kst
   ...: reet])
   ...: 
[6214, '6030000', '京都府', '京都市北区', '以下に掲載がない場合']

In [6]: d=Zipcode.objects.filter(kprefecture__endswith="府",kcity__conta
   ...: ins="区")
   ...: print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kst
   ...: reet])
   ...: 
[6214, '6030000', '京都府', '京都市北区', '以下に掲載がない場合']

In [7]: d=Zipcode.objects.filter(Q(kprefecture__endswith="府")|Q(kcity__
   ...: contains="区"))
   ...: print([ len(d), d[0].zip, d[0].kprefecture, d[0].kcity, d[0].kst
   ...: reet])
   ...: 
[24247, '0600000', '北海道', '札幌市中央区', '以下に掲載がない場合']

In [8]: 

16.3 この章でのまとめ

  • shell機能を活用することで、インタラクティブに動作確認や機能の確認を行うことができる(デバッグや、アプリ構築の際に非常に便利)

17 MySQLの利用

17.1 以下の操作を行っている動画


17.2 MySQLのインストール

17.2.1 Ubuntuの場合

sudo apt install mysql-client mysql-server

17.2.2 WindowsやMacの場合

  • 本家のGetting Startや、「OS名 MySQL インストール」などでネット検索かけて頂ければ、インストール方法みつかります

17.3 MySQLへの最初のログイン

  • 最初結構はまりました、/usr/share/doc/mysql-clientにも文書なかったし
  • Ubuntuの19.10の場合、インストール時にrootパスワードの設定がでてきません
  • 以下のコマンドを実行して、パスワードを設定してください。
  • 残りの質問は全部デフォルト(エンターのみ)でOK
sudo mysql_secure_installation
  • 設定してる画面は以下の感じ

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: 
Please set the password for root here.

New password: 

Re-enter new password: 
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : 

 ... skipping.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : 

 ... skipping.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : 

 ... skipping.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : 

 ... skipping.
All done! 

17.4 MySQLへの最初の接続

  • 以下のコマンドを実行し、上で設定したパスワードを入力するとプロンプトが表示されます
sudo mysql -u root -p
  • ログインが上手くいくと以下の感じに
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 18
Server version: 8.0.18-0ubuntu0.19.10.1 (Ubuntu)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

17.5 django用のデータベース作成

  • database_nameは好きなデータベース名に
CREATE DATABASE database_name;
  • 例えばデータベース名を testdb とすると
CREATE DATABASE testdb;

17.6 ユーザーの作成

  • username は希望するユーザー名に
  • host はホスト名,ローカルならlocalhost
  • passward は 希望するパスワードに
CREATE USER 'user_name'@'host' IDENTIFIED BY 'password';
  • 例えば、ユーザー名をtester, ホスト名を localhost, パスワードを how7OjIcus にするなら
CREATE USER 'tester'@'localhost' IDENTIFIED BY 'how7OjIcus';

17.7 ユーザーに権限を付与

  • ‘tester’@’localhost’ にdatabase_nameがtestdb への操作を全部許可する場合
GRANT ALL PRIVILEGES ON testdb.* TO 'tester'@'localhost';
FLUSH PRIVILEGES;

17.8 データベース一覧表示

SHOW DATABASES;

17.9 作成したユーザーで作成したデータベースにアクセスできるか確認

  • パスワードをきかれたら、設定したパスワードを答える
mysql  -u tester -p testdb

17.10 python3-mysqldb(mysqlclient)のインストール

  • sudo apt install python3-mysqldb だと以下になってバージョン古すぎメッセージが出て使えないので、pipでインストール
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 1.3.10.
  • mysql_configが必用になるため、mysql_configを含む libmysqlclient-dev をインストール
sudo apt install libmysqlclient-dev
  • Ubuntuでローカルにインストールする場合
  • windowsとかMacなど他なら、pip3をpipにして -t 以降無しで実行 ( pip install mysqlclient )
pip3 install mysqlclient -t ~/python3/dist-packages
  • これらをアップグレードする場合
pip3 install --upgrade Django -t ~/python3/dist-packages
pip3 install --upgrade mysqlclient -t ~/python3/dist-packages

17.10.1 UbuntuなどDebian系以外の場合(windowsやmacや他の系統のLinux)

  • ローカルじゃなく普通にインストールする場合
pip install mysqlclient

17.11 MySQLをプロジェクトで利用

17.11.1 プロジェクトの作成

  • カスタムユーザーアプリの作成と、カスタムユーザーアプリの初期設定は省略します。通常の場合、後でカスタムユーザー追加は操作が大変なので最初に必ず追加しましょう。
django-admin startproject mytest007
cd mytest007

17.11.2 プロジェクト名/setting.pyを変更

  • 作成したデータベース名 testdb
  • ログインユーザー名が tester@localhost の場合
  • 日本語設定や、タイムゾーンの設定は省略します。
DATABASES = {
    #    'default': {
    #        'ENGINE': 'django.db.backends.sqlite3',
    #        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    #    }
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testdb',
        'USER': 'tester',
        'PASSWORD': 'how7OjIcus', 
        'HOST': '',
        'PORT': '',
    }
}

17.11.3 データベースとの連携

python manage.py makemigrations
python manage.py migrate

17.11.4 作成されたtableを確認

$ mysql -u tester -p testdb
Enter password: 
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 8.0.18-0ubuntu0.19.10.1 (Ubuntu)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show tables;
+------------------------------+
| Tables_in_testdb           |
+------------------------------+
| auth_group                   |
| auth_group_permissions       |
| auth_permission              |
| django_admin_log             |
| django_content_type          |
| django_migrations            |
| django_session               |
+------------------------------+
11 rows in set (0.01 sec)

mysql> quit
Bye

17.11.5 作成したデータベースのバックアップ

  • ユーザー名 tester
  • パスワードが how7OjIcus
  • データベース名が testdb
  • バックアップファイル名が dump.sqlの場合
mysqldump -u tester -phow7OjIcus testdb > dump.sql

17.12 この章について

  • デフォルトのSqlite3ではなくMySQLをデータベースとして使う方法
  • 他MySQLを使うにあたっての最低限の操作例
  • ユーザー名やパスワードは同じものを使わないで!

18 実際裏で実行されてるSQLの確認方法

18.1 以下の操作を行っている動画


18.2 裏で実行されてるSQLの確認方法例

  • 以前この文書で作成した 郵便番号検索アプリ を利用して試してみます
  • djangoのshell機能を利用します
  • DEBUG=Trueの時のみこの方法可能だそうです

18.2.1 djangoのshell起動

  • 郵便番号アプリのmanage.pyがあるディレクトリで以下を実行
python manage.py shell

18.2.2 モデルのクラスをimport

from zipcodes.models import Zipcode
from django.db.models import Q

18.2.3 実際に調べてみる1

d1=Zipcode.objects.filter(Q(kprefecture__endswith="府")|Q(kcity__contains="区"))
str(d1.query)

18.2.4 実際に調べてみる2

d2=Zipcode.objects.filter(Q(kprefecture__endswith="府")&Q(kcity__contains="区"))
str(d2.query)

18.2.5 実際に調べてみる3

d3=Zipcode.objects.filter(kprefecture__endswith="府",kcity__contains="区")
str(d3.query)

18.2.6 実際に調べてみる4

from django.db import connection
connection.queries

18.2.7 実際に操作したときのスクショ

$ python manage.py shell
Python 3.7.5 (default, Nov 20 2019, 09:21:52) 
Type "copyright", "credits" or "license" for more information.

IPython 5.8.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from zipcodes.models import Zipcode

In [2]: from django.db.models import Q

In [3]: d1=Zipcode.objects.filter(Q(kprefecture__endswith="府")|Q(kcity_
   ...: _contains="区"))

In [4]: str(d1.query)
Out[4]: 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE %府 ESCAPE \'\\\' OR "zipcodes_zipcode"."kcity" LIKE %区% ESCAPE \'\\\')'

In [5]: from django.db import connection

In [6]: connection.queries
Out[6]: []

In [7]: len(d1)
Out[7]: 24247

In [8]: connection.queries
Out[8]: 
[{'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' OR "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.001'}]

In [9]: d2=Zipcode.objects.filter(Q(kprefecture__endswith="府")&Q(kcity_
   ...: _contains="区"))
   ...: str(d2.query)
   ...: 
Out[9]: 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE %府 ESCAPE \'\\\' AND "zipcodes_zipcode"."kcity" LIKE %区% ESCAPE \'\\\')'

In [10]: connection.queries
Out[10]: 
[{'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' OR "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.001'}]

In [11]: len(d2)
Out[11]: 6214

In [12]: connection.queries
Out[12]: 
[{'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' OR "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.001'},
 {'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' AND "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.030'}]

In [13]: d3=Zipcode.objects.filter(kprefecture__endswith="府",kcity__con
    ...: tains="区")
    ...: str(d3.query)
    ...: 
Out[13]: 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kcity" LIKE %区% ESCAPE \'\\\' AND "zipcodes_zipcode"."kprefecture" LIKE %府 ESCAPE \'\\\')'

In [14]: len(d3)
Out[14]: 6214

In [15]: connection.queries
Out[15]: 
[{'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' OR "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.001'},
 {'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' AND "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.030'},
 {'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\' AND "zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\')',
  'time': '0.036'}]

In [16]: connection.queries4
------------------------------------------------------------------------
AttributeError                         Traceback (most recent call last)
<ipython-input-16-7e2a5aa2c672> in <module>()
----> 1 connection.queries4

/home/pano/python3/dist-packages/django/db/__init__.py in __getattr__(self, item)
     26     """
     27     def __getattr__(self, item):
---> 28         return getattr(connections[DEFAULT_DB_ALIAS], item)
     29 
     30     def __setattr__(self, name, value):

AttributeError: 'DatabaseWrapper' object has no attribute 'queries4'

In [17]: connection.queries
Out[17]: 
[{'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' OR "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.001'},
 {'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\' AND "zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\')',
  'time': '0.030'},
 {'sql': 'SELECT "zipcodes_zipcode"."id", "zipcodes_zipcode"."jisx", "zipcodes_zipcode"."zipold", "zipcodes_zipcode"."zip", "zipcodes_zipcode"."prefecture", "zipcodes_zipcode"."city", "zipcodes_zipcode"."street", "zipcodes_zipcode"."kprefecture", "zipcodes_zipcode"."kcity", "zipcodes_zipcode"."kstreet", "zipcodes_zipcode"."c1", "zipcodes_zipcode"."c2", "zipcodes_zipcode"."c3", "zipcodes_zipcode"."c4", "zipcodes_zipcode"."c5", "zipcodes_zipcode"."c6" FROM "zipcodes_zipcode" WHERE ("zipcodes_zipcode"."kcity" LIKE \'%区%\' ESCAPE \'\\\' AND "zipcodes_zipcode"."kprefecture" LIKE \'%府\' ESCAPE \'\\\')',
  'time': '0.036'}]

In [18]: quit

18.3 この章のまとめ

  • モデルを利用した時に裏で実行されているSQL文の確認方法を試してみた
  • 実際SQL文が実行されるタイミングは必用となってからのケースもある

19 この文書のチェンジログ

  • 2019/11/10 初版
  • 2019/11/10 修正および、テンプレートファイルを利用する章の追加
  • 2019/11/10 足し算アプリ作成する章の追加
  • 2019/11/11 一部修正及び、ファイルアップロードする章の追加
  • 2019/11/11 urlからパラメーター取り出しする章の追加
  • 2019/11/11 カスタムフィルタ作成利用の章追加
  • 2019/11/16 セッションの利用の章を追加
  • 2019/11/16 python3 と入力していた命令を python に変更(Ubuntu以外はpythonであるため) Ubuntuの場合上で.bash_rcで設定しておらず、python2系と3系をインストールしているならpythonとコマンド入力している部分はpython3と入力すべきかも
  • 2019/11/17 カスタムユーザー(AbstractUserを継承タイプ)の章追加
  • 2019/11/18 カスタムユーザー(AbstractBaseUserを継承タイプ)の章追加、最初の概要変更
  • 2019/11/27 郵便番号検索アプリ作成の章追加
  • 2019/11/28 djangoのシェル機能の章追加
  • 2019/11/28 MySQLの利用の章追加
  • 2019/11/28 実際裏で実行されてるSQLの確認方法の章追加

20 続きを追記してきます。

著者: NM Max

Created: 2019-11-28 木 07:43

Validate

MBR(bios)からもESP(uefi)からも起動できるUSBメモリの作り方

MBR(bios)からもESP(uefi)からも起動できるUSBメモリの作り方

その1 バックアップとパーティション変更、フォーマット、2タイプのgrubのインストール

1 概要

  • UbuntuでブータブルUSBメモリを作成する手順
  • 2019/10/23現在だと、Ubuntu18.04を利用して作成してください。
  • 今後Ubuntu 19系でもgrubのバージョンアップにより不具合なしのものが同じ手順で作成できるようになるかも

2 注意

  • 2019/10/23現在だと、Ubuntu18.04を利用して作成してください。19.10ではgrubが2.04でisoイメージを起動するときに利用するloopbackのところでフリーズしています。

3 手順

**以下の操作を行っている動画




3.1 必要パッケージのインストール

sudo apt install dosfstools e2fsprogs gdisk util-linux

3.2 USBメモリ接続

接続したら、自動マウントされるので、取り出しではなくアンマウント

sudo umount マウントポイント(ディレクトリ)
sudo umount /media/user/xxxx-xxx-xxx

3.3 現状のバックアップ

3.3.1 現状のディスクイメージのパーティション情報保存

  • /dev/sdc はマシンや環境で変化するので、実際に使いたいUSBメモリのデバイスを割り当てたものを使ってください。(/dev/sdb,/dev/sddとかの場合もあり)
sudo gdisk -l /dev/sdc
Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048         1024000   499.0 MiB   EF00  EFI System
   3         1026048        10485726   4.5 GiB     8300  Linux filesystem

3.3.2 初期状態のパーティション情報のバックアップ

  • 以下のコマンドで usborggdisk-l.txt に情報が保存される
  • /dev/sdc はマシンや環境で変化するので、実際に使いたいUSBメモリのデバイスを割り当てたものを使ってください。(/dev/sdb,/dev/sddとかの場合もあり)
sudo gdsik -l /dev/sdc > usb_org_gdisk-l.txt

3.3.3 初期状態のフルバックアップ(USBメモリ)

  • 以下のコマンドで usborg.img.gz っていうファイル名でgzip圧縮したイメージをバックアップできます。
  • 私は32GのUSBメモリで以下のコマンドを実行した時数時間必要になりました。相当時間かかります。
  • パーティション情報から空のディスクを生成可能なので、このバックアップ作業をスキップしても良い
sudo cat /dev/sdc | gzip -9c > usb_org.img.gz

3.4 ディスクパーティション変更

  • 以下のコマンドでパーティションを変更するコマンドを実行
  • /dev/sdc はマシンや環境で変化するので、実際に使いたいUSBメモリのデバイスを割り当てたものを使ってください。(/dev/sdb,/dev/sddとかの場合もあり)
sudo gdisk /dev/sdc

3.4.1 gdisk 起動して、初期のパーティション確認、その後初期パーティション削除

$ sudo  gdisk /dev/sdc
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by
typing 'q' if you don't want to convert your MBR partitions
to GPT format!
***************************************************************

Warning! Main partition table overlaps the first partition by 2 blocks!
Try reducing the partition table size by 8 entries.
(Use the 's' item on the experts' menu.)

Warning! Secondary partition table overlaps the last partition by
33 blocks!
You will need to delete this partition or resize it in another utility.

Command (? for help): p
Disk /dev/sdc: 61741056 sectors, 29.4 GiB
Model: USB DISK        
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): CC3D509A-4DB7-47F6-B6BC-8A51B37DADEC
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 61741022
Partitions will be aligned on 32-sector boundaries
Total free space is 0 sectors (0 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              32        61741055   29.4 GiB    0700  Microsoft basic data

Command (? for help): d
Using 1

Command (? for help): p
Disk /dev/sdc: 61741056 sectors, 29.4 GiB
Model: USB DISK        
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): CC3D509A-4DB7-47F6-B6BC-8A51B37DADEC
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 61741022
Partitions will be aligned on 32-sector boundaries
Total free space is 61740989 sectors (29.4 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name

3.4.2 MBRパーティション作成

  • 設定変更
Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 1

Expert command (? for help): m
  • パーティション追加
Command (? for help): n
Partition number (1-128, default 1): 
First sector (34-61741022, default = 34) or {+-}size{KMGTP}: 
Last sector (34-61741022, default = 61741022) or {+-}size{KMGTP}: 2047
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): ef02
Changed type of partition to 'BIOS boot partition'

  • パーティション確認
Command (? for help): p
Disk /dev/sdc: 61741056 sectors, 29.4 GiB
Model: USB DISK        
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): CC3D509A-4DB7-47F6-B6BC-8A51B37DADEC
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 61741022
Partitions will be aligned on 1-sector boundaries
Total free space is 61738975 sectors (29.4 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition

  • 設定を元に戻す
Command (? for help): x

Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 

Expert command (? for help): m

3.4.3 ESP用パーティション作成

Command (? for help): n
Partition number (2-128, default 2): 
First sector (2048-61741022, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-61741022, default = 61741022) or {+-}size{KMGTP}: +500M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): ef00
Changed type of partition to 'EFI System'

  • パーティション確認
Command (? for help): p
Disk /dev/sdc: 61741056 sectors, 29.4 GiB
Model: USB DISK        
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): CC3D509A-4DB7-47F6-B6BC-8A51B37DADEC
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 61741022
Partitions will be aligned on 2048-sector boundaries
Total free space is 60714975 sectors (29.0 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048         1026047   500.0 MiB   EF00  EFI System

3.4.4 grub関係用パーティション作成

  • 動画ではパーティションサイズの前に+をいれてませんが、入れたらそのサイズのパーティションを割当可能です
Command (? for help): n
Partition number (3-128, default 3): 
First sector (1026048-61741022, default = 1026048) or {+-}size{KMGTP}: 
Last sector (1026048-61741022, default = 61741022) or {+-}size{KMGTP}: +600M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/sdc: 61741056 sectors, 29.4 GiB
Model: USB DISK        
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): CC3D509A-4DB7-47F6-B6BC-8A51B37DADEC
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 61741022
Partitions will be aligned on 2048-sector boundaries
Total free space is 59486175 sectors (28.4 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048         1026047   500.0 MiB   EF00  EFI System
   3         1026048         2254847   600.0 MiB   8300  Linux filesystem

3.4.5 データ用パーティション作成

  • 動画ではパーティションサイズの前に+をいれてませんが、入れたらそのサイズのパーティションを割当可能です
Command (? for help): n
Partition number (4-128, default 4): 
First sector (2254848-61741022, default = 2254848) or {+-}size{KMGTP}: 
Last sector (2254848-61741022, default = 61741022) or {+-}size{KMGTP}: 
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/sdc: 61741056 sectors, 29.4 GiB
Model: USB DISK        
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): CC3D509A-4DB7-47F6-B6BC-8A51B37DADEC
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 61741022
Partitions will be aligned on 2048-sector boundaries
Total free space is 0 sectors (0 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048         1026047   500.0 MiB   EF00  EFI System
   3         1026048         2254847   600.0 MiB   8300  Linux filesystem
   4         2254848        61741022   28.4 GiB    8300  Linux filesystem

3.4.6 変更書き込み

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sdc.
The operation has completed successfully.

3.5 作成した後のディスクパーティション確認

gdisk -l /dev/sdc

3.6 変更したパーティションのフォーマット

sudo /sbin/mkfs.vfat -F32 /dev/sdc2
sudo /sbin/mkfs.ext4  /dev/sdc3
sudo /sbin/mkfs.ext4  /dev/sdc4

3.7 grubのインストールMBR用

sudo mount /dev/sdc3 /mnt
sudo grub-install --target=i386-pc --boot-directory=/mnt/boot --force /dev/sdc

3.8 grubのインストールESP用

sudo mkdir /mnt/boot/efi
sudo mount /dev/sdc2 /mnt/boot/efi
sudo grub-install --target=x86_64-efi --efi-directory=/mnt/boot/efi --boot-directory=/mnt/boot

3.9 アンマウント

sudo umount /mnt/boot/efi
sudo umount /mnt

wget -m -l 1 http://releases.ubuntu.com/19.10/MD5SUMS http://releases.ubuntu.com/19.10/ubuntu-19.10-desktop-amd64.iso

cd releases.ubuntu.com/19.10/ cat MD5SUMS cat ubuntu-19.10-desktop-amd64.iso.md5sum

sudo mount /dev/sdc4 /mnt
sudo cp ubuntu-19.10-desktop-amd64.iso* /mnt/ISO/
sudo touch /mnt/ISO/usbMemoryBoot.txt 
sudo tree /mnt
sudo umount /mnt

3.10 grub.cfg を作成し適切な場所にコピー

insmod iso9660
insmod part_gpt
insmod fat
insmod ext2
insmod ext4

set dafault=0
set timeout=20

menuentry 'ubuntu-19.10-desktop-amd64.iso' {
    search --file --set isopart /ISO/usbMemoryBoot.txt 
    set isofile="/ISO/ubuntu-19.10-desktop-amd64.iso"
    loopback loop ($isopart)$isofile
    linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=$isofile debian-installer/language=ja keyboard-configuration/layoutcode?=jp keyboard-configuration/modelcode?=jp106 noeject quiet splash --
    initrd (loop)/casper/initrd.lz
}
  • コピーは以下のコマンドで
sudo mount /dev/sdc3 /mnt
sudo cp -i grub.cfg /mnt/boot/grub/
sudo umount /mnt

3.11 qemu でテスト

  • qemuをインストール設定済みでkvmを利用した場合は以下のコマンドで実行可能
  • /dev/sdc はマシンや環境で変化するので、実際に使いたいUSBメモリのデバイスを割り当てたものを使ってください。(/dev/sdb,/dev/sddとかの場合もあり)
  • qemuでなく実機で確認する方がよいかも
sudo kvm -m 1G -hda /dev/sdc

4 続きを追記してきます。

  • 初版 2019/10/23

著者: NM Max

Created: 2019-10-23 水 19:47

Validate

Android開発ツールadb便利すぎ

Android開発ツールadb便利すぎ

2 特徴

  • Androidの開発環境に含まれているツール
  • パッケージ管理や、バックアップ、ファイル転送、パッケージの転送、パッケージインストール、アンインストール、シェルの起動ナドナド色々できちゃいます。超便利!

3 インストール方法

3.1 UbuntuとかDebian

  • 以下のコマンドでインストール可能
sudo apt install adb
  • Android Studioをインストールしても含まれます

3.2 Windowsユーザー

  • Andorid Sdudioをインストールして、adb.exeをファイル検索で探してください。
  • 絶対パスで命令実行したくない場合、adb.exeの入っているディレクトリにパスを通す

4 事前準備

  • Android側の設定画面でusbデバッグを有効に設定する必要があります
  • 設定ツールをひらいて → システム → 詳細設定 → 開発者向けオプション → USBデバッグをオンに変更

5 スクリーンショット画像の一括転送

  • 以下の内容の copyScreenshots.sh を作成
#!/bin/bash
#adb shell find /sdcard/Movies/Screencasts/ -iname "*.mp4" | while read X
adb shell find /sdcard/Pictures/Screenshots/ -iname "Screenshot*"  -type f | while read X
do
  echo "adb pull \"$X\""
done
  • 以下のコマンドを実行
bash ./copyScreenshots.sh | bash
  • 以下のようにtmp.shを生成してから、エディタで内容を確認、必要なら修正して、実行するのでもOK
bash ./copyScreenshots.sh > tmp.sh
vi tmp.sh
bash ./tmp.sh

6 動画の一括転送

  • 以下の内容の copyMovies.sh を作成
#!/bin/bash
adb shell find /sdcard/Movies/Screencasts/ -iname "*.mp4" | while read X
do
  echo "adb pull \"$X\""
done
  • 以下のコマンドを実行
bash ./copyMovies.sh | bash
  • 以下のようにtmp.shを生成してから、エディタで内容を確認、必要なら修正して、実行するのでもOK
bash ./copyMovies.sh > tmp.sh
vi tmp.sh
bash ./tmp.sh

7 バックアップ

7.1 フルバックアップ

  • 私は以下のコマンドで実行してます
  • umidigi-f1-play-20190502.002.full.bk がバックアップファイルの名前、これは好きな名前にしてください
  • Android側の設定画面でusbデバッグを有効に設定する必要があります
adb backup -apk -shared -all -f umidigi-f1-play-20190502.002.full.bk
  • USB接続した時にUSBデバッグを承認するか確認画面がでるので、OKをタップ
  • 上の命令を入れると、Android側でパスワードいれて、バックアップするをタップすると操作開始
  • バックアップ終わるまでに操作しないようにしないと、私の場合途中で中断してる感じしました

7.2 アプリデータのバックアップ

7.2.1 パッケージ名の調査

adb shell pm list packages -f > info.txt
grep -i antiy info.txt
  • これで調べると私の場合以下でした

 

/data/app/yio.tro.antiyoy.android

7.2.2 アプリデータのバックアップ

adb backup yio.tro.antiyoy.android
  • 上のコマンドを実行すると backup.ab ファイルが生成されました
  • コマンド実行にはAndroid端末で開発モードをオンにする、承認操作、暗証番号を入れてのバックアップ承認操作が必要になりました

7.2.3 バックアップデータの解凍

  • ツールを使うことで backup.ab ファイルを解凍することができました

7.2.4 ツールのurl

java -jar abe.jar unpack backup.ab backup.tar
  • backup.tarをunarコマンドで解凍しました(tar xvf backup.tarでも解凍可能)
unar backup.tar

8 adbコマンドを利用したapkファイルの吸出しについて(Android)

  • adbはAndroidの開発環境をインストールするとインストールされるコマンド

8.1 パッケージ名の調査

adb shell pm list packages -f > info.txt
grep -i antiy info.txt
  • これで調べると私の場合以下でした

 

/data/app/yio.tro.antiyoy.android-yjqt8P2F_63BojDlz7eGeQ==/base.apk

8.2 apkの吸出し

  • 以下のコマンドでbase.apkを抜き出し出来ました。
  • 抜き出したapkを再度インストールするコマンドもあります
adb pull /data/app/yio.tro.antiyoy.android-yjqt8P2F_63BojDlz7eGeQ==/base.apk

9 スクリーンショットの転送

  • 以下のコマンドで一時ファイル作成せずにホスト側に画像ファイルを作成可能
adb exec-out screencap -p > screen.png

10 USBではなくネットで接続

10.1 接続手順

  1. usbで接続して
  2. 以下のコマンドで5555ポートでポート指定
adb tcpip 5555
  1. usbケーブルを外して以下のコマンド実行
adb connect device_ip_address
  1. テストでスクショ転送して接続確認
adb exec-out screencap -p > screen.png

10.2 端末側でのポートクローズ

  • 以下のコマンドで閉じれました
adb kill-server
  • 閉じたことを確認
adb devices

11 続きを追記してきます。

  • 初版 2019/09/26
  • スクショ、ネット接続追記 2019/09/27

著者: NM Max

Created: 2019-09-27 金 19:13

Validate

メッチャ楽しいシンプルルール、ゲームアプリAntiyoy攻略情報

メッチャ楽しいシンプルなゲームAntiyoy攻略情報

1 概要

  • 無料で、無課金、広告もなく、オープンソースで面白いという無敵のゲームアプリ!!!
  • Antiyoy-Screenshot005-icon.png アイコン
  • スマホアプリのゲーム
  • 陣取り
  • ターンベースのヘックス画面のゲーム
  • シンプルなのに、滅茶楽しい

3 ルール

3.1 ルールを説明したYoutube動画

  • この文書を説明した動画
  • この文書作るかなり前に作成した動画になります

3.1.1 ユニットの移動方法

3.1.2 ユニット雇用関係

3.1.3 タワー、ストロングタワーの建て方

3.1.4 ファームの建て方

3.1.5 操作のやり直し方(undo)

3.1.6 ターン終了

3.2 ルール概要

  • 何もない領地からは1ターン毎に1収入
  • farmAntiyoy-farm1.pngを領地にたてるとターン毎に+4収入
  • 弱いユニット同士を重ねると強いユニットに
  • 強いユニット程毎ターンお金を消費
  • お金がなくなると兵士がお墓に
  • お墓をほっておくと木が発生
  • 領地に木が生えると、その領地からの収入がなくなる
  • 木はユニットをかさねると伐採可能
  • 本拠地はユニット強さ2以上ないと破壊出来ない(拠点の移動できる先がある場合、破壊すると移動)

3.3 ユニット

  • 移動前のユニットを重ねあわせると強さ合計のユニットに変身可能(peasant+peasant で spearmanにとか、peasant + peasant + peasant でbaronとか)
  • 既存のユニットに新規を追加することで進化可能
  • ユニットで木の増殖ブロック可能
イメージ ユニット名 購入費 維持費 強さ
Antiyoy-man0.png peasant 10 2 1
Antiyoy-man1.png spearman 20 6 2
Antiyoy-man2.png baron 30 18 3
Antiyoy-man3.png knight 40 36 4

3.4 防御物

  • towerとかstrong towerで木の増殖ブロック可能
  • towerとかstrong towerの周囲はzone指定があり、そのユニットの領土が隣接している場合、その領域にはそれより強いユニットでないと侵入不可
  • ユニットの周囲はzone指定があり、そのユニットの領土が隣接している場合、その領域にはそれより強いユニットでないと侵入不可
イメージ ユニット名 購入費 維持費 破壊に必要なユニット強度
Antiyoy-tower.png tower 15 1 3
Antiyoy-strong_tower.png strong_tower 35 6 4

3.5 地形

イメージ ユニット名 収入 備考
Antiyoy-farm1.png farm +4 最初購入費用12、次から+2毎価格が上昇
Antiyoy-palm.png palm 0に  
Antiyoy-pine.png pine 0に  

3.6 ゲームマニュアルのスクリーンショット

3.6.1 ヘルプを押した時の画面

Antiyoy-Screenshot001-info.png

3.6.2 ゲーム内の文書のメニュー

Antiyoy-Screenshot010-help-Menu.png

3.6.3 ルール

Antiyoy-Screenshot011-help-Rules.png

3.6.4 ユニットの説明

Antiyoy-Screenshot012-help-Units.png

3.6.5 木の説明

Antiyoy-Screenshot013-help-Trees.png

3.6.6 Towerの説明

Antiyoy-Screenshot014-help-Towers.png

3.6.7 お金について

Antiyoy-Screenshot015-help-Money.png

3.6.8 戦術

Antiyoy-Screenshot015-help-Tactics.png

3.6.9 外交1

Antiyoy-Screenshot016-help-Diplomacy1.png

3.6.10 外交1

Antiyoy-Screenshot016-help-Diplomacy2.png

3.6.11 同じ作者の他の作品へのリンク

Antiyoy-Screenshot016-help-MyGames.png

4 adbコマンドを利用したゲームデータバックアップについて(Android)

  • adbはAndroidの開発環境をインストールするとインストールされるコマンド

4.1 パッケージ名の調査

adb shell pm list packages -f > info.txt
grep -i antiy info.txt 
  • これで調べると私の場合以下でした

 

/data/app/yio.tro.antiyoy.android

4.2 ゲームデータのバックアップ

adb backup yio.tro.antiyoy.android
  • 上のコマンドを実行すると backup.ab ファイルが生成されました
  • コマンド実行にはAndroid端末で開発モードをオンにする、承認操作、暗証番号を入れてのバックアップ承認操作が必要になりました

4.3 バックアップデータの解凍

  • ツールを使うことで backup.ab ファイルを解凍することができました

4.3.1 ツールのurl

java -jar abe.jar unpack backup.ab backup.tar
  • backup.tarをunarコマンドで解凍しました(tar xvf backup.tarでも解凍可能)
unar backup.tar

5 adbコマンドを利用したapkファイルの吸出しについて(Android)

  • adbはAndroidの開発環境をインストールするとインストールされるコマンド

5.1 パッケージ名の調査

adb shell pm list packages -f > info.txt
grep -i antiy info.txt 
  • これで調べると私の場合以下でした

 

/data/app/yio.tro.antiyoy.android-yjqt8P2F_63BojDlz7eGeQ==/base.apk

5.2 apkの吸出し

  • 以下のコマンドでbase.apkを抜き出し出来ました。
  • 抜き出したapkを再度インストールするコマンドもあります
adb pull /data/app/yio.tro.antiyoy.android-yjqt8P2F_63BojDlz7eGeQ==/base.apk

6 続きを追記してきます。

  • 初版 2019/09/26
  • 動画リンク追加、各種修正 2019/09/26
  • 説明動画追加、各種修正 2019/09/28

著者: NM Max

Created: 2019-09-28 土 16:04

Validate