| from flask import Flask, jsonify, render_template_string |
| import psutil |
| import mtprotoproxy |
| import time |
| import os |
|
|
| app = Flask(__name__) |
|
|
| HTML_TEMPLATE = """ |
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>MTProto Proxy Dashboard</title> |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> |
| <style> |
| body { background-color: #f8f9fa; padding-top: 20px; } |
| .card { margin-bottom: 20px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); } |
| .metric-value { font-size: 2rem; font-weight: bold; color: #0d6efd; } |
| </style> |
| <script> |
| async function updateStats() { |
| try { |
| const response = await fetch('/api/stats'); |
| const data = await response.json(); |
| |
| document.getElementById('cpu-load').innerText = data.cpu_percent + '%'; |
| document.getElementById('mem-load').innerText = data.mem_percent + '%'; |
| |
| // Calculate total connections |
| let totalConnections = 0; |
| let userHtml = ''; |
| for (const [user, stats] of Object.entries(data.user_stats)) { |
| totalConnections += stats.curr_connects || 0; |
| userHtml += `<tr> |
| <td>${user}</td> |
| <td>${stats.curr_connects || 0}</td> |
| <td>${stats.connects || 0}</td> |
| <td>${(((stats.octets_from_client || 0) + (stats.octets_to_client || 0)) / 1024 / 1024).toFixed(2)} MB</td> |
| </tr>`; |
| } |
| document.getElementById('total-users').innerText = totalConnections; |
| document.getElementById('user-table-body').innerHTML = userHtml; |
| } catch (e) { |
| console.error("Failed to fetch stats", e); |
| } |
| } |
| |
| setInterval(updateStats, 2000); |
| window.onload = updateStats; |
| </script> |
| </head> |
| <body> |
| <div class="container"> |
| <h1 class="mb-4 text-center">MTProto Proxy Dashboard</h1> |
| |
| <div class="row"> |
| <div class="col-md-4"> |
| <div class="card text-center"> |
| <div class="card-body"> |
| <h5 class="card-title">Active Connections</h5> |
| <p class="metric-value" id="total-users">0</p> |
| </div> |
| </div> |
| </div> |
| <div class="col-md-4"> |
| <div class="card text-center"> |
| <div class="card-body"> |
| <h5 class="card-title">CPU Load</h5> |
| <p class="metric-value" id="cpu-load">0%</p> |
| </div> |
| </div> |
| </div> |
| <div class="col-md-4"> |
| <div class="card text-center"> |
| <div class="card-body"> |
| <h5 class="card-title">Memory Load</h5> |
| <p class="metric-value" id="mem-load">0%</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="card mt-4"> |
| <div class="card-header bg-primary text-white"> |
| <h5 class="mb-0">User Statistics</h5> |
| </div> |
| <div class="card-body"> |
| <table class="table table-striped"> |
| <thead> |
| <tr> |
| <th>User Name</th> |
| <th>Active Connections</th> |
| <th>Total Connects</th> |
| <th>Data Transferred</th> |
| </tr> |
| </thead> |
| <tbody id="user-table-body"> |
| <!-- Filled by JS --> |
| </tbody> |
| </table> |
| </div> |
| </div> |
| </div> |
| </body> |
| </html> |
| """ |
|
|
| @app.route('/') |
| def index(): |
| return render_template_string(HTML_TEMPLATE) |
|
|
| @app.route('/api/stats') |
| def stats(): |
| user_stats = {} |
| try: |
| |
| |
| items = list(mtprotoproxy.user_stats.items()) |
| for user, counter in items: |
| user_stats[user] = dict(counter) |
| except Exception as e: |
| print(f"Error reading stats: {e}") |
|
|
| return jsonify({ |
| "cpu_percent": psutil.cpu_percent(interval=None), |
| "mem_percent": psutil.virtual_memory().percent, |
| "user_stats": user_stats |
| }) |
|
|
| def start_webui(): |
| |
| app.run(host='0.0.0.0', port=7860, debug=False, use_reloader=False) |
|
|
| if __name__ == "__main__": |
| start_webui() |
|
|