dnscrypt-proxy/dnscrypt-proxy/time_ranges.go

116 lines
2.8 KiB
Go

package main
import (
"fmt"
"strconv"
"strings"
"time"
)
type TimeRange struct {
after int
before int
}
type WeeklyRanges struct {
ranges [7][]TimeRange
}
type TimeRangeStr struct {
After string
Before string
}
type WeeklyRangesStr struct {
Sun, Mon, Tue, Wed, Thu, Fri, Sat []TimeRangeStr
}
func daySecsFromStr(str string) (int, error) {
parts := strings.Split(str, ":")
if len(parts) != 2 {
return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str)
}
hours, err := strconv.Atoi(parts[0])
if err != nil || hours < 0 || hours > 23 {
return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str)
}
minutes, err := strconv.Atoi(parts[1])
if err != nil || minutes < 0 || minutes > 59 {
return -1, fmt.Errorf("Syntax error in a time expression: [%s]", str)
}
return (hours*60 + minutes) * 60, nil
}
func parseTimeRanges(timeRangesStr []TimeRangeStr) ([]TimeRange, error) {
timeRanges := []TimeRange{}
for _, timeRangeStr := range timeRangesStr {
after, err := daySecsFromStr(timeRangeStr.After)
if err != nil {
return timeRanges, err
}
before, err := daySecsFromStr(timeRangeStr.Before)
if err != nil {
return timeRanges, err
}
if after == before {
after, before = -1, 86402
}
timeRanges = append(timeRanges, TimeRange{after: after, before: before})
}
return timeRanges, nil
}
func parseWeeklyRanges(weeklyRangesStr WeeklyRangesStr) (WeeklyRanges, error) {
weeklyRanges := WeeklyRanges{}
weeklyRangesStrX := [7][]TimeRangeStr{
weeklyRangesStr.Sun,
weeklyRangesStr.Mon,
weeklyRangesStr.Tue,
weeklyRangesStr.Wed,
weeklyRangesStr.Thu,
weeklyRangesStr.Fri,
weeklyRangesStr.Sat,
}
for day, weeklyRangeStrX := range weeklyRangesStrX {
timeRanges, err := parseTimeRanges(weeklyRangeStrX)
if err != nil {
return weeklyRanges, err
}
weeklyRanges.ranges[day] = timeRanges
}
return weeklyRanges, nil
}
func ParseAllWeeklyRanges(allWeeklyRangesStr map[string]WeeklyRangesStr) (*map[string]WeeklyRanges, error) {
allWeeklyRanges := make(map[string]WeeklyRanges)
for weeklyRangesName, weeklyRangesStr := range allWeeklyRangesStr {
weeklyRanges, err := parseWeeklyRanges(weeklyRangesStr)
if err != nil {
return nil, err
}
allWeeklyRanges[weeklyRangesName] = weeklyRanges
}
return &allWeeklyRanges, nil
}
func (weeklyRanges *WeeklyRanges) Match() bool {
now := time.Now().Local()
day := now.Weekday()
weeklyRange := weeklyRanges.ranges[day]
if len(weeklyRange) == 0 {
return false
}
hour, min, _ := now.Clock()
nowX := (hour*60 + min) * 60
for _, timeRange := range weeklyRange {
if timeRange.after > timeRange.before {
if nowX >= timeRange.after || nowX <= timeRange.before {
return true
}
} else if nowX >= timeRange.after && nowX <= timeRange.before {
return true
}
}
return false
}