You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

188 lines
4.4 KiB

package config
import (
"encoding/json"
"fmt"
"github.com/wailsapp/wails"
"optimus/backend/jpeg"
"optimus/backend/localstore"
"optimus/backend/png"
"optimus/backend/webp"
"os"
"path"
"path/filepath"
"strconv"
)
const filename = "conf.json"
// App represents application persistent configuration values.
type App struct {
OutDir string `json:"outDir"`
Target string `json:"target"`
Prefix string `json:"prefix"`
Suffix string `json:"suffix"`
Sizes []*size `json:"sizes"`
JpegOpt *jpeg.Options `json:"jpegOpt"`
PngOpt *png.Options `json:"pngOpt"`
WebpOpt *webp.Options `json:"webpOpt"`
}
// Config represents the application settings.
type Config struct {
App *App
Runtime *wails.Runtime
Logger *wails.CustomLogger
localStore *localstore.LocalStore
}
// WailsInit performs setup when Wails is ready.
func (c *Config) WailsInit(runtime *wails.Runtime) error {
c.Runtime = runtime
c.Logger = c.Runtime.Log.New("Config")
c.Logger.Info("Config initialized...")
return nil
}
// NewConfig returns a new instance of Config.
func NewConfig() *Config {
c := &Config{}
c.localStore = localstore.NewLocalStore()
a, err := c.localStore.Load(filename)
if err != nil {
c.App, _ = defaults()
}
if err = json.Unmarshal(a, &c.App); err != nil {
fmt.Printf("error")
}
return c
}
// GetAppConfig returns the application configuration.
func (c *Config) GetAppConfig() map[string]interface{} {
return map[string]interface{}{
"outDir": c.App.OutDir,
"target": c.App.Target,
"prefix": c.App.Prefix,
"suffix": c.App.Suffix,
"sizes": c.App.Sizes,
"jpegOpt": c.App.JpegOpt,
"pngOpt": c.App.PngOpt,
"webpOpt": c.App.WebpOpt,
}
}
// OpenOutputDir opens the output directory using the native system browser.
func (c *Config) OpenOutputDir() error {
if err := c.Runtime.Browser.OpenURL(c.App.OutDir); err != nil {
return err
}
return nil
}
// RestoreDefaults sets the app configuration to defaults.
func (c *Config) RestoreDefaults() (err error) {
var a *App
a, err = defaults()
if err != nil {
return err
}
c.App = a
if err = c.store(); err != nil {
return err
}
return nil
}
// SetConfig sets and stores the given configuration.
func (c *Config) SetConfig(cfg string) error {
a := &App{}
if err := json.Unmarshal([]byte(cfg), &a); err != nil {
c.Logger.Errorf("failed to unmarshal config: %v", err)
return err
}
c.App = a
if err := c.store(); err != nil {
c.Logger.Errorf("failed to store config: %v", err)
return err
}
return nil
}
// SetOutDir opens a directory select dialog and sets the output directory to
// the chosen directory.
func (c *Config) SetOutDir() string {
dir := c.Runtime.Dialog.SelectDirectory()
if dir != "" {
c.App.OutDir = dir
c.Logger.Infof("set output directory: %s", dir)
if err := c.store(); err != nil {
c.Logger.Errorf("failed to store config: %v", err)
}
}
return c.App.OutDir
}
// defaults returns the application configuration defaults.
func defaults() (*App, error) {
a := &App{
Target: "webp",
JpegOpt: &jpeg.Options{Quality: 80},
PngOpt: &png.Options{Quality: 80},
WebpOpt: &webp.Options{Lossless: false, Quality: 80},
}
ud, err := os.UserHomeDir()
if err != nil {
fmt.Printf("failed to get user directory: %v", err)
return nil, err
}
od := path.Join(ud, "Optimus")
cp := filepath.Clean(od)
if _, err = os.Stat(od); os.IsNotExist(err) {
if err = os.Mkdir(od, 0777); err != nil {
od = "./"
fmt.Printf("failed to create default output directory: %v", err)
return nil, err
}
}
a.OutDir = cp
return a, nil
}
// store stores the configuration state to the file system.
func (c *Config) store() error {
js, err := json.Marshal(c.GetAppConfig())
if err != nil {
c.Logger.Errorf("failed to marshal config: %v", err)
return err
}
if err = c.localStore.Store(js, filename); err != nil {
c.Logger.Errorf("failed to store config: %v", err)
return err
}
return nil
}
// rect represents an image width and height size.
type rect struct {
Height int `json:"height,omitempty"`
Width int `json:"width,omitempty"`
}
// String returns a string representation of the rect.
// For example, "1280x720"
func (r *rect) String() string {
w := strconv.Itoa(r.Width)
h := strconv.Itoa(r.Height)
return fmt.Sprintf("%sx%s", w, h)
}
// size represents an image resizing. Strategy represents an image resizing
// strategy, such as cropping.
type size struct {
rect
Strategy int `json:"strategy"`
}