Files
socks-manager/routes/api.py
T
Your Name aa8af6c2e0 feat: SOCKS5 代理管理系统 v1.0
Flask + SQLite + Bootstrap5 暗色主题
- 仪表盘: 在线/离线统计 + 最近代理 + 操作日志
- 代理 CRUD: 增删改 + 启用/禁用 + 单/批量健康检测(SOCKS5)
- 分组管理: 创建/删除/筛选
- 操作日志: 分页查询
- RESTful API + Web 界面
- 管理员登录认证 (SM_ADMIN_PASSWORD 环境变量)
2026-07-16 16:40:20 +08:00

96 lines
2.8 KiB
Python

from flask import Blueprint, request, jsonify
from models import Proxy, Group, Log, db
from auth import login_required
from health import check_proxy
bp = Blueprint("api", __name__)
@bp.route("/proxies", methods=["GET"])
@login_required
def list_proxies():
g = request.args.get("group")
query = Proxy.query
if g:
query = query.filter_by(group_id=g)
items = query.order_by(Proxy.updated_at.desc()).all()
return jsonify([{
"id": p.id, "name": p.name, "host": p.host, "port": p.port,
"username": p.username, "group": p.group.name if p.group else None,
"enabled": p.enabled, "status": p.status,
"latency_ms": round(p.latency_ms, 1) if p.latency_ms else None,
"last_check": p.last_check.isoformat() if p.last_check else None,
} for p in items])
@bp.route("/proxies", methods=["POST"])
@login_required
def create_proxy():
data = request.get_json()
p = Proxy(
name=data["name"], host=data["host"], port=int(data["port"]),
username=data.get("username"), password=data.get("password"),
group_id=int(data["group_id"]) if data.get("group_id") else None,
notes=data.get("notes"),
)
db.session.add(p)
db.session.commit()
return jsonify({"id": p.id}), 201
@bp.route("/proxies/<int:pid>", methods=["PUT"])
@login_required
def update_proxy(pid):
p = Proxy.query.get_or_404(pid)
data = request.get_json()
for k in ("name", "host", "port", "username", "password", "group_id", "notes"):
v = data.get(k)
if v is not None:
setattr(p, k, int(v) if k in ("port", "group_id") and v else v)
db.session.commit()
return jsonify({"ok": True})
@bp.route("/proxies/<int:pid>", methods=["DELETE"])
@login_required
def delete_proxy(pid):
p = Proxy.query.get_or_404(pid)
db.session.delete(p)
db.session.commit()
return jsonify({"ok": True})
@bp.route("/proxies/<int:pid>/check", methods=["POST"])
@login_required
def check_single(pid):
p = Proxy.query.get_or_404(pid)
result = check_proxy(p)
return jsonify(result)
@bp.route("/proxies/<int:pid>/toggle", methods=["POST"])
@login_required
def toggle(pid):
p = Proxy.query.get_or_404(pid)
p.enabled = not p.enabled
db.session.commit()
return jsonify({"enabled": p.enabled})
@bp.route("/groups", methods=["GET"])
@login_required
def list_groups():
groups = Group.query.all()
return jsonify([{"id": g.id, "name": g.name, "color": g.color,
"description": g.description,
"count": len(g.proxies)} for g in groups])
@bp.route("/stats")
@login_required
def stats():
total = Proxy.query.count()
online = Proxy.query.filter_by(status="online", enabled=True).count()
offline = Proxy.query.filter_by(status="offline").count()
return jsonify({"total": total, "online": online, "offline": offline})