Taf2023 commited on
Commit
b86e5bd
·
verified ·
1 Parent(s): 1e11ef6

Deploy Gradio app with multiple files

Browse files
Files changed (4) hide show
  1. app.py +244 -0
  2. config.py +16 -0
  3. requirements.txt +2 -0
  4. utils.py +352 -0
app.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import threading
3
+ import socket
4
+ import time
5
+ import json
6
+ import requests
7
+ from datetime import datetime
8
+ from typing import Dict, List, Optional
9
+ import logging
10
+ from utils import SOCKS5ProxyServer, ProxyManager
11
+ from config import *
12
+
13
+ # สร้างตัวจัดการ proxy
14
+ proxy_manager = ProxyManager()
15
+
16
+ def start_proxy_server():
17
+ """เริ่มต้น proxy server"""
18
+ success = proxy_manager.start_server()
19
+ if success:
20
+ return "✅ เริ่มต้น Proxy Server สำเร็จ"
21
+ else:
22
+ return "❌ ไม่สามารถเริ่มต้น Proxy Server ได้"
23
+
24
+ def stop_proxy_server():
25
+ """หยุด proxy server"""
26
+ proxy_manager.stop_server()
27
+ return "🛑 หยุด Proxy Server แล้ว"
28
+
29
+ def restart_proxy_server():
30
+ """รีสตาร์ท proxy server"""
31
+ proxy_manager.stop_server()
32
+ time.sleep(1)
33
+ success = proxy_manager.start_server()
34
+ if success:
35
+ return "🔄 รีสตาร์ท Proxy Server สำเร็จ"
36
+ else:
37
+ return "❌ ไม่สามารถรีสตาร์ท Proxy Server ได้"
38
+
39
+ def get_current_proxy_url():
40
+ """ดึง URL proxy ปัจจุบัน"""
41
+ if proxy_manager.is_running():
42
+ return f"socks5://localhost:{PROXY_PORT}"
43
+ return "ไม่ได้เชื่อมต่อ"
44
+
45
+ def get_server_info():
46
+ """ดึงข้อมูล server"""
47
+ return json.dumps(proxy_manager.get_server_info(), indent=2, ensure_ascii=False)
48
+
49
+ def get_usage_stats():
50
+ """ดึงสถิติการใช้งาน"""
51
+ return json.dumps(proxy_manager.get_usage_stats(), indent=2, ensure_ascii=False)
52
+
53
+ def get_user_stats():
54
+ """ดึงข้อมูลผู้ใช้"""
55
+ return json.dumps(proxy_manager.get_user_stats(), indent=2, ensure_ascii=False)
56
+
57
+ def get_connection_logs():
58
+ """ดึง log การเชื่อมต่อ"""
59
+ return json.dumps(proxy_manager.get_recent_logs(), indent=2, ensure_ascii=False)
60
+
61
+ def refresh_all():
62
+ """รีเฟรชข้อมูลทั้งหมด"""
63
+ return (
64
+ get_current_proxy_url(),
65
+ get_server_info(),
66
+ get_usage_stats(),
67
+ get_user_stats(),
68
+ get_connection_logs()
69
+ )
70
+
71
+ def setup_interface():
72
+ """สร้าง Gradio interface"""
73
+
74
+ # Custom CSS สำหรับ styling
75
+ css = """
76
+ .main-container {
77
+ max-width: 1200px;
78
+ margin: auto;
79
+ padding: 20px;
80
+ }
81
+ .status-indicator {
82
+ padding: 10px;
83
+ border-radius: 5px;
84
+ margin: 5px 0;
85
+ }
86
+ .status-running {
87
+ background-color: #d4edda;
88
+ color: #155724;
89
+ border: 1px solid #c3e6cb;
90
+ }
91
+ .status-stopped {
92
+ background-color: #f8d7da;
93
+ color: #721c24;
94
+ border: 1px solid #f5c6cb;
95
+ }
96
+ .info-box {
97
+ background-color: #e9ecef;
98
+ padding: 15px;
99
+ border-radius: 5px;
100
+ margin: 10px 0;
101
+ border-left: 4px solid #007bff;
102
+ }
103
+ .stats-grid {
104
+ display: grid;
105
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
106
+ gap: 15px;
107
+ margin: 20px 0;
108
+ }
109
+ .stat-card {
110
+ background: white;
111
+ padding: 15px;
112
+ border-radius: 8px;
113
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
114
+ border: 1px solid #dee2e6;
115
+ }
116
+ .stat-number {
117
+ font-size: 24px;
118
+ font-weight: bold;
119
+ color: #007bff;
120
+ }
121
+ .stat-label {
122
+ color: #6c757d;
123
+ font-size: 14px;
124
+ }
125
+ """
126
+
127
+ with gr.Blocks(css=css, title="SOCKS5 Proxy Dashboard") as demo:
128
+ gr.HTML("""
129
+ <div class="main-container">
130
+ <div style="text-align: center; margin-bottom: 30px;">
131
+ <h1>🔒 SOCKS5 Proxy Server Dashboard</h1>
132
+ <p style="color: #6c757d;">ระบบจัดการ SOCKS5 Proxy Server พร้อมการติดตามการใช้งาน</p>
133
+ <div style="margin-top: 10px;">
134
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="text-decoration: none; color: #007bff; font-weight: bold;">Built with anycoder</a>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ """)
139
+
140
+ # สถานะปัจจุบัน
141
+ with gr.Row():
142
+ with gr.Column(scale=1):
143
+ gr.HTML('<h3>🎮 การควบคุม</h3>')
144
+ with gr.Row():
145
+ start_btn = gr.Button("▶️ เริ่มต้น", variant="primary", size="lg")
146
+ stop_btn = gr.Button("⏹️ หยุด", variant="stop", size="lg")
147
+ restart_btn = gr.Button("🔄 รีสตาร์ท", variant="secondary", size="lg")
148
+
149
+ status_html = gr.HTML()
150
+ proxy_url_output = gr.Textbox(
151
+ label="🌐 Proxy URL ปัจจุบัน",
152
+ value=get_current_proxy_url,
153
+ interactive=False,
154
+ elem_classes=["info-box"]
155
+ )
156
+
157
+ with gr.Column(scale=2):
158
+ gr.HTML('<h3>📊 สถิติการใช้งาน</h3>')
159
+ with gr.Row():
160
+ total_connections = gr.Number(label="📈 การเชื่อมต่อทั้งหมด", value=0)
161
+ active_connections = gr.Number(label="🔗 การเชื่อมต่อที่กำลังใช้งาน", value=0)
162
+ bandwidth_used = gr.Number(label="📊 Bandwidth ใช้งาน (MB)", value=0)
163
+
164
+ uptime_output = gr.Textbox(
165
+ label="⏱️ เวลาทำงาน",
166
+ interactive=False,
167
+ value="00:00:00"
168
+ )
169
+
170
+ # ข้อมูลผู้ใช้
171
+ with gr.Tab("👥 ผู้ใช้งาน"):
172
+ user_stats = gr.JSON(
173
+ label="ข้อมูลผู้ใช้ทั้งหมด",
174
+ value=get_user_stats
175
+ )
176
+
177
+ # ข้อมูล Server
178
+ with gr.Tab("🖥️ ข้อมูล Server"):
179
+ server_info = gr.JSON(
180
+ label="ข้อมูล Server",
181
+ value=get_server_info
182
+ )
183
+
184
+ # สถิติการใช้งาน
185
+ with gr.Tab("📊 สถิติ"):
186
+ usage_stats = gr.JSON(
187
+ label="สถิติการใช้งาน",
188
+ value=get_usage_stats
189
+ )
190
+
191
+ # ล็อก
192
+ with gr.Tab("📝 ล็อก"):
193
+ logs = gr.JSON(
194
+ label="ล็อกการเชื่อมต่อล่าสุด",
195
+ value=get_connection_logs
196
+ )
197
+
198
+ # ปุ่มรีเฟรช
199
+ with gr.Row():
200
+ refresh_btn = gr.Button("🔄 รีเฟรชข้อมูลทั้งหมด", variant="primary")
201
+
202
+ # ผูก events
203
+ start_btn.click(start_proxy_server, outputs=proxy_url_output)
204
+ stop_btn.click(stop_proxy_server, outputs=proxy_url_output)
205
+ restart_btn.click(restart_proxy_server, outputs=proxy_url_output)
206
+ refresh_btn.click(
207
+ refresh_all,
208
+ outputs=[
209
+ proxy_url_output,
210
+ server_info,
211
+ usage_stats,
212
+ user_stats,
213
+ logs
214
+ ]
215
+ )
216
+
217
+ # อัปเดตข้อมูลอัตโนมัติ
218
+ demo.load(
219
+ refresh_all,
220
+ outputs=[
221
+ proxy_url_output,
222
+ server_info,
223
+ usage_stats,
224
+ user_stats,
225
+ logs
226
+ ]
227
+ )
228
+
229
+ return demo
230
+
231
+ if __name__ == "__main__":
232
+ # สร้าง interface
233
+ demo = setup_interface()
234
+
235
+ # เริ่มต้น proxy server อัตโนมัติ
236
+ proxy_manager.start_server()
237
+
238
+ # เริ่ม UI
239
+ demo.launch(
240
+ server_name="0.0.0.0",
241
+ server_port=8080,
242
+ show_api=False,
243
+ title="SOCKS5 Proxy Dashboard"
244
+ )
config.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # การตั้งค่า SOCKS5 Proxy Server
2
+ PROXY_HOST = "0.0.0.0"
3
+ PROXY_PORT = 1080
4
+
5
+ # การตั้งค่า Web Interface
6
+ WEB_HOST = "0.0.0.0"
7
+ WEB_PORT = 8080
8
+
9
+ # การตั้งค่า Logging
10
+ LOG_LEVEL = "INFO"
11
+ LOG_FILE = "proxy.log"
12
+
13
+ # การตั้งค่าอื่นๆ
14
+ MAX_CONNECTIONS = 100
15
+ CONNECTION_TIMEOUT = 300 # วินาที
16
+ BUFFER_SIZE = 4096 # bytes
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ gradio
2
+ requests
utils.py ADDED
@@ -0,0 +1,352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import socket
2
+ import threading
3
+ import time
4
+ import json
5
+ import logging
6
+ from datetime import datetime, timedelta
7
+ from typing import Dict, List, Optional
8
+ from dataclasses import dataclass
9
+ import struct
10
+
11
+ @dataclass
12
+ class ConnectionInfo:
13
+ ip: str
14
+ port: int
15
+ start_time: datetime
16
+ bytes_sent: int = 0
17
+ bytes_received: int = 0
18
+ is_active: bool = True
19
+
20
+ class SOCKS5ProxyServer:
21
+ def __init__(self, host='0.0.0.0', port=1080):
22
+ self.host = host
23
+ self.port = port
24
+ self.server_socket = None
25
+ self.running = False
26
+ self.connections: Dict[str, ConnectionInfo] = {}
27
+ self.total_connections = 0
28
+ self.start_time = None
29
+ self._lock = threading.Lock()
30
+
31
+ def start(self):
32
+ """เริ่มต้น SOCKS5 proxy server"""
33
+ try:
34
+ self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
35
+ self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
36
+ self.server_socket.bind((self.host, self.port))
37
+ self.server_socket.listen(50)
38
+ self.running = True
39
+ self.start_time = datetime.now()
40
+
41
+ logging.info(f"SOCKS5 Proxy Server เริ่มต้นที่ {self.host}:{self.port}")
42
+
43
+ # เริ่ม thread สำหรับ accept connections
44
+ threading.Thread(target=self._accept_connections, daemon=True).start()
45
+
46
+ return True
47
+ except Exception as e:
48
+ logging.error(f"เริ่มต้น proxy server ผิดพลาด: {e}")
49
+ return False
50
+
51
+ def stop(self):
52
+ """หยุด SOCKS5 proxy server"""
53
+ self.running = False
54
+ if self.server_socket:
55
+ try:
56
+ self.server_socket.close()
57
+ except:
58
+ pass
59
+ logging.info("SOCKS5 Proxy Server หยุดทำงาน")
60
+
61
+ def _accept_connections(self):
62
+ """รับการเชื่อมต่อใหม่"""
63
+ while self.running:
64
+ try:
65
+ client_socket, client_address = self.server_socket.accept()
66
+ client_ip, client_port = client_address
67
+
68
+ # บันทึกการเชื่อมต่อ
69
+ with self._lock:
70
+ self.connections[f"{client_ip}:{client_port}"] = ConnectionInfo(
71
+ ip=client_ip,
72
+ port=client_port,
73
+ start_time=datetime.now()
74
+ )
75
+ self.total_connections += 1
76
+
77
+ # สร้าง thread สำหรับจัดการการเชื่อมต่อ
78
+ threading.Thread(
79
+ target=self._handle_client,
80
+ args=(client_socket, client_ip, client_port),
81
+ daemon=True
82
+ ).start()
83
+
84
+ except socket.error:
85
+ if self.running:
86
+ logging.error("Error ในการรับการเชื่อมต่อ")
87
+ break
88
+
89
+ def _handle_client(self, client_socket, client_ip, client_port):
90
+ """จัดการการเชื่อมต่อจาก client"""
91
+ try:
92
+ # SOCKS5 handshake
93
+ if not self._handle_socks5_handshake(client_socket):
94
+ return
95
+
96
+ # รับคำขอจาก client
97
+ request = client_socket.recv(1024)
98
+ if len(request) < 10:
99
+ return
100
+
101
+ # แยกคำขอ SOCKS5
102
+ if request[0] != 0x05: # Version 5
103
+ return
104
+
105
+ cmd = request[1] # Command
106
+ addr_type = request[3] # Address type
107
+
108
+ if cmd == 0x01: # CONNECT
109
+ self._handle_connect(client_socket, request, client_ip, client_port)
110
+ elif cmd == 0x02: # BIND
111
+ self._handle_bind(client_socket, client_ip, client_port)
112
+ elif cmd == 0x03: # UDP ASSOCIATE
113
+ self._handle_udp_associate(client_socket, client_ip, client_port)
114
+
115
+ except Exception as e:
116
+ logging.error(f"Error ในการจัดการ client {client_ip}:{client_port}: {e}")
117
+ finally:
118
+ # ปิดการเชื่อมต่อ
119
+ try:
120
+ client_socket.close()
121
+ except:
122
+ pass
123
+
124
+ # อัปเดตสถานะ
125
+ with self._lock:
126
+ if f"{client_ip}:{client_port}" in self.connections:
127
+ self.connections[f"{client_ip}:{client_port}"].is_active = False
128
+
129
+ def _handle_socks5_handshake(self, client_socket):
130
+ """จัดการ SOCKS5 handshake"""
131
+ try:
132
+ # ��ับ client hello
133
+ data = client_socket.recv(1024)
134
+ if len(data) < 2:
135
+ return False
136
+
137
+ version = data[0]
138
+ nmethods = data[1]
139
+
140
+ if version != 0x05: # Version 5
141
+ return False
142
+
143
+ # ตอบกลับว่าใช้ no authentication
144
+ response = b'\x05\x00'
145
+ client_socket.send(response)
146
+ return True
147
+
148
+ except Exception as e:
149
+ logging.error(f"Handshake error: {e}")
150
+ return False
151
+
152
+ def _handle_connect(self, client_socket, request, client_ip, client_port):
153
+ """จัดการ SOCKS5 CONNECT command"""
154
+ try:
155
+ addr_type = request[3]
156
+ dest_addr = ""
157
+ dest_port = 0
158
+
159
+ if addr_type == 0x01: # IPv4
160
+ dest_ip = socket.inet_ntoa(request[4:8])
161
+ dest_port = struct.unpack('!H', request[8:10])[0]
162
+ dest_addr = dest_ip
163
+ elif addr_type == 0x03: # Domain name
164
+ domain_length = request[4]
165
+ dest_addr = request[5:5+domain_length].decode('utf-8')
166
+ dest_port = struct.unpack('!H', request[5+domain_length:7+domain_length])[0]
167
+ elif addr_type == 0x04: # IPv6
168
+ dest_ip = socket.inet_ntop(socket.AF_INET6, request[4:20])
169
+ dest_port = struct.unpack('!H', request[20:22])[0]
170
+ dest_addr = dest_ip
171
+
172
+ # เชื่อมต่อไปยังเป้าหมาย
173
+ target_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
174
+ target_socket.connect((dest_addr, dest_port))
175
+
176
+ # ตอบกลับว่าสำเร็จ
177
+ reply = b'\x05\x00\x00\x01' + socket.inet_aton('0.0.0.0') + b'\x00\x00'
178
+ client_socket.send(reply)
179
+
180
+ # เริ่มตัวกลางข้อมูล
181
+ threading.Thread(
182
+ target=self._relay_data,
183
+ args=(client_socket, target_socket, client_ip, client_port),
184
+ daemon=True
185
+ ).start()
186
+
187
+ logging.info(f"CONNECT: {client_ip}:{client_port} -> {dest_addr}:{dest_port}")
188
+
189
+ except Exception as e:
190
+ # ส่ง error response
191
+ reply = b'\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00'
192
+ try:
193
+ client_socket.send(reply)
194
+ except:
195
+ pass
196
+ logging.error(f"CONNECT error: {e}")
197
+
198
+ def _handle_bind(self, client_socket, client_ip, client_port):
199
+ """จัดการ SOCKS5 BIND command"""
200
+ # BIND command implementation (สำหรับ incoming connections)
201
+ reply = b'\x05\x07\x00\x01\x00\x00\x00\x00\x00\x00' # Command not supported
202
+ try:
203
+ client_socket.send(reply)
204
+ except:
205
+ pass
206
+
207
+ def _handle_udp_associate(self, client_socket, client_ip, client_port):
208
+ """จัดการ SOCKS5 UDP ASSOCIATE command"""
209
+ # UDP ASSOCIATE implementation
210
+ reply = b'\x05\x00\x00\x01\x00\x00\x00\x00\x00\x00'
211
+ try:
212
+ client_socket.send(reply)
213
+ except:
214
+ pass
215
+
216
+ def _relay_data(self, client_socket, target_socket, client_ip, client_port):
217
+ """ส่งข้อมูลระหว่าง client และ target"""
218
+ try:
219
+ while True:
220
+ try:
221
+ data = client_socket.recv(4096)
222
+ if not data:
223
+ break
224
+
225
+ # ส่งต่อไปยัง target
226
+ target_socket.send(data)
227
+
228
+ # อัปเดตสถิติ
229
+ with self._lock:
230
+ if f"{client_ip}:{client_port}" in self.connections:
231
+ conn = self.connections[f"{client_ip}:{client_port}"]
232
+ conn.bytes_sent += len(data)
233
+
234
+ except socket.error:
235
+ break
236
+
237
+ try:
238
+ data = target_socket.recv(4096)
239
+ if not data:
240
+ break
241
+
242
+ # ส่งต่อกลับไปยัง client
243
+ client_socket.send(data)
244
+
245
+ # อัปเดตสถิติ
246
+ with self._lock:
247
+ if f"{client_ip}:{client_port}" in self.connections:
248
+ conn = self.connections[f"{client_ip}:{client_port}"]
249
+ conn.bytes_received += len(data)
250
+
251
+ except socket.error:
252
+ break
253
+
254
+ except Exception as e:
255
+ logging.error(f"Relay error: {e}")
256
+ finally:
257
+ try:
258
+ client_socket.close()
259
+ target_socket.close()
260
+ except:
261
+ pass
262
+
263
+ class ProxyManager:
264
+ def __init__(self, host='0.0.0.0', port=1080):
265
+ self.proxy_server = SOCKS5ProxyServer(host, port)
266
+ self.host = host
267
+ self.port = port
268
+
269
+ def start_server(self):
270
+ """เริ่มต้น proxy server"""
271
+ return self.proxy_server.start()
272
+
273
+ def stop_server(self):
274
+ """หยุด proxy server"""
275
+ self.proxy_server.stop()
276
+
277
+ def is_running(self):
278
+ """ตรวจสอบว่า server กำลังทำงานอยู่หรือไม่"""
279
+ return self.proxy_server.running
280
+
281
+ def get_server_info(self):
282
+ """ดึงข้อมูล server"""
283
+ info = {
284
+ "server_status": "รันอยู่" if self.proxy_server.running else "หยุดทำงาน",
285
+ "host": self.proxy_server.host,
286
+ "port": self.proxy_server.port,
287
+ "version": "SOCKS5",
288
+ "authentication": "ไม่ต้องยืนยันตัวตน",
289
+ "start_time": self.proxy_server.start_time.isoformat() if self.proxy_server.start_time else None,
290
+ "uptime": str(datetime.now() - self.proxy_server.start_time) if self.proxy_server.start_time else "00:00:00"
291
+ }
292
+ return info
293
+
294
+ def get_usage_stats(self):
295
+ """ดึงสถิติการใช้งาน"""
296
+ total_connections = len([c for c in self.proxy_server.connections.values() if not c.is_active])
297
+ active_connections = len([c for c in self.proxy_server.connections.values() if c.is_active])
298
+
299
+ total_bytes = sum(c.bytes_sent + c.bytes_received for c in self.proxy_server.connections.values())
300
+
301
+ stats = {
302
+ "total_connections": total_connections,
303
+ "active_connections": active_connections,
304
+ "total_bandwidth_bytes": total_bytes,
305
+ "total_bandwidth_mb": round(total_bytes / (1024 * 1024), 2),
306
+ "peak_concurrent": max(active_connections, 0),
307
+ "average_session_duration": "ไม่มีข้อมูล"
308
+ }
309
+
310
+ return stats
311
+
312
+ def get_user_stats(self):
313
+ """ดึงข้อมูลผู้ใช้"""
314
+ users = []
315
+ for conn_id, conn in self.proxy_server.connections.items():
316
+ users.append({
317
+ "id": conn_id,
318
+ "ip": conn.ip,
319
+ "port": conn.port,
320
+ "connected_since": conn.start_time.isoformat(),
321
+ "is_active": conn.is_active,
322
+ "bytes_sent": conn.bytes_sent,
323
+ "bytes_received": conn.bytes_received,
324
+ "total_bytes": conn.bytes_sent + conn.bytes_received,
325
+ "session_duration": str(datetime.now() - conn.start_time)
326
+ })
327
+
328
+ return {
329
+ "total_users": len(users),
330
+ "active_users": len([u for u in users if u["is_active"]]),
331
+ "users": users
332
+ }
333
+
334
+ def get_recent_logs(self):
335
+ """ดึงล็อกการเชื่อมต่อล่าสุด"""
336
+ logs = []
337
+ for conn_id, conn in self.proxy_server.connections.items():
338
+ logs.append({
339
+ "timestamp": conn.start_time.isoformat(),
340
+ "client": f"{conn.ip}:{conn.port}",
341
+ "status": "เชื่อมต่ออยู่" if conn.is_active else "เสร็จสิ้น",
342
+ "bytes_transferred": conn.bytes_sent + conn.bytes_received,
343
+ "session_duration": str(datetime.now() - conn.start_time)
344
+ })
345
+
346
+ # เรียงตามเวลาใหม่สุดก่อน
347
+ logs.sort(key=lambda x: x["timestamp"], reverse=True)
348
+
349
+ return {
350
+ "recent_connections": logs[:50], # แสดง 50 รายการล่าสุด
351
+ "total_log_entries": len(logs)
352
+ }