Further implementation of config management
This commit is contained in:
parent
1b5d77e07a
commit
fffd67f8c0
|
@ -9,7 +9,8 @@ The GUI will work off a config similar to the following. Use the ```generate con
|
|||
```
|
||||
|
||||
[slideshow]
|
||||
duration = "300s"
|
||||
slideinterval = "300s"
|
||||
restartinterval = "7d"
|
||||
|
||||
[hdmi]
|
||||
# These are SYSTEMD.TIME formatted times
|
||||
|
|
|
@ -15,27 +15,6 @@ import (
|
|||
"git.kemonine.info/PiFrame/ui"
|
||||
)
|
||||
|
||||
const (
|
||||
CLI_FLAG_CONFIG_ONLY = "config-ui-only"
|
||||
)
|
||||
|
||||
const (
|
||||
CONFIG_FILE_PATH = "/etc/default/pf.toml"
|
||||
CONFIG_KEY_SLIDESHOW_DURATION = "slideshow.duration"
|
||||
CONFIG_KEY_HDMI_OFF = "hdmi.off"
|
||||
CONFIG_KEY_HDMI_ON = "hdmi.on"
|
||||
CONFIG_KEY_ALBUMS_ROOT = "albums.root"
|
||||
CONFIG_KEY_ALBUMS_SELECTED = "albums.selected"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_SLIDESHOW_DURATION = "300s"
|
||||
DEFAULT_HDMI_OFF = "*-*-* 00:00:00"
|
||||
DEFAULT_HDMI_ON = "*-*-* 06:00:00"
|
||||
DEFAULT_ALBUMS_ROOT = "/tank/pictures"
|
||||
DEFAULT_ALBUM_SELECTED = "/"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Command line flag handler
|
||||
f := flag.NewFlagSet("piframe", flag.ContinueOnError)
|
||||
|
@ -44,8 +23,8 @@ func main() {
|
|||
os.Exit(0)
|
||||
}
|
||||
// Command line flags
|
||||
f.Bool(CLI_FLAG_CONFIG_ONLY, false, "Only show the config UI, NOT the slideshow")
|
||||
cliFlag := f.Lookup(CLI_FLAG_CONFIG_ONLY)
|
||||
f.Bool(ui.CLI_FLAG_CONFIG_ONLY, false, "Only show the config UI, NOT the slideshow")
|
||||
cliFlag := f.Lookup(ui.CLI_FLAG_CONFIG_ONLY)
|
||||
if cliFlag != nil {
|
||||
cliFlag.NoOptDefVal = "true"
|
||||
}
|
||||
|
@ -57,23 +36,22 @@ func main() {
|
|||
|
||||
// Setup some defaults
|
||||
pfConfig.Load(confmap.Provider(map[string]interface{}{
|
||||
CONFIG_KEY_SLIDESHOW_DURATION: DEFAULT_SLIDESHOW_DURATION,
|
||||
CONFIG_KEY_HDMI_OFF: DEFAULT_HDMI_OFF,
|
||||
CONFIG_KEY_HDMI_ON: DEFAULT_HDMI_ON,
|
||||
CONFIG_KEY_ALBUMS_ROOT: DEFAULT_ALBUMS_ROOT,
|
||||
CONFIG_KEY_ALBUMS_SELECTED: []string{DEFAULT_ALBUM_SELECTED},
|
||||
ui.CONFIG_KEY_SLIDESHOW_INTERVAL: ui.DEFAULT_SLIDESHOW_INTERVAL,
|
||||
ui.CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL: ui.DEFAULT_SLIDESHOW_RESTART_INTERVAL,
|
||||
ui.CONFIG_KEY_HDMI_OFF: ui.DEFAULT_HDMI_OFF,
|
||||
ui.CONFIG_KEY_HDMI_ON: ui.DEFAULT_HDMI_ON,
|
||||
ui.CONFIG_KEY_ALBUMS_ROOT: ui.DEFAULT_ALBUMS_ROOT,
|
||||
ui.CONFIG_KEY_ALBUMS_SELECTED: []string{ui.DEFAULT_ALBUM_SELECTED},
|
||||
}, "."), nil)
|
||||
|
||||
// Bring in /etc/defaults/pf.toml if it exists
|
||||
configFileProvider := file.Provider(CONFIG_FILE_PATH)
|
||||
_, err := os.Stat(CONFIG_FILE_PATH)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// log.Printf("%s does not exist, USING DEFAULTS", CONFIG_FILE_PATH)
|
||||
} else {
|
||||
if errConfigFile := pfConfig.Load(configFileProvider, toml.Parser()); errConfigFile != nil {
|
||||
log.Fatalf("Error loading config : %s", err)
|
||||
}
|
||||
configFileProvider := file.Provider(ui.CONFIG_FILE_PATH)
|
||||
_, err := os.Stat(ui.CONFIG_FILE_PATH)
|
||||
if os.IsNotExist(err) {
|
||||
//log.Printf("%s does not exist, USING DEFAULTS", ui.CONFIG_FILE_PATH)
|
||||
} else {
|
||||
if errConfigFile := pfConfig.Load(configFileProvider, toml.Parser()); errConfigFile != nil {
|
||||
log.Fatalf("Error loading config : %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,9 +70,9 @@ func main() {
|
|||
log.Fatalf("Error loading command line flags : %s", err)
|
||||
}
|
||||
|
||||
if !pfConfig.Bool(CLI_FLAG_CONFIG_ONLY) {
|
||||
ui.Slideshow()
|
||||
if !pfConfig.Bool(ui.CLI_FLAG_CONFIG_ONLY) {
|
||||
ui.Slideshow(pfConfig)
|
||||
}
|
||||
|
||||
ui.ConfigGui()
|
||||
ui.ConfigGui(pfConfig)
|
||||
}
|
||||
|
|
83
ui/config.go
83
ui/config.go
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/guillermo/go.procmeminfo"
|
||||
"github.com/knadh/koanf"
|
||||
"github.com/rivo/tview"
|
||||
|
||||
"git.kemonine.info/PiFrame/wifi"
|
||||
|
@ -24,7 +25,6 @@ const (
|
|||
CMD_FINDMNT = "/usr/bin/findmnt"
|
||||
CMD_VCGENCMD = "/opt/vc/bin/vcgencmd"
|
||||
FILE_CPU_TEMP = "/sys/class/thermal/thermal_zone0/temp"
|
||||
ALBUM_ROOT_DIR = "/tank/pictures/"
|
||||
SYNCTHING_FOLDER_SKIP = ".stfolder"
|
||||
)
|
||||
|
||||
|
@ -35,7 +35,7 @@ const (
|
|||
PAGE_POWEROFF = "PAGE_POWEROFF"
|
||||
)
|
||||
|
||||
func ConfigGui() {
|
||||
func ConfigGui(config *koanf.Koanf) {
|
||||
// Memory info for status panel
|
||||
meminfo := &procmeminfo.MemInfo{}
|
||||
err := meminfo.Update()
|
||||
|
@ -80,7 +80,7 @@ func ConfigGui() {
|
|||
|
||||
// Get list of all folders that can be used as albums
|
||||
var albums []string
|
||||
err = filepath.Walk(ALBUM_ROOT_DIR, func(path string, fi os.FileInfo, err error) error {
|
||||
err = filepath.Walk(config.String(CONFIG_KEY_ALBUMS_ROOT), func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ func ConfigGui() {
|
|||
if strings.Contains(path, SYNCTHING_FOLDER_SKIP) {
|
||||
return nil
|
||||
}
|
||||
albumName := strings.TrimPrefix(path, ALBUM_ROOT_DIR)
|
||||
albumName := strings.TrimPrefix(path, config.String(CONFIG_KEY_ALBUMS_ROOT))
|
||||
if albumName == "" {
|
||||
albumName = "Main Folder"
|
||||
}
|
||||
|
@ -154,7 +154,9 @@ func ConfigGui() {
|
|||
SetTitle("Menu").
|
||||
SetTitleColor(tcell.ColorAqua)
|
||||
menu.AddItem("Select Albums", "", '1', nil)
|
||||
menu.AddItem("Configure WiFi", "", '2', nil)
|
||||
menu.AddItem("Intervals", "", '2', nil)
|
||||
menu.AddItem("WiFi", "", '3', nil)
|
||||
menu.AddItem("HDMI On/Off", "", '5', nil)
|
||||
|
||||
// Setup base var for main column so the menu setup is easier to manage
|
||||
main := tview.NewFlex().
|
||||
|
@ -165,6 +167,39 @@ func ConfigGui() {
|
|||
SetBorder(true).
|
||||
SetTitleColor(tcell.ColorAqua)
|
||||
|
||||
// Select Albums Form
|
||||
selectAlbumsForm := tview.NewForm()
|
||||
configSelectedAlbums := config.Strings(CONFIG_KEY_ALBUMS_SELECTED)
|
||||
for _, album := range albums {
|
||||
albumSelected := false
|
||||
for _, configSelectedAlbum := range configSelectedAlbums {
|
||||
if configSelectedAlbum == "/" {
|
||||
configSelectedAlbum = "Main Folder"
|
||||
}
|
||||
if album == configSelectedAlbum {
|
||||
albumSelected = true
|
||||
}
|
||||
}
|
||||
selectAlbumsForm.AddCheckbox(album, albumSelected, nil)
|
||||
}
|
||||
selectAlbumsForm.AddButton("Apply", nil)
|
||||
selectAlbumsForm.AddButton("Cancel", func() {
|
||||
main.Clear()
|
||||
app.SetFocus(menu)
|
||||
})
|
||||
|
||||
// Slide Interval Form
|
||||
intervalsForm := tview.NewForm()
|
||||
configSlideInterval := config.String(CONFIG_KEY_SLIDESHOW_INTERVAL)
|
||||
configRestartInterval := config.String(CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL)
|
||||
intervalsForm.AddInputField("Slide", configSlideInterval, 0, nil, nil)
|
||||
intervalsForm.AddInputField("Restart/Reshuffle", configRestartInterval, 0, nil, nil)
|
||||
intervalsForm.AddButton("Apply", nil)
|
||||
intervalsForm.AddButton("Cancel", func() {
|
||||
main.Clear()
|
||||
app.SetFocus(menu)
|
||||
})
|
||||
|
||||
// WiFi Config Form
|
||||
wifiConfigForm := tview.NewForm()
|
||||
wifiConfigAccessPoint := ""
|
||||
|
@ -185,13 +220,14 @@ func ConfigGui() {
|
|||
app.SetFocus(menu)
|
||||
})
|
||||
|
||||
// Select Albums Form
|
||||
selectAlbumsForm := tview.NewForm()
|
||||
for _, album := range albums {
|
||||
selectAlbumsForm.AddCheckbox(album, true, nil)
|
||||
}
|
||||
selectAlbumsForm.AddButton("Apply", nil)
|
||||
selectAlbumsForm.AddButton("Cancel", func() {
|
||||
// HDMI On/Off Form
|
||||
hdmiForm := tview.NewForm()
|
||||
configHDMIOff := config.String(CONFIG_KEY_HDMI_OFF)
|
||||
configHDMIOn := config.String(CONFIG_KEY_HDMI_ON)
|
||||
hdmiForm.AddInputField("HDMI Off Schedule", configHDMIOff, 0, nil, nil)
|
||||
hdmiForm.AddInputField("HDMI On Schedule", configHDMIOn, 0, nil, nil)
|
||||
hdmiForm.AddButton("Apply", nil)
|
||||
hdmiForm.AddButton("Cancel", func() {
|
||||
main.Clear()
|
||||
app.SetFocus(menu)
|
||||
})
|
||||
|
@ -204,12 +240,24 @@ func ConfigGui() {
|
|||
main.AddItem(selectAlbumsForm, 0, 1, true)
|
||||
app.SetFocus(selectAlbumsForm)
|
||||
}
|
||||
if title == "Configure WiFi" {
|
||||
if title == "WiFi" {
|
||||
main.SetTitle("Configure WiFi")
|
||||
main.Clear()
|
||||
main.AddItem(wifiConfigForm, 0, 1, true)
|
||||
app.SetFocus(wifiConfigForm)
|
||||
}
|
||||
if title == "Intervals" {
|
||||
main.SetTitle("Configure Intervals")
|
||||
main.Clear()
|
||||
main.AddItem(intervalsForm, 0, 1, true)
|
||||
app.SetFocus(intervalsForm)
|
||||
}
|
||||
if title == "HDMI On/Off" {
|
||||
main.SetTitle("Configure HDMI On/Off")
|
||||
main.Clear()
|
||||
main.AddItem(hdmiForm, 0, 1, true)
|
||||
app.SetFocus(hdmiForm)
|
||||
}
|
||||
})
|
||||
|
||||
// Side bar fields
|
||||
|
@ -364,9 +412,14 @@ func ConfigGui() {
|
|||
// Override some of the default behavior so up/dn move between fields in forms
|
||||
// Per API GetFocusedItemIndex on a form will be -1 if a form item isn't currently focused
|
||||
// We use this as a bit of a cheat to figure out if we're inside of a form that needs better nav options for users (ie. tab doesn't exist on a remote)
|
||||
wifiField, wifiButton := wifiConfigForm.GetFocusedItemIndex()
|
||||
albumField, albumButton := selectAlbumsForm.GetFocusedItemIndex()
|
||||
if wifiField != -1 || wifiButton != -1 || albumField != -1 || albumButton != -1 {
|
||||
intervalField, intervalButton := intervalsForm.GetFocusedItemIndex()
|
||||
wifiField, wifiButton := wifiConfigForm.GetFocusedItemIndex()
|
||||
hdmiField, hdmiButton := hdmiForm.GetFocusedItemIndex()
|
||||
if (wifiField != -1 || wifiButton != -1 ||
|
||||
albumField != -1 || albumButton != -1 ||
|
||||
intervalField != -1 || intervalButton != -1 ||
|
||||
hdmiField != -1 || hdmiButton != -1) {
|
||||
switch event.Key() {
|
||||
case tcell.KeyUp:
|
||||
return tcell.NewEventKey(tcell.KeyBacktab, 0, event.Modifiers())
|
||||
|
|
24
ui/constants.go
Normal file
24
ui/constants.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package ui
|
||||
|
||||
const (
|
||||
CLI_FLAG_CONFIG_ONLY = "config-ui-only"
|
||||
)
|
||||
|
||||
const (
|
||||
CONFIG_FILE_PATH = "/etc/default/pf.toml"
|
||||
CONFIG_KEY_SLIDESHOW_INTERVAL = "slideshow.slideinterval"
|
||||
CONFIG_KEY_SLIDESHOW_RESTART_INTERVAL = "slideshow.restartinterval"
|
||||
CONFIG_KEY_HDMI_OFF = "hdmi.off"
|
||||
CONFIG_KEY_HDMI_ON = "hdmi.on"
|
||||
CONFIG_KEY_ALBUMS_ROOT = "albums.root"
|
||||
CONFIG_KEY_ALBUMS_SELECTED = "albums.selected"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_SLIDESHOW_INTERVAL = "300s"
|
||||
DEFAULT_SLIDESHOW_RESTART_INTERVAL = "7d"
|
||||
DEFAULT_HDMI_OFF = "*-*-* 00:00:00"
|
||||
DEFAULT_HDMI_ON = "*-*-* 06:00:00"
|
||||
DEFAULT_ALBUMS_ROOT = "/tank/pictures"
|
||||
DEFAULT_ALBUM_SELECTED = "/"
|
||||
)
|
|
@ -9,14 +9,14 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/eiannone/keyboard"
|
||||
"github.com/knadh/koanf"
|
||||
)
|
||||
|
||||
const (
|
||||
CMD_FIM = "/usr/local/bin/pf-fim.sh"
|
||||
SLIDESHOW_INTERVAL = 300 * time.Second
|
||||
CMD_FIM = "/usr/local/bin/pf-fim.sh"
|
||||
)
|
||||
|
||||
func Slideshow() {
|
||||
func Slideshow(config *koanf.Koanf) {
|
||||
// fim placeholder so we can operate on it when a exit slideshow is received
|
||||
var fim *exec.Cmd = nil
|
||||
|
||||
|
@ -32,7 +32,7 @@ func Slideshow() {
|
|||
}
|
||||
|
||||
// Advance slideshow every interval as defined in const()
|
||||
ticker := time.NewTicker(SLIDESHOW_INTERVAL)
|
||||
ticker := time.NewTicker(config.Duration(CONFIG_KEY_SLIDESHOW_INTERVAL))
|
||||
stop_ticker := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
|
@ -68,7 +68,6 @@ func Slideshow() {
|
|||
if event.Err != nil {
|
||||
log.Fatalf("Error listening to key events : %s", err)
|
||||
}
|
||||
log.Printf("You pressed: key %X\n", event.Key)
|
||||
|
||||
// Keys for fim event management (previous/next in particular)
|
||||
fimKey := ""
|
||||
|
@ -100,7 +99,7 @@ func Slideshow() {
|
|||
if err != nil {
|
||||
log.Fatalf("Error controlling fim : %s", err)
|
||||
}
|
||||
ticker.Reset(SLIDESHOW_INTERVAL)
|
||||
ticker.Reset(config.Duration(CONFIG_KEY_SLIDESHOW_INTERVAL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue