This commit is contained in:
aceberg 2024-08-22 14:07:05 +07:00
parent 3a3bc5da09
commit 534c7cedb0
9 changed files with 122 additions and 158 deletions

View file

@ -4,9 +4,15 @@ import (
"net/http"
"github.com/gin-gonic/gin"
// "github.com/aceberg/WatchYourLAN/internal/models"
)
func apiAll(c *gin.Context) {
c.IndentedJSON(http.StatusOK, allHosts)
}
func apiHistory(c *gin.Context) {
c.IndentedJSON(http.StatusOK, histHosts)
}

View file

@ -10,8 +10,8 @@ var (
// appConfig - config for Web Gui
appConfig models.Conf
allHosts []models.Host
// histHosts []models.Host
allHosts []models.Host
histHosts []models.Host
quitScan chan bool
)

View file

@ -15,3 +15,11 @@ func indexHandler(c *gin.Context) {
c.HTML(http.StatusOK, "header.html", guiData)
c.HTML(http.StatusOK, "index.html", guiData)
}
func historyHandler(c *gin.Context) {
var guiData models.GuiData
guiData.Config = appConfig
c.HTML(http.StatusOK, "header.html", guiData)
c.HTML(http.StatusOK, "history.html", guiData)
}

View file

@ -1,45 +1,43 @@
var histArray = {};
var addrsArray = {};
loadHistory();
loadAddrs();
function createHTML(hist, i) {
let allState = "";
let color = "";
function createHTML(addr, i) {
let now = '';
for (let state of hist.State){
if (state.State) {
color = `bi-check-circle-fill" style="color:var(--bs-success);"`;
} else {
color = `bi-dash-circle-fill" style="color:var(--bs-danger);"`;
}
allState = allState + `<i class="bi ${color} title="${state.Date}"></i>`;
if (addr.Now == 0) {
now = `<i class="bi bi-circle-fill" style="color:var(--bs-gray-500);"></i>`;
} else {
now = `<i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>`;
}
let html = `
<tr>
<td style="opacity: 45%;">${i}.</td>
<td><a href="/scan/?addr=${hist.Addr}">${hist.Name}</a></td>
<td><a href="/scan/?addr=${hist.Addr}">${hist.Addr}</a></td>
<td><a href="http://${hist.Addr}:${hist.Port}">${hist.Port}</a></td>
<td><a href="http://${hist.Addr}:${hist.Port}">${hist.PortName}</a></td>
<td>${allState}</td>
</tr>`;
<td>${addr.Name}</td>
<td>${addr.Iface}</td>
<td>
<a href="http://${addr.IP}">${addr.IP}</a>
</td>
<td>${addr.Mac}</td>
<td>${now}</td>
</tr>
`;
return html;
}
async function loadHistory() {
async function loadAddrs() {
let url = '/api/history';
let histMap = await (await fetch(url)).json();
if (histMap != null) {
histArray = Object.values(histMap);
let addrsMap = await (await fetch(url)).json();
if (addrsMap != null) {
addrsArray = Object.values(addrsMap);
}
displayArrayData(histArray);
displayArrayData(addrsArray);
}
function sortBy(field) {
sortByAny(histArray, field);
sortByAny(addrsArray, field);
}

View file

@ -0,0 +1,45 @@
var histArray = {};
loadHistory();
function createHTML(hist, i) {
let allState = "";
let color = "";
for (let state of hist.State){
if (state.State) {
color = `bi-check-circle-fill" style="color:var(--bs-success);"`;
} else {
color = `bi-dash-circle-fill" style="color:var(--bs-danger);"`;
}
allState = allState + `<i class="bi ${color} title="${state.Date}"></i>`;
}
let html = `
<tr>
<td style="opacity: 45%;">${i}.</td>
<td><a href="/scan/?addr=${hist.Addr}">${hist.Name}</a></td>
<td><a href="/scan/?addr=${hist.Addr}">${hist.Addr}</a></td>
<td><a href="http://${hist.Addr}:${hist.Port}">${hist.Port}</a></td>
<td><a href="http://${hist.Addr}:${hist.Port}">${hist.PortName}</a></td>
<td>${allState}</td>
</tr>`;
return html;
}
async function loadHistory() {
let url = '/api/history';
let histMap = await (await fetch(url)).json();
if (histMap != null) {
histArray = Object.values(histMap);
}
displayArrayData(histArray);
}
function sortBy(field) {
sortByAny(histArray, field);
}

View file

@ -1,125 +0,0 @@
var addr = '';
var stop = false;
var portMap = {};
var portArray = [];
// Run, when page loadad
window.addEventListener('load', function() {
loadSavedPorts();
});
function delRow(id) {
document.getElementById(id).innerHTML = "";
}
function stopScan() {
stop = true;
}
async function scanAddr() {
let begin = document.getElementById("begin").value;
let end = document.getElementById("end").value;
let savedPorts = [];
if (begin == "") {
begin = 1
}
if (end == "") {
end = 65535
}
let port = {};
stop = false;
if (portMap != null) {
savedPorts = Object.keys(portMap);
}
// console.log("Saved ports:", savedPorts);
document.getElementById('stopBtn').style.visibility = "visible";
for (let i = begin ; i <= end; i++) {
if (stop) {
break;
}
let url = '/api/port/'+addr+'/'+i;
port = await (await fetch(url)).json();
document.getElementById("curPort").innerHTML = "Scanning port "+i;
if ((port.State) && (!savedPorts.includes(port.Port.toString()))) {
html = createHTML(port, '', true);
document.getElementById('tBody').insertAdjacentHTML('afterbegin', html);
}
}
document.getElementById('stopBtn').style.visibility = "hidden";
}
function createHTML(port, i, found) {
let state = ``;
let checked = ``;
let sup = ``;
if (found) {
sup = `&nbsp;<sup style="background-color:var(--bs-danger);">new</sup>`;
}
if (port.Watch) {
checked = `checked`;
if (port.State) {
state = `<i class="bi bi-check-circle-fill" style="color:var(--bs-success);"></i>`;
} else {
state = `<i class="bi bi-dash-circle-fill" style="color:var(--bs-danger);"></i>`;
}
} else {
state = `<i class="bi bi-circle-fill" style="color:var(--bs-gray-500);"></i>`;
}
let html = `
<tr id="row${port.Port}">
<td style="opacity: 45%;">${i}.</td>
<td>
<input name="name" type="text" class="form-control" value="${port.Name}">
</td>
<td>
<a href="http://${addr}:${port.Port}">${port.Port}</a>${sup}
<input name="port" type="hidden" value="${port.Port}">
<input name="state" type="hidden" value="${port.State}">
</td>
<td>
${state}
</td>
<td>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" value="${port.Port}" name="watch" ${checked}>
</div>
</td>
<td>
<a href="#" onclick="delRow('row${port.Port}')">
<i class="bi bi-x-circle"></i>
</a>
</td>
</tr>`;
return html;
}
async function loadSavedPorts() {
addr = document.getElementById("pageAddr").value;
let url = '/api/port/'+addr;
portMap = await (await fetch(url)).json();
if (portMap != null) {
portArray = Object.values(portMap);
}
displayArrayData(portArray); // sort.js
}
function sortBy(field) {
sortByAny(portArray, field); // sort.js
}

View file

@ -13,7 +13,7 @@ func updateScan() {
db.Create(appConfig.DBPath)
allHosts = db.Select(appConfig.DBPath, "now")
// histHosts = db.Select(appConfig.DBPath, "history")
histHosts = db.Select(appConfig.DBPath, "history")
quitScan = make(chan bool)
go startScan()
@ -35,7 +35,7 @@ func startScan() {
foundHosts := arp.Scan(appConfig.Ifaces)
compareHosts(foundHosts)
allHosts = db.Select(appConfig.DBPath, "now")
// histHosts = db.Select(appConfig.DBPath, "history")
histHosts = db.Select(appConfig.DBPath, "history")
lastDate = time.Now()
}

View file

@ -0,0 +1,30 @@
{{ define "history.html" }}
</head>
<script src="/fs/public/js/history.js"></script>
<script src="/fs/public/js/sort.js"></script>
<body>
<div class="container-lg">
<div class="row">
<div class="col-md mt-4 mb-4">
<div class="card border-primary">
<div class="card-body table-responsive">
<table class="table table-striped">
<thead>
<th style="width: 3em;"></th>
<th>Name <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Name')"></i></th>
<th>Iface <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Iface')"></i></th>
<th>IP <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('IP')"></i></th>
<th>MAC <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Mac')"></i></th>
<th>History <i class="bi bi-sort-down-alt my-btn" onclick="sortBy('Now')"></i></th>
</thead>
<tbody id="tBody"></tbody>
<!-- index.js -->
</table>
</div>
</div>
</div>
</div>
</div>
{{ template "footer.html" }}
{{ end }}

View file

@ -42,10 +42,12 @@ func Gui(dirPath, nodePath string) {
router.StaticFS("/fs/", http.FS(pubFS)) // public
router.GET("/api/all", apiAll) // api.go
router.GET("/api/all", apiAll) // api.go
router.GET("/api/history", apiHistory) // api.go
router.GET("/", indexHandler) // index.go
router.GET("/config/", configHandler) // config.go
router.GET("/", indexHandler) // index.go
router.GET("/history/", historyHandler) // index.go
router.GET("/config/", configHandler) // config.go
router.POST("/config/", saveConfigHandler) // config.go