from flask import Flask, render_template_string, jsonify, Response import requests import os app = Flask(__name__) lightModeStyle = """ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, sans-serif; background: #f0f2f5; color: #333; padding: 20px; min-height: 100vh; } .container { max-width: 1400px; margin: 0 auto; animation: fadeIn 0.5s ease; padding: 0 20px; } .overview { background: #fff; border-radius: 15px; padding: 25px; margin-bottom: 30px; border: 1px solid #dfe1e6; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } .overview-title { font-size: 20px; display: flex; align-items: center; gap: 10px; margin-bottom: 20px; color: #2e86de; font-weight: 600; } .overview-title i { margin-right: 8px; } #summary { display: grid; grid-template-columns: repeat(5, 1fr); gap: 15px; } #summary div { background: #f9fafb; padding: 15px; border-radius: 8px; border: 1px solid #dfe1e6; transition: background-color 0.2s ease; } #summary div:hover { background-color: #f0f2f5; } #summary div { font-size: 14px; color: #555; } #summary span { display: block; font-size: 24px; font-weight: bold; margin-top: 5px; color: #333; } .stats-container { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 20px; } .server-card { background: #fff; border-radius: 10px; padding: 20px; border: 1px solid #dfe1e6; transition: transform 0.2s ease, box-shadow 0.2s ease; height: auto; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } .server-card:hover { transform: translateY(-3px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); } .server-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; font-size: 16px; color: #444; } .server-name { display: flex; align-items: center; gap: 10px; } .server-flag { width: 20px; height: 20px; border-radius: 4px; } .metric-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-top: 15px; } .metric-item { background: #f9fafb; padding: 12px; border-radius: 8px; border: 1px solid #dfe1e6; transition: background-color 0.2s ease; } .metric-item:hover { background-color: #f0f2f5; } .metric-label { color: #777; font-size: 13px; margin-bottom: 5px; } .metric-value { font-size: 16px; font-weight: 500; color: #333; } .status-dot { display: inline-block; border-radius: 50%; animation: pulse 2s infinite; width: 12px; height: 12px; } .status-online { background-color: #2ecc71; color: #2ecc71; box-shadow: 0 0 5px rgba(46, 204, 113, 0.4); } .status-offline { background-color: #e74c3c; color: #e74c3c; box-shadow: 0 0 5px rgba(231, 76, 60, 0.4); } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(46, 204, 113, 0); } 100% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); } } @media (max-width: 768px) { #summary { grid-template-columns: 1fr; } .stats-container { grid-template-columns: 1fr; } .metric-grid { grid-template-columns: 1fr; } } .progress-bar-container { width: 100%; background-color: #ddd; border-radius: 4px; margin-top: 4px; } .progress-bar { height: 8px; border-radius: 4px; background-color: #2e86de; width: 0%; } .cpu-progress-bar { height: 8px; border-radius: 4px; background-color: #2ecc71; width: 0%; } .memory-progress-bar{ height: 8px; border-radius: 4px; background-color: #e67e22; width: 0%; } """ htmlTemplate = f"""