NS高キャンパスの図書管理システム開発！

# Flaskを用いたCPの「図書管理システム開発」の概要
![SystemImg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/e6351992-8b1b-f224-0a1f-d9a791933189.png)

### 制作デモページ
制作中のものになりますが、９割型完成しています。
ngrokを使用したデモになるので、自宅でProgramを動かしてないときは止まります。
基本的にこの記事公開中は動かしっぱにしておく予定ですが、メンテナンスの影響で停止させることや想定外のエラーで停止する可能性があります。
データベースなどは、テスト用のデータなので、アカウント登録などは自由にやっていただいて大丈夫です。
https://frank-sole-boss.ngrok-free.app/


###  制作意図
筆者が通学するNS高等学校"F"キャンパスには３００冊以上の先輩や歴代のキャンパス長が寄贈していただいた本が多くあり、もっと管理を確実にしてより多くの人ひとに本の魅力を伝えたいという思いから制作を決意しました。

### 過去情報
本システムには、それ以前に使用されていたシステムを元に再度設計をしています。
[~~図書管理システムVersion1~~](https://github.com/n-s-fukuoka-cp-book/cp-book-management)→スプレッドシートの設計のため、使用非推奨
~~図書管理システムVersion2~~→システム設計中止
[図書管理システムVersion3(本システム)](https://github.com/MT472562/Library_Tool_Ver3)→製作途中のため、GitHubは限定公開

<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/42e7b912-5185-374d-bdeb-0d8d65c28918.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/0de2d8e9-b787-3532-8ba8-ecfbade88fec.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/c59c31f1-5126-06d5-51da-7fe8d4220c9b.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/cc1ba9f5-49f8-b746-e9b2-2b9d992e6484.png">

### 記事に関して
あまり詳しくないひとでも読みやすいようにロジック的なことは極力含まないようにしますね！！

# 環境

### 開発環境
- 開発環境は以下のとおりです。
- M1 MacBook Air （Windows10とラズパイOS　で動作確認中）
- Mac OS Ventura 13.4.1 → Sonoma 14.0
- Python3.11.4
- venvを使用


### 使用技術

| 技術名称          | 使用用途                                          |
|---------------|-----------------------------------------------|
| Python        | バックエンドの処理                            |
| SQLite3       | データの保存                  |
| HTML          | フロントエンドの構造全般              |
| JavaScript    | フロントエンドの処理全般 |
| CSS           | フロントエンドのデザイン全般 |

<details><summary>使用モジュールのリファレンスリンク</summary>

| パッケージ | バージョン | 公式リファレンスページ |
|------------|------------|------------------------|
| APScheduler | 3.10.1     | [APScheduler](https://apscheduler.readthedocs.io/en/stable/) |
| arrow      | 1.2.3      | [Arrow](https://arrow.readthedocs.io/en/latest/) |
| asgiref    | 3.7.2      | [asgiref](https://asgiref.readthedocs.io/en/latest/) |
| attrs      | 23.1.0     | [attrs](https://www.attrs.org/en/stable/) |
| blinker    | 1.6.2      | [blinker](https://pythonhosted.org/blinker/) |
| cachetools | 5.3.0      | [cachetools](https://cachetools.readthedocs.io/en/stable/) |
| certifi    | 2023.5.7   | [certifi](https://certifiio.readthedocs.io/en/latest/) |
| chardet    | 4.0.0      | [chardet](https://chardet.readthedocs.io/en/latest/) |
| charset-normalizer | 3.1.0  | [charset-normalizer](https://charset-normalizer.readthedocs.io/en/latest/) |
| click      | 8.1.3      | [Click](https://click.palletsprojects.com/en/8.x/) |
| crypto     | 1.4.1      | [python-crypto](https://python-crypto.readthedocs.io/en/latest/) |
| Django     | 4.2.3      | [Django](https://docs.djangoproject.com/en/4.2/) |
| django-scheduler | 0.10.1 | [django-scheduler](https://django-scheduler.readthedocs.io/en/latest/) |
| Flask      | 2.3.2      | [Flask](https://flask.palletsprojects.com/en/2.0.x/) |
| Flask-BasicAuth | 0.2.0  | [Flask-BasicAuth](https://flask-basicauth.readthedocs.io/en/latest/) |
| Flask-Dance | 7.0.0      | [Flask-Dance](https://flask-dance.readthedocs.io/en/latest/) |
| Flask-HTTPAuth | 4.8.0    | [Flask-HTTPAuth](https://flask-httpauth.readthedocs.io/en/latest/) |
| google-api-core | 2.11.0  | [google-api-core](https://googleapis.dev/python/google-api-core/latest/) |
| google-api-python-client | 2.86.0 | [google-api-python-client](https://developers.google.com/api-client-library/python) |
| google-auth | 2.18.1    | [google-auth](https://google-auth.readthedocs.io/en/latest/) |
| google-auth-httplib2 | 0.1.0 | [google-auth-httplib2](https://google-auth-httplib2.readthedocs.io/en/latest/) |
| google-auth-oauthlib | 1.0.0 | [google-auth-oauthlib](https://google-auth-oauthlib.readthedocs.io/en/latest/) |
| googleapis-common-protos | 1.59.0 | [googleapis-common-protos](https://googleapis.dev/python/protobuf/latest/) |
| httplib2   | 0.22.0     | [httplib2](https://httplib2.readthedocs.io/en/latest/) |
| icalendar  | 5.0.7      | [icalendar](https://icalendar.readthedocs.io/en/latest/) |
| ics        | 0.7.2      | [ics](https://icspy.readthedocs.io/en/stable/) |
| idna       | 2.10       | [idna](https://idna.readthedocs.io/en/latest/) |
| itsdangerous | 2.1.2    | [itsdangerous](https://itsdangerous.palletsprojects.com/en/2.0.x/) |
| Jinja2     | 3.1.2      | [Jinja2](https://jinja.palletsprojects.com/en/3.0.x/) |
| joblib     | 1.3.2      | [joblib](https://joblib.readthedocs.io/en/latest/) |
| Levenshtein | 0.21.0    | [python-Levenshtein](https://github.com/ztane/python-Levenshtein) |
| Markdown   | 3.4.3      | [Markdown](https://python-markdown.github.io/) |
| MarkupSafe | 2.1.2      | [MarkupSafe](https://markupsafe.palletsprojects.com/en/2.0.x/) |
| Naked      | 0.1.32     | [Naked](https://naked.readthedocs.io/en/latest/) |
| ngrok-api  | 0.10.0     | [ngrok-api](https://github.com/inconshreveable/ngrok/blob/master/docs/api.md) |
| nltk       | 3.8.1      | [NLTK](https://www.nltk.org/) |
| numpy      | 1.26.0     | [NumPy](https://numpy.org/doc/stable/) |
| oauthlib   | 3.2.2      | [oauthlib](https://oauthlib.readthedocs.io/en/latest/) |
| Pillow     | 9.5.0      | [Pillow](https://pillow.readthedocs.io/en/stable/) |
| protobuf   | 4.23.1     | [protobuf](https://developers.google.com/protocol-buffers/docs/pythontutorial) |
| pyasn1     | 0.5.0      | [pyasn1](https://pyasn1.readthedocs.io/en/latest/) |
| pyasn1-modules | 0.3.0   | [pyasn1-modules](https://pyasn1-modules.readthedocs.io/en/latest/) |
| pyparsing  | 3.0.9      | [pyparsing](https://pyparsing.palletsprojects.com/en/3.0.x/) |
| pypng      | 0.20220715.0 | [pypng](https://pypng.readthedocs.io/en/latest/) |
| python-barcode | 0.14.0 | [python-barcode](https://python-barcode.readthedocs.io/en/stable/) |
| python-dateutil | 2.8.2  | [python-dateutil](https://dateutil.readthedocs.io/en/stable/) |
| python-Levenshtein | 0.21.0 | [python-Levenshtein](https://github.com/ztane/python-Levenshtein) |
| pytz       | 2023.3     | [pytz](https://pythonhosted.org/pytz/) |
| PyYAML     | 6.0        | [PyYAML](https://pyyaml.org/wiki/PyYAMLDocumentation) |
| qrcode     | 7.4.2      | [qrcode](https://github.com/lincolnloop/python-qrcode) |
| rapidfuzz  | 3.0.0      | [rapidfuzz](https://rapidfuzz.readthedocs.io/en/latest/) |
| regex      | 2023.8.8   | [regex](https://regex.readthedocs.io/en/latest/) |
| requests   | 2.25.1     | [requests](https://docs.python-requests.org/en/master/) |
| requests-oauthlib | 1.3.1 | [requests-oauthlib](https://requests-oauthlib.readthedocs.io/en/latest/) |
| romkan     | 0.2.1      | [romkan](https://github.com/soimort/python-romkan) |
| rsa        | 4.9        | [rsa](https://stuvel.eu/python-rsa-doc/) |
| scikit-learn | 1.3.0    | [scikit-learn](https://scikit-learn.org/stable/documentation.html) |
| scipy      | 1.11.2     | [SciPy](https://docs.scipy.org/doc/scipy/reference/) |
| shellescape | 3.8.1     | [shellescape](https://pypi.org/project/shellescape/) |
| six        | 1.16.0     | [six](https://pypi.org/project/six/) |
| sqlparse   | 0.4.4      | [sqlparse](https://sqlparse.readthedocs.io/en/latest/) |
| TatSu      | 5.8.3      | [TatSu](https://tatsu.readthedocs.io/en/stable/) |
| threadpoolctl | 3.2.0   | [threadpoolctl](https://joblib.readthedocs.io/en/latest/externals.html#threadpoolctl) |
| tqdm       | 4.66.1     | [tqdm](https://tqdm.github.io/) |
| typing_extensions | 4.8.0 | [typing-extensions](https://docs.python.org/3/library/typing.html) |
| tzlocal    | 5.0.1      | [tzlocal](https://tzlocal.readthedocs.io/en/latest/) |
| uritemplate | 4.1.1     | [uritemplate](https://uritemplate.readthedocs.io/en/latest/) |
| urllib3    | 1.26.15    | [urllib3](https://urllib3.readthedocs.io/en/latest/) |
| URLObject  | 2.4.3      | [URLObject](https://github.com/zacharyvoase/urlobject) |
| Werkzeug   | 2.3.4      | [Werkzeug](https://werkzeug.palletsprojects.com/en/2.0.x/) |
</details>

# 利用
## メニューバー
<img width="80" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/6052e82c-429d-1e55-6c76-0865ab842f3d.png">
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/0ed9c7bf-3f6f-5f37-5235-6ecfe92fd487.png">


### 各種メニュー(上から順）
- トップページ
- アカウント
- 検索
- 貸出
- 返却
- 新本登録
- 棚卸し
- Info

### バックグラウンドイメージ変更
好きな背景色を選択することができます。
Cookieを使用してページ推移をしてもカラーを維持できるようになっています。

# headerの各メニューについて

## [トップページ](https://frank-sole-boss.ngrok-free.app/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/2b5367f6-29a5-8424-31d6-917894e86206.png)

### 機能
新しく購入した本を３冊紹介しています
紹介中の本をクリックするとほんの詳細ページへ移動できます。


## [アカウントページ](https://frank-sole-boss.ngrok-free.app/account)

<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/6279d865-2f6c-2e09-e8af-150a01be86c1.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/405c206f-899b-e85e-dc9d-98ef7aff607f.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/2bda5eeb-2db5-a433-d66e-74644b698330.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/d1865c0f-0f59-6e20-b104-75b137a91317.png">

### 機能
制作済みのアカウントでログインをしたり、アカウントの情報を更新するためのページです。

## [アカウント作成ページ](https://frank-sole-boss.ngrok-free.app/new_account)
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/1d7f1e11-222b-9cab-d0fa-7a70119c1f3c.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/4c87acd4-5237-59af-7cb4-22a002f1835d.png">
<iframe width="560" height="315" src="https://www.youtube.com/embed/dKLmapyHmP8?si=TIWQ54qusgdy88Gb" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

### 機能
新規でアカウントを登録するためのページです。
You Tubeにアカウントの作り方を詳細に説明した動画がアップロードされています。

## [パスワードのリセットページ](https://frank-sole-boss.ngrok-free.app/reset_account)
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/7fced62b-542c-1c6a-81e1-2bd26e2458b4.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/51cb4884-e374-62f1-0ab7-f692b256a49e.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/520bc1a5-f272-a1b6-f2bd-99554402ada2.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/f311260b-98d8-5a44-a436-91d93eef5fd5.png">

### 機能
パスワードやそもそもユーザーIDを忘れてしまった場合にでもすぐに解決できるようにパスワードのリセットページが設けてあります。


## [本の検索ページ](https://frank-sole-boss.ngrok-free.app/search)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/6a99b359-cfb9-6aad-19f5-1825b4f20db4.png)

### 機能
本の検索をするためのページです
デフォルトでは本のタイトルのみの検索ですがチェックマークを入れることで関連ワードなどから検索をすることができます
また、ISBNやバーコードから本を検索することが可能となります。
サジェスト機能を導入することでいち早く探している本を見つけることが可能になっています。


#### 以下が本の検索の例です!
実際にアクセスして違いを確認してみてください

[本のタイトルのみの絞り込みで”日本一”で検索](https://frank-sole-boss.ngrok-free.app/search?k=%E6%97%A5%E6%9C%AC%E4%B8%80)
[関連キーワードも含む絞り込みで”日本一”で検索](https://frank-sole-boss.ngrok-free.app/search?k=%E6%97%A5%E6%9C%AC%E4%B8%80&o=true)
[ISBNで検索](https://frank-sole-boss.ngrok-free.app/search?k=9784041098301&o=true)
[特殊コマンド(貸出中の本を絞り込む)](https://frank-sole-boss.ngrok-free.app/search?k=%24%E8%B2%B8%E5%87%BA%E4%B8%AD)



## [本の貸出ページ](https://frank-sole-boss.ngrok-free.app/lending)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/ee862ed8-bcf9-da45-89fb-4c312a6d46a3.png)

### 機能　
本の裏にあるバーコードを手入力または、バーコードリーダーまたは、WEBカメラ入力で読み込むことができます。
貸出ボタンを押すことでログイン中のアカウントで本を借りることができます。

## [本の返却ページ](https://frank-sole-boss.ngrok-free.app/return)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/8de115a5-1f54-b318-524c-38c90879e60b.png)


### 機能　
貸出時に付与された返却コードを読み込むことで本の返却ができます。
また、メールに貸出時に送信されているQRコードを用いてWEBカメラで読み取り本を返却することができます。
貸出時にICSファイル（カレンダーファイル）が自動生成されて送付されているので返却忘れを防ぐことが可能になっています。


## [新本登録ページページ](https://frank-sole-boss.ngrok-free.app/new-book)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/d8e15f5a-d658-ed95-493c-46d021612cbc.png)

### 機能
キャンパス図書に新しく追加した本を登録します。
管理番号は、キャンパスで印刷したバーコードのコードを登録します。
本の情報に関しては[GoogleBooksAPI](https://developers.google.com/books?hl=ja)を使用して、情報を取得し、自動で入力（結果がない場合のみ、手動で入力）するようになっています。
取得する情報は以下のとおりです
→ISBNを入力
Response:
- タイトル
- 著者
- ヘッダー文章
- サンプル画像URL
- ページ数
- 公開日

GoogleBooksAPIを使用することによって入力のミスなどを減らすことができるようになりました。

## [棚卸しページ](https://frank-sole-boss.ngrok-free.app/inventory)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/935186b7-ed57-1092-754d-6023b6318333.png)

### 機能
このページでは棚卸しを行うことができます。
年に一度図書委員会では、蔵書されている本が、今も本棚にあるかどうかを確認するためにすべての本のバーコードを読み取り、データの整合性が取れているのかを確認します。
すべてのスキャンが終了したら、以下のようなCSVデータをダウンロードすることができます。
```tex
ID,管理コード,ISBNコード,書籍名,蔵書状況
1,10000013,9784781651033,福岡はすごい,在庫確認
2,10000020,9784121022820,地方消滅,在庫不足
3,10000107,9784052051715,なぜ僕らは働くのか,在庫確認
4,10000008,9784062200172,ミライの授業,在庫あり
5,10000209,9784844365174,なるほどデザイン,在庫不足
6,10000007,9784838729470,漫画君たちはどう生きるか,在庫不足
7,10000068,9784478470886,餃子屋と高級フレンチでは、どちらが儲かるか?,在庫不足
8,10000088,9784344033597,いま君に伝えたいお金の話,在庫不足
9,10000006,9784479393245,僕らが生きているよのなかのしくみは「法」でわかる,在庫確認
10,10000441,9784335357923,こども六法,在庫不足
11,10000041,9784794969552,11歳からの正しく怖がるインターネット,在庫確認
12,10000057,9784865014228,岩田さん　岩田聡はこんなことを話していた。,在庫不足
13,10000063,9784763135667,「孤独」は消せる。,在庫確認
14,10000061,9784866630625,サイボーグ時代,在庫確認
15,10000042,9784040642734,ありのままに生きてます,在庫不足
16,10000001,9784478105870,プレゼン資料のデザイン図鑑,在庫確認
17,10000054,9784775311073,ストーリーの作り方,在庫不足
18,10000052,9784297105129,ゲームプランナー入門アイデア・企画書・仕様書の技術から就職まで,在庫確認
19,10000050,9784862464149,クリエイターのための権利の本,在庫確認
20,10000028,9784062206624,デザインの仕事,在庫確認
```


## [infoページ](https://frank-sole-boss.ngrok-free.app/info)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/e7d3a38b-705e-e8a8-4bc0-7e5311b9ca2c.png)

### 機能
このページではヘルプページへのアクセスや貸出ランキングの表示などをしています。



# 上級管理メニュー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/f05dbc87-5fee-8c7b-5083-c80c0a60b5c2.png)

上級の管理メニュー　主にシステム自体の設定を開くには、Digest認証をクリアした後、図書管理システムのユーザー登録でアクセス権限レベル4以上の場合のみアクセスができるようになっています。

今回は以下のメニューに付いて可能な限り説明したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/e2dfec02-3fb8-be01-4bc3-6ecc3b11a903.png)

## DB操作ログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/e487fe08-2e9c-edc7-c66f-8f378c719fd3.png)

この機能は、データベースへの操作を行った際に、どのユーザーがなんの操作をしたのかを記録します。
履歴には保存等級を1-3でつけ
```
1 - 1ヶ月保存  (ユーザーのログインやメール送信など)
2 - 1年保存   （パスワードリセットのリクエストや本の貸出など）
3 - 永久保存   （アカウントの作成や本の登録・削除など）
```
の形で分けています。

また、絞り込み機能を取り付けて以下のような項目を組み合わせてログを特定しやすくなっています。
-　範囲検索（開始日付：終了日付)
-　保存等級　(1〜3)
-　フリーワード　（”削除”などのワード）

ログを残すことで、エラーが起きた際に原因を早急に見つけることが可能になります。


## ユーザー管理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/bca23e80-67f7-d9dd-a958-22b1d211dbd7.png)

この機能ではアカウント登録をしているユーザーを一覧で確認することができます。
この機能から直接ポイント操作を行ったり、ユーザーに対してメールを送信する事ができるようになっています。
利用用途としては、ポイントデータの訂正や、GoogleFormsから問い合わせいただいた内容を返信する場合に使用することを考えています。

## 貸出管理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/035bd1d5-5fc2-9330-290b-6cb39a97e5f7.png)


この機能ではどのユーザーがなんの本をいつ借りたのかを確認することができます。
また、手動で貸出状態を返却済みの状態に変更したり、または逆のことをすることができるようになっています。
利用用途としては、誤って返却してしまった場合に貸出状態に復元をしてあげることが可能になります。

## 蔵書管理と本の情報更新
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/5ed3add7-b637-5cf4-4258-b5f8f05467ae.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/47a2143d-43d7-51a4-0a94-78f9e907a3a8.png">

この機能では蔵書している本のデータを更新したり、追加したり削除したりすることができるようになっています。
現在は300冊前後が蔵書されています。
本のタイトルなどを誤って登録していた場合などに訂正をすることができます。
また、廃書になった場合に削除をすることができます。


## システムログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/783192c3-2280-c972-ce8f-b15cbe252ecb.png)

この機能では、Flaskが出力するログを保存しているfileをダウンロードすることができます。
実際に以下のようなデータが保存されています。
```log
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:54321
 * Running on http://10.7.100.81:54321
2023-12-08 10:15:18,555 - werkzeug - INFO - [33mPress CTRL+C to quit[0m
2023-12-08 10:15:20,129 - pyngrok.process.ngrok - INFO - t=2023-12-08T10:15:20+0900 lvl=info msg="join connections" obj=join id=55860bbbf481 l=127.0.0.1:54321 r=125.103.68.146:53300
2023-12-08 10:15:20,133 - main - INFO - 127.0.0.1
2023-12-08 10:15:20,133 - main - INFO - 127.0.0.1/32
2023-12-08 10:15:20,141 - werkzeug - INFO - 127.0.0.1 - - [08/Dec/2023 10:15:20] "GET /account HTTP/1.1" 200 -
2023-12-08 10:15:20,187 - pyngrok.process.ngrok - INFO - t=2023-12-08T10:15:20+0900 lvl=info msg="update available" obj=updater
2023-12-08 10:15:20,224 - pyngrok.process.ngrok - INFO - t=2023-12-08T10:15:20+0900 lvl=info msg="join connections" obj=join id=b7569c1bac6c l=127.0.0.1:54321 r=125.103.68.146:53300
2023-12-08 10:15:20,224 - pyngrok.process.ngrok - INFO - t=2023-12-08T10:15:20+0900 lvl=info msg="join connections" obj=join id=22f0e89e8e7b l=127.0.0.1:54321 r=125.103.68.146:53300
2023-12-08 10:15:20,227 - main - INFO - 127.0.0.1
2023-12-08 10:15:20,228 - main - INFO - 127.0.0.1
2023-12-08 10:15:20,228 - main - INFO - 127.0.0.1/32
2023-12-08 10:15:20,228 - main - INFO - 127.0.0.1/32
```

Flaskが出力するログを確認することで、システムの詳細エラーを確認し、システムの改善につなげることが可能となります。



## エラー設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/2f792a91-f609-39bd-f12c-f6d812e634a3.png)

この機能では、エラーページに出力するエラーの内容を確認・変更することができるようになっています。
案内方法に変更があった際に速やかに反映させることができるようになります。


## メンテナンス・データベースバックアップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/a8abf219-d141-f98e-78c6-8b0c6c4d183d.png)

この機能では、システムのメンテナンスやデータベースのフルバックアップを行うことができます。
定期的にメンテナンスを行うことで、不要なログデータを削除したり、処理漏れする可能性があるデータのクリーンアップをすることができます。

データベースのバックアップを取ることで、データが紛失する可能性を減らすことが可能になります。


## セキュリティのお話
- ユーザーのアカウント登録時に、パスワードはランダムなソルトと連結した状態でSHA-512のハッシュ化をされています。

- アカウントログイン試行回数が記録されており、パスワードを5回間違えると、パスワードのリセットをしないとログインできなくなるように成っています。※画像１

- 上級管理メニューはDigest認証が実装されており、固有のユーザーIDとパスワードを知らないと入ることができなくなっています。　※画像2

- 全てのページに置いてIPアドレスによるフィルタリングを実施しており、指定されたIPアドレス以外からのアクセスは、全てブロックすることができます。※画像3/4


<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/8010cf00-2a32-ea89-f71b-e20896a0a5d7.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/1d13209e-de78-3f85-8577-d7acf5f1a4b6.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/fc367ee8-56c4-98a6-4b6f-f0c314cb84f2.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/e9c24384-a406-4d80-c82a-7a296ab5b25a.png">

### 補足
ip_gps_data.jsonの値に以下の値を追加するとIPフィルタリングを無効化することができます。
```json 
  "ip_host3": [
    "999.99.999",
    "aaa.bbb.ccc.ddd"
  ]
```

## システムアップデート

[システムアップデート配信サーバー](https://github.com/MT472562/Library_Tool_Ver3_Update_Server)から配信されるデータとシステムバージョンを比較してアップデートがあるシステムファイルのアップデートを行います。

<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/f8f419d8-8c65-e632-c4ff-2c003d7ec9d4.png">
<img width="49%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538359/df3ff9de-d13f-a05c-f61e-c744223b0e28.png">

```json
{
  "next_url": "https://raw.githubusercontent.com/MT472562/Library_Tool_Ver3_Update_Server/main/",
  "version_data": "https://raw.githubusercontent.com/MT472562/Library_Tool_Ver3_Update_Server/main/system_version.json",
  "SystemVersion": 1.1,
  "spare": "spare",
  "spare": "spare",
  "make_directory": [],
  "main.py": 1.1,
  "Maintenance.py": 1.0,
  "database_reset.py": 1.0,
  "Install_check.py": 1.0,
  "templates/resources/css/base.css": 1.1,
  "templates/resources/css/style.css": 1.0,
  ".......その他システム構成ファイル"
}
```



# プロジェクトを通して

色々なプロジェクトを同時並行しながらで、なんやかんやで１年近くここに来るまで時間がかかったけれども、今はRaspberryPiにデプロイして自分の卒業制作として、キャンパスに残していければいいな。。と思っています。