mirror of
https://github.com/MikroWizard/mikroman.git
synced 2025-06-26 07:08:36 +02:00
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:
parent
81a1172660
commit
ccfe9f622c
3 changed files with 124 additions and 2 deletions
|
@ -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'])
|
||||||
|
|
|
@ -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
78
py/libs/ping.py
Normal 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))
|
Loading…
Add table
Add a link
Reference in a new issue