196 lines
4.0 KiB
Go
196 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"math"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"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)
|
|
}
|
|
|
|
func getNextWait(config sunsetConfig) time.Duration {
|
|
index := nextIndex(config)
|
|
now := time.Now()
|
|
nextHr, nextMin := getTime(config.Files[index].Time)
|
|
|
|
// Today at the time
|
|
nextTime := time.Date(now.Year(), now.Month(), now.Day(), nextHr, nextMin, 0, 0, now.Location())
|
|
|
|
until := nextTime.Sub(now)
|
|
|
|
if math.Floor(until.Minutes()) > 0 {
|
|
return until
|
|
}
|
|
|
|
// Next day the the time
|
|
nextTime = nextTime.AddDate(0, 0, 1)
|
|
return nextTime.Sub(now)
|
|
}
|
|
|
|
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)
|
|
for {
|
|
until := getNextWait(config)
|
|
timer := time.NewTimer(until)
|
|
<-timer.C
|
|
log.Printf("Running command: %s\n", command)
|
|
image := currentImage(configPath, config)
|
|
go runCommand(command, image)
|
|
}
|
|
}
|
|
|
|
func runCommand(command, image string) {
|
|
cmd := exec.Command(command, image)
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
log.Printf("Command %s returned a non 0 code", command)
|
|
}
|
|
}
|
|
|
|
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")
|
|
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")
|
|
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 {
|
|
unitl := getNextWait(conf)
|
|
fmt.Printf("%s", unitl)
|
|
|
|
} else if *blockFlag {
|
|
if *blockCommand == "" {
|
|
fmt.Println("Must provide a command.")
|
|
os.Exit(1)
|
|
}
|
|
block(*configFile, conf, *blockCommand)
|
|
} else {
|
|
fmt.Printf("%s", currentImage(*configFile, conf))
|
|
}
|
|
|
|
}
|