refactor
This commit is contained in:
parent
4326c673bb
commit
7aaee08bb5
13 changed files with 249 additions and 48 deletions
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
custom: https://aceberg.github.io/MyDocs/sponsor
|
||||
|
|
@ -20,6 +20,7 @@ func dbExec(path, sqlStatement string) {
|
|||
check.IfError(err)
|
||||
}
|
||||
|
||||
// Select - select all hosts
|
||||
func Select(path string) (dbHosts []models.Host) {
|
||||
db, _ := sql.Open("sqlite", path)
|
||||
defer db.Close()
|
||||
|
|
@ -38,8 +39,8 @@ func Select(path string) (dbHosts []models.Host) {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// oneHost.Name = unquote_str(oneHost.Name)
|
||||
// oneHost.Hw = unquote_str(oneHost.Hw)
|
||||
oneHost.Name = unquoteStr(oneHost.Name)
|
||||
oneHost.Hw = unquoteStr(oneHost.Hw)
|
||||
dbHosts = append(dbHosts, oneHost)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
// "fmt"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
// Create - create DB if not exists
|
||||
|
|
@ -26,7 +28,32 @@ func Create(path string) {
|
|||
}
|
||||
}
|
||||
|
||||
// SetNow - mark all hosts as offline
|
||||
func SetNow(path string) {
|
||||
sqlStatement := `UPDATE "now" set NOW = '0';`
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// Insert - insert host into table
|
||||
func Insert(path string, oneHost models.Host) {
|
||||
oneHost.Name = quoteStr(oneHost.Name)
|
||||
oneHost.Hw = quoteStr(oneHost.Hw)
|
||||
sqlStatement := `INSERT INTO "now" (NAME, IP, MAC, HW, DATE, KNOWN, NOW)
|
||||
VALUES ('%s','%s','%s','%s','%s','%d','%d');`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now)
|
||||
//fmt.Println("Insert statement:", sqlStatement)
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// Update - update host
|
||||
func Update(path string, oneHost models.Host) {
|
||||
oneHost.Name = quoteStr(oneHost.Name)
|
||||
oneHost.Hw = quoteStr(oneHost.Hw)
|
||||
sqlStatement := `UPDATE "now" set
|
||||
NAME = '%s', IP = '%s', MAC = '%s', HW = '%s', DATE = '%s',
|
||||
KNOWN = '%d', NOW = '%d'
|
||||
WHERE ID = '%d';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, oneHost.Name, oneHost.IP, oneHost.Mac, oneHost.Hw, oneHost.Date, oneHost.Known, oneHost.Now, oneHost.ID)
|
||||
//fmt.Println("Update statement:", sqlStatement)
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
|
|
|||
11
internal/db/quote_str.go
Normal file
11
internal/db/quote_str.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package db
|
||||
|
||||
import "strings"
|
||||
|
||||
func quoteStr(str string) string {
|
||||
return strings.ReplaceAll(str, "'", "''")
|
||||
}
|
||||
|
||||
func unquoteStr(str string) string {
|
||||
return strings.ReplaceAll(str, "''", "'")
|
||||
}
|
||||
|
|
@ -1,33 +1,33 @@
|
|||
package scan
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
// func host_in_db(host Host, dbHosts []Host) bool { // Check if host is already in DB
|
||||
// for _, oneHost := range dbHosts {
|
||||
// if host.Ip == oneHost.Ip && host.Mac == oneHost.Mac && host.Hw == oneHost.Hw {
|
||||
// oneHost.Date = host.Date
|
||||
// oneHost.Now = 1
|
||||
// db_update(oneHost)
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
func hostInDB(path string, host models.Host, dbHosts []models.Host) bool { // Check if host is already in DB
|
||||
for _, oneHost := range dbHosts {
|
||||
if host.IP == oneHost.IP && host.Mac == oneHost.Mac && host.Hw == oneHost.Hw {
|
||||
oneHost.Date = host.Date
|
||||
oneHost.Now = 1
|
||||
db.Update(path, oneHost)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hostsCompare(foundHosts []models.Host, dbHosts []models.Host) {
|
||||
func hostsCompare(path string, foundHosts, dbHosts []models.Host) {
|
||||
for _, oneHost := range foundHosts {
|
||||
// if !(host_in_db(oneHost, dbHosts)) {
|
||||
// oneHost.Now = 1 // Mark host online
|
||||
// msg := fmt.Sprintf("UNKNOWN HOST IP: '%s', MAC: '%s', Hw: '%s'", oneHost.Ip, oneHost.Mac, oneHost.Hw)
|
||||
// log.Println("WARN:", msg)
|
||||
// shoutr_notify(msg) // Notify through Shoutrrr
|
||||
// db_insert(oneHost)
|
||||
// }
|
||||
log.Println("FOUND:", oneHost)
|
||||
if !(hostInDB(path, oneHost, dbHosts)) {
|
||||
oneHost.Now = 1 // Mark host online
|
||||
msg := fmt.Sprintf("UNKNOWN HOST IP: '%s', MAC: '%s', Hw: '%s'", oneHost.IP, oneHost.Mac, oneHost.Hw)
|
||||
log.Println("WARN:", msg)
|
||||
// shoutr_notify(msg) // Notify through Shoutrrr
|
||||
db.Insert(path, oneHost)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@ import (
|
|||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
// Start - start arp-scan goroutine
|
||||
func Start(appConfig models.Conf) {
|
||||
var foundHosts []models.Host
|
||||
var dbHosts []models.Host
|
||||
for { // Endless
|
||||
foundHosts = arpScan(appConfig.Iface) // Scan interfaces
|
||||
dbHosts = db.Select(appConfig.DbPath) // Select everything from DB
|
||||
db.SetNow(appConfig.DbPath) // Mark hosts in DB as offline
|
||||
hostsCompare(foundHosts, dbHosts) // Compare hosts online and in DB
|
||||
// and add them to DB
|
||||
foundHosts = arpScan(appConfig.Iface) // Scan interfaces
|
||||
dbHosts = db.Select(appConfig.DbPath) // Select everything from DB
|
||||
db.SetNow(appConfig.DbPath) // Mark hosts in DB as offline
|
||||
hostsCompare(appConfig.DbPath, foundHosts, dbHosts) // Compare hosts online and in DB and add them to DB
|
||||
time.Sleep(time.Duration(appConfig.Timeout) * time.Second) // Timeout
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,15 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/check"
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
func index(w http.ResponseWriter, r *http.Request) {
|
||||
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var guiData models.GuiData
|
||||
|
||||
AllHosts = db.Select(AppConfig.DbPath)
|
||||
|
||||
guiData.Config = AppConfig
|
||||
guiData.Hosts = AllHosts
|
||||
guiData.Icon = Icon
|
||||
|
|
|
|||
49
internal/web/on-off-line.go
Normal file
49
internal/web/on-off-line.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/check"
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
func offlineHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var guiData models.GuiData
|
||||
|
||||
guiData.Config = AppConfig
|
||||
guiData.Hosts = []models.Host{}
|
||||
guiData.Icon = Icon
|
||||
|
||||
for _, oneHost := range AllHosts {
|
||||
if oneHost.Now == 0 {
|
||||
guiData.Hosts = append(guiData.Hosts, oneHost)
|
||||
}
|
||||
}
|
||||
|
||||
tmpl, _ := template.ParseFiles(TemplPath+"offline.html", TemplPath+"header.html", TemplPath+"footer.html")
|
||||
err := tmpl.ExecuteTemplate(w, "header", guiData)
|
||||
check.IfError(err)
|
||||
err = tmpl.ExecuteTemplate(w, "offline", guiData)
|
||||
check.IfError(err)
|
||||
}
|
||||
|
||||
func onlineHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var guiData models.GuiData
|
||||
|
||||
guiData.Config = AppConfig
|
||||
guiData.Hosts = []models.Host{}
|
||||
guiData.Icon = Icon
|
||||
|
||||
for _, oneHost := range AllHosts {
|
||||
if oneHost.Now == 1 {
|
||||
guiData.Hosts = append(guiData.Hosts, oneHost)
|
||||
}
|
||||
}
|
||||
|
||||
tmpl, _ := template.ParseFiles(TemplPath+"offline.html", TemplPath+"header.html", TemplPath+"footer.html")
|
||||
err := tmpl.ExecuteTemplate(w, "header", guiData)
|
||||
check.IfError(err)
|
||||
err = tmpl.ExecuteTemplate(w, "offline", guiData)
|
||||
check.IfError(err)
|
||||
}
|
||||
82
internal/web/sort.go
Normal file
82
internal/web/sort.go
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
func sortByIPs(method string) {
|
||||
type ipHost struct {
|
||||
Host models.Host
|
||||
IP net.IP
|
||||
}
|
||||
toSort := []ipHost{}
|
||||
var oneSort ipHost
|
||||
|
||||
for _, oneHost := range AllHosts {
|
||||
oneSort.Host = oneHost
|
||||
oneSort.IP = net.ParseIP(oneHost.IP)
|
||||
toSort = append(toSort, oneSort)
|
||||
}
|
||||
|
||||
switch method {
|
||||
case "asc":
|
||||
sort.Slice(toSort, func(i, j int) bool {
|
||||
return bytes.Compare(toSort[i].IP, toSort[j].IP) < 0
|
||||
})
|
||||
case "desc":
|
||||
sort.Slice(toSort, func(i, j int) bool {
|
||||
return bytes.Compare(toSort[i].IP, toSort[j].IP) > 0
|
||||
})
|
||||
}
|
||||
|
||||
AllHosts = []models.Host{}
|
||||
for _, oneSort := range toSort {
|
||||
AllHosts = append(AllHosts, oneSort.Host)
|
||||
}
|
||||
}
|
||||
|
||||
func sortHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
sortMethod := r.FormValue("sort_method")
|
||||
|
||||
switch sortMethod {
|
||||
case "name-up":
|
||||
sort.SliceStable(AllHosts, func(i, j int) bool {
|
||||
return AllHosts[i].Name < AllHosts[j].Name
|
||||
})
|
||||
case "name-down":
|
||||
sort.SliceStable(AllHosts, func(i, j int) bool {
|
||||
return AllHosts[i].Name > AllHosts[j].Name
|
||||
})
|
||||
case "ip-up":
|
||||
sortByIPs("asc")
|
||||
case "ip-down":
|
||||
sortByIPs("desc")
|
||||
case "date-up":
|
||||
sort.SliceStable(AllHosts, func(i, j int) bool {
|
||||
return AllHosts[i].Date < AllHosts[j].Date
|
||||
})
|
||||
case "date-down":
|
||||
sort.SliceStable(AllHosts, func(i, j int) bool {
|
||||
return AllHosts[i].Date > AllHosts[j].Date
|
||||
})
|
||||
case "known-up":
|
||||
sort.SliceStable(AllHosts, func(i, j int) bool {
|
||||
return AllHosts[i].Known < AllHosts[j].Known
|
||||
})
|
||||
case "known-down":
|
||||
sort.SliceStable(AllHosts, func(i, j int) bool {
|
||||
return AllHosts[i].Known > AllHosts[j].Known
|
||||
})
|
||||
default:
|
||||
AllHosts = db.Select(AppConfig.DbPath)
|
||||
}
|
||||
|
||||
http.Redirect(w, r, r.Header.Get("Referer"), 302)
|
||||
}
|
||||
|
|
@ -5,14 +5,10 @@
|
|||
<meta charset="utf-8">
|
||||
<!--Favicon-->
|
||||
<link href="data:image/x-icon;base64,{{ .Icon }}" rel="icon" type="image/x-icon" />
|
||||
<!--Auto refresh (seconds)-->
|
||||
<!-- <meta http-equiv="refresh" content="{{ .Config.Timeout }}"> -->
|
||||
<!-- Bootstrap and theme -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootswatch@5.2.0/dist/{{ .Config.Theme }}/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font for icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
|
||||
<!-- JavaScript Bundle with Popper -->
|
||||
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script> -->
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-sm navbar-dark bg-primary">
|
||||
|
|
@ -35,7 +31,7 @@
|
|||
<button type="submit" class="btn btn-primary">Search</button>
|
||||
</li>
|
||||
</form>
|
||||
<li class="nav-item"><a class="nav-link active" href="https://github.com/aceberg/WatchYourLAN">
|
||||
<li class="nav-item"><a class="nav-link active" target="_blank" href="https://github.com/aceberg/WatchYourLAN">
|
||||
<h3> <i class="bi bi-github"></i></h3>
|
||||
</a></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,4 @@
|
|||
{{ define "offline"}}
|
||||
|
||||
{{ template "header" }}
|
||||
<!--Auto refresh (seconds)-->
|
||||
<!-- <meta http-equiv="refresh" content="{{ .Config.Timeout }}"> -->
|
||||
<!--Bootstrap theme-->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootswatch@5.2.0/dist/{{ .Config.Theme }}/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-3">
|
||||
<table class="table table-striped">
|
||||
|
|
|
|||
36
internal/web/update.go
Normal file
36
internal/web/update.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
)
|
||||
|
||||
func updateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
idStr := r.FormValue("id")
|
||||
name := r.FormValue("name")
|
||||
knownStr := r.FormValue("known")
|
||||
|
||||
if idStr == "" {
|
||||
fmt.Fprintf(w, "No data!")
|
||||
} else {
|
||||
var known uint16
|
||||
id, _ := strconv.Atoi(idStr)
|
||||
known = 0
|
||||
if knownStr == "on" {
|
||||
known = 1
|
||||
}
|
||||
|
||||
for i, oneHost := range AllHosts {
|
||||
if oneHost.ID == uint16(id) {
|
||||
AllHosts[i].Name = name
|
||||
AllHosts[i].Known = known
|
||||
db.Update(AppConfig.DbPath, AllHosts[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
http.Redirect(w, r, r.Header.Get("Referer"), 302)
|
||||
}
|
||||
|
|
@ -35,14 +35,14 @@ func Gui(appConfig models.Conf) {
|
|||
log.Printf("Web GUI at http://%s", address)
|
||||
log.Println("=================================== ")
|
||||
|
||||
http.HandleFunc("/", index)
|
||||
http.HandleFunc("/home/", index)
|
||||
// http.HandleFunc("/offline/", offline)
|
||||
// http.HandleFunc("/online/", online)
|
||||
http.HandleFunc("/", indexHandler)
|
||||
http.HandleFunc("/home/", indexHandler)
|
||||
http.HandleFunc("/offline/", offlineHandler)
|
||||
http.HandleFunc("/online/", onlineHandler)
|
||||
// http.HandleFunc("/search_hosts/", search_hosts)
|
||||
// http.HandleFunc("/sort_hosts/", sort_hosts)
|
||||
http.HandleFunc("/sort_hosts/", sortHandler)
|
||||
// http.HandleFunc("/theme/", theme)
|
||||
// http.HandleFunc("/update_host/", update_host)
|
||||
http.HandleFunc("/update_host/", updateHandler)
|
||||
err := http.ListenAndServe(address, nil)
|
||||
check.IfError(err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue