sunset/main.go

196 lines
4.0 KiB
Go
Raw Normal View History

2020-10-26 00:39:45 +00:00
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
2020-10-27 23:38:44 +00:00
"math"
2020-10-27 21:12:18 +00:00
"os"
"os/exec"
2020-10-26 00:39:45 +00:00
"path"
2020-10-27 21:26:09 +00:00
"path/filepath"
2020-10-26 00:39:45 +00:00
"strconv"
"strings"
"time"
)
type sunsetConfig struct {
Files []sunsetImage `json:"files"`
}
type sunsetImage struct {
File string `json:"file"`
Time string `json:"time"`
}
func loadSunsetConfig(filepath string) sunsetConfig {
data, err := ioutil.ReadFile(filepath)
var result sunsetConfig
err = json.Unmarshal(data, &result)
if err != nil {
log.Fatal("Failed to load file: ", err.Error())
}
return result
}
func currentIndex(config sunsetConfig) int {
currentTime := getCurrentTime()
var min int = 2401
var minIndex int = -1
for i := 0; i < len(config.Files); i++ {
element := getTimeSimple(config.Files[i].Time)
diff := currentTime - element
if diff < 0 {
diff = 2400 - (diff * -1)
}
if diff < min {
min = diff
minIndex = i
}
}
return minIndex
}
func nextIndex(config sunsetConfig) int {
currentTime := getCurrentTime()
var min int = 2401
var minIndex int = -1
for i := 0; i < len(config.Files); i++ {
element := getTimeSimple(config.Files[i].Time)
diff := element - currentTime
if diff < 0 {
diff = 2400 - (diff * -1)
}
if diff < min {
min = diff
minIndex = i
}
}
return minIndex
}
func getCurrentTime() int {
now := time.Now()
hr := now.Hour()
min := now.Minute()
return hr*100 + min
}
func getTimeSimple(timeString string) int {
hr, min := getTime(timeString)
return hr*100 + min
}
func getNextTime(config sunsetConfig) string {
index := nextIndex(config)
return config.Files[index].Time
}
func getTime(timeString string) (int, int) {
splits := strings.Split(timeString, ":")
hr, _ := strconv.ParseInt(splits[0], 10, 32)
min, _ := strconv.ParseInt(splits[1], 10, 32)
// res, err := time.Parse("15:04", fmt.Sprintf("%02d:%02d", hr, min))
// if err != nil {
// log.Fatal(err)
// }
return int(hr), int(min)
}
2020-10-27 23:38:44 +00:00
func getNextWait(config sunsetConfig) time.Duration {
2020-10-26 00:39:45 +00:00
index := nextIndex(config)
now := time.Now()
nextHr, nextMin := getTime(config.Files[index].Time)
2020-10-27 23:38:44 +00:00
// Today at the time
nextTime := time.Date(now.Year(), now.Month(), now.Day(), nextHr, nextMin, 0, 0, now.Location())
2020-10-26 00:39:45 +00:00
2020-10-27 23:38:44 +00:00
until := nextTime.Sub(now)
if math.Floor(until.Minutes()) > 0 {
return until
2020-10-26 00:39:45 +00:00
}
2020-10-27 23:38:44 +00:00
// Next day the the time
nextTime = nextTime.AddDate(0, 0, 1)
return nextTime.Sub(now)
2020-10-27 21:12:18 +00:00
}
2020-10-27 21:26:09 +00:00
func currentImage(configPath string, config sunsetConfig) string {
index := currentIndex(config)
absFile, err := filepath.Abs(path.Join(path.Dir(configPath), config.Files[index].File))
if err != nil {
log.Panic(err)
}
return absFile
}
func block(configPath string, config sunsetConfig, command string) {
image := currentImage(configPath, config)
go runCommand(command, image)
2020-10-27 21:12:18 +00:00
for {
2020-10-27 23:38:44 +00:00
until := getNextWait(config)
timer := time.NewTimer(until)
2020-10-27 21:12:18 +00:00
<-timer.C
2020-10-27 21:17:37 +00:00
log.Printf("Running command: %s\n", command)
image := currentImage(configPath, config)
go runCommand(command, image)
2020-10-27 21:12:18 +00:00
}
}
func runCommand(command, image string) {
cmd := exec.Command(command, image)
2020-10-27 21:12:18 +00:00
err := cmd.Run()
if err != nil {
log.Printf("Command %s returned a non 0 code", command)
}
2020-10-26 00:39:45 +00:00
}
func main() {
printNextTime := flag.Bool("next", false, "Print the time to the next change")
printNextWait := flag.Bool("wait", false, "Print the time to wait for the next change")
2020-10-27 21:12:18 +00:00
blockFlag := flag.Bool("block", false, "Block and call the provided command when the background changes")
blockCommand := flag.String("command", "", "Specify a command to run when the background changed")
2020-10-26 00:39:45 +00:00
configFile := flag.String("file", "./sunset.json", "Specify the file to load")
flag.Parse()
conf := loadSunsetConfig(*configFile)
if *printNextTime {
fmt.Printf("%s", getNextTime(conf))
} else if *printNextWait {
2020-10-27 23:38:44 +00:00
unitl := getNextWait(conf)
fmt.Printf("%s", unitl)
2020-10-27 21:12:18 +00:00
} else if *blockFlag {
if *blockCommand == "" {
fmt.Println("Must provide a command.")
os.Exit(1)
}
block(*configFile, conf, *blockCommand)
2020-10-26 00:39:45 +00:00
} else {
2020-10-27 21:26:09 +00:00
fmt.Printf("%s", currentImage(*configFile, conf))
2020-10-26 00:39:45 +00:00
}
}