scron/config.go
kekskurse fc3549d722
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
fix: remove debug println
2025-08-06 19:04:49 +02:00

208 lines
4.9 KiB
Go

package main
import (
"fmt"
"os"
"strconv"
"strings"
"time"
"github.com/rs/zerolog/log"
"gopkg.in/yaml.v2"
)
type config struct {
Jobs []jobconfig `yaml:"jobs"`
Notification []notificationConfig `yaml:"notification"`
}
type jobconfig struct {
Name string `yaml:"name"`
Hour string `yaml:"hour"`
Minute string `yaml:"minute"`
Weekday string `yaml:"weekday"`
Timezone string `yaml:"timezone"`
Command string `yaml:"command"`
Notification string `yaml:"notification,omitempty"`
}
type notificationConfig struct {
Name string `yaml:"name"`
Success notification `yaml:"success,omitempty"`
Error notification `yaml:"error,omitempty"`
}
type notification struct {
Gotify gotifyConfig `yaml:"gotify,omitempty"`
Smtp smtpConfig `yaml:"smtp,omitempty"`
}
type gotifyConfig struct {
URL string `yaml:"url"`
}
type smtpConfig struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username,omitempty"`
Password string `yaml:"password,omitempty"`
From string `yaml:"from"`
To string `yaml:"to"`
UseSSL bool `yaml:"use_ssl,omitempty"`
}
func ReadFromFile(path string) (config, error) {
f, err := os.ReadFile(path)
if err != nil {
return config{}, fmt.Errorf(ErrWrapTemplate, ErrCantReadConfigFile, err)
}
c := config{}
err = yaml.Unmarshal(f, &c)
if err != nil {
return config{}, fmt.Errorf(ErrWrapTemplate, ErrCantParseConfigFile, err)
}
return c, nil
}
func (jc jobconfig) MatchCurrentTime(t time.Time) (bool, error) {
loc, err := time.LoadLocation("UTC")
if err != nil {
panic(err)
}
if jc.Timezone != "" {
loc, err = time.LoadLocation(jc.Timezone)
if err != nil {
return false, err
}
}
matchWeekDay, err := matchTime(jc.Weekday, int(t.In(loc).Weekday()))
if err != nil {
return false, err
}
if !matchWeekDay {
return false, nil
}
matchHour, err := matchTime(jc.Hour, t.In(loc).Hour())
if err != nil {
return false, err
}
if !matchHour {
return false, nil
}
matchMinute, err := matchTime(jc.Minute, t.In(loc).Minute())
if err != nil {
return false, err
}
if !matchMinute {
return false, nil
}
return true, nil
}
func matchTime(pattern string, currentValue int) (bool, error) {
pattern = strings.TrimSpace(pattern)
log.Debug().Str("pattern", pattern).Int("currentValue", currentValue).Msg("Check if Pattern match current Value")
// All numbers
if pattern == "*" {
return true, nil
}
// Multible arguments
details := strings.Split(pattern, ",")
if len(details) > 1 {
for i := range details {
res, err := matchTime(details[i], currentValue)
if err != nil {
return false, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, err)
}
if res {
return res, nil
}
}
return false, nil // Non of the part match so nothing will match
}
// Singel number
valueAsInt, err := strconv.Atoi(pattern)
if err == nil {
if valueAsInt == currentValue {
return true, nil
}
return false, nil
}
// Normal ranges no ranges with defision
if strings.Contains(pattern, "-") && !strings.Contains(pattern, "/") {
smallNumber, largeNumber, err := getNumbersOfRange(pattern)
if err != nil {
return false, err
}
if smallNumber < currentValue && largeNumber > currentValue {
return true, nil
}
return false, nil
}
if strings.Contains(pattern, "/") {
numbers := strings.Split(pattern, "/")
if len(numbers) != 2 {
return false, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, "pattern dont include 2 numbers")
}
numberDivisor, err := strconv.Atoi(numbers[1])
if err != nil {
return false, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, err)
}
if numbers[0] == "*" {
res := currentValue % numberDivisor
if res == 0 {
return true, nil
}
return false, nil
}
if strings.Contains(numbers[0], "-") {
smallNumber, largeNumber, err := getNumbersOfRange(numbers[0])
if err != nil {
return false, err
}
if !(smallNumber < currentValue && largeNumber > currentValue) {
return false, nil
}
newValue := currentValue - smallNumber
res := newValue % numberDivisor
if res == 0 {
return true, nil
}
return false, nil
}
}
// Cant Parse the time
return false, ErrCantParseTimePattern
}
func getNumbersOfRange(pattern string) (int, int, error) {
numbers := strings.Split(pattern, "-")
if len(numbers) != 2 {
return 0, 0, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, "range include more than 2 parameter")
}
smallNumber, err := strconv.Atoi(strings.TrimSpace(numbers[0]))
if err != nil {
return 0, 0, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, err)
}
largeNumber, err := strconv.Atoi(strings.TrimSpace(numbers[1]))
if err != nil {
return 0, 0, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, err)
}
if smallNumber >= largeNumber {
return 0, 0, fmt.Errorf(ErrWrapTemplate, ErrCantParseTimePattern, "smaler number should be first")
}
return smallNumber, largeNumber, nil
}