DB: history
This commit is contained in:
parent
a0173f9132
commit
b8f7d3bfb3
14 changed files with 208 additions and 51 deletions
|
|
@ -2,35 +2,36 @@ package db
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
// Create - create DB if not exists
|
||||
func Create(path string) {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
log.Println("INFO: DB exists")
|
||||
} else {
|
||||
sqlStatement := `CREATE TABLE "now" (
|
||||
"ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
"NAME" TEXT NOT NULL,
|
||||
"IP" TEXT,
|
||||
"MAC" TEXT,
|
||||
"HW" TEXT,
|
||||
"DATE" TEXT,
|
||||
"KNOWN" INTEGER DEFAULT 0,
|
||||
"NOW" INTEGER DEFAULT 0
|
||||
);`
|
||||
dbExec(path, sqlStatement)
|
||||
log.Println("INFO: Table created!")
|
||||
}
|
||||
}
|
||||
|
||||
// SetNow - mark all hosts as offline
|
||||
func SetNow(path string) {
|
||||
sqlStatement := `UPDATE "now" set NOW = '0';`
|
||||
sqlStatement := `CREATE TABLE IF NOT EXISTS "now" (
|
||||
"ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
"NAME" TEXT NOT NULL,
|
||||
"IP" TEXT,
|
||||
"MAC" TEXT,
|
||||
"HW" TEXT,
|
||||
"DATE" TEXT,
|
||||
"KNOWN" INTEGER DEFAULT 0,
|
||||
"NOW" INTEGER DEFAULT 0
|
||||
);`
|
||||
dbExec(path, sqlStatement)
|
||||
|
||||
sqlStatement = `CREATE TABLE IF NOT EXISTS "history" (
|
||||
"ID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
"HOST" INTEGER DEFAULT 0,
|
||||
"NAME" TEXT NOT NULL,
|
||||
"IP" TEXT,
|
||||
"MAC" TEXT,
|
||||
"HW" TEXT,
|
||||
"DATE" TEXT,
|
||||
"KNOWN" INTEGER DEFAULT 0,
|
||||
"STATE" INTEGER DEFAULT 0
|
||||
);`
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +42,7 @@ func Insert(path string, oneHost models.Host) {
|
|||
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)
|
||||
}
|
||||
|
||||
|
|
@ -54,12 +55,12 @@ func Update(path string, oneHost models.Host) {
|
|||
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)
|
||||
}
|
||||
|
||||
// Delete - delete host from DB
|
||||
func Delete(path string, id uint16) {
|
||||
func Delete(path string, id int) {
|
||||
sqlStatement := `DELETE FROM "now" WHERE ID='%d';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, id)
|
||||
dbExec(path, sqlStatement)
|
||||
|
|
|
|||
31
internal/db/hist-edit.go
Normal file
31
internal/db/hist-edit.go
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
// InsertHist - insert history into table
|
||||
func InsertHist(path string, hist models.History) {
|
||||
hist.Name = quoteStr(hist.Name)
|
||||
hist.Hw = quoteStr(hist.Hw)
|
||||
sqlStatement := `INSERT INTO "history" (HOST, NAME, IP, MAC, HW, DATE, KNOWN, STATE)
|
||||
VALUES ('%d','%s','%s','%s','%s','%s','%d','%d');`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, hist.Host, hist.Name, hist.IP, hist.Mac, hist.Hw, hist.Date, hist.Known, hist.State)
|
||||
//fmt.Println("Insert statement:", sqlStatement)
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// DeleteHist - delete history from DB
|
||||
func DeleteHist(path string, id int) {
|
||||
sqlStatement := `DELETE FROM "history" WHERE ID='%d';`
|
||||
sqlStatement = fmt.Sprintf(sqlStatement, id)
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
||||
// ClearHist - delete all history from table
|
||||
func ClearHist(path string) {
|
||||
sqlStatement := `DELETE FROM "history";`
|
||||
dbExec(path, sqlStatement)
|
||||
}
|
||||
|
|
@ -41,8 +41,27 @@ func Select(path string) (dbHosts []models.Host) {
|
|||
mu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("ERROR: db_select: ", err)
|
||||
log.Fatal("ERROR: db.Select: ", err)
|
||||
}
|
||||
|
||||
return dbHosts
|
||||
}
|
||||
|
||||
// SelectHist - select all history
|
||||
func SelectHist(path string) (hist []models.History) {
|
||||
|
||||
sqlStatement := `SELECT * FROM "history" ORDER BY DATE DESC`
|
||||
|
||||
mu.Lock()
|
||||
db, _ := sqlx.Connect("sqlite", path)
|
||||
defer db.Close()
|
||||
|
||||
err := db.Select(&hist, sqlStatement)
|
||||
mu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("ERROR: db.SelectHist: ", err)
|
||||
}
|
||||
|
||||
return hist
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,25 +23,28 @@ type Conf struct {
|
|||
|
||||
// Host - one host
|
||||
type Host struct {
|
||||
ID uint16 `db:"ID"`
|
||||
ID int `db:"ID"`
|
||||
Name string `db:"NAME"`
|
||||
IP string `db:"IP"`
|
||||
Mac string `db:"MAC"`
|
||||
Hw string `db:"HW"`
|
||||
Date string `db:"DATE"`
|
||||
Known uint16 `db:"KNOWN"`
|
||||
Now uint16 `db:"NOW"`
|
||||
Known int `db:"KNOWN"`
|
||||
Now int `db:"NOW"`
|
||||
}
|
||||
|
||||
// // History for hosts
|
||||
// type History struct {
|
||||
// ID int
|
||||
// HostID int
|
||||
// Name string
|
||||
// IP string
|
||||
// Date string
|
||||
// State bool
|
||||
// }
|
||||
// History for hosts
|
||||
type History struct {
|
||||
ID int `db:"ID"`
|
||||
Host int `db:"HOST"`
|
||||
Name string `db:"NAME"`
|
||||
IP string `db:"IP"`
|
||||
Mac string `db:"MAC"`
|
||||
Hw string `db:"HW"`
|
||||
Date string `db:"DATE"`
|
||||
Known int `db:"KNOWN"`
|
||||
State int `db:"STATE"`
|
||||
}
|
||||
|
||||
// GuiData - all data sent to html page
|
||||
type GuiData struct {
|
||||
|
|
@ -50,5 +53,5 @@ type GuiData struct {
|
|||
Themes []string
|
||||
Version string
|
||||
Auth auth.Conf
|
||||
// HistLog []History
|
||||
Hist []History
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,20 @@ import (
|
|||
"github.com/aceberg/WatchYourLAN/internal/notify"
|
||||
)
|
||||
|
||||
func hostsCompare(appConfig models.Conf) {
|
||||
func hostsCompare() {
|
||||
|
||||
for _, oneHost := range dbHosts {
|
||||
|
||||
host, exists := foundHostsMap[oneHost.Mac]
|
||||
|
||||
if exists && (appConfig.IgnoreIP == "yes" || host.IP == oneHost.IP) {
|
||||
|
||||
oneHost.Date = host.Date
|
||||
|
||||
if oneHost.Now == 0 {
|
||||
histAdd(oneHost, 1)
|
||||
}
|
||||
|
||||
oneHost.Now = 1
|
||||
|
||||
delete(foundHostsMap, oneHost.Mac)
|
||||
|
|
@ -26,6 +32,8 @@ func hostsCompare(appConfig models.Conf) {
|
|||
} else if oneHost.Now == 1 {
|
||||
oneHost.Now = 0
|
||||
db.Update(appConfig.DbPath, oneHost)
|
||||
|
||||
histAdd(oneHost, 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,5 +44,33 @@ func hostsCompare(appConfig models.Conf) {
|
|||
notify.Shoutrrr(msg, appConfig.ShoutURL) // Notify through Shoutrrr
|
||||
|
||||
db.Insert(appConfig.DbPath, oneHost)
|
||||
|
||||
histAdd(oneHost, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func histAdd(oneHost models.Host, state int) {
|
||||
var history models.History
|
||||
|
||||
if oneHost.ID == 0 {
|
||||
dbHosts = db.Select(appConfig.DbPath)
|
||||
|
||||
for _, host := range dbHosts {
|
||||
if host.IP == oneHost.IP && host.Mac == oneHost.Mac {
|
||||
oneHost.ID = host.ID
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
history.Host = oneHost.ID
|
||||
history.Name = oneHost.Name
|
||||
history.IP = oneHost.IP
|
||||
history.Mac = oneHost.Mac
|
||||
history.Hw = oneHost.Hw
|
||||
history.Date = oneHost.Date
|
||||
history.Known = oneHost.Known
|
||||
history.State = state
|
||||
|
||||
db.InsertHist(appConfig.DbPath, history)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,17 @@ import (
|
|||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
var appConfig models.Conf
|
||||
var dbHosts, structHosts []models.Host
|
||||
var foundHostsMap map[string]models.Host
|
||||
|
||||
// Start - start arp-scan goroutine
|
||||
func Start(appConfig models.Conf, quit chan bool) {
|
||||
func Start(config models.Conf, quit chan bool) {
|
||||
var lastDate time.Time
|
||||
|
||||
appConfig = config
|
||||
db.Create(appConfig.DbPath)
|
||||
dbHosts = db.Select(appConfig.DbPath)
|
||||
|
||||
for {
|
||||
select {
|
||||
|
|
@ -29,7 +32,7 @@ func Start(appConfig models.Conf, quit chan bool) {
|
|||
dbHosts = db.Select(appConfig.DbPath)
|
||||
|
||||
toMap()
|
||||
hostsCompare(appConfig) // compare.go
|
||||
hostsCompare() // compare.go
|
||||
|
||||
lastDate = time.Now()
|
||||
}
|
||||
|
|
|
|||
17
internal/web/history.go
Normal file
17
internal/web/history.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/db"
|
||||
"github.com/aceberg/WatchYourLAN/internal/models"
|
||||
)
|
||||
|
||||
func historyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var guiData models.GuiData
|
||||
|
||||
guiData.Config = AppConfig
|
||||
guiData.Hist = db.SelectHist(AppConfig.DbPath)
|
||||
|
||||
execTemplate(w, "history", guiData)
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ func delHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
log.Println("INFO: delete host ID =", id)
|
||||
|
||||
db.Delete(AppConfig.DbPath, uint16(id))
|
||||
db.Delete(AppConfig.DbPath, id)
|
||||
|
||||
http.Redirect(w, r, "/", 302)
|
||||
}
|
||||
|
|
@ -35,10 +35,8 @@ func hostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
id, err := strconv.Atoi(idStr)
|
||||
check.IfError(err)
|
||||
|
||||
id16 := uint16(id)
|
||||
|
||||
for _, oneHost := range AllHosts {
|
||||
if id16 == oneHost.ID {
|
||||
if id == oneHost.ID {
|
||||
host = oneHost
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@
|
|||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/line?state=off">Offline</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/history/">History</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/config/">Config</a>
|
||||
</li>
|
||||
|
|
|
|||
45
internal/web/templates/history.html
Normal file
45
internal/web/templates/history.html
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{{ define "history"}}
|
||||
<!--Auto refresh (seconds)-->
|
||||
<meta http-equiv="refresh" content="{{ .Config.Timeout }}">
|
||||
<body>
|
||||
<div class="container mt-3">
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>IP</th>
|
||||
<th>Mac</th>
|
||||
<th>Hardware</th>
|
||||
<th>Last seen</th>
|
||||
<th>Known</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
{{ range .Hist }}
|
||||
<tr>
|
||||
<td><a href="/host?id={{ .Host }}">{{ .Host }}</a></td>
|
||||
<td>{{ .Name }}</td>
|
||||
<td><a href="http://{{ .IP }}" target="_blank">{{ .IP }}</a></td>
|
||||
<td><a href="/host?id={{ .Host }}">{{ .Mac }}</a></td>
|
||||
<td>{{ .Hw }}</td>
|
||||
<td>{{ .Date }}</td>
|
||||
<td>
|
||||
{{ if eq .Known 1 }}
|
||||
Yes
|
||||
{{ else }}
|
||||
No
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
{{ if eq .State 1 }}
|
||||
<i class="bi bi-circle-fill text-success"></i>
|
||||
{{ else }}
|
||||
<i class="bi bi-circle-fill text-danger"></i>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{ template "footer" }}
|
||||
{{ end }}
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
<td>Domain name</td>
|
||||
<td>
|
||||
{{ range .Themes }}
|
||||
{{ . }}
|
||||
<a href="http://{{ . }}" target="_blank">{{ . }}</a>
|
||||
{{ end }}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ func updateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if idStr == "" {
|
||||
fmt.Fprintf(w, "No data!")
|
||||
} else {
|
||||
var known uint16
|
||||
var known int
|
||||
id, _ := strconv.Atoi(idStr)
|
||||
known = 0
|
||||
if knownStr == "on" {
|
||||
|
|
@ -24,7 +24,7 @@ func updateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
for i, oneHost := range AllHosts {
|
||||
if oneHost.ID == uint16(id) {
|
||||
if oneHost.ID == id {
|
||||
AllHosts[i].Name = name
|
||||
AllHosts[i].Known = known
|
||||
db.Update(AppConfig.DbPath, AllHosts[i])
|
||||
|
|
|
|||
|
|
@ -34,11 +34,12 @@ func Gui(configPath, nodePath string) {
|
|||
http.HandleFunc("/login/", loginHandler) // login.go
|
||||
|
||||
http.HandleFunc("/", auth.Auth(indexHandler, &authConf))
|
||||
http.HandleFunc("/auth_conf/", auth.Auth(authConfHandler, &authConf)) // auth-conf.go
|
||||
http.HandleFunc("/auth_save/", auth.Auth(saveAuthHandler, &authConf)) // auth-conf.go
|
||||
http.HandleFunc("/auth_conf/", auth.Auth(authConfHandler, &authConf)) // auth.go
|
||||
http.HandleFunc("/auth_save/", auth.Auth(saveAuthHandler, &authConf)) // auth.go
|
||||
http.HandleFunc("/clear/", auth.Auth(clearHandler, &authConf)) // config.go
|
||||
http.HandleFunc("/config/", auth.Auth(configHandler, &authConf)) // config.go
|
||||
http.HandleFunc("/del_host/", auth.Auth(delHandler, &authConf)) // host.go
|
||||
http.HandleFunc("/history/", auth.Auth(historyHandler, &authConf)) // history.go
|
||||
http.HandleFunc("/host/", auth.Auth(hostHandler, &authConf)) // host.go
|
||||
http.HandleFunc("/line/", auth.Auth(lineHandler, &authConf)) // line.go
|
||||
http.HandleFunc("/port_scan/", auth.Auth(portHandler, &authConf)) // port.go
|
||||
|
|
|
|||
Loading…
Reference in a new issue