From 394c77f13976cbb724ff0a39cfb5ef10d173382f Mon Sep 17 00:00:00 2001 From: Justin Hawkins Date: Thu, 7 Apr 2022 21:46:39 +0930 Subject: [PATCH] Enable portable mode by reading a config file 'gropple.yml' from the current directory, if present. Closes #13 --- CHANGELOG.md | 1 + README.md | 7 +++++++ config/config.go | 29 ++++++++++++++++++----------- main.go | 19 ++++++++++++------- version/version.go | 2 -- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60ebb21..fd44871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Add a stop button in the popup to abort a download (Linux/Mac only) - Move included JS to local app instead of accessing from a CDN - Make the simultaneous download limit apply to each unique domain +- Support "portable" mode, reading gropple.yml from the current directory, if present ## [v0.5.3] - 2021-11-21 diff --git a/README.md b/README.md index 278c400..090c6dd 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,13 @@ While gropple will use your `PATH` to find the executable, you can also specify instead. Note that any tools that the downloader calls itself (for instance, ffmpeg) will probably need to be available on your path. +## Portable mode + +If you'd like to use gropple from a USB stick or similar, copy the config file from +it's default location (shown when you start gropple) to the same location as the binary, and rename it to `gropple.yml`. + +If that file is present in the same directory as the binary, it will be used instead. + ## Problems Most download problems are probably diagnosable via the log - check in the popup window and scroll diff --git a/config/config.go b/config/config.go index 9ca45f6..31810cc 100644 --- a/config/config.go +++ b/config/config.go @@ -40,7 +40,8 @@ type Config struct { // ConfigService is a struct to handle configuration requests, allowing for the // location that config files are loaded to be customised. type ConfigService struct { - Config *Config + Config *Config + ConfigPath string } func (cs *ConfigService) LoadTestConfig() { @@ -166,9 +167,17 @@ func (c *Config) UpdateFromJSON(j []byte) error { return nil } -// configPath returns the full path to the config file (which may or may -// not yet exist) and also creates the subdir if needed (one level) -func (cs *ConfigService) configPath() string { +// DetermineConfigDir determines where the config is (or should be) stored. +func (cs *ConfigService) DetermineConfigDir() { + // check current directory first, for a file called gropple.yml + _, err := os.Stat("gropple.yml") + if err == nil { + // exists in current directory, use that. + cs.ConfigPath = "gropple.yml" + return + } + + // otherwise fall back to using the UserConfigDir dir, err := os.UserConfigDir() if err != nil { log.Fatalf("cannot find a directory to store config: %v", err) @@ -186,13 +195,13 @@ func (cs *ConfigService) configPath() string { } fullFilename := fullPath + string(os.PathSeparator) + "config.yml" - return fullFilename + cs.ConfigPath = fullFilename } // ConfigFileExists checks if the config file already exists, and also checks // if there is an error accessing it func (cs *ConfigService) ConfigFileExists() (bool, error) { - path := cs.configPath() + path := cs.ConfigPath info, err := os.Stat(path) if os.IsNotExist(err) { return false, nil @@ -209,7 +218,7 @@ func (cs *ConfigService) ConfigFileExists() (bool, error) { // LoadConfig loads the configuration from disk, migrating and updating it to the // latest version if needed. func (cs *ConfigService) LoadConfig() error { - path := cs.configPath() + path := cs.ConfigPath b, err := os.ReadFile(path) if err != nil { return fmt.Errorf("Could not read config '%s': %v", path, err) @@ -246,18 +255,16 @@ func (cs *ConfigService) WriteConfig() { panic(err) } - path := cs.configPath() + path := cs.ConfigPath file, err := os.Create( path, ) if err != nil { - log.Fatalf("Could not open config file") + log.Fatalf("Could not open config file %s: %s", path, err) } defer file.Close() file.Write(s) file.Close() - - log.Printf("Wrote configuration out to %s", path) } diff --git a/main.go b/main.go index f9dd562..32316ee 100644 --- a/main.go +++ b/main.go @@ -39,20 +39,26 @@ type errorResponse struct { } func main() { - cs := config.ConfigService{} - exists, err := cs.ConfigFileExists() + log.Printf("Starting gropple %s - https://github.com/tardisx/gropple", versionInfo.CurrentVersion) + + configService = &config.ConfigService{} + configService.DetermineConfigDir() + exists, err := configService.ConfigFileExists() if err != nil { log.Fatal(err) } if !exists { log.Print("No config file - creating default config") - cs.LoadDefaultConfig() - cs.WriteConfig() + configService.LoadDefaultConfig() + configService.WriteConfig() + log.Printf("Configuration written to %s", configService.ConfigPath) } else { - err := cs.LoadConfig() + err := configService.LoadConfig() if err != nil { log.Fatal(err) } + log.Printf("Configuration loaded from %s", configService.ConfigPath) + } r := mux.NewRouter() @@ -97,8 +103,7 @@ func main() { } }() - log.Printf("starting gropple %s - https://github.com/tardisx/gropple", versionInfo.CurrentVersion) - log.Printf("go to %s for details on installing the bookmarklet and to check status", configService.Config.Server.Address) + log.Printf("Visit %s for details on installing the bookmarklet and to check status", configService.Config.Server.Address) log.Fatal(srv.ListenAndServe()) } diff --git a/version/version.go b/version/version.go index 2f065e5..50876e5 100644 --- a/version/version.go +++ b/version/version.go @@ -63,8 +63,6 @@ func (i *Info) canUpgrade() bool { return false } - log.Printf("We are %s, github is %s", i.CurrentVersion, i.GithubVersion) - if !semver.IsValid(i.CurrentVersion) { log.Printf("current version %s is invalid", i.CurrentVersion) }