0% found this document useful (0 votes)
8 views28 pages

Scripts

Uploaded by

moin.nikchre89
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views28 pages

Scripts

Uploaded by

moin.nikchre89
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 28

import tkinter as tk

from tkinter import ttk, scrolledtext, messagebox


import threading
import socket
import time
import psutil
import platform
import datetime
from flask import Flask, render_template, request, jsonify, send_file
import json
import subprocess
import os
import re
import sys
import ctypes
import winreg
import select
import ping3

# ====================
# GLOBAL CONFIGURATION
# ====================
SERVER_PORT = 6499
LOG_PREFIX = "LSE"
NETWORK_SETTINGS = {
'ip': '169.254.2.10',
'mask': '255.255.255.0',
'gateway': '169.254.2.2',
'dns1': '8.8.8.8',
'dns2': '8.8.4.4'
}

# Network monitoring variables


prev_bytes_sent = 0
prev_bytes_recv = 0
prev_time = time.time()

# CPU monitoring
cpu_percent = 0
def monitor_cpu():
global cpu_percent
while True:
cpu_percent = psutil.cpu_percent(interval=1)

# Start CPU monitoring thread


cpu_thread = threading.Thread(target=monitor_cpu, daemon=True)
cpu_thread.start()

# Ping monitoring
ping_status = "Disconnected"
ping_time = "0ms"
def monitor_ping():
global ping_status, ping_time
while True:
try:
response_time = ping3.ping('google.com', timeout=2)
if response_time is not None:
ping_status = "Connected"
ping_time = f"{int(response_time * 1000)}ms"
else:
ping_status = "Disconnected"
ping_time = "Timeout"
except:
ping_status = "Disconnected"
ping_time = "Error"
time.sleep(5)

# Start ping monitoring thread


ping_thread = threading.Thread(target=monitor_ping, daemon=True)
ping_thread.start()

# =================
# LOGGING MECHANISM
# =================
class LogSync:
def __init__(self):
self.logs = []
self.lock = threading.Lock()

def add_log(self, message):


with self.lock:
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
entry = f"[{timestamp}] {LOG_PREFIX} {message}"
self.logs.append(entry)
return entry

log_sync = LogSync()

# ===================
# SYSTEM INFO HELPERS
# ===================
def get_system_specs():
return {
"hostname": socket.gethostname(),
"os": f"{platform.system()} {platform.release()}",
"processor": platform.processor(),
"ram": f"{round(psutil.virtual_memory().total / (1024**3), 2)} GB",
"architecture": platform.architecture()[0]
}

def get_performance_data():
global prev_bytes_sent, prev_bytes_recv, prev_time

# Get current time


current_time = time.time()
time_diff = current_time - prev_time

# Get current network stats


net_io = psutil.net_io_counters()
current_bytes_sent = net_io.bytes_sent
current_bytes_recv = net_io.bytes_recv

# Calculate network usage (KB/s)


if prev_bytes_sent == 0 or prev_bytes_recv == 0 or time_diff < 0.1:
network_usage = 0
else:
sent_diff = current_bytes_sent - prev_bytes_sent
recv_diff = current_bytes_recv - prev_bytes_recv
network_usage = (sent_diff + recv_diff) / 1024 / time_diff # KB/s

# Update previous values


prev_bytes_sent = current_bytes_sent
prev_bytes_recv = current_bytes_recv
prev_time = current_time

return {
"cpu": cpu_percent,
"memory": psutil.virtual_memory().percent,
"network": network_usage,
"ping_status": ping_status,
"ping_time": ping_time
}

# =========================
# NETWORK CONFIGURATION
# =========================
def get_ethernet_interfaces():
"""Get Ethernet interfaces using netsh command"""
try:
# Run netsh command to get interfaces
result = subprocess.check_output('netsh interface show interface',
shell=True, text=True)

interfaces = []
lines = result.split('\n')

# Skip the header lines (first 2 lines)


for line in lines[2:]:
if line.strip() == '':
continue

# Extract interface name from the line


# Format: Admin State State Type Interface Name
parts = line.split()
if len(parts) >= 4:
# The interface name is the last part
interface_name = ' '.join(parts[3:])

# Check if it's an Ethernet interface (case-insensitive)


if 'ethernet' in interface_name.lower():
interfaces.append(interface_name)

return interfaces
except Exception as e:
log_sync.add_log(f"Error getting interfaces: {str(e)}")
return ["Ethernet"] # Default fallback

def set_static_ip(interface, ip, mask, gateway):


"""Set static IP using netsh commands"""
try:
# Run commands in background without showing console window
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# Build the command


cmd = f'netsh interface ip set address name="{interface}" source=static
addr={ip} mask={mask} gateway={gateway}'
subprocess.run(cmd, startupinfo=startupinfo, shell=True, check=True)

return True, f"Static IP set: {ip} on {interface}"


except subprocess.CalledProcessError as e:
return False, f"Error updating IP: {e}"

def set_dhcp_ip(interface):
"""Set DHCP IP using netsh commands"""
try:
# Run commands in background without showing console window
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# Build the command


cmd = f'netsh interface ip set address name="{interface}" source=dhcp'
subprocess.run(cmd, startupinfo=startupinfo, shell=True, check=True)

return True, f"DHCP enabled on {interface}"


except subprocess.CalledProcessError as e:
return False, f"Error setting DHCP: {e}"

def set_static_dns(interface, dns1, dns2=None):


"""Set static DNS using netsh commands"""
try:
# Run commands in background without showing console window
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# Set primary DNS


cmd = f'netsh interface ip set dns name="{interface}" source=static
addr={dns1}'
subprocess.run(cmd, startupinfo=startupinfo, shell=True, check=True)

# Set secondary DNS if provided


if dns2:
cmd = f'netsh interface ip add dns name="{interface}" addr={dns2}
index=2'
subprocess.run(cmd, startupinfo=startupinfo, shell=True, check=True)

return True, f"Static DNS set: {dns1}, {dns2} on {interface}"


except subprocess.CalledProcessError as e:
return False, f"Error updating DNS: {e}"

def set_dhcp_dns(interface):
"""Set DHCP DNS using netsh commands"""
try:
# Run commands in background without showing console window
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

# Build the command


cmd = f'netsh interface ip set dns name="{interface}" source=dhcp'
subprocess.run(cmd, startupinfo=startupinfo, shell=True, check=True)

return True, f"DHCP DNS enabled on {interface}"


except subprocess.CalledProcessError as e:
return False, f"Error setting DNS to DHCP: {e}"

def get_network_info():
"""Get detailed network information using ipconfig"""
net_info = []

try:
# Get ipconfig output
result = subprocess.check_output('ipconfig /all', shell=True, text=True)

current_adapter = ""
adapter_info = {}

for line in result.split('\n'):


# Check for adapter name
if 'adapter' in line.lower() and ':' in line:
if current_adapter:
net_info.append(adapter_info)
adapter_info = {}

current_adapter = line.split(':')[0].strip()
adapter_info = {
'name': current_adapter,
'ipv4': [],
'ipv6': [],
'mac': None,
'dns': [],
'gateway': []
}

# Parse MAC address


if 'physical address' in line.lower():
mac = line.split(':')[-1].strip()
adapter_info['mac'] = mac

# Parse IPv4 address


if 'ipv4 address' in line.lower():
ip_match = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
if ip_match:
adapter_info['ipv4'].append({
'address': ip_match.group(1),
'netmask': '255.255.255.0' # Simplified for display
})

# Parse DNS servers


if 'dns servers' in line.lower():
dns_match = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
if dns_match:
adapter_info['dns'].append(dns_match.group(1))

# Parse default gateway


if 'default gateway' in line.lower():
gw_match = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
if gw_match:
adapter_info['gateway'].append(gw_match.group(1))

# Add last adapter


if current_adapter:
net_info.append(adapter_info)

return net_info
except Exception as e:
log_sync.add_log(f"Error getting network info: {str(e)}")
return []

# =========================
# FLASK WEB PANEL (Backend)
# =========================
app = Flask(__name__, template_folder='', static_folder='')

@app.route('/')
def index():
return render_template('index.html')

@app.route('/system_info')
def system_info():
return jsonify({
"specs": get_system_specs(),
"performance": get_performance_data()
})

@app.route('/get_logs')
def get_logs():
return jsonify(logs=log_sync.logs)

@app.route('/get_interfaces')
def get_interfaces():
return jsonify(interfaces=get_ethernet_interfaces())

@app.route('/get_network_info')
def get_network_info_route():
return jsonify(network_info=get_network_info())

@app.route('/update_ip_settings', methods=['POST'])
def update_ip_settings():
data = request.json
interface = data.get('interface')
mode = data.get('mode')
ip = data.get('ip')
mask = data.get('mask')
gateway = data.get('gateway')

if mode == 'static':
success, message = set_static_ip(interface, ip, mask, gateway)
else:
success, message = set_dhcp_ip(interface)

log_sync.add_log(f"IP settings updated: {message}")


return jsonify(success=success, message=message)

@app.route('/update_dns_settings', methods=['POST'])
def update_dns_settings():
data = request.json
interface = data.get('interface')
mode = data.get('mode')
dns1 = data.get('dns1')
dns2 = data.get('dns2')

if mode == 'static':
success, message = set_static_dns(interface, dns1, dns2)
else:
success, message = set_dhcp_dns(interface)

log_sync.add_log(f"DNS settings updated: {message}")


return jsonify(success=success, message=message)

@app.route('/update_datetime', methods=['POST'])
def update_datetime():
data = request.json
date_str = data.get('date')
time_str = data.get('time')

try:
# Create datetime object
dt = datetime.datetime.strptime(f"{date_str} {time_str}", "%Y/%m/%d %H:%M:
%S")

# Format for Windows command


date_cmd = dt.strftime("%m/%d/%Y")
time_cmd = dt.strftime("%H:%M:%S")

# Run commands in background


startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

subprocess.run(f'date {date_cmd}', startupinfo=startupinfo, shell=True,


check=True)
subprocess.run(f'time {time_cmd}', startupinfo=startupinfo, shell=True,
check=True)

message = f"System date/time updated to {date_str} {time_str}"


log_sync.add_log(message)
return jsonify(success=True, message=message)
except Exception as e:
message = f"Error updating date/time: {str(e)}"
log_sync.add_log(message)
return jsonify(success=False, message=message)

@app.route('/export_logs')
def export_logs():
log_content = "\n".join(log_sync.logs)
with open("panel_logs.lsremplog", "w") as f:
f.write(log_content)
return send_file("panel_logs.lsremplog", as_attachment=True)

# =====================
# TKINTER CONTROL PANEL
# =====================
class ControlPanel:
def __init__(self, root):
self.root = root
self.root.title("Teknir Control Panel")
self.root.geometry("800x500")
self.root.configure(bg='#2d2d39')

self.create_widgets()
self.server_running = False
self.server_thread = None
self.status_frame = None
def create_widgets(self):
# Header
header = tk.Frame(self.root, bg='#1e1e2d', height=50)
header.pack(fill='x')

tk.Label(header, text="TEKNIR CONTROL PANEL", font=("System", 14),


fg="white", bg='#1e1e2d').pack(side='left', padx=20)

# Control buttons
btn_frame = tk.Frame(header, bg='#1e1e2d')
btn_frame.pack(side='right', padx=20)

self.start_btn = tk.Button(btn_frame, text="Start Server",


command=self.toggle_server,
bg='#4CAF50', fg='white', relief='flat')
self.start_btn.pack(side='right', padx=5)

# Log display
log_frame = tk.LabelFrame(self.root, text="Server Logs", font=("System",
10),
fg="white", bg='#2d2d39', bd=1, relief='sunken')
log_frame.pack(fill='both', expand=True, padx=10, pady=10)

self.log_area = scrolledtext.ScrolledText(log_frame, bg='#1e1e2d',


fg='#e0e0e0',
font=("Consolas", 10), wrap='word')
self.log_area.pack(fill='both', expand=True, padx=5, pady=5)
self.log_area.config(state='disabled')

# Add initial logs


log_sync.add_log("Control panel initialized")
self.update_log_display()

# Status frame for messages


self.status_frame = tk.Frame(self.root, bg='#2d2d39')
self.status_frame.pack(fill='x', padx=10, pady=(0, 10))

def show_status(self, message, is_error=False):


if not self.status_frame:
return

for widget in self.status_frame.winfo_children():


widget.destroy()

color = '#f44336' if is_error else '#4CAF50'


lbl = tk.Label(self.status_frame, text=message, fg='white', bg=color,
font=("System", 10), padx=10, pady=5)
lbl.pack(fill='x', ipady=5)

# Auto-hide after 5 seconds


self.root.after(5000, lambda: lbl.destroy() if lbl.winfo_exists() else
None)

def toggle_server(self):
if not self.server_running:
self.start_server()
else:
self.stop_server()
def start_server(self):
def run_flask():
app.run(port=SERVER_PORT, debug=False, use_reloader=False)

self.server_thread = threading.Thread(target=run_flask, daemon=True)


self.server_thread.start()
self.server_running = True
self.start_btn.config(text="Stop Server", bg='#f44336')
log_sync.add_log(f"Web server started on port {SERVER_PORT}")
log_sync.add_log(f"Access panel at: http://localhost:{SERVER_PORT}")
self.update_log_display()
self.show_status("Server started successfully", False)

def stop_server(self):
self.server_running = False
self.start_btn.config(text="Start Server", bg='#4CAF50')
log_sync.add_log("Web server stopped")
self.update_log_display()
self.show_status("Server stopped", False)

def update_log_display(self):
self.log_area.config(state='normal')
self.log_area.delete(1.0, tk.END)
for log in log_sync.logs:
self.log_area.insert(tk.END, log + '\n')
self.log_area.config(state='disabled')
self.log_area.yview(tk.END)
self.root.after(1000, self.update_log_display)

# ===================
# HTML/CSS/JS CONTENT
# ===================
html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Teknir Web Panel</title>
<style>
:root {
--bg-primary: #2d2d39;
--bg-secondary: #1e1e2d;
--bg-tertiary: #252533;
--text-primary: #e0e0e0;
--text-secondary: #a0a0b0;
--accent: #4d7cff;
--success: #4CAF50;
--error: #f44336;
--warning: #FF9800;
--sidebar-width: 250px;
--transition-speed: 0.3s;
}

[data-theme="light"] {
--bg-primary: #f5f5f7;
--bg-secondary: #ffffff;
--bg-tertiary: #eaeaea;
--text-primary: #333333;
--text-secondary: #666666;
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'system-ui', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
'Open Sans', 'Helvetica Neue', sans-serif;
}

body {
background-color: var(--bg-primary);
color: var(--text-primary);
display: flex;
min-height: 100vh;
overflow: hidden;
transition: background-color var(--transition-speed);
}

.sidebar {
width: var(--sidebar-width);
background: var(--bg-secondary);
height: 100vh;
padding: 20px 0;
transition: width var(--transition-speed);
overflow-y: auto;
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
z-index: 100;
}

.sidebar.collapsed {
width: 60px;
}

.sidebar-header {
padding: 0 20px 20px;
border-bottom: 1px solid var(--bg-tertiary);
margin-bottom: 20px;
}

.sidebar-header h2 {
font-size: 1.2rem;
white-space: nowrap;
overflow: hidden;
}

.sidebar.collapsed .sidebar-header h2 {
display: none;
}

.section-title {
padding: 10px 20px;
color: var(--text-secondary);
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 1px;
white-space: nowrap;
}

.sidebar.collapsed .section-title {
display: none;
}

.nav-item {
display: flex;
align-items: center;
padding: 12px 20px;
color: var(--text-primary);
text-decoration: none;
transition: all 0.2s;
white-space: nowrap;
}

.nav-item:hover {
background: var(--bg-tertiary);
}

.nav-item.active {
background: var(--bg-tertiary);
border-left: 4px solid var(--accent);
}

.nav-icon {
margin-right: 15px;
font-size: 1.2rem;
}

.sidebar.collapsed .nav-text {
display: none;
}

.main-content {
flex: 1;
display: flex;
flex-direction: column;
overflow-y: auto;
height: 100vh;
transition: margin-left var(--transition-speed);
}

.topbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px;
background: var(--bg-secondary);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
z-index: 10;
}

.theme-toggle {
background: var(--bg-tertiary);
border: none;
color: var(--text-primary);
padding: 8px 15px;
border-radius: 20px;
cursor: pointer;
display: flex;
align-items: center;
transition: background 0.3s;
}

.sidebar-toggle {
background: none;
border: none;
color: var(--text-primary);
font-size: 1.5rem;
cursor: pointer;
margin-right: 15px;
}

.controls {
display: flex;
align-items: center;
}

.tehran-time {
margin: 0 15px;
font-size: 0.9rem;
font-weight: 500;
}

.ping-status {
margin: 0 15px;
padding: 5px 10px;
border-radius: 20px;
font-size: 0.9rem;
font-weight: 500;
}

.ping-connected {
background: rgba(76, 175, 80, 0.2);
border: 1px solid #4CAF50;
color: #4CAF50;
}

.ping-disconnected {
background: rgba(244, 67, 54, 0.2);
border: 1px solid #f44336;
color: #f44336;
}

.content-area {
padding: 20px;
flex: 1;
overflow-y: auto;
}

/* Hide scrollbars */
.content-area::-webkit-scrollbar,
.sidebar::-webkit-scrollbar,
.log-container::-webkit-scrollbar {
width: 0;
height: 0;
background: transparent;
}

.card {
background: var(--bg-secondary);
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
}

.card-title {
font-size: 1.2rem;
margin-bottom: 20px;
display: flex;
align-items: center;
}

.card-title i {
margin-right: 10px;
}

.metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}

.metric-card {
background: var(--bg-tertiary);
border-radius: 8px;
padding: 15px;
}

.metric-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}

.metric-title {
font-weight: 500;
}

.metric-value {
font-size: 1.8rem;
font-weight: bold;
margin: 10px 0;
}

.progress-bar {
height: 10px;
background: var(--bg-primary);
border-radius: 5px;
overflow: hidden;
}

.progress {
height: 100%;
background: var(--accent);
border-radius: 5px;
transition: width 0.5s;
}

.specs-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 15px;
}

.spec-item {
background: var(--bg-tertiary);
padding: 15px;
border-radius: 8px;
}

.spec-label {
color: var(--text-secondary);
font-size: 0.9rem;
margin-bottom: 5px;
}

.spec-value {
font-weight: 500;
}

.log-container {
background: var(--bg-tertiary);
border-radius: 8px;
padding: 15px;
height: 400px;
overflow-y: auto;
font-family: monospace;
font-size: 0.9rem;
white-space: pre-wrap;
}

.log-entry {
margin-bottom: 5px;
line-height: 1.4;
}

.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}

.form-group {
margin-bottom: 15px;
}

.form-label {
display: block;
margin-bottom: 5px;
font-weight: 500;
}

.form-input, .form-select {
width: 100%;
padding: 10px;
background: var(--bg-tertiary);
border: 1px solid var(--bg-primary);
border-radius: 5px;
color: var(--text-primary);
}

.btn {
padding: 10px 20px;
background: var(--accent);
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: 500;
transition: background 0.3s;
margin-right: 10px;
}

.btn:hover {
background: #3a6bff;
}

.btn-secondary {
background: var(--bg-tertiary);
}

.btn-secondary:hover {
background: #333342;
}

.hidden {
display: none;
}

.mode-toggle {
display: flex;
align-items: center;
margin-bottom: 15px;
}

.mode-option {
margin-right: 15px;
}

.netinfo-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 20px;
}

.netinfo-card {
background: var(--bg-tertiary);
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
}
.netinfo-header {
font-weight: bold;
margin-bottom: 10px;
border-bottom: 1px solid var(--bg-primary);
padding-bottom: 5px;
}

.netinfo-item {
margin-bottom: 8px;
}

.netinfo-label {
font-weight: 500;
color: var(--text-secondary);
}

.status-message {
padding: 10px;
margin-bottom: 15px;
border-radius: 5px;
font-weight: 500;
}

.status-success {
background: rgba(76, 175, 80, 0.2);
border: 1px solid #4CAF50;
color: #4CAF50;
}

.status-error {
background: rgba(244, 67, 54, 0.2);
border: 1px solid #f44336;
color: #f44336;
}
</style>
</head>
<body>
<!-- Sidebar -->
<div class="sidebar" id="sidebar">
<div class="sidebar-header">
<h2>Teknir Panel</h2>
</div>

<!-- STATUS Section -->


<div class="section-title">STATUS</div>
<a href="#" class="nav-item active" data-page="dashboard">
<span class="nav-icon">📊</span>
<span class="nav-text">Dashboard</span>
</a>
<a href="#" class="nav-item" data-page="logs">
<span class="nav-icon">📝</span>
<span class="nav-text">Panel Logs</span>
</a>

<!-- INBOUND Section -->


<div class="section-title">INBOUND</div>
<a href="#" class="nav-item" data-page="ipv4">
<span class="nav-icon">🔌</span>
<span class="nav-text">IPv4 Settings</span>
</a>
<a href="#" class="nav-item" data-page="dns">
<span class="nav-icon">🌐</span>
<span class="nav-text">DNS Configuration</span>
</a>

<!-- SYSTEM Section -->


<div class="section-title">SYSTEM</div>
<a href="#" class="nav-item" data-page="datetime">
<span class="nav-icon">🕒</span>
<span class="nav-text">Date & Time</span>
</a>
<a href="#" class="nav-item" data-page="report">
<span class="nav-icon">📋</span>
<span class="nav-text">Report</span>
</a>

<!-- Netinf Section -->


<div class="section-title">NETINF</div>
<a href="#" class="nav-item" data-page="netinfo">
<span class="nav-icon">📡</span>
<span class="nav-text">Network Info</span>
</a>
</div>

<!-- Main Content -->


<div class="main-content">
<div class="topbar">
<div class="controls">
<button class="sidebar-toggle" id="sidebarToggle">☰</button>
<h3 id="pageTitle">Dashboard</h3>
</div>
<div class="tehran-time" id="tehranTime">Tehran 00:00:00</div>
<div id="pingStatus" class="ping-status ping-
disconnected">Disconnected: 0ms</div>
<button class="theme-toggle" id="themeToggle">
<span id="themeIcon">🌙</span> Dark Mode
</button>
</div>

<div class="content-area">
<!-- Dashboard Page -->
<div id="dashboardPage">
<div class="card">
<div class="card-title">📈 Performance Metrics</div>
<div class="metrics">
<div class="metric-card">
<div class="metric-header">
<div class="metric-title">CPU Usage</div>
<div id="cpuValue">0%</div>
</div>
<div class="progress-bar">
<div class="progress" id="cpuProgress"
style="width: 0%"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-header">
<div class="metric-title">Memory Usage</div>
<div id="memValue">0%</div>
</div>
<div class="progress-bar">
<div class="progress" id="memProgress"
style="width: 0%"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-header">
<div class="metric-title">Network Activity</div>
<div id="netValue">0 KB/s</div>
</div>
<div class="progress-bar">
<div class="progress" id="netProgress"
style="width: 0%"></div>
</div>
</div>
</div>
</div>

<div class="card">
<div class="card-title"> System Specifications</div>
<div class="specs-grid" id="specsGrid">
<!-- Dynamically populated -->
</div>
</div>
</div>

<!-- Logs Page -->


<div id="logsPage" class="hidden">
<div class="card">
<div class="card-title">📋 Panel Logs</div>
<div class="log-container" id="logContainer">
<!-- Logs will be populated here -->
</div>
</div>
</div>

<!-- IPv4 Settings Page -->


<div id="ipv4Page" class="hidden">
<div class="card">
<div class="card-title">🔌 IPv4 Configuration</div>

<div class="form-group">
<label class="form-label">Interface Name</label>
<select class="form-select" id="ipInterface">
<!-- Populated by JavaScript -->
</select>
</div>

<div class="mode-toggle">
<div class="mode-option">
<input type="radio" id="ipModeStatic" name="ipMode"
value="static" checked>
<label for="ipModeStatic">Static IP</label>
</div>
<div class="mode-option">
<input type="radio" id="ipModeDHCP" name="ipMode"
value="dhcp">
<label for="ipModeDHCP">DHCP (Automatic)</label>
</div>
</div>

<div id="ipStaticSettings">
<div class="form-grid">
<div class="form-group">
<label class="form-label">IP Address</label>
<input type="text" class="form-input"
id="ipAddress" value="169.254.2.10">
</div>
<div class="form-group">
<label class="form-label">Subnet Mask</label>
<input type="text" class="form-input"
id="subnetMask" value="255.255.255.0">
</div>
<div class="form-group">
<label class="form-label">Default Gateway</label>
<input type="text" class="form-input"
id="defaultGateway" value="169.254.2.2">
</div>
</div>
</div>

<div class="form-group">
<button class="btn" id="saveIPv4">Save Settings</button>
<button class="btn btn-secondary" id="resetIPv4">Reset to
Default</button>
</div>

<div id="ipResult" class="form-group"></div>


</div>
</div>

<!-- DNS Settings Page -->


<div id="dnsPage" class="hidden">
<div class="card">
<div class="card-title">🌐 DNS Configuration</div>

<div class="form-group">
<label class="form-label">Interface Name</label>
<select class="form-select" id="dnsInterface">
<!-- Populated by JavaScript -->
</select>
</div>

<div class="mode-toggle">
<div class="mode-option">
<input type="radio" id="dnsModeStatic" name="dnsMode"
value="static" checked>
<label for="dnsModeStatic">Static DNS</label>
</div>
<div class="mode-option">
<input type="radio" id="dnsModeDHCP" name="dnsMode"
value="dhcp">
<label for="dnsModeDHCP">DHCP (Automatic)</label>
</div>
</div>
<div id="dnsStaticSettings">
<div class="form-grid">
<div class="form-group">
<label class="form-label">Primary DNS</label>
<input type="text" class="form-input" id="dns1"
value="8.8.8.8">
</div>
<div class="form-group">
<label class="form-label">Secondary DNS</label>
<input type="text" class="form-input" id="dns2"
value="8.8.4.4">
</div>
</div>
</div>

<div class="form-group">
<button class="btn" id="saveDNS">Save Settings</button>
<button class="btn btn-secondary" id="resetDNS">Reset to
Default</button>
</div>

<div id="dnsResult" class="form-group"></div>


</div>
</div>

<!-- Date & Time Page -->


<div id="datetimePage" class="hidden">
<div class="card">
<div class="card-title">🕒 Date & Time Settings</div>
<div class="form-grid">
<div class="form-group">
<label class="form-label">Date (YYYY/MM/DD)</label>
<input type="text" class="form-input" id="dateInput"
value="2038/01/01">
</div>
<div class="form-group">
<label class="form-label">Time (HH:MM:SS)</label>
<input type="text" class="form-input" id="timeInput"
value="00:00:00">
</div>
</div>
<div class="form-group">
<button class="btn" id="saveDateTime">Save
Settings</button>
<button class="btn btn-secondary" id="resetDateTime">Reset
to Default</button>
</div>
<div id="datetimeResult" class="form-group"></div>
</div>
</div>

<!-- Report Page -->


<div id="reportPage" class="hidden">
<div class="card">
<div class="card-title">📋 System Report</div>
<div class="log-container" id="reportContainer">
<!-- Report will be populated here -->
</div>
<button class="btn" id="exportLogs" style="margin-top:
20px;">Export Logs</button>
</div>
</div>

<!-- Network Info Page -->


<div id="netinfoPage" class="hidden">
<div class="card">
<div class="card-title">📡 Network Information</div>
<div id="netinfoContent" class="netinfo-grid">
<!-- Will be populated by JavaScript -->
</div>
</div>
</div>
</div>
</div>

<script>
// DOM Elements
const sidebar = document.getElementById('sidebar');
const sidebarToggle = document.getElementById('sidebarToggle');
const themeToggle = document.getElementById('themeToggle');
const themeIcon = document.getElementById('themeIcon');
const navItems = document.querySelectorAll('.nav-item');
const pages = {
dashboard: document.getElementById('dashboardPage'),
logs: document.getElementById('logsPage'),
ipv4: document.getElementById('ipv4Page'),
dns: document.getElementById('dnsPage'),
datetime: document.getElementById('datetimePage'),
report: document.getElementById('reportPage'),
netinfo: document.getElementById('netinfoPage')
};
const pageTitle = document.getElementById('pageTitle');
const tehranTime = document.getElementById('tehranTime');
const pingStatus = document.getElementById('pingStatus');

// Toggle Sidebar
sidebarToggle.addEventListener('click', () => {
sidebar.classList.toggle('collapsed');
});

// Theme Toggle
themeToggle.addEventListener('click', () => {
const isDark = document.body.getAttribute('data-theme') !== 'light';
document.body.setAttribute('data-theme', isDark ? 'light' : '');
themeIcon.textContent = isDark ? '☀️' : '';
themeToggle.innerHTML = `${themeIcon.outerHTML} ${isDark ? 'Light' :
'Dark'} Mode`;
});

// Navigation
navItems.forEach(item => {
item.addEventListener('click', (e) => {
e.preventDefault();
const page = item.getAttribute('data-page');

// Update active nav item


navItems.forEach(nav => nav.classList.remove('active'));
item.classList.add('active');
// Show selected page
Object.values(pages).forEach(p => {
if (p) p.classList.add('hidden');
});

if (pages[page]) {
pages[page].classList.remove('hidden');
pageTitle.textContent = item.querySelector('.nav-
text').textContent;

// Special handling for certain pages


if (page === 'netinfo') {
updateNetworkInfo();
} else if (page === 'ipv4' || page === 'dns') {
loadInterfaces();
}
}
});
});

// Tehran Time
function updateTehranTime() {
const now = new Date();
const tehranTimeStr = now.toLocaleString("en-US", {
timeZone: "Asia/Tehran",
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
document.getElementById('tehranTime').textContent = `Tehran $
{tehranTimeStr}`;
}

// Ping Status
function updatePingStatus() {
const pingStatus = document.getElementById('pingStatus');
if (!pingStatus) return;

pingStatus.textContent = `${ping_status}: ${ping_time}`;


if (ping_status === "Connected") {
pingStatus.className = 'ping-status ping-connected';
} else {
pingStatus.className = 'ping-status ping-disconnected';
}
}

// Performance Metrics
async function updatePerformance() {
try {
const response = await fetch('/system_info');
const data = await response.json();

// CPU
const cpuPercent = data.performance.cpu || 0;
document.getElementById('cpuValue').textContent = `${cpuPercent}%`;
document.getElementById('cpuProgress').style.width = `${cpuPercent}
%`;
// Memory
const memPercent = data.performance.memory || 0;
document.getElementById('memValue').textContent = `${memPercent}%`;
document.getElementById('memProgress').style.width = `${memPercent}
%`;

// Network - show KB/s and use dynamic scaling for progress bar
const netKB = Math.round(data.performance.network || 0);
document.getElementById('netValue').textContent = `${netKB} KB/s`;

// Dynamic scaling for network progress bar (0-500 KB/s range)


const netPercentage = Math.min(netKB / 5, 100); // 500 KB/s = 100%
document.getElementById('netProgress').style.width = `$
{netPercentage}%`;

// Update specs
const specsGrid = document.getElementById('specsGrid');
if (specsGrid) {
specsGrid.innerHTML = '';

for (const [key, value] of Object.entries(data.specs || {})) {


const specItem = document.createElement('div');
specItem.className = 'spec-item';
specItem.innerHTML = `
<div class="spec-label">${key.replace(/_/g, '
').toUpperCase()}</div>
<div class="spec-value">${value}</div>
`;
specsGrid.appendChild(specItem);
}
}

// Update ping status


updatePingStatus();

} catch (error) {
console.error('Failed to fetch system info:', error);
}
}

// Logs Display
async function updateLogs() {
try {
const response = await fetch('/get_logs');
const data = await response.json();
const logContainer = document.getElementById('logContainer');

if (logContainer) {
logContainer.innerHTML = data.logs.map(log =>
`<div class="log-entry">${log}</div>`
).join('');

// Auto-scroll to bottom
logContainer.scrollTop = logContainer.scrollHeight;
}

// Also update report page if it's open


const reportContainer = document.getElementById('reportContainer');
if (reportContainer) {
reportContainer.innerHTML = data.logs.map(log =>
`<div class="log-entry">${log}</div>`
).join('');
}

} catch (error) {
console.error('Failed to fetch logs:', error);
}
}

// Load network interfaces


async function loadInterfaces() {
try {
const response = await fetch('/get_interfaces');
const data = await response.json();

const ipSelect = document.getElementById('ipInterface');


const dnsSelect = document.getElementById('dnsInterface');

// Clear existing options


if (ipSelect) ipSelect.innerHTML = '';
if (dnsSelect) dnsSelect.innerHTML = '';

// Add new options


if (data.interfaces && data.interfaces.length > 0) {
data.interfaces.forEach(iface => {
const option = document.createElement('option');
option.value = iface;
option.textContent = iface;
if (ipSelect) ipSelect.appendChild(option.cloneNode(true));
if (dnsSelect) dnsSelect.appendChild(option);
});

// Select first interface by default


if (ipSelect) ipSelect.selectedIndex = 0;
if (dnsSelect) dnsSelect.selectedIndex = 0;
} else {
// Fallback if no interfaces found
const option = document.createElement('option');
option.textContent = 'No interfaces found';
if (ipSelect) ipSelect.appendChild(option.cloneNode(true));
if (dnsSelect) dnsSelect.appendChild(option);
}

} catch (error) {
console.error('Failed to load interfaces:', error);
}
}

// Save IPv4 Settings


document.getElementById('saveIPv4').addEventListener('click', async () => {
const interface = document.getElementById('ipInterface').value;
const mode =
document.querySelector('input[name="ipMode"]:checked').value;
const ip = document.getElementById('ipAddress').value;
const mask = document.getElementById('subnetMask').value;
const gateway = document.getElementById('defaultGateway').value;
const resultDiv = document.getElementById('ipResult');
resultDiv.innerHTML = '<div class="status-message status-
success">Applying settings...</div>';

try {
const response = await fetch('/update_ip_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ interface, mode, ip, mask, gateway })
});

const data = await response.json();


const statusClass = data.success ? 'status-success' : 'status-
error';
resultDiv.innerHTML = `<div class="status-message ${statusClass}">$
{data.message}</div>`;
updateLogs();
} catch (error) {
resultDiv.innerHTML = `<div class="status-message status-
error">Error: ${error.message}</div>`;
}
});

// Reset IPv4 Settings


document.getElementById('resetIPv4').addEventListener('click', () => {
document.getElementById('ipAddress').value = '169.254.2.10';
document.getElementById('subnetMask').value = '255.255.255.0';
document.getElementById('defaultGateway').value = '169.254.2.2';
document.getElementById('ipResult').innerHTML = '';
});

// Save DNS Settings


document.getElementById('saveDNS').addEventListener('click', async () => {
const interface = document.getElementById('dnsInterface').value;
const mode =
document.querySelector('input[name="dnsMode"]:checked').value;
const dns1 = document.getElementById('dns1').value;
const dns2 = document.getElementById('dns2').value;

const resultDiv = document.getElementById('dnsResult');


resultDiv.innerHTML = '<div class="status-message status-
success">Applying settings...</div>';

try {
const response = await fetch('/update_dns_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ interface, mode, dns1, dns2 })
});

const data = await response.json();


const statusClass = data.success ? 'status-success' : 'status-
error';
resultDiv.innerHTML = `<div class="status-message ${statusClass}">$
{data.message}</div>`;
updateLogs();
} catch (error) {
resultDiv.innerHTML = `<div class="status-message status-
error">Error: ${error.message}</div>`;
}
});

// Reset DNS Settings


document.getElementById('resetDNS').addEventListener('click', () => {
document.getElementById('dns1').value = '8.8.8.8';
document.getElementById('dns2').value = '8.8.4.4';
document.getElementById('dnsResult').innerHTML = '';
});

// Save Date & Time


document.getElementById('saveDateTime').addEventListener('click', async ()
=> {
const date = document.getElementById('dateInput').value;
const time = document.getElementById('timeInput').value;

const resultDiv = document.getElementById('datetimeResult');


resultDiv.innerHTML = '<div class="status-message status-
success">Applying settings...</div>';

try {
const response = await fetch('/update_datetime', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ date, time })
});

const data = await response.json();


const statusClass = data.success ? 'status-success' : 'status-
error';
resultDiv.innerHTML = `<div class="status-message ${statusClass}">$
{data.message}</div>`;
updateLogs();
} catch (error) {
resultDiv.innerHTML = `<div class="status-message status-
error">Error: ${error.message}</div>`;
}
});

// Reset Date & Time


document.getElementById('resetDateTime').addEventListener('click', () => {
document.getElementById('dateInput').value = '2038/01/01';
document.getElementById('timeInput').value = '00:00:00';
document.getElementById('datetimeResult').innerHTML = '';
});

// Export Logs
document.getElementById('exportLogs').addEventListener('click', () => {
window.location.href = '/export_logs';
});

// Update Network Info


async function updateNetworkInfo() {
try {
const response = await fetch('/get_network_info');
const data = await response.json();
const netinfoContent = document.getElementById('netinfoContent');

if (!netinfoContent) return;
netinfoContent.innerHTML = '';

if (!data.network_info || data.network_info.length === 0) {


netinfoContent.innerHTML = '<div class="status-message status-
error">No network information available</div>';
return;
}

data.network_info.forEach(iface => {
const card = document.createElement('div');
card.className = 'netinfo-card';

let content = `<div


class="netinfo-header">${iface.name}</div>`;

if (iface.mac) {
content += `<div class="netinfo-item"><span class="netinfo-
label">MAC Address:</span> ${iface.mac}</div>`;
}

if (iface.ipv4 && iface.ipv4.length > 0) {


content += '<div class="netinfo-item"><span class="netinfo-
label">IPv4:</span></div>';
iface.ipv4.forEach(addr => {
content += `<div class="netinfo-item">- Address: $
{addr.address || 'N/A'}</div>`;
content += `<div class="netinfo-item">- Netmask: $
{addr.netmask || 'N/A'}</div>`;
});
}

if (iface.dns && iface.dns.length > 0) {


content += '<div class="netinfo-item"><span class="netinfo-
label">DNS Servers:</span></div>';
iface.dns.forEach(dns => {
content += `<div class="netinfo-item">- ${dns}</div>`;
});
}

if (iface.gateway && iface.gateway.length > 0) {


content += '<div class="netinfo-item"><span class="netinfo-
label">Gateway:</span></div>';
iface.gateway.forEach(gw => {
content += `<div class="netinfo-item">- ${gw}</div>`;
});
}

card.innerHTML = content;
netinfoContent.appendChild(card);
});

} catch (error) {
netinfoContent.innerHTML = `<div class="status-message status-
error">Error loading network info: ${error.message}</div>`;
}
}

// Toggle DHCP/Static fields


if (document.getElementById('ipModeDHCP')) {
document.getElementById('ipModeDHCP').addEventListener('change', () =>
{
document.getElementById('ipStaticSettings').style.display = 'none';
});

document.getElementById('ipModeStatic').addEventListener('change', ()
=> {
document.getElementById('ipStaticSettings').style.display =
'block';
});
}

if (document.getElementById('dnsModeDHCP')) {
document.getElementById('dnsModeDHCP').addEventListener('change', () =>
{
document.getElementById('dnsStaticSettings').style.display =
'none';
});

document.getElementById('dnsModeStatic').addEventListener('change', ()
=> {
document.getElementById('dnsStaticSettings').style.display =
'block';
});
}

// Initialize
updatePerformance();
updateLogs();
updateTehranTime();
updatePingStatus();
setInterval(updatePerformance, 1000);
setInterval(updateLogs, 3000);
setInterval(updateTehranTime, 1000);
loadInterfaces();
</script>
</body>
</html>
"""

# =====================
# MAIN APPLICATION
# =====================
if __name__ == "__main__":
# Initialize network monitoring
net_io = psutil.net_io_counters()
prev_bytes_sent = net_io.bytes_sent
prev_bytes_recv = net_io.bytes_recv
prev_time = time.time()

# Create temporary files for Flask


with open("index.html", "w", encoding="utf-8") as f:
f.write(html_content)

# Start Tkinter control panel


root = tk.Tk()
app_ui = ControlPanel(root)
root.mainloop()

You might also like