Added ping data

Device details page now displays current active users
Added ability to terminate active user sessions
Enhanced License Information
This commit is contained in:
sepehr 2025-02-03 12:29:37 +03:00
parent 81a1172660
commit ccfe9f622c
3 changed files with 124 additions and 2 deletions

View file

@ -8,12 +8,11 @@
from flask import request,redirect ,session from flask import request,redirect ,session
import datetime import datetime
import html import html
import config import config
import re import re
from libs.red import RedisDB from libs.red import RedisDB
from libs.webutil import app,buildResponse,login_required,get_myself,get_ip,get_agent from libs.webutil import app,buildResponse,login_required,get_myself,get_ip,get_agent
from libs import util from libs import util,ping
from libs.db import db_device,db_groups,db_user_group_perm,db_user_tasks,db_sysconfig,db_syslog from libs.db import db_device,db_groups,db_user_group_perm,db_user_tasks,db_sysconfig,db_syslog
import logging import logging
import json import json
@ -299,12 +298,16 @@ def dev_info():
res=db_device.get_device(devid) res=db_device.get_device(devid)
options=util.build_api_options(db_device.get_devices_by_id([res['id'],])[0]) options=util.build_api_options(db_device.get_devices_by_id([res['id'],])[0])
network_info=[] network_info=[]
res['online']=True
try: try:
if util.check_port(options['host'],options['port']): if util.check_port(options['host'],options['port']):
router=util.RouterOSCheckResource(options) router=util.RouterOSCheckResource(options)
network_info=util.get_network_data(router) network_info=util.get_network_data(router)
del network_info['total'] del network_info['total']
else:
res['online']=False
except: except:
res['online']=False
pass pass
interfaces=[] interfaces=[]
for iface in network_info: for iface in network_info:
@ -325,6 +328,45 @@ def dev_info():
log.error(e) log.error(e)
return buildResponse({'status': 'failed'}, 200, error="Wrong Data") return buildResponse({'status': 'failed'}, 200, error="Wrong Data")
pass pass
try:
res['active_users']=[]
if res['online']:
res['active_users']=tuple(router.api("/user/active/print"))
except:
res['active_users']=[]
try:
res['ping']=ping.get_ping_results(res['ip'], 5, 1)
except Exception as e:
res['ping']=[]
return buildResponse(res,200)
@app.route('/api/dev/kill_session', methods = ['POST'])
@login_required(role='admin',perm={'device':'full'})
def dev_kill_session():
"""return dev info"""
input = request.json
devid=input.get('devid',False)
item=input.get('item',False)
if not devid or not isinstance(devid, int):
return buildResponse({'status': 'failed'},200,error="Wrong Data")
try:
dev=db_device.get_devices_by_id([devid,])[0]
except:
return buildResponse({'status': 'failed'},200,error="Wrong Data")
if not dev:
return buildResponse({'status': 'failed'},200,error="Wrong Data")
options=util.build_api_options(dev)
router=util.RouterOSCheckResource(options)
# active_users=tuple(router.api("/user/active/print"))
# if item in active_users:
try:
acturl=router.api.path("user","active")
res=tuple(acturl('request-logout', **{'.id': item['.id']}))
log.error(res)
except Exception as e:
log.error(e)
pass
res=tuple(router.api("/user/active/print"))
return buildResponse(res,200) return buildResponse(res,200)
@app.route('/api/dev/sensors', methods = ['POST']) @app.route('/api/dev/sensors', methods = ['POST'])

View file

@ -402,6 +402,8 @@ def dashboard_stats():
# res['update_available']=True # res['update_available']=True
if username: if username:
res['username']=username res['username']=username
else:
res['username']=False
res['blog']=[] res['blog']=[]
noconnectiondata={ noconnectiondata={
"content": "Unable to connect to mikrowizard.com! please check server connection", "content": "Unable to connect to mikrowizard.com! please check server connection",

78
py/libs/ping.py Normal file
View file

@ -0,0 +1,78 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# ping.py: ping tool for MikroWizard
# MikroWizard.com , Mikrotik router management solution
# Author: sepehr.ha@gmail.com
import asyncio
import platform
def ping_quality(time_ms):
if time_ms is None:
return "unreachable", "fa-solid fa-times-circle", "#dc3545" # Red, times circle
if time_ms <= 50:
return "excellent", "fa-solid fa-check-circle", "#28a745" # Green, check circle
elif time_ms <= 100:
return "good", "fa-solid fa-thumbs-up", "#80c29e" # Light green, thumbs up
elif time_ms <= 200:
return "average", "fa-solid fa-exclamation-circle", "#ffc107" # Yellow, exclamation circle
else:
return "poor", "fa-solid fa-times-circle", "#dc3545" # Red, times circle
async def ping_host(host, timeout=1):
system = platform.system()
cmd = ["ping", "-c", "1", "-W", str(timeout), host]
process = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await process.communicate()
result = stdout.decode().strip()
error = stderr.decode().strip()
# Extract time from output
time_ms = None
if "time=" in result:
try:
time_part = result.split("time=")[-1].split()[0]
time_ms = float(time_part)
except ValueError:
pass
quality, icon, color = ping_quality(time_ms)
raw_response = result.split("\n")[0] if result else error.split("\n")[0]
return {
"host": host,
"status": "success" if time_ms is not None else "failed",
"time": time_ms if time_ms is not None else None,
"ping_quality": quality,
"icon": icon,
"color": color,
"raw_response": raw_response
}
async def multi_ping_one_host(host, count=4, timeout=1):
tasks = [ping_host(host, timeout) for _ in range(count)]
results = await asyncio.gather(*tasks)
successful_pings = [r["time"] for r in results if r["status"] == "success"]
failed_pings = count - len(successful_pings)
average_ping_time = round(sum(successful_pings) / len(successful_pings), 2) if successful_pings else None
response = {
"host": host,
"count": count,
"successful_pings": len(successful_pings),
"failed_pings": failed_pings,
"average_ping_time": average_ping_time,
"results": results
}
return response
def get_ping_results(host, count=4, timeout=1):
return asyncio.run(multi_ping_one_host(host, count, timeout))