Add/edit notifications

This commit is contained in:
Magnus Åhall 2024-06-28 15:28:52 +02:00
parent 1ede36b8aa
commit c7ad2aa1b6
19 changed files with 531 additions and 11 deletions

View file

@ -6,6 +6,12 @@ import (
// Standard
"log/slog"
"slices"
"strings"
)
var (
allServices []Service
)
func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *slog.Logger) (Service, error) {
@ -30,3 +36,25 @@ func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *sl
return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000")
}
func GetInstance(typ string) Service {
for _, svc := range allServices {
if strings.ToLower(svc.GetType()) == strings.ToLower(typ) {
return svc
}
}
return nil
}
func AvailableServices() []Service {
slices.SortFunc(allServices, func(a, b Service) int {
if a.GetType() < b.GetType() {
return -1
}
if a.GetType() > b.GetType() {
return 1
}
return 0
})
return allServices
}

View file

@ -11,6 +11,9 @@ import (
"io"
"log/slog"
"net/http"
"net/url"
"strconv"
"strings"
)
type NTFY struct {
@ -18,6 +21,13 @@ type NTFY struct {
Prio int
AcknowledgeURL string
logger *slog.Logger
exists bool
updated Service
}
func init() {
allServices = append(allServices, &NTFY{})
}
func NewNTFY(config []byte, prio int, ackURL string) (instance *NTFY, err error) {
@ -44,6 +54,22 @@ func (ntfy *NTFY) GetPrio() int {
return ntfy.Prio
}
func (ntfy *NTFY) SetPrio(prio int) {
ntfy.Prio = prio
}
func (ntfy *NTFY) SetExists(exists bool) {
ntfy.exists = exists
}
func (ntfy NTFY) Exists() bool {
return ntfy.exists
}
func (ntfy *NTFY) String() string {
return ntfy.URL
}
func (ntfy NTFY) Send(problemID int, msg []byte) (err error) {
var req *http.Request
var res *http.Response
@ -81,3 +107,40 @@ func (ntfy NTFY) Send(problemID int, msg []byte) (err error) {
return
}
func (ntfy *NTFY) Update(values url.Values) (err error) {
updated := NTFY{}
ntfy.updated = &updated
updated.Prio, err = strconv.Atoi(values.Get("prio"))
if err != nil {
return werr.Wrap(err)
}
givenURL := values.Get("url")
if strings.TrimSpace(givenURL) == "" {
return werr.New("URL cannot be empty")
}
updated.URL = strings.TrimSpace(givenURL)
return
}
func (ntfy *NTFY) Updated() Service {
return ntfy.updated
}
func (ntfy *NTFY) Commit() {
updatedNTFY := ntfy.updated.(*NTFY)
ntfy.Prio = updatedNTFY.Prio
ntfy.URL = updatedNTFY.URL
}
func (ntfy NTFY) JSON() []byte {
data := struct {
URL string `json:"url"`
}{
ntfy.URL,
}
j, _ := json.Marshal(data)
return j
}

View file

@ -6,6 +6,7 @@ import (
// Standard
"log/slog"
"net/url"
"slices"
)
@ -13,7 +14,15 @@ type Service interface {
SetLogger(*slog.Logger)
GetPrio() int
GetType() string
SetPrio(int)
SetExists(bool) // Exists in database
Exists() bool // Exists in database
String() string
Send(int, []byte) error
Update(url.Values) error
Updated() Service
Commit()
JSON() []byte
}
type Manager struct {
@ -28,6 +37,7 @@ func NewManager(logger *slog.Logger) (nm Manager) {
}
func (nm *Manager) AddService(service Service) {
service.SetExists(true)
nm.services = append(nm.services, service)
slices.SortFunc(nm.services, func(a, b Service) int {
if a.GetPrio() < b.GetPrio() {
@ -40,6 +50,16 @@ func (nm *Manager) AddService(service Service) {
})
}
func (nm *Manager) GetService(prio int) *Service {
for _, svc := range nm.services {
if svc.GetPrio() == prio {
return &svc
}
}
return nil
}
func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (err error) {
for i, service := range nm.services {
nm.logger.Info("notification", "service", service.GetType(), "prio", service.GetPrio())
@ -49,7 +69,7 @@ func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (er
} else {
data := struct {
ProblemID int
Msg []byte
Msg []byte
}{
problemID,
msg,
@ -61,3 +81,7 @@ func (nm *Manager) Send(problemID int, msg []byte, fn func(*Service, error)) (er
return
}
func (nm *Manager) Services() (services []Service) {
return nm.services
}

View file

@ -7,6 +7,7 @@ import (
// Standard
"encoding/json"
"log/slog"
"net/url"
"os/exec"
"strconv"
"strings"
@ -17,6 +18,13 @@ type Script struct {
Prio int
AcknowledgeURL string
logger *slog.Logger
exists bool
updated Service
}
func init() {
allServices = append(allServices, &Script{})
}
func NewScript(config []byte, prio int, ackURL string) (instance *Script, err error) {
@ -43,6 +51,22 @@ func (script *Script) GetPrio() int {
return script.Prio
}
func (script *Script) SetPrio(prio int) {
script.Prio = prio
}
func (script *Script) SetExists(exists bool) {
script.exists = exists
}
func (script Script) Exists() bool {
return script.exists
}
func (script *Script) String() string {
return script.Filename
}
func (script Script) Send(problemID int, msg []byte) (err error) {
var errbuf strings.Builder
cmd := exec.Command(script.Filename, strconv.Itoa(problemID), script.AcknowledgeURL, string(msg))
@ -68,3 +92,40 @@ func (script Script) Send(problemID int, msg []byte) (err error) {
return
}
func (script *Script) Update(values url.Values) (err error) {
updated := Script{}
updated.Prio, err = strconv.Atoi(values.Get("prio"))
if err != nil {
return werr.Wrap(err)
}
givenFilename := values.Get("filename")
if strings.TrimSpace(givenFilename) == "" {
return werr.New("Filename cannot be empty")
}
updated.Filename = strings.TrimSpace(givenFilename)
script.updated = &updated
return
}
func (script *Script) Updated() Service {
return script.updated
}
func (script *Script) Commit() {
updated := script.updated.(*Script)
script.Prio = updated.Prio
script.Filename = updated.Filename
}
func (script Script) JSON() []byte {
data := struct {
Filename string `json:"filename"`
}{
script.Filename,
}
j, _ := json.Marshal(data)
return j
}