Notes/schedule.go

172 lines
3.3 KiB
Go
Raw Permalink Normal View History

2024-03-28 21:49:48 +01:00
package main
import (
// External
werr "git.gibonuddevalla.se/go/wrappederror"
2024-03-28 21:49:48 +01:00
// Standard
"encoding/json"
"fmt"
"regexp"
"strings"
"time"
)
func init() {
fmt.Printf("")
}
type Schedule struct {
ID int
UserID int `json:"user_id" db:"user_id"`
2024-03-28 21:49:48 +01:00
Node Node
ScheduleUUID string `db:"schedule_uuid"`
Time time.Time
Description string
Acknowledged bool
}
2024-03-30 09:46:48 +01:00
func ScanForSchedules(timeOffset int, content string) (schedules []Schedule) {// {{{
2024-03-28 21:49:48 +01:00
schedules = []Schedule{}
rxp := regexp.MustCompile(`\{\s*([0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}(?::[0-9]{2})?)\s*\,\s*([^\]]+?)\s*\}`)
foundSchedules := rxp.FindAllStringSubmatch(content, -1)
for _, data := range foundSchedules {
// Missing seconds
if strings.Count(data[1], ":") == 1 {
data[1] = data[1] + ":00"
}
2024-03-30 09:46:48 +01:00
var timeTZ string
if timeOffset < 0 {
hours := (-timeOffset) / 60
mins := (-timeOffset) % 60
timeTZ = fmt.Sprintf("%s -%02d%02d", data[1], hours, mins)
} else {
hours := timeOffset / 60
mins := timeOffset % 60
timeTZ = fmt.Sprintf("%s +%02d%02d", data[1], hours, mins)
}
timestamp, err := time.Parse("2006-01-02 15:04:05 -0700", timeTZ)
2024-03-28 21:49:48 +01:00
if err != nil {
continue
}
schedule := Schedule{
Time: timestamp,
Description: data[2],
}
schedules = append(schedules, schedule)
}
return
}// }}}
func RetrieveSchedules(userID int, nodeID int) (schedules []Schedule, err error) {// {{{
2024-03-28 21:49:48 +01:00
schedules = []Schedule{}
res := service.Db.Conn.QueryRow(`
WITH schedule_events AS (
SELECT
id,
user_id,
json_build_object('id', node_id) AS node,
schedule_uuid,
2024-03-30 09:46:48 +01:00
time,
2024-03-28 21:49:48 +01:00
description,
acknowledged
FROM schedule
WHERE
user_id=$1 AND
CASE
WHEN $2 > 0 THEN node_id = $2
ELSE true
END
)
SELECT
COALESCE(jsonb_agg(s.*), '[]'::jsonb)
FROM schedule_events s
`,
userID,
nodeID,
)
var data []byte
err = res.Scan(&data)
if err != nil {
return
}
err = json.Unmarshal(data, &schedules)
return
}// }}}
func (a Schedule) IsEqual(b Schedule) bool {// {{{
return a.UserID == b.UserID &&
a.Node.ID == b.Node.ID &&
a.Time.Equal(b.Time) &&
a.Description == b.Description
}// }}}
func (s *Schedule) Insert(queryable Queryable) error {// {{{
res := queryable.QueryRow(`
INSERT INTO schedule(user_id, node_id, time, description)
VALUES($1, $2, $3, $4)
RETURNING id
`,
s.UserID,
s.Node.ID,
s.Time,
s.Description,
)
2024-03-28 21:49:48 +01:00
return res.Scan(&s.ID)
}// }}}
func (s *Schedule) Delete(queryable Queryable) error {// {{{
_, err := queryable.Exec(`
DELETE FROM schedule
WHERE
user_id = $1 AND
id = $2
`,
s.UserID,
s.ID,
)
return err
}// }}}
func ExpiredSchedules() (schedules []Schedule) {// {{{
schedules = []Schedule{}
res, err := service.Db.Conn.Queryx(`
2024-03-28 21:49:48 +01:00
SELECT
id,
user_id,
node_id,
schedule_uuid,
time,
description
2024-03-28 21:49:48 +01:00
FROM schedule
WHERE
time < NOW() AND
NOT acknowledged
ORDER BY
time ASC
`)
if err != nil {
err = werr.Wrap(err).WithCode("002-0009")
return
}
defer res.Close()
for res.Next() {
s := Schedule{}
if err = res.Scan(&s.ID, &s.UserID, &s.Node.ID, &s.ScheduleUUID, &s.Time, &s.Description); err != nil {
werr.Wrap(err).WithCode("002-000a")
continue
}
schedules = append(schedules, s)
}
return
}// }}}