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
parent
5929676a17
commit
e66327c50a
@ -1,98 +1,243 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
disabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/disabledicon"
|
||||
enabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/enabledicon"
|
||||
|
||||
"github.com/gen2brain/beeep"
|
||||
"github.com/getlantern/systray"
|
||||
ge "github.com/ronaldr1985/graceful-exit"
|
||||
)
|
||||
|
||||
const (
|
||||
TIME_INBETWEEN_NOTIFICATIONS = 20 * time.Minute
|
||||
)
|
||||
|
||||
func SendNotification(title string, message string) bool {
|
||||
path, err := exec.LookPath("herbe")
|
||||
if err == nil {
|
||||
var args []string
|
||||
args = append(args, title, message)
|
||||
cmd := exec.Command(path, args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if out == nil && err == nil {
|
||||
return true
|
||||
}
|
||||
} else if strings.Contains(err.Error(), "executable file not found in ") {
|
||||
err := beeep.Notify(title, message, "assets/Eye-Reminder-Icon.png")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
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(-20 * time.Minute)
|
||||
|
||||
for {
|
||||
if enabled && time.Since(lastTimeNotificationWasSent) > TIME_INBETWEEN_NOTIFICATIONS {
|
||||
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)
|
||||
|
||||
systrayOnExit := func() {
|
||||
}
|
||||
systray.Run(systrayOnReady, systrayOnExit)
|
||||
}
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
disabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/disabledicon"
|
||||
enabledicon "gitea.ronald1985.uk/ronald1985/Eye-Reminder/icons/enabledicon"
|
||||
|
||||
"github.com/gen2brain/beeep"
|
||||
"github.com/getlantern/systray"
|
||||
ge "github.com/ronaldr1985/graceful-exit"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_TIME_INBETWEEN_NOTIFICATIONS = 20 * time.Minute
|
||||
EYE_REMINDER_ICON_URL = "https://gitea.ronald1985.uk/ronald1985/Eye-Reminder/raw/branch/master/assets/Eye-Reminder-Icon.png"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Interval int `yaml:"Interval"`
|
||||
imageLocation string
|
||||
}
|
||||
|
||||
var (
|
||||
DEFAULT_UNIX_DIRECTORY = os.Getenv("HOME") + "/.config/Eye-Reminder/"
|
||||
DEFAULT_WINDOWS_DIRECTORY = os.Getenv("LOCALAPPDATA") + "/Eye-Reminder/"
|
||||
ProgramConfig Config
|
||||
)
|
||||
|
||||
func print_fatal_error(err ...string) {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func ReadConfig(filename string) (Config, error) {
|
||||
config := &Config{}
|
||||
|
||||
bytes, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return *config, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(bytes, config)
|
||||
if err != nil {
|
||||
return *config, fmt.Errorf("in file %q: %w", filename, err)
|
||||
}
|
||||
|
||||
return *config, err
|
||||
}
|
||||
|
||||
func CheckIfFileExists(filename string) (bool, error) {
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
return true, nil
|
||||
} else if errors.Is(err, os.ErrNotExist) {
|
||||
return false, nil
|
||||
} else {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
func DownloadFile(filename, url string) bool {
|
||||
out, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
out.Close()
|
||||
os.Remove(filename)
|
||||
return false
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func SendNotification(title string, message string) bool {
|
||||
path, err := exec.LookPath("herbe")
|
||||
if err == nil {
|
||||
var args []string
|
||||
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…
Reference in New Issue