Added an app directory and a config file.

We now also download the image for notifications if a local copy cannot
be found.
Also ensure that we are using Unix line endings and not DOS ones.
master
Ronald1985 2 years ago
parent 5929676a17
commit e66327c50a

@ -1,98 +1,243 @@
package main package main
import ( import (
"fmt" "errors"
"os/exec" "fmt"
"strings" "io"
"time" "net/http"
"os"
disabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/disabledicon" "os/exec"
enabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/enabledicon" "runtime"
"strings"
"github.com/gen2brain/beeep" "time"
"github.com/getlantern/systray"
ge "github.com/ronaldr1985/graceful-exit" disabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/disabledicon"
) enabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/enabledicon"
const ( "github.com/gen2brain/beeep"
TIME_INBETWEEN_NOTIFICATIONS = 20 * time.Minute "github.com/getlantern/systray"
) ge "github.com/ronaldr1985/graceful-exit"
"gopkg.in/yaml.v3"
func SendNotification(title string, message string) bool { )
path, err := exec.LookPath("herbe")
if err == nil { const (
var args []string DEFAULT_TIME_INBETWEEN_NOTIFICATIONS = 20 * time.Minute
args = append(args, title, message) EYE_REMINDER_ICON_URL = "https://gitea.ronald1985.uk/ronald1985/Eye-Reminder/raw/branch/master/assets/Eye-Reminder-Icon.png"
cmd := exec.Command(path, args...) )
out, err := cmd.CombinedOutput()
if out == nil && err == nil { type Config struct {
return true Interval int `yaml:"Interval"`
} imageLocation string
} else if strings.Contains(err.Error(), "executable file not found in ") { }
err := beeep.Notify(title, message, "assets/Eye-Reminder-Icon.png")
if err != nil { var (
panic(err) DEFAULT_UNIX_DIRECTORY = os.Getenv("HOME") + "/.config/Eye-Reminder/"
} DEFAULT_WINDOWS_DIRECTORY = os.Getenv("LOCALAPPDATA") + "/Eye-Reminder/"
} ProgramConfig Config
)
return false
} func print_fatal_error(err ...string) {
fmt.Fprintln(os.Stderr, err)
func systrayOnReady() { os.Exit(1)
var enabled bool = true }
systray.SetTitle("Eye Reminder")
systray.SetTooltip("Eye Reminder") func ReadConfig(filename string) (Config, error) {
systray.SetIcon(enabledicon.Data) config := &Config{}
mQuitOrig := systray.AddMenuItem("Quit", "Quit the whole app")
bytes, err := os.ReadFile(filename)
go func() { if err != nil {
<-mQuitOrig.ClickedCh return *config, err
fmt.Println("Requesting quit") }
systray.Quit()
fmt.Println("Finished quitting") err = yaml.Unmarshal(bytes, config)
}() if err != nil {
return *config, fmt.Errorf("in file %q: %w", filename, err)
go func() { }
lastTimeNotificationWasSent := time.Now().Add(-20 * time.Minute)
return *config, err
for { }
if enabled && time.Since(lastTimeNotificationWasSent) > TIME_INBETWEEN_NOTIFICATIONS {
SendNotification("Eye Reminder", "Look away for the screen for atleast 20 seconds") func CheckIfFileExists(filename string) (bool, error) {
if _, err := os.Stat(filename); err == nil {
lastTimeNotificationWasSent = time.Now() return true, nil
} } else if errors.Is(err, os.ErrNotExist) {
} return false, nil
}() } else {
return false, err
go func() { }
systray.AddSeparator() }
mEnabled := systray.AddMenuItemCheckbox("Enabled", "Check Me", true)
func DownloadFile(filename, url string) bool {
for { out, err := os.Create(filename)
select { if err != nil {
case <-mEnabled.ClickedCh: return false
if mEnabled.Checked() { }
mEnabled.Uncheck() defer out.Close()
enabled = false resp, err := http.Get(url)
if err != nil {
systray.SetIcon(disabledicon.Data) out.Close()
} else { os.Remove(filename)
mEnabled.Check() return false
}
enabled = true defer resp.Body.Close()
systray.SetIcon(enabledicon.Data) _, err = io.Copy(out, resp.Body)
} if err != nil {
} return false
} }
}()
} return true
}
func main() {
ge.HandleSignals(false) func SendNotification(title string, message string) bool {
path, err := exec.LookPath("herbe")
systrayOnExit := func() { if err == nil {
} var args []string
systray.Run(systrayOnReady, systrayOnExit) args = append(args, title, message)
} cmd := exec.Command(path, args...)
err := cmd.Start()
if err != nil {
return false
}
} else if strings.Contains(err.Error(), "executable file not found in ") {
err := beeep.Notify(title, message, "assets/Eye-Reminder-Icon.png")
if err != nil {
return false
}
}
return true
}
func systrayOnReady() {
var enabled bool = true
systray.SetTitle("Eye Reminder")
systray.SetTooltip("Eye Reminder")
systray.SetIcon(enabledicon.Data)
mQuitOrig := systray.AddMenuItem("Quit", "Quit the whole app")
go func() {
<-mQuitOrig.ClickedCh
fmt.Println("Requesting quit")
systray.Quit()
fmt.Println("Finished quitting")
}()
go func() {
lastTimeNotificationWasSent := time.Now().Add(time.Duration(-ProgramConfig.Interval) * time.Minute)
for {
if enabled && time.Since(lastTimeNotificationWasSent) > time.Duration(ProgramConfig.Interval) {
fmt.Println("Sending notification")
SendNotification("Eye Reminder", "Look away for the screen for atleast 20 seconds")
lastTimeNotificationWasSent = time.Now()
}
}
}()
go func() {
systray.AddSeparator()
mEnabled := systray.AddMenuItemCheckbox("Enabled", "Check Me", true)
for {
select {
case <-mEnabled.ClickedCh:
if mEnabled.Checked() {
mEnabled.Uncheck()
enabled = false
systray.SetIcon(disabledicon.Data)
} else {
mEnabled.Check()
enabled = true
systray.SetIcon(enabledicon.Data)
}
}
}
}()
}
func main() {
ge.HandleSignals(false)
var possibleConfigFileLocations []string
possibleConfigFileLocations = append(possibleConfigFileLocations, os.Getenv("HOME")+"/.config/Eye-Reminder/config.yaml")
possibleConfigFileLocations = append(possibleConfigFileLocations, os.Getenv("HOME")+"/.config/Eye-Reminder/config.yml")
possibleConfigFileLocations = append(possibleConfigFileLocations, os.Getenv("XDG_CONFIG_HOME")+"/Eye-Reminder/config.yaml")
possibleConfigFileLocations = append(possibleConfigFileLocations, os.Getenv("XDG_CONFIG_HOME")+"/Eye-Reminder/config.yml")
possibleConfigFileLocations = append(possibleConfigFileLocations, os.Getenv("LOCALAPPDATA")+"/Eye-Reminder/config.yml")
possibleConfigFileLocations = append(possibleConfigFileLocations, os.Getenv("LOCALAPPDATA")+"/Eye-Reminder/config.yml")
configFileLocation := "not found"
for _, file := range possibleConfigFileLocations {
if fileExists, err := CheckIfFileExists(file); fileExists {
configFileLocation = file
break
} else if err != nil {
fmt.Fprintln(os.Stderr, "Error checking for config file:", err)
}
}
var err error
appDirectory := "not found"
if configFileLocation == "not found" {
ProgramConfig.Interval = int(DEFAULT_TIME_INBETWEEN_NOTIFICATIONS)
var possibleAppDirectoryLocations []string
possibleAppDirectoryLocations = append(possibleAppDirectoryLocations, os.Getenv("HOME")+"/.config/Eye-Reminder/")
possibleAppDirectoryLocations = append(possibleAppDirectoryLocations, os.Getenv("HOME")+"/.config/Eye-Reminder/")
possibleAppDirectoryLocations = append(possibleAppDirectoryLocations, os.Getenv("XDG_CONFIG_HOME")+"/Eye-Reminder/")
possibleAppDirectoryLocations = append(possibleAppDirectoryLocations, os.Getenv("XDG_CONFIG_HOME")+"/Eye-Reminder/")
possibleAppDirectoryLocations = append(possibleAppDirectoryLocations, os.Getenv("LOCALAPPDATA")+"/Eye-Reminder/")
possibleAppDirectoryLocations = append(possibleAppDirectoryLocations, os.Getenv("LOCALAPPDATA")+"/Eye-Reminder/")
for _, folder := range possibleAppDirectoryLocations {
if _, err := os.Stat(folder); !os.IsNotExist(err) {
appDirectory = folder
break
}
}
if appDirectory == "not found" {
if runtime.GOOS == "windows" {
appDirectory = DEFAULT_WINDOWS_DIRECTORY
} else {
appDirectory = DEFAULT_UNIX_DIRECTORY
}
fmt.Println("Creating config directory:", appDirectory)
err := os.Mkdir(appDirectory, 0755)
fmt.Println("Created folder:", appDirectory)
if err != nil {
panic(err)
}
}
} else {
appDirectory = configFileLocation[:strings.IndexByte(configFileLocation, '/')+1]
ProgramConfig, err = ReadConfig(configFileLocation)
if err != nil {
panic(err)
}
}
ProgramConfig.imageLocation = appDirectory + "Eye-Reminder-Icon.png"
if fileExists, err := CheckIfFileExists(ProgramConfig.imageLocation); !fileExists && err == nil {
fmt.Println("Downloading icon")
DownloadFile(ProgramConfig.imageLocation, EYE_REMINDER_ICON_URL)
fmt.Println("Downloaded icon")
} else if err != nil {
print_fatal_error("Failed to check if ", ProgramConfig.imageLocation, " exists.")
}
systrayOnExit := func() {
}
systray.Run(systrayOnReady, systrayOnExit)
}

Loading…
Cancel
Save