from flask import Flask, render_template, jsonify from datetime import datetime, timezone, timedelta import os from dotenv import load_dotenv load_dotenv() import db from clients import jellyfin app = Flask(__name__) PHT = timezone(timedelta(hours=8)) def current_week(): """Return (week_start, week_end, cutoff_utc) for the current week in PHT. week_start = most recent Sunday (PHT date) week_end = that Sunday + 6 days (Saturday) cutoff_utc = Sunday 00:00 PHT expressed in UTC (= Saturday 16:00 UTC) """ now_pht = datetime.now(PHT) days_since_sunday = (now_pht.weekday() + 1) % 7 sunday_midnight_pht = (now_pht - timedelta(days=days_since_sunday)).replace( hour=0, minute=0, second=0, microsecond=0 ) week_start = sunday_midnight_pht.date() week_end = week_start + timedelta(days=6) cutoff_utc = sunday_midnight_pht.astimezone(timezone.utc) return week_start, week_end, cutoff_utc def format_date_range(week_start, week_end) -> str: """Format date range: 'Feb 8-14' (same month) or 'Mar 29 - Apr 4' (different).""" if week_start.month == week_end.month: return f"{week_start.strftime('%b %-d')}-{week_end.strftime('%-d')}" return f"{week_start.strftime('%b %-d')} - {week_end.strftime('%b %-d')}" @app.route("/") def index(): week_start, week_end, _ = current_week() config = { "JELLYFIN_HOST": os.environ.get("JELLYFIN_HOST", ""), "JELLYFIN_API_KEY": os.environ.get("JELLYFIN_API_KEY", ""), "JELLYFIN_USER_ID": os.environ.get("JELLYFIN_USER_ID", ""), "TOTAL_EPISODES": os.environ.get("TOTAL_EPISODES", "1155"), "DB_PATH": os.environ.get("DB_PATH", "/app/data/episodes.db"), } return render_template( "index.html", week_start=week_start.isoformat(), week_end=week_end.isoformat(), date_range=format_date_range(week_start, week_end), config=config, ) @app.route("/api/report") def report(): week_start, week_end, cutoff_utc = current_week() total_episodes = int(os.environ.get("TOTAL_EPISODES", 1155)) try: ep_info = jellyfin.find_last_one_piece_before(cutoff_utc) except Exception as e: return jsonify({"error": str(e)}), 502 db.save_episode( episode_number=ep_info["episode_number"], week_start=week_start.isoformat(), week_end=week_end.isoformat(), item_id=ep_info.get("item_id"), media_name=ep_info.get("media_name"), watched_at=ep_info.get("watched_at"), ) prev = db.get_previous_episode(week_start.isoformat()) previous_episode = prev["episode_number"] if prev else ep_info["episode_number"] watched_this_week = ep_info["episode_number"] - previous_episode date_range = format_date_range(week_start, week_end) report_text = ( f"ONE PIECE PROGRESS!!! ({date_range})\n" f"Episode {ep_info['episode_number']}/{total_episodes}\n" f"Around {watched_this_week} episodes watched this week!" ) return jsonify({ "week_start": week_start.isoformat(), "week_end": week_end.isoformat(), "date_range": date_range, "latest_episode": ep_info["episode_number"], "previous_episode": previous_episode, "watched_this_week": watched_this_week, "total_episodes": total_episodes, "media_name": ep_info.get("media_name"), "watched_at": ep_info.get("watched_at"), "report": report_text, }) @app.route("/api/history") def history(): return jsonify(db.get_all_history()) if __name__ == "__main__": db.init_db() port = int(os.environ.get("PORT", 5000)) app.run(host="0.0.0.0", port=port, debug=False)