from datetime import date, timedelta from flask import Blueprint, jsonify, request from .auth import login_required from .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/") @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/") @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()