Files
WebChecker--Web-app-/routes/user_dashboard.py
T
2026-06-04 13:25:57 -04:00

120 lines
4.2 KiB
Python

"""
routes/user_dashboard.py — Regular user: shift check dashboard.
"""
import logging
import time
import requests as _http_req
from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify
from models import (
get_today_checks, mark_website_checked, unmark_website_checked,
update_check_note, get_user_active_shifts, get_website_credentials,
get_website_url, log_action,
)
from utils.decorators import login_required
logger = logging.getLogger("routes.user_dashboard")
user_dashboard_bp = Blueprint("user_dashboard", __name__, url_prefix="/dashboard")
@user_dashboard_bp.route("/")
@login_required
def my_shifts():
user_id = session["user"]["id"]
try:
sites = get_today_checks(user_id)
shifts = get_user_active_shifts(user_id)
except Exception as e:
logger.error(f"my_shifts error: {e}")
sites, shifts = [], []
checked = sum(1 for s in sites if s.get("check_id"))
total = len(sites)
pct = round(checked * 100 / total) if total else 0
return render_template("user/dashboard.html",
sites=sites, shifts=shifts,
checked=checked, total=total, pct=pct)
@user_dashboard_bp.route("/check/<int:website_id>", methods=["POST"])
@login_required
def check_site(website_id):
user_id = session["user"]["id"]
user_note = request.form.get("user_note", "").strip()
try:
mark_website_checked(user_id, website_id, user_note)
flash("Site marked as checked.", "success")
logger.info(f"User {user_id} checked website {website_id}.")
except Exception as e:
logger.error(f"check_site error: {e}")
flash(f"Error: {e}", "danger")
return redirect(url_for("user_dashboard.my_shifts"))
@user_dashboard_bp.route("/uncheck/<int:website_id>", methods=["POST"])
@login_required
def uncheck_site(website_id):
user_id = session["user"]["id"]
try:
unmark_website_checked(user_id, website_id)
flash("Check removed.", "info")
logger.info(f"User {user_id} unchecked website {website_id}.")
except Exception as e:
logger.error(f"uncheck_site error: {e}")
flash(f"Error: {e}", "danger")
return redirect(url_for("user_dashboard.my_shifts"))
@user_dashboard_bp.route("/note/<int:website_id>", methods=["POST"])
@login_required
def update_note(website_id):
user_id = session["user"]["id"]
user_note = request.form.get("user_note", "").strip()
try:
update_check_note(user_id, website_id, user_note)
flash("Note updated.", "success")
except Exception as e:
logger.error(f"update_note error: {e}")
flash(f"Error: {e}", "danger")
return redirect(url_for("user_dashboard.my_shifts"))
@user_dashboard_bp.route("/credentials/<int:website_id>")
@login_required
def view_credentials(website_id):
"""JSON endpoint: return decrypted credentials for a site."""
try:
creds = get_website_credentials(website_id)
user_id = session["user"]["id"]
log_action(user_id, "VIEW_CREDENTIALS", "websites", website_id,
f"User viewed credentials for website {website_id}.")
return jsonify([{
"label": c.get("label", ""),
"username": c.get("username", ""),
"password": c.get("password", ""),
} for c in creds])
except Exception as e:
logger.error(f"view_credentials error: {e}")
return jsonify({"error": str(e)}), 500
@user_dashboard_bp.route("/health/<int:website_id>")
@login_required
def health_check(website_id):
"""Server-side HEAD probe for a website's reachability."""
url = get_website_url(website_id)
if not url:
return jsonify({"status": "not_found"}), 404
try:
t0 = time.time()
resp = _http_req.head(url, timeout=6, allow_redirects=True,
headers={"User-Agent": "WebsiteChecker/1.0 (health-check)"})
ms = int((time.time() - t0) * 1000)
ok = resp.status_code < 400
return jsonify({"status": "ok" if ok else "error", "ms": ms})
except _http_req.exceptions.Timeout:
return jsonify({"status": "timeout", "ms": 6000})
except Exception:
return jsonify({"status": "unreachable", "ms": None})