Scripts
Scripts
# ====================
# 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'
}
# CPU monitoring
cpu_percent = 0
def monitor_cpu():
global cpu_percent
while True:
cpu_percent = psutil.cpu_percent(interval=1)
# 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)
# =================
# LOGGING MECHANISM
# =================
class LogSync:
def __init__(self):
self.logs = []
self.lock = threading.Lock()
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
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')
return interfaces
except Exception as e:
log_sync.add_log(f"Error getting interfaces: {str(e)}")
return ["Ethernet"] # Default fallback
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
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
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 = {}
current_adapter = line.split(':')[0].strip()
adapter_info = {
'name': current_adapter,
'ipv4': [],
'ipv6': [],
'mac': None,
'dns': [],
'gateway': []
}
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)
@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)
@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")
@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')
# Control buttons
btn_frame = tk.Frame(header, bg='#1e1e2d')
btn_frame.pack(side='right', padx=20)
# 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)
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)
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>
<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>
<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 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>
<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');
if (pages[page]) {
pages[page].classList.remove('hidden');
pageTitle.textContent = item.querySelector('.nav-
text').textContent;
// 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;
// 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`;
// Update specs
const specsGrid = document.getElementById('specsGrid');
if (specsGrid) {
specsGrid.innerHTML = '';
} 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;
}
} catch (error) {
console.error('Failed to fetch logs:', error);
}
}
} catch (error) {
console.error('Failed to load interfaces:', error);
}
}
try {
const response = await fetch('/update_ip_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ interface, mode, ip, mask, gateway })
});
try {
const response = await fetch('/update_dns_settings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ interface, mode, dns1, dns2 })
});
try {
const response = await fetch('/update_datetime', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ date, time })
});
// Export Logs
document.getElementById('exportLogs').addEventListener('click', () => {
window.location.href = '/export_logs';
});
if (!netinfoContent) return;
netinfoContent.innerHTML = '';
data.network_info.forEach(iface => {
const card = document.createElement('div');
card.className = 'netinfo-card';
if (iface.mac) {
content += `<div class="netinfo-item"><span class="netinfo-
label">MAC Address:</span> ${iface.mac}</div>`;
}
card.innerHTML = content;
netinfoContent.appendChild(card);
});
} catch (error) {
netinfoContent.innerHTML = `<div class="status-message status-
error">Error loading network info: ${error.message}</div>`;
}
}
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()