""" routes/admin_settings.py — Application settings (email, Groq API, etc.) """ import logging import os import requests as http_requests from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify from config import get_settings_dict, set_setting, get_setting from models import log_action from utils.decorators import admin_required logger = logging.getLogger("routes.admin_settings") admin_settings_bp = Blueprint("admin_settings", __name__, url_prefix="/admin/settings") @admin_settings_bp.route("/") @admin_required def settings(): email_settings = get_settings_dict("email.") groq_settings = get_settings_dict("groq.") registration_settings = get_settings_dict("registration.") return render_template("admin/settings.html", email=email_settings, groq=groq_settings, registration=registration_settings) @admin_settings_bp.route("/email", methods=["POST"]) @admin_required def save_email(): admin = session["user"] fields = [ "email.enabled", "email.smtp_host", "email.smtp_port", "email.smtp_user", "email.smtp_password", "email.security", "email.smtp_from", "email.recipients", "email.send_time", ] for field in fields: key = field form_key = field.replace(".", "_") value = request.form.get(form_key, "") set_setting(key, value) log_action(admin["id"], "UPDATE_EMAIL_SETTINGS", "app_settings", None, "Email settings updated via web UI.") flash("Email settings saved successfully.", "success") logger.info(f"Email settings updated by admin_id={admin['id']}.") return redirect(url_for("admin_settings.settings")) @admin_settings_bp.route("/groq", methods=["POST"]) @admin_required def save_groq(): admin = session["user"] set_setting("groq.api_key", request.form.get("groq_api_key", "")) set_setting("groq.model", request.form.get("groq_model", "llama-3.3-70b-versatile")) log_action(admin["id"], "UPDATE_GROQ_SETTINGS", "app_settings", None, "Groq API settings updated via web UI.") flash("Groq settings saved successfully.", "success") logger.info(f"Groq settings updated by admin_id={admin['id']}.") return redirect(url_for("admin_settings.settings")) @admin_settings_bp.route("/registration", methods=["POST"]) @admin_required def save_registration(): admin = session["user"] enabled = "1" if request.form.get("registration_enabled") == "1" else "0" set_setting("registration.enabled", enabled) log_action(admin["id"], "UPDATE_REGISTRATION_SETTINGS", "app_settings", None, f"User self-registration {'enabled' if enabled == '1' else 'disabled'}.") flash(f"Registration {'enabled' if enabled == '1' else 'disabled'} successfully.", "success") logger.info(f"Registration setting set to '{enabled}' by admin_id={admin['id']}.") return redirect(url_for("admin_settings.settings")) @admin_settings_bp.route("/test-email", methods=["POST"]) @admin_required def test_email(): from utils.email import send_email admin = session["user"] to = (admin.get("email") or "").strip() if not to: return jsonify({"error": "Your admin account has no email address. Add one in User Management."}), 400 try: send_email( to, "Bid Checker — SMTP Test", "This is a test email from Bid Checker. Your SMTP configuration is working correctly.", ) log_action(admin["id"], "TEST_EMAIL", "app_settings", None, f"SMTP test email sent to {to}.") return jsonify({"ok": True, "to": to}) except Exception as e: logger.error(f"SMTP test failed: {e}") return jsonify({"error": str(e)}), 500 @admin_settings_bp.route("/test-groq", methods=["POST"]) @admin_required def test_groq(): admin = session["user"] api_key = (os.environ.get("GROQ_API_KEY") or "").strip() or get_setting("groq.api_key", "").strip() if not api_key: return jsonify({"error": "No Groq API key is configured. Save one first."}), 400 model = get_setting("groq.model", "llama-3.3-70b-versatile") try: resp = http_requests.post( "https://api.groq.com/openai/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}, json={"model": model, "messages": [{"role": "user", "content": "Hi"}], "max_tokens": 5}, timeout=15, ) if resp.ok: log_action(admin["id"], "TEST_GROQ", "app_settings", None, "Groq API test successful.") return jsonify({"ok": True, "model": model}) return jsonify({"error": f"Groq API returned {resp.status_code}: {resp.text[:200]}"}), 400 except Exception as e: logger.error(f"Groq test failed: {e}") return jsonify({"error": str(e)}), 500