ファイル名:「main.py」更新日:2024/12/21

2024年12月21日土曜日

source code 公開

t f B! P L

     



 
#******************************************************************************#
# ファイル名:main.py
# バージョン:p0001 Ver1.0
# 機能:
# 作成日:2024/11/25
# 更新日:2024/12/21 W009
#*******************************************************************************#

import os
import json
from flask import Flask, render_template, request, redirect, Response # --- 追加 2-1 render_template 追加 6-1 request 追加 9 redirect, Response
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required #--- 追加 9 事前に $ pip install flask-login でインストール # 仮想環境の場合はpipenv
from flask_sqlalchemy import SQLAlchemy  #--- 追加 9 事前に $ pip install flask_sqlalchemy  でインストール # 仮想環境の場合はpipenv
from werkzeug.security import generate_password_hash, check_password_hash #--- 追加 9 パスワードのハッシュ化
from KDpay import PayManager #--- 追加 7-1

file_path = 'KDjson.json'

app = Flask(__name__)

# DB設定 #--- 追加 9
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///user_flask.db'
app.config['SECRET_KEY'] = os.urandom(24) # パスワード設定 #--- 追加 9
db = SQLAlchemy(app) # DB設定 #--- 追加 9

login_manager = LoginManager()
login_manager.init_app(app)
# login_manager.login_view = "users.login" # login_viewのrouteを設定

# ユーザーDBの作成 #--- 追加 9
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(255), nullable=False, unique=True)
    password = db.Column(db.String(255))

# 認証ユーザーの呼び出し方を定義する  #--- 追加 9
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# ------------------------------------------------------------------------------ #
#
# ------------------------------------------------------------------------------ #
@app.route('/')
def hello_show():
    return 'Hello World!'

# ------------------------------------------------------------------------------ #
#
# ------------------------------------------------------------------------------ #
@app.route('/index')
def index():
    insert_dict = {
        'insert_1': 'insert_1部分です。',
        'insert_2': 'insert_2部分です。',
    }
    return render_template('index.html', title='Webアプリテスト', insert_dict=insert_dict)
# ------------------------------------------------------------------------------ #
#  ユーザー管理  #--- 追加 9
# ------------------------------------------------------------------------------ #
'''''''''''''''''
signup
'''''''''''''''''
@app.route('/signup', methods=['GET', 'POST'])
def signup():
    if request.method == "POST":
        username = request.form.get('username')
        password = request.form.get('password')
        # Userのインスタンスを作成
        user = User(username=username, password=password)
        # hashを使用する場合(def login():も修正必要箇所あり)
        # user = User(username=username, password=generate_password_hash(password, method='pbkdf2:sha256'))        
        db.session.add(user)
        db.session.commit()
        return redirect('login')
    else:
        return render_template('signup.html')
'''''''''''''''''
login
'''''''''''''''''
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == "POST":
        username = request.form.get('username')
        password = request.form.get('password')
        # Userテーブルからusernameに一致するユーザを取得
        user = User.query.filter_by(username=username).first()
        if user.password == password:
        # hashを使用する場合(def signup()も修正必要箇所あり)
        # if check_password_hash(user.password, password):
            login_user(user)
            return redirect('/kakeibo') # 家計簿へ
        else:
            # 入力したユーザー名のパスワードが間違っている場合
            # return "<p>パスワードが間違っています。</p>"
            return Response(status=404, response="ページが見つかりません。")
       
    else:
        return render_template('login.html')
'''''''''''''''''
logout
'''''''''''''''''
@app.route('/logout')
@login_required # ログインしているユーザーのみに制限 #--- 追加 9
def logout():
    logout_user()
    return redirect('login')


# ------------------------------------------------------------------------------ #
# 家計簿
# ------------------------------------------------------------------------------ #
@app.route('/kakeibo', methods=['GET', 'POST']) #--- 修正6-1
@login_required # ログインしているユーザーのみに制限 #--- 追加 9
def kd():
    # 既存ファイルを確認
    if not os.path.exists(file_path):
        # 無ければ作成
        with open( file_path, mode='w', encoding="UTF-8" ) as open_json:
            initial_list = [{
                            "month"   : []  , # "月"
                            "day"     : []  , # "日"
                            "content" : []  , # "内訳"
                            "amount"  : []    # "金額"
            } ]
            json.dump( initial_list, open_json, indent=4, ensure_ascii=False)

    # ペイ(収支)データ管理用クラス(KDpay.py)オブジェクト作成  #--- 追加7
    pay_manager = PayManager()

    # JSONファイルを読み込んで、辞書型リストを作成
    with open( file_path, mode='r', encoding="UTF-8") as open_json:
        json_load_list = json.load(open_json)

    # 読み込んだファイルをペイ(収支)データ管理用クラスオブジェクトに追加 --- 修正7
    for pay_data in json_load_list:
        pay_manager.add_pay(pay_data)


#### HTTPリクエスト GETメソッド受信 # --- 修正6
    if request.method == 'GET':
        # 更新した辞書型リストを送信し、HTMLをレンダリング        
        return render_template('kakeibo_test_json/kd.html', title='kakeibo', pay_list=pay_manager.pay_data_list) #--- 修正7-4  json_load_list → pay_manager.pay_data_list

#### HTTPリクエスト POSTメソッド受信 「削除」ボタンが押されたときの処理  # --- 追加 7
    if request.method == 'POST' and request.form.get('delete_number') != None :
        # 入力された削除番号を整数型に変換、リストの要素番号が0から始まるため1マイナス
        number = int( request.form.get('delete_number') ) - 1
        pay_manager.delete_pay(number)

        # JSONファイルに書き込み --- 修正7
        with open(file_path, mode='w',encoding="UTF-8") as open_json:
            updated_data_list=[]
            for pay in pay_manager.pay_data_list:
                updated_data_list.append({
                                    "month":   pay.month,              
                                    "day":     pay.day,
                                    "content": pay.content,
                                    "amount":  pay.amount
                })
            json.dump(updated_data_list, open_json ,indent=4,ensure_ascii=False)

        # 更新した辞書型リストを送信し、HTMLをレンダリング
        return render_template('kakeibo_test_json/kd.html', title='kakeibo', pay_list=pay_manager.pay_data_list)# 修正7-4  json_load_list → pay_manager.pay_data_list

#### HTTPリクエスト POSTメソッド受信 「送信」ボタンが押されたときの処理 # --- 追加6-2
    if request.method == 'POST':
        # 画面上で入力された情報を取得し、辞書データを作成
        add_dict = {"month":request.form.get('month'),
                    "day":request.form.get('day'),
                    "content":request.form.get('content'),
                    "amount":request.form.get('amount')
                   }
       
        # 辞書データを辞書型リスト(PayManagerオブジェクト)に追加
        pay_manager.add_pay(add_dict) #--- 修正7-5 (前)  json_load_list.append(add_dict)

        # JSONファイルに書き込み # --- 修正7-6
        with open(file_path, mode='w',encoding="UTF-8") as open_json:
            updated_data_list=[]
            for pay in pay_manager.pay_data_list:
                updated_data_list.append({
                                    "month":   pay.month,              
                                    "day":     pay.day,
                                    "content": pay.content,
                                    "amount":  pay.amount
                })
            json.dump(updated_data_list, open_json ,indent=4,ensure_ascii=False)

        # 更新した辞書型リストを送信し、HTMLをレンダリング
        return render_template('kakeibo_test_json/kd.html', title='kakeibo', pay_list=pay_manager.pay_data_list)# 修正7-4  json_load_list → pay_manager.pay_data_list


# ------------------------------------------------------------------------------ #
#
# ------------------------------------------------------------------------------ #

if __name__ == '__main__':
    app.run()


 

 

 

このブログを検索

アーカイブ

カテゴリー

QooQ