From Json to PostgreSQL
This commit is contained in:
parent
00365460d4
commit
94b0f9f693
121
app.py
121
app.py
@ -1,32 +1,92 @@
|
||||
from flask import Flask, render_template, request, jsonify, send_from_directory
|
||||
import json
|
||||
from flask import Flask, render_template, request, jsonify
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import func
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
DATA_FILE = 'data/attendance_data.json'
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
# Default player names
|
||||
DEFAULT_PLAYERS = [
|
||||
"Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Hannah"
|
||||
]
|
||||
DEFAULT_GUEST = "Guest"
|
||||
# Models
|
||||
class Player(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(50), nullable=False, unique=True)
|
||||
|
||||
def load_data():
|
||||
if not os.path.exists(DATA_FILE):
|
||||
data = {
|
||||
"players": DEFAULT_PLAYERS,
|
||||
"guest": DEFAULT_GUEST,
|
||||
"dates": [],
|
||||
"attendance": {}
|
||||
}
|
||||
with open(DATA_FILE, 'w') as f:
|
||||
json.dump(data, f)
|
||||
with open(DATA_FILE, 'r') as f:
|
||||
return json.load(f)
|
||||
class Date(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
date_str = db.Column(db.String(20), nullable=False, unique=True) # e.g. '08/05/25'
|
||||
|
||||
def save_data(data):
|
||||
with open(DATA_FILE, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
class Attendance(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
date_id = db.Column(db.Integer, db.ForeignKey('date.id'), nullable=False)
|
||||
player_id = db.Column(db.Integer, db.ForeignKey('player.id'), nullable=False)
|
||||
status = db.Column(db.String(10), nullable=False) # 'yes' or 'no'
|
||||
|
||||
__table_args__ = (db.UniqueConstraint('date_id', 'player_id', name='_date_player_uc'),)
|
||||
|
||||
class GuestName(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
date_id = db.Column(db.Integer, db.ForeignKey('date.id'), nullable=False, unique=True)
|
||||
name = db.Column(db.String(50), nullable=False)
|
||||
|
||||
def get_initial_data():
|
||||
# Ensure tables exist
|
||||
db.create_all()
|
||||
# If no players, insert defaults
|
||||
if Player.query.count() == 0:
|
||||
for name in ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Hannah"]:
|
||||
db.session.add(Player(name=name))
|
||||
db.session.commit()
|
||||
if not GuestName.query.first():
|
||||
# Set default guest name for all dates
|
||||
pass
|
||||
|
||||
def db_to_json():
|
||||
players = [p.name for p in Player.query.order_by(Player.id)]
|
||||
guest = "Guest"
|
||||
dates = [d.date_str for d in Date.query.order_by(Date.id)]
|
||||
attendance = {}
|
||||
for att in Attendance.query.all():
|
||||
date = Date.query.get(att.date_id).date_str
|
||||
player = Player.query.get(att.player_id)
|
||||
colIdx = players.index(player.name) if player.name in players else len(players) # guest is last
|
||||
key = f"{date}|{colIdx}"
|
||||
attendance[key] = True if att.status == 'yes' else 'no'
|
||||
guest_names = {Date.query.get(g.date_id).date_str: g.name for g in GuestName.query.all()}
|
||||
return {
|
||||
"players": players,
|
||||
"guest": guest,
|
||||
"dates": dates,
|
||||
"attendance": attendance,
|
||||
"guestNames": guest_names
|
||||
}
|
||||
|
||||
def json_to_db(data):
|
||||
db.session.query(Attendance).delete()
|
||||
db.session.query(Date).delete()
|
||||
db.session.query(GuestName).delete()
|
||||
db.session.commit()
|
||||
# Players are assumed fixed
|
||||
for date_str in data.get("dates", []):
|
||||
date = Date(date_str=date_str)
|
||||
db.session.add(date)
|
||||
db.session.commit()
|
||||
# Attendance
|
||||
for idx, player_name in enumerate(data["players"] + [data["guest"]]):
|
||||
key = f"{date_str}|{idx}"
|
||||
status = data["attendance"].get(key)
|
||||
if status:
|
||||
if player_name == data["guest"]:
|
||||
# Guest is not stored as player, skip
|
||||
continue
|
||||
player = Player.query.filter_by(name=player_name).first()
|
||||
if player:
|
||||
db.session.add(Attendance(date_id=date.id, player_id=player.id, status='yes' if status is True else 'no'))
|
||||
# Guest name
|
||||
guest_name = data.get("guestNames", {}).get(date_str)
|
||||
if guest_name:
|
||||
db.session.add(GuestName(date_id=date.id, name=guest_name))
|
||||
db.session.commit()
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
@ -38,17 +98,26 @@ def reports():
|
||||
|
||||
@app.route('/api/data', methods=['GET'])
|
||||
def get_data():
|
||||
return jsonify(load_data())
|
||||
get_initial_data()
|
||||
return jsonify(db_to_json())
|
||||
|
||||
@app.route('/api/data', methods=['POST'])
|
||||
def update_data():
|
||||
data = request.json
|
||||
save_data(data)
|
||||
json_to_db(data)
|
||||
return jsonify({"status": "success"})
|
||||
|
||||
# Optional: export from DB as JSON (for compatibility)
|
||||
@app.route('/export-data')
|
||||
def export_data():
|
||||
return send_from_directory(directory='data', path='attendance_data.json', as_attachment=True)
|
||||
from flask import Response
|
||||
get_initial_data()
|
||||
data = db_to_json()
|
||||
return Response(
|
||||
response=json.dumps(data, indent=2),
|
||||
mimetype='application/json',
|
||||
headers={'Content-Disposition': 'attachment;filename=attendance_data.json'}
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
|
||||
@ -1 +1,3 @@
|
||||
flask
|
||||
sqlalchemy
|
||||
psycopg2-binary
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user