monitor-app 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- monitor_app-0.1.0/LICENSE +6 -0
- monitor_app-0.1.0/PKG-INFO +177 -0
- monitor_app-0.1.0/README.md +149 -0
- monitor_app-0.1.0/monitor_app/__init__.py +0 -0
- monitor_app-0.1.0/monitor_app/app.py +87 -0
- monitor_app-0.1.0/monitor_app/cli.py +180 -0
- monitor_app-0.1.0/monitor_app/config/__pycache__/config.cpython-313.pyc +0 -0
- monitor_app-0.1.0/monitor_app/config/config.py +95 -0
- monitor_app-0.1.0/monitor_app/csv/data.csv +5 -0
- monitor_app-0.1.0/monitor_app/csv/data_sub.csv +5 -0
- monitor_app-0.1.0/monitor_app/csv/data_sub_2.csv +5 -0
- monitor_app-0.1.0/monitor_app/csv/orders.csv +6 -0
- monitor_app-0.1.0/monitor_app/csv/products.csv +4 -0
- monitor_app-0.1.0/monitor_app/csv/users.csv +6 -0
- monitor_app-0.1.0/monitor_app/csv_to_db.py +85 -0
- monitor_app-0.1.0/monitor_app/instances/database.db +0 -0
- monitor_app-0.1.0/monitor_app/instances/test_database.db +0 -0
- monitor_app-0.1.0/monitor_app/static/css/bootstrap.min.css +6 -0
- monitor_app-0.1.0/monitor_app/static/favicon.ico +0 -0
- monitor_app-0.1.0/monitor_app/static/js/bootstrap.bundle.min.js +7 -0
- monitor_app-0.1.0/monitor_app/templates/base.html +45 -0
- monitor_app-0.1.0/monitor_app/templates/index.html +14 -0
- monitor_app-0.1.0/monitor_app/templates/table.html +40 -0
- monitor_app-0.1.0/pyproject.toml +41 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: monitor-app
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A simple Flask-based database viewer and manager
|
|
5
|
+
Home-page: https://github.com/hardwork9047/monitor-app
|
|
6
|
+
License: MIT
|
|
7
|
+
Author: hardwork9047
|
|
8
|
+
Author-email: tomatosimple1104@gmail.com
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Requires-Dist: click (>=8.1.3,<9.0.0)
|
|
17
|
+
Requires-Dist: flask (>=3.1.0,<4.0.0)
|
|
18
|
+
Requires-Dist: flask-cors (>=4.0.0,<5.0.0)
|
|
19
|
+
Requires-Dist: flask-sqlalchemy (>=3.1.1,<4.0.0)
|
|
20
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
|
21
|
+
Requires-Dist: psycopg2-binary (>=2.9.10,<3.0.0)
|
|
22
|
+
Requires-Dist: pymysql (>=1.1.0,<2.0.0)
|
|
23
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
24
|
+
Project-URL: Documentation, https://github.com/hardwork9047/monitor-app
|
|
25
|
+
Project-URL: Repository, https://github.com/hardwork9047/monitor-app
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# Monitor App 🚀
|
|
29
|
+
|
|
30
|
+
Monitor App は、CSV データをデータベースに取り込み、Web ブラウザで閲覧できるシンプルなアプリケーションです。
|
|
31
|
+
SQLite / MySQL / PostgreSQL に対応し、Django のように `startproject` コマンドでプロジェクトを作成できます。
|
|
32
|
+
|
|
33
|
+
## 📌 特徴
|
|
34
|
+
- `monitor-app startproject` で新しいプロジェクトを作成
|
|
35
|
+
- CSV データをデータベースに簡単にインポート
|
|
36
|
+
- Web UI でデータを表示
|
|
37
|
+
- `Flask-SQLAlchemy` を使用し、SQLite / MySQL / PostgreSQL に対応
|
|
38
|
+
- Bootstrap を使用したスタイリッシュな UI
|
|
39
|
+
- `config.py` でカスタマイズ可能
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 🚀 インストール方法
|
|
44
|
+
`pip install` で簡単にインストールできます。
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pip install monitor-app
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 🔧 使い方
|
|
53
|
+
|
|
54
|
+
### **1️⃣ 新しいプロジェクトを作成**
|
|
55
|
+
```sh
|
|
56
|
+
monitor-app startproject my_project
|
|
57
|
+
```
|
|
58
|
+
➡ `my_project` フォルダに Flask アプリのテンプレートが作成されます。
|
|
59
|
+
|
|
60
|
+
### **2️⃣ CSV をデータベースに登録**
|
|
61
|
+
```sh
|
|
62
|
+
cd my_project
|
|
63
|
+
monitor-app import-csv
|
|
64
|
+
```
|
|
65
|
+
➡ `csv/` フォルダの CSV をデータベースに登録します。
|
|
66
|
+
|
|
67
|
+
### **3️⃣ Web アプリを起動**
|
|
68
|
+
```sh
|
|
69
|
+
monitor-app runserver
|
|
70
|
+
```
|
|
71
|
+
➡ `http://127.0.0.1:9990` にアクセス!
|
|
72
|
+
|
|
73
|
+
### **📌 `runserver` のオプション**
|
|
74
|
+
| オプション | 説明 |
|
|
75
|
+
|------------|--------------------------------|
|
|
76
|
+
| `--csv` | CSV を登録してから起動する |
|
|
77
|
+
| `--debug` | デバッグモードで起動する |
|
|
78
|
+
| `--port <PORT>` | ポートを指定する(デフォルト: 9990) |
|
|
79
|
+
|
|
80
|
+
📌 **例: CSV を登録後に起動**
|
|
81
|
+
```sh
|
|
82
|
+
monitor-app runserver --csv
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
📌 **例: デバッグモードでポート `8000` で起動**
|
|
86
|
+
```sh
|
|
87
|
+
monitor-app runserver --debug --port 8000
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 📂 フォルダ構成
|
|
93
|
+
```sh
|
|
94
|
+
my_project/
|
|
95
|
+
│── monitor_app/
|
|
96
|
+
│ ├── app.py # Flask アプリのメインファイル
|
|
97
|
+
│ ├── config.py # 設定ファイル
|
|
98
|
+
│ ├── csv_to_db.py # CSV をデータベースにインポートするスクリプト
|
|
99
|
+
│ ├── templates/ # HTML テンプレート
|
|
100
|
+
│ ├── static/ # CSS / JavaScript / 画像
|
|
101
|
+
│ ├── csv/ # CSV データを保存するフォルダ
|
|
102
|
+
│ ├── instances/ # データベースの保存先
|
|
103
|
+
│── pyproject.toml # Poetry の設定ファイル
|
|
104
|
+
│── README.md # このファイル
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 🔧 `config.py` の設定
|
|
110
|
+
プロジェクトの設定は `monitor_app/config.py` で変更できます。
|
|
111
|
+
|
|
112
|
+
📌 **データベースの設定**
|
|
113
|
+
```python
|
|
114
|
+
# SQLite(デフォルト)
|
|
115
|
+
SQLALCHEMY_DATABASE_URI = "sqlite:///instances/database.db"
|
|
116
|
+
|
|
117
|
+
# MySQL を使用する場合
|
|
118
|
+
# SQLALCHEMY_DATABASE_URI = "mysql+pymysql://user:password@localhost/dbname"
|
|
119
|
+
|
|
120
|
+
# PostgreSQL を使用する場合
|
|
121
|
+
# SQLALCHEMY_DATABASE_URI = "postgresql://user:password@localhost/dbname"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
📌 **カスタムテーブルと JOIN の設定**
|
|
125
|
+
```python
|
|
126
|
+
ALLOWED_TABLES = {
|
|
127
|
+
"users": {"columns": ["id", "name", "email"], "primary_key": "id"},
|
|
128
|
+
"products": {"columns": ["id", "name", "price"], "primary_key": "id"},
|
|
129
|
+
"orders": {
|
|
130
|
+
"columns": ["id", "user_id", "product_id", "amount"],
|
|
131
|
+
"primary_key": "id",
|
|
132
|
+
"foreign_keys": {"user_id": "users.id", "product_id": "products.id"},
|
|
133
|
+
"join": '''
|
|
134
|
+
SELECT orders.id, users.name AS user_name, products.name AS product_name, orders.amount
|
|
135
|
+
FROM orders
|
|
136
|
+
JOIN users ON orders.user_id = users.id
|
|
137
|
+
JOIN products ON orders.product_id = products.id
|
|
138
|
+
''',
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 📌 `monitor-app` の CLI コマンド一覧
|
|
146
|
+
| コマンド | 説明 |
|
|
147
|
+
|------------|----------------------------------|
|
|
148
|
+
| `monitor-app startproject <name>` | 新しいプロジェクトを作成 |
|
|
149
|
+
| `monitor-app import-csv` | CSV をデータベースに登録 |
|
|
150
|
+
| `monitor-app runserver` | Web アプリを起動 |
|
|
151
|
+
| `monitor-app runserver --csv` | CSV 登録後に起動 |
|
|
152
|
+
| `monitor-app runserver --port <PORT>` | 指定ポートで起動 |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 📌 必要な環境
|
|
157
|
+
- Python 3.10+
|
|
158
|
+
- `Flask`, `Flask-SQLAlchemy`, `pandas`, `click`
|
|
159
|
+
- `Poetry` (開発環境)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 📌 ライセンス
|
|
164
|
+
MIT ライセンスのもとで提供されています。
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 📌 貢献
|
|
169
|
+
Pull Request 大歓迎!🚀
|
|
170
|
+
バグ報告や改善提案もお待ちしています!
|
|
171
|
+
|
|
172
|
+
🔗 **GitHub:** [Monitor App Repository](https://github.com/hardwork9047/monitor-app)
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
✅ **これで `monitor-app` を簡単にインストール&利用できるようになります!** 🚀
|
|
177
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Monitor App 🚀
|
|
2
|
+
|
|
3
|
+
Monitor App は、CSV データをデータベースに取り込み、Web ブラウザで閲覧できるシンプルなアプリケーションです。
|
|
4
|
+
SQLite / MySQL / PostgreSQL に対応し、Django のように `startproject` コマンドでプロジェクトを作成できます。
|
|
5
|
+
|
|
6
|
+
## 📌 特徴
|
|
7
|
+
- `monitor-app startproject` で新しいプロジェクトを作成
|
|
8
|
+
- CSV データをデータベースに簡単にインポート
|
|
9
|
+
- Web UI でデータを表示
|
|
10
|
+
- `Flask-SQLAlchemy` を使用し、SQLite / MySQL / PostgreSQL に対応
|
|
11
|
+
- Bootstrap を使用したスタイリッシュな UI
|
|
12
|
+
- `config.py` でカスタマイズ可能
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 🚀 インストール方法
|
|
17
|
+
`pip install` で簡単にインストールできます。
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
pip install monitor-app
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🔧 使い方
|
|
26
|
+
|
|
27
|
+
### **1️⃣ 新しいプロジェクトを作成**
|
|
28
|
+
```sh
|
|
29
|
+
monitor-app startproject my_project
|
|
30
|
+
```
|
|
31
|
+
➡ `my_project` フォルダに Flask アプリのテンプレートが作成されます。
|
|
32
|
+
|
|
33
|
+
### **2️⃣ CSV をデータベースに登録**
|
|
34
|
+
```sh
|
|
35
|
+
cd my_project
|
|
36
|
+
monitor-app import-csv
|
|
37
|
+
```
|
|
38
|
+
➡ `csv/` フォルダの CSV をデータベースに登録します。
|
|
39
|
+
|
|
40
|
+
### **3️⃣ Web アプリを起動**
|
|
41
|
+
```sh
|
|
42
|
+
monitor-app runserver
|
|
43
|
+
```
|
|
44
|
+
➡ `http://127.0.0.1:9990` にアクセス!
|
|
45
|
+
|
|
46
|
+
### **📌 `runserver` のオプション**
|
|
47
|
+
| オプション | 説明 |
|
|
48
|
+
|------------|--------------------------------|
|
|
49
|
+
| `--csv` | CSV を登録してから起動する |
|
|
50
|
+
| `--debug` | デバッグモードで起動する |
|
|
51
|
+
| `--port <PORT>` | ポートを指定する(デフォルト: 9990) |
|
|
52
|
+
|
|
53
|
+
📌 **例: CSV を登録後に起動**
|
|
54
|
+
```sh
|
|
55
|
+
monitor-app runserver --csv
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
📌 **例: デバッグモードでポート `8000` で起動**
|
|
59
|
+
```sh
|
|
60
|
+
monitor-app runserver --debug --port 8000
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 📂 フォルダ構成
|
|
66
|
+
```sh
|
|
67
|
+
my_project/
|
|
68
|
+
│── monitor_app/
|
|
69
|
+
│ ├── app.py # Flask アプリのメインファイル
|
|
70
|
+
│ ├── config.py # 設定ファイル
|
|
71
|
+
│ ├── csv_to_db.py # CSV をデータベースにインポートするスクリプト
|
|
72
|
+
│ ├── templates/ # HTML テンプレート
|
|
73
|
+
│ ├── static/ # CSS / JavaScript / 画像
|
|
74
|
+
│ ├── csv/ # CSV データを保存するフォルダ
|
|
75
|
+
│ ├── instances/ # データベースの保存先
|
|
76
|
+
│── pyproject.toml # Poetry の設定ファイル
|
|
77
|
+
│── README.md # このファイル
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 🔧 `config.py` の設定
|
|
83
|
+
プロジェクトの設定は `monitor_app/config.py` で変更できます。
|
|
84
|
+
|
|
85
|
+
📌 **データベースの設定**
|
|
86
|
+
```python
|
|
87
|
+
# SQLite(デフォルト)
|
|
88
|
+
SQLALCHEMY_DATABASE_URI = "sqlite:///instances/database.db"
|
|
89
|
+
|
|
90
|
+
# MySQL を使用する場合
|
|
91
|
+
# SQLALCHEMY_DATABASE_URI = "mysql+pymysql://user:password@localhost/dbname"
|
|
92
|
+
|
|
93
|
+
# PostgreSQL を使用する場合
|
|
94
|
+
# SQLALCHEMY_DATABASE_URI = "postgresql://user:password@localhost/dbname"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
📌 **カスタムテーブルと JOIN の設定**
|
|
98
|
+
```python
|
|
99
|
+
ALLOWED_TABLES = {
|
|
100
|
+
"users": {"columns": ["id", "name", "email"], "primary_key": "id"},
|
|
101
|
+
"products": {"columns": ["id", "name", "price"], "primary_key": "id"},
|
|
102
|
+
"orders": {
|
|
103
|
+
"columns": ["id", "user_id", "product_id", "amount"],
|
|
104
|
+
"primary_key": "id",
|
|
105
|
+
"foreign_keys": {"user_id": "users.id", "product_id": "products.id"},
|
|
106
|
+
"join": '''
|
|
107
|
+
SELECT orders.id, users.name AS user_name, products.name AS product_name, orders.amount
|
|
108
|
+
FROM orders
|
|
109
|
+
JOIN users ON orders.user_id = users.id
|
|
110
|
+
JOIN products ON orders.product_id = products.id
|
|
111
|
+
''',
|
|
112
|
+
},
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 📌 `monitor-app` の CLI コマンド一覧
|
|
119
|
+
| コマンド | 説明 |
|
|
120
|
+
|------------|----------------------------------|
|
|
121
|
+
| `monitor-app startproject <name>` | 新しいプロジェクトを作成 |
|
|
122
|
+
| `monitor-app import-csv` | CSV をデータベースに登録 |
|
|
123
|
+
| `monitor-app runserver` | Web アプリを起動 |
|
|
124
|
+
| `monitor-app runserver --csv` | CSV 登録後に起動 |
|
|
125
|
+
| `monitor-app runserver --port <PORT>` | 指定ポートで起動 |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 📌 必要な環境
|
|
130
|
+
- Python 3.10+
|
|
131
|
+
- `Flask`, `Flask-SQLAlchemy`, `pandas`, `click`
|
|
132
|
+
- `Poetry` (開発環境)
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 📌 ライセンス
|
|
137
|
+
MIT ライセンスのもとで提供されています。
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 📌 貢献
|
|
142
|
+
Pull Request 大歓迎!🚀
|
|
143
|
+
バグ報告や改善提案もお待ちしています!
|
|
144
|
+
|
|
145
|
+
🔗 **GitHub:** [Monitor App Repository](https://github.com/hardwork9047/monitor-app)
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
✅ **これで `monitor-app` を簡単にインストール&利用できるようになります!** 🚀
|
|
File without changes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import os
|
|
3
|
+
import subprocess # ✅ `csv_to_db.py` を実行するために追加
|
|
4
|
+
from flask import Flask, render_template, abort
|
|
5
|
+
from flask_cors import CORS
|
|
6
|
+
from flask_sqlalchemy import SQLAlchemy
|
|
7
|
+
from sqlalchemy import text
|
|
8
|
+
from monitor_app.config.config import (
|
|
9
|
+
SQLALCHEMY_DATABASE_URI,
|
|
10
|
+
SQLALCHEMY_TRACK_MODIFICATIONS,
|
|
11
|
+
ALLOWED_TABLES,
|
|
12
|
+
APP_TITLE,
|
|
13
|
+
HEADER_TEXT,
|
|
14
|
+
FOOTER_TEXT,
|
|
15
|
+
FAVICON_PATH, # ✅ Favicon を追加
|
|
16
|
+
TABLE_CELL_STYLES,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
app = Flask(__name__)
|
|
20
|
+
CORS(app)
|
|
21
|
+
|
|
22
|
+
# 設定を `config.py` から読み込む
|
|
23
|
+
app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
|
|
24
|
+
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = SQLALCHEMY_TRACK_MODIFICATIONS
|
|
25
|
+
|
|
26
|
+
db = SQLAlchemy(app)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@app.route("/")
|
|
30
|
+
def index():
|
|
31
|
+
"""トップページ"""
|
|
32
|
+
tables = list(ALLOWED_TABLES.keys()) # 📌 許可されたテーブルのみ表示
|
|
33
|
+
return render_template(
|
|
34
|
+
"index.html",
|
|
35
|
+
tables=tables,
|
|
36
|
+
app_title=APP_TITLE,
|
|
37
|
+
header_text=HEADER_TEXT,
|
|
38
|
+
footer_text=FOOTER_TEXT,
|
|
39
|
+
favicon_path=FAVICON_PATH, # ✅ Favicon を追加
|
|
40
|
+
title=APP_TITLE, # ✅ タイトルを設定
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@app.route("/table/<table_name>")
|
|
45
|
+
def show_table(table_name):
|
|
46
|
+
"""指定されたテーブルのデータを表示"""
|
|
47
|
+
if table_name not in ALLOWED_TABLES: # 📌 許可されていないテーブルは 404
|
|
48
|
+
abort(404)
|
|
49
|
+
|
|
50
|
+
table_info = ALLOWED_TABLES[table_name]
|
|
51
|
+
|
|
52
|
+
# 📌 `join` 設定があれば JOIN クエリを実行
|
|
53
|
+
query = (
|
|
54
|
+
text(table_info["join"])
|
|
55
|
+
if "join" in table_info
|
|
56
|
+
else text(f"SELECT * FROM {table_name}")
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
result = db.session.execute(query)
|
|
60
|
+
columns = result.keys()
|
|
61
|
+
data = [dict(zip(columns, row)) for row in result.fetchall()]
|
|
62
|
+
|
|
63
|
+
return render_template(
|
|
64
|
+
"table.html",
|
|
65
|
+
table_name=table_name,
|
|
66
|
+
columns=columns,
|
|
67
|
+
data=data,
|
|
68
|
+
cell_styles=TABLE_CELL_STYLES,
|
|
69
|
+
app_title=APP_TITLE,
|
|
70
|
+
header_text=HEADER_TEXT,
|
|
71
|
+
footer_text=FOOTER_TEXT,
|
|
72
|
+
favicon_path=FAVICON_PATH, # ✅ Favicon を追加
|
|
73
|
+
title=f"{table_name} - {APP_TITLE}", # ✅ タイトルを設定
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def run_server(host="0.0.0.0", port=9990, debug=False):
|
|
78
|
+
"""Flask Web アプリを起動"""
|
|
79
|
+
app.run(host=host, port=port, debug=debug)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def main():
|
|
83
|
+
run_server()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
if __name__ == "__main__":
|
|
87
|
+
main()
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import subprocess
|
|
4
|
+
import click
|
|
5
|
+
import toml
|
|
6
|
+
from monitor_app.app import run_server # `app.py` の `run_server()` を直接呼び出す
|
|
7
|
+
|
|
8
|
+
# TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "monitor_app")
|
|
9
|
+
PARENT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
10
|
+
MONITOR_APP_DIR = os.path.dirname(__file__)
|
|
11
|
+
CONFIG_DIR = os.path.join(MONITOR_APP_DIR, "config")
|
|
12
|
+
CSV_DIR = os.path.join(MONITOR_APP_DIR, "csv")
|
|
13
|
+
TEMPLATES_DIR = os.path.join(MONITOR_APP_DIR, "templates")
|
|
14
|
+
STATIC_DIR = os.path.join(MONITOR_APP_DIR, "static")
|
|
15
|
+
STATIC_CSS_DIR = os.path.join(STATIC_DIR, "css")
|
|
16
|
+
STATIC_JS_DIR = os.path.join(STATIC_DIR, "js")
|
|
17
|
+
PYPROJECT_TEMPLATE = os.path.join(MONITOR_APP_DIR, "pyproject.toml")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@click.group()
|
|
21
|
+
def cli():
|
|
22
|
+
"""Monitor App CLI ツール"""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@click.command()
|
|
27
|
+
@click.argument("project_name")
|
|
28
|
+
def startproject(project_name):
|
|
29
|
+
"""新しい Monitor App プロジェクトを作成"""
|
|
30
|
+
project_path = os.path.abspath(project_name)
|
|
31
|
+
|
|
32
|
+
if os.path.exists(project_path):
|
|
33
|
+
click.echo(f"⚠️ 既に '{project_name}' が存在します!")
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
# 📂 プロジェクトフォルダ作成
|
|
37
|
+
os.makedirs(project_path)
|
|
38
|
+
|
|
39
|
+
# 📂 monitor_app アプリフォルダ作成
|
|
40
|
+
DEST_MONITOR_APP_DIR = os.path.join(project_path, "monitor_app")
|
|
41
|
+
DEST_PARENT_DIR = os.path.dirname(DEST_MONITOR_APP_DIR)
|
|
42
|
+
DEST_CONFIG_DIR = os.path.join(DEST_MONITOR_APP_DIR, "config")
|
|
43
|
+
DEST_CSV_DIR = os.path.join(DEST_MONITOR_APP_DIR, "csv")
|
|
44
|
+
DEST_INSTANCES_DIR = os.path.join(DEST_MONITOR_APP_DIR, "instances")
|
|
45
|
+
DEST_TEMPLATES_DIR = os.path.join(DEST_MONITOR_APP_DIR, "templates")
|
|
46
|
+
DEST_STATIC_DIR = os.path.join(DEST_MONITOR_APP_DIR, "static")
|
|
47
|
+
DEST_STATIC_CSS_DIR = os.path.join(DEST_STATIC_DIR, "css")
|
|
48
|
+
DEST_STATIC_JS_DIR = os.path.join(DEST_STATIC_DIR, "js")
|
|
49
|
+
os.makedirs(DEST_MONITOR_APP_DIR)
|
|
50
|
+
|
|
51
|
+
# 📂 CSV・インスタンスフォルダ作成
|
|
52
|
+
os.makedirs(DEST_CSV_DIR, exist_ok=True)
|
|
53
|
+
os.makedirs(DEST_CONFIG_DIR, exist_ok=True)
|
|
54
|
+
os.makedirs(DEST_INSTANCES_DIR, exist_ok=True)
|
|
55
|
+
os.makedirs(DEST_TEMPLATES_DIR, exist_ok=True)
|
|
56
|
+
os.makedirs(DEST_STATIC_JS_DIR, exist_ok=True)
|
|
57
|
+
os.makedirs(DEST_STATIC_CSS_DIR, exist_ok=True)
|
|
58
|
+
|
|
59
|
+
# 📄 `project_template` からファイルをコピー
|
|
60
|
+
monitor_app_files = ["app.py", "cli.py", "csv_to_db.py"]
|
|
61
|
+
for file in monitor_app_files:
|
|
62
|
+
src_path = os.path.join(MONITOR_APP_DIR, file)
|
|
63
|
+
dest_path = os.path.join(DEST_MONITOR_APP_DIR, file)
|
|
64
|
+
if os.path.exists(src_path):
|
|
65
|
+
shutil.copy(src_path, dest_path)
|
|
66
|
+
else:
|
|
67
|
+
click.echo(
|
|
68
|
+
f"⚠️ {file} が `project_template` に見つかりません。スキップします。"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
config_files = ["config.py"]
|
|
72
|
+
for file in config_files:
|
|
73
|
+
src_path = os.path.join(CONFIG_DIR, file)
|
|
74
|
+
dest_path = os.path.join(DEST_CONFIG_DIR, file)
|
|
75
|
+
if os.path.exists(src_path):
|
|
76
|
+
shutil.copy(src_path, dest_path)
|
|
77
|
+
else:
|
|
78
|
+
click.echo(
|
|
79
|
+
f"⚠️ {file} が `project_template` に見つかりません。スキップします。"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
templates_files = ["base.html", "index.html", "table.html"]
|
|
83
|
+
for file in templates_files:
|
|
84
|
+
src_path = os.path.join(TEMPLATES_DIR, file)
|
|
85
|
+
dest_path = os.path.join(DEST_TEMPLATES_DIR, file)
|
|
86
|
+
if os.path.exists(src_path):
|
|
87
|
+
shutil.copy(src_path, dest_path)
|
|
88
|
+
else:
|
|
89
|
+
click.echo(
|
|
90
|
+
f"⚠️ {file} が `project_template` に見つかりません。スキップします。"
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
css_files = ["bootstrap.min.css"]
|
|
94
|
+
for file in css_files:
|
|
95
|
+
src_path = os.path.join(STATIC_CSS_DIR, file)
|
|
96
|
+
dest_path = os.path.join(DEST_STATIC_CSS_DIR, file)
|
|
97
|
+
if os.path.exists(src_path):
|
|
98
|
+
shutil.copy(src_path, dest_path)
|
|
99
|
+
else:
|
|
100
|
+
click.echo(
|
|
101
|
+
f"⚠️ {file} が `project_template` に見つかりません。スキップします。"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
js_files = ["bootstrap.bundle.min.js"]
|
|
105
|
+
for file in js_files:
|
|
106
|
+
src_path = os.path.join(STATIC_JS_DIR, file)
|
|
107
|
+
dest_path = os.path.join(DEST_STATIC_JS_DIR, file)
|
|
108
|
+
if os.path.exists(src_path):
|
|
109
|
+
shutil.copy(src_path, dest_path)
|
|
110
|
+
else:
|
|
111
|
+
click.echo(
|
|
112
|
+
f"⚠️ {file} が `project_template` に見つかりません。スキップします。"
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# 📄 Favicon コピー
|
|
116
|
+
favicon_src = os.path.join(MONITOR_APP_DIR, "static/favicon.ico")
|
|
117
|
+
favicon_dest = os.path.join(DEST_MONITOR_APP_DIR, "static/favicon.ico")
|
|
118
|
+
if os.path.exists(favicon_src):
|
|
119
|
+
shutil.copy(favicon_src, favicon_dest)
|
|
120
|
+
else:
|
|
121
|
+
click.echo(
|
|
122
|
+
"⚠️ favicon.ico が `project_template` に見つかりません。スキップします。"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
parent_files = ["pyproject.toml"]
|
|
126
|
+
for file in parent_files:
|
|
127
|
+
src_path = os.path.join(PARENT_DIR, file)
|
|
128
|
+
dest_path = os.path.join(DEST_PARENT_DIR, file)
|
|
129
|
+
if os.path.exists(src_path):
|
|
130
|
+
shutil.copy(src_path, dest_path)
|
|
131
|
+
else:
|
|
132
|
+
click.echo(
|
|
133
|
+
f"⚠️ {file} が `project_template` に見つかりません。スキップします。"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def run_command(command_list):
|
|
138
|
+
"""
|
|
139
|
+
📌 poetry がインストールされていれば `poetry run` を使用し、なければ `python` を使用
|
|
140
|
+
"""
|
|
141
|
+
if shutil.which("poetry"):
|
|
142
|
+
command_list.insert(0, "poetry")
|
|
143
|
+
command_list.insert(1, "run")
|
|
144
|
+
else:
|
|
145
|
+
command_list.insert(0, "python")
|
|
146
|
+
|
|
147
|
+
subprocess.run(command_list, check=True)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@click.command()
|
|
151
|
+
@click.option("--host", default="0.0.0.0", help="ホストアドレス")
|
|
152
|
+
@click.option("--port", default=9990, help="ポート番号")
|
|
153
|
+
@click.option("--csv", is_flag=True, help="CSV をデータベースに登録してから起動")
|
|
154
|
+
@click.option("--debug", is_flag=True, help="デバッグモードを有効化")
|
|
155
|
+
def runserver(host, port, csv, debug):
|
|
156
|
+
"""Flask Web アプリを起動"""
|
|
157
|
+
|
|
158
|
+
if csv:
|
|
159
|
+
click.echo("🔄 CSV をデータベースに登録中...")
|
|
160
|
+
run_command(["monitor_app/csv_to_db.py"])
|
|
161
|
+
click.echo("✅ CSV 登録完了!アプリを起動します...")
|
|
162
|
+
|
|
163
|
+
click.echo(f"🚀 Web アプリを {host}:{port} で起動")
|
|
164
|
+
run_server(host=host, port=port, debug=debug) # `run_server()` を直接呼び出す
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@click.command()
|
|
168
|
+
def import_csv():
|
|
169
|
+
"""CSV をデータベースにインポート"""
|
|
170
|
+
click.echo("📂 CSV をデータベースに登録中...")
|
|
171
|
+
run_command(["monitor_app/csv_to_db.py"])
|
|
172
|
+
click.echo("✅ CSV 登録完了!")
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
cli.add_command(startproject)
|
|
176
|
+
cli.add_command(runserver)
|
|
177
|
+
cli.add_command(import_csv)
|
|
178
|
+
|
|
179
|
+
if __name__ == "__main__":
|
|
180
|
+
cli()
|
|
Binary file
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
# 📌 プロジェクトのルートディレクトリ
|
|
4
|
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
5
|
+
|
|
6
|
+
# 📌 インスタンスディレクトリ(データベースの保存先)
|
|
7
|
+
INSTANCE_DIR = os.path.join(BASE_DIR, "instances")
|
|
8
|
+
os.makedirs(INSTANCE_DIR, exist_ok=True)
|
|
9
|
+
|
|
10
|
+
# 📌 使用するデータベースの種類(sqlite, mysql, postgresql)
|
|
11
|
+
DB_TYPE = "sqlite"
|
|
12
|
+
|
|
13
|
+
# 📌 SQLite のカスタムパス設定(None にするとデフォルトを使用)
|
|
14
|
+
CUSTOM_SQLITE_DB_PATH = None
|
|
15
|
+
|
|
16
|
+
# 📌 CSV ファイルの保存ディレクトリ
|
|
17
|
+
DEFAULT_CSV_DIR = os.path.join(BASE_DIR, "csv")
|
|
18
|
+
CUSTOM_CSV_DIR = None
|
|
19
|
+
|
|
20
|
+
CSV_DIR = os.path.abspath(CUSTOM_CSV_DIR) if CUSTOM_CSV_DIR else DEFAULT_CSV_DIR
|
|
21
|
+
os.makedirs(CSV_DIR, exist_ok=True)
|
|
22
|
+
|
|
23
|
+
# 📌 各データベースの接続設定
|
|
24
|
+
if DB_TYPE == "sqlite":
|
|
25
|
+
if CUSTOM_SQLITE_DB_PATH:
|
|
26
|
+
DB_PATH = os.path.abspath(CUSTOM_SQLITE_DB_PATH)
|
|
27
|
+
else:
|
|
28
|
+
DB_PATH = os.path.join(INSTANCE_DIR, "database.db")
|
|
29
|
+
|
|
30
|
+
SQLALCHEMY_DATABASE_URI = f"sqlite:///{DB_PATH}"
|
|
31
|
+
|
|
32
|
+
elif DB_TYPE == "mysql":
|
|
33
|
+
MYSQL_USER = "root"
|
|
34
|
+
MYSQL_PASSWORD = "password"
|
|
35
|
+
MYSQL_HOST = "localhost"
|
|
36
|
+
MYSQL_PORT = "3306"
|
|
37
|
+
MYSQL_DB = "monitor_app"
|
|
38
|
+
|
|
39
|
+
SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DB}"
|
|
40
|
+
|
|
41
|
+
elif DB_TYPE == "postgresql":
|
|
42
|
+
POSTGRES_USER = "postgres"
|
|
43
|
+
POSTGRES_PASSWORD = "password"
|
|
44
|
+
POSTGRES_HOST = "localhost"
|
|
45
|
+
POSTGRES_PORT = "5432"
|
|
46
|
+
POSTGRES_DB = "monitor_app"
|
|
47
|
+
|
|
48
|
+
SQLALCHEMY_DATABASE_URI = f"postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}:{POSTGRES_PORT}/{POSTGRES_DB}"
|
|
49
|
+
|
|
50
|
+
else:
|
|
51
|
+
raise ValueError(f"Unsupported DB_TYPE: {DB_TYPE}")
|
|
52
|
+
|
|
53
|
+
# 📌 SQLAlchemy 設定
|
|
54
|
+
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
55
|
+
|
|
56
|
+
# 📌 許可されたテーブルのみを表示
|
|
57
|
+
ALLOWED_TABLES = {
|
|
58
|
+
"users": {"columns": ["id", "name", "email"], "primary_key": "id"},
|
|
59
|
+
"products": {"columns": ["id", "name", "price"], "primary_key": "id"},
|
|
60
|
+
"orders": {
|
|
61
|
+
"columns": ["id", "user_id", "product_id", "amount"],
|
|
62
|
+
"primary_key": "id",
|
|
63
|
+
"foreign_keys": {"user_id": "users.id", "product_id": "products.id"},
|
|
64
|
+
"join": """
|
|
65
|
+
SELECT orders.id, users.name AS user_name, products.name AS product_name, orders.amount
|
|
66
|
+
FROM orders
|
|
67
|
+
JOIN users ON orders.user_id = users.id
|
|
68
|
+
JOIN products ON orders.product_id = products.id
|
|
69
|
+
""",
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# 📌 ヘッダーとフッターの設定
|
|
74
|
+
APP_TITLE = "Monitor App"
|
|
75
|
+
HEADER_TEXT = "📊 Monitor Dashboard"
|
|
76
|
+
FOOTER_TEXT = "© 2025 Monitor App - Powered by Flask & Bootstrap"
|
|
77
|
+
FAVICON_PATH = "favicon.ico"
|
|
78
|
+
|
|
79
|
+
# 📌 **テーブルセルのスタイル**
|
|
80
|
+
TABLE_CELL_STYLES = {
|
|
81
|
+
"orders": {
|
|
82
|
+
"amount": {
|
|
83
|
+
"greater_than": {"value": 10, "class": "bg-danger text-white"},
|
|
84
|
+
"less_than": {"value": 5, "class": "bg-warning text-dark"},
|
|
85
|
+
"equal_to": {"value": 7, "class": "bg-success text-white"},
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"products": {
|
|
89
|
+
"price": {
|
|
90
|
+
"greater_than": {"value": 1000, "class": "bg-primary text-white"},
|
|
91
|
+
"less_than": {"value": 500, "class": "bg-info text-dark"},
|
|
92
|
+
"equal_to": {"value": 750, "class": "bg-secondary text-white"},
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
}
|