Files

174 lines
5.1 KiB
Python

from datetime import date, timedelta
from flask import Blueprint, jsonify, request
from server.auth import login_required
from server.db import get_db, now_iso
entries_bp = Blueprint("entries", __name__)
def row_to_dict(row):
return dict(row)
@entries_bp.get("/api/entries")
@login_required
def list_entries(user):
conn = get_db()
try:
rows = conn.execute(
"""
SELECT id, date, spanish, english, chinese, created_at, updated_at
FROM entries
WHERE user_id = ?
ORDER BY date DESC, id DESC
""",
(user["id"],),
).fetchall()
return jsonify([row_to_dict(r) for r in rows])
finally:
conn.close()
@entries_bp.post("/api/entries")
@login_required
def create_entry(user):
data = request.get_json(silent=True) or {}
spanish = (data.get("spanish") or "").strip()
if not spanish:
return jsonify({"error": "日记内容不能为空"}), 400
entry_date = (data.get("date") or date.today().isoformat()).strip()
conn = get_db()
try:
cur = conn.execute(
"""
INSERT INTO entries (user_id, date, spanish, english, chinese, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(
user["id"],
entry_date,
spanish,
(data.get("english") or "").strip(),
(data.get("chinese") or "").strip(),
now_iso(),
now_iso(),
),
)
conn.commit()
row = conn.execute(
"SELECT id, date, spanish, english, chinese, created_at, updated_at FROM entries WHERE id = ?",
(cur.lastrowid,),
).fetchone()
return jsonify(row_to_dict(row)), 201
finally:
conn.close()
@entries_bp.put("/api/entries/<int:entry_id>")
@login_required
def update_entry(user, entry_id):
data = request.get_json(silent=True) or {}
spanish = (data.get("spanish") or "").strip()
if not spanish:
return jsonify({"error": "日记内容不能为空"}), 400
conn = get_db()
try:
row = conn.execute(
"SELECT id FROM entries WHERE id = ? AND user_id = ?",
(entry_id, user["id"]),
).fetchone()
if row is None:
return jsonify({"error": "日记不存在或无权访问"}), 404
conn.execute(
"""
UPDATE entries
SET date = ?, spanish = ?, english = ?, chinese = ?, updated_at = ?
WHERE id = ?
""",
(
(data.get("date") or row["date"]).strip(),
spanish,
(data.get("english") or "").strip(),
(data.get("chinese") or "").strip(),
now_iso(),
entry_id,
),
)
conn.commit()
updated = conn.execute(
"SELECT id, date, spanish, english, chinese, created_at, updated_at FROM entries WHERE id = ?",
(entry_id,),
).fetchone()
return jsonify(row_to_dict(updated))
finally:
conn.close()
@entries_bp.delete("/api/entries/<int:entry_id>")
@login_required
def delete_entry(user, entry_id):
conn = get_db()
try:
row = conn.execute(
"SELECT id FROM entries WHERE id = ? AND user_id = ?",
(entry_id, user["id"]),
).fetchone()
if row is None:
return jsonify({"error": "日记不存在或无权访问"}), 404
conn.execute("DELETE FROM entries WHERE id = ?", (entry_id,))
conn.commit()
return jsonify({"ok": True})
finally:
conn.close()
@entries_bp.get("/api/entries/stats")
@login_required
def entry_stats(user):
conn = get_db()
try:
rows = conn.execute(
"""
SELECT date, spanish FROM entries
WHERE user_id = ?
""",
(user["id"],),
).fetchall()
total = len(rows)
total_chars = sum(len(r["spanish"]) for r in rows)
dates = [r["date"] for r in rows]
today = date.today()
month_start = today.replace(day=1)
week_start = today - timedelta(days=today.weekday())
month_count = sum(1 for d in dates if d >= month_start.isoformat())
week_count = sum(1 for d in dates if d >= week_start.isoformat())
streak = 0
cursor = today
if cursor.isoformat() not in dates:
cursor -= timedelta(days=1)
while cursor.isoformat() in dates:
streak += 1
cursor -= timedelta(days=1)
daily = []
for offset in range(6, -1, -1):
day = today - timedelta(days=offset)
daily.append({"date": day.isoformat(), "count": sum(1 for d in dates if d == day.isoformat())})
return jsonify(
{
"total": total,
"month": month_count,
"week": week_count,
"streak": streak,
"totalChars": total_chars,
"daily": daily,
}
)
finally:
conn.close()