Files
SwipedModSwitcher/main.go
2023-07-28 15:42:37 -05:00

194 lines
4.1 KiB
Go

package main
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
"gopkg.in/yaml.v3"
cp "github.com/otiai10/copy"
)
type Config struct {
ProfilesRoot string `yaml:"profiles_root"`
ArchiveRoot string `yaml:"archive_root"`
}
func saveConfig(cfg Config) {
d, err := yaml.Marshal(cfg)
if err != nil {
fmt.Println(err)
}
err = os.WriteFile("config.yaml", d, 0775)
if err != nil {
fmt.Println(err)
}
}
func loadConfig() *Config {
_, err := os.Stat("config.yaml")
if err != nil {
fmt.Println(err)
saveConfig(Config{ProfilesRoot: "", ArchiveRoot: ""})
}
d, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println(err)
}
cfg := Config{}
err = yaml.Unmarshal(d, &cfg)
if err != nil {
fmt.Println(err)
return &Config{}
}
return &cfg
}
var cfg = loadConfig()
func main() {
ap := app.New()
wp := ap.NewWindow("Cyberpunk Mod Switcher")
wp.Resize(fyne.NewSize(1024, 768))
wp.CenterOnScreen()
grid := container.NewVBox()
scroll := container.NewVScroll(grid)
scroll.SetMinSize(fyne.NewSize(-1, 768))
//load grid
fillGrid(grid, wp)
profilesrootentry := widget.NewEntry()
profilesrootentry.SetText(cfg.ProfilesRoot)
profilesrootentry.Disable()
archiverootentry := widget.NewEntry()
archiverootentry.SetText(cfg.ArchiveRoot)
archiverootentry.Disable()
container := container.NewVBox(
widget.NewForm(widget.NewFormItem("Profiles Directory", profilesrootentry)),
widget.NewButtonWithIcon("Select", theme.FolderIcon(), func() {
dialog.NewFolderOpen(func(lu fyne.ListableURI, err error) {
if err != nil {
fmt.Println(err)
}
if lu == nil {
return
}
profilesrootentry.SetText(lu.Path())
cfg.ProfilesRoot = lu.Path()
saveConfig(*cfg)
fillGrid(grid, wp)
}, wp).Show()
}),
widget.NewForm(widget.NewFormItem("Archive Directory", archiverootentry)),
widget.NewButtonWithIcon("Select", theme.FolderIcon(), func() {
dialog.NewFolderOpen(func(lu fyne.ListableURI, err error) {
if err != nil {
fmt.Println(err)
}
if lu == nil {
return
}
archiverootentry.SetText(lu.Path())
cfg.ArchiveRoot = lu.Path()
saveConfig(*cfg)
fillGrid(grid, wp)
}, wp).Show()
}),
widget.NewSeparator(),
widget.NewButton("Reload Profiles", func() {
fillGrid(grid, wp)
}),
scroll,
)
wp.SetContent(container)
wp.ShowAndRun()
}
func fillGrid(grid *fyne.Container, parent fyne.Window) {
profiles := scanProfiles(cfg.ProfilesRoot)
archive := cfg.ArchiveRoot
grid.Hide()
defer grid.Show()
grid.RemoveAll()
for _, profile := range profiles {
profilename := strings.TrimSuffix(filepath.Base(profile), ".cpms")
grid.Add(widget.NewButton(profilename, makeIFunc(profile, archive, parent)))
}
}
func scanProfiles(profilesroot string) []string {
dir := filepath.Join(profilesroot, "*.cpms/")
m, err := filepath.Glob(dir)
if err != nil {
fmt.Println(err)
}
return m
}
func makeIFunc(profile, archive string, parent fyne.Window) func() {
return func() {
if cfg.ArchiveRoot == "" || cfg.ProfilesRoot == "" {
d := dialog.NewInformation("Notice", "you must select a archive root and profiles root before", parent)
d.Show()
return
}
dialog.NewConfirm("Are You Sure?", fmt.Sprintf("the current contents of %s will be lost", archive), func(b bool) {
if b {
err := walk(archive, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
err = os.Remove(path)
if err != nil {
fmt.Println(err)
}
return nil
})
if err != nil {
fmt.Println(err)
}
err = cp.Copy(profile, archive)
if err != nil {
fmt.Println(err)
}
dialog.NewInformation("Success", fmt.Sprintf("copied all files from %s to %s", filepath.Base(profile), archive), parent).Show()
}
}, parent).Show()
}
}
func walk(root string, fn filepath.WalkFunc) error {
initial := false
return filepath.Walk(root, func(path string, info fs.FileInfo, err error) error {
if !initial {
initial = true
return nil
}
return fn(path, info, err)
})
}