Enable portable mode by reading a config file 'gropple.yml' from the current directory, if present. Closes #13

This commit is contained in:
Justin Hawkins 2022-04-07 21:46:39 +09:30
parent b88df9beff
commit 394c77f139
5 changed files with 38 additions and 20 deletions

View File

@ -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) - 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 - Move included JS to local app instead of accessing from a CDN
- Make the simultaneous download limit apply to each unique domain - 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 ## [v0.5.3] - 2021-11-21

View File

@ -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 instead. Note that any tools that the downloader calls itself (for instance, ffmpeg) will
probably need to be available on your path. 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 ## Problems
Most download problems are probably diagnosable via the log - check in the popup window and scroll Most download problems are probably diagnosable via the log - check in the popup window and scroll

View File

@ -40,7 +40,8 @@ type Config struct {
// ConfigService is a struct to handle configuration requests, allowing for the // ConfigService is a struct to handle configuration requests, allowing for the
// location that config files are loaded to be customised. // location that config files are loaded to be customised.
type ConfigService struct { type ConfigService struct {
Config *Config Config *Config
ConfigPath string
} }
func (cs *ConfigService) LoadTestConfig() { func (cs *ConfigService) LoadTestConfig() {
@ -166,9 +167,17 @@ func (c *Config) UpdateFromJSON(j []byte) error {
return nil return nil
} }
// configPath returns the full path to the config file (which may or may // DetermineConfigDir determines where the config is (or should be) stored.
// not yet exist) and also creates the subdir if needed (one level) func (cs *ConfigService) DetermineConfigDir() {
func (cs *ConfigService) configPath() string { // 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() dir, err := os.UserConfigDir()
if err != nil { if err != nil {
log.Fatalf("cannot find a directory to store config: %v", err) 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" fullFilename := fullPath + string(os.PathSeparator) + "config.yml"
return fullFilename cs.ConfigPath = fullFilename
} }
// ConfigFileExists checks if the config file already exists, and also checks // ConfigFileExists checks if the config file already exists, and also checks
// if there is an error accessing it // if there is an error accessing it
func (cs *ConfigService) ConfigFileExists() (bool, error) { func (cs *ConfigService) ConfigFileExists() (bool, error) {
path := cs.configPath() path := cs.ConfigPath
info, err := os.Stat(path) info, err := os.Stat(path)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return false, nil 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 // LoadConfig loads the configuration from disk, migrating and updating it to the
// latest version if needed. // latest version if needed.
func (cs *ConfigService) LoadConfig() error { func (cs *ConfigService) LoadConfig() error {
path := cs.configPath() path := cs.ConfigPath
b, err := os.ReadFile(path) b, err := os.ReadFile(path)
if err != nil { if err != nil {
return fmt.Errorf("Could not read config '%s': %v", path, err) return fmt.Errorf("Could not read config '%s': %v", path, err)
@ -246,18 +255,16 @@ func (cs *ConfigService) WriteConfig() {
panic(err) panic(err)
} }
path := cs.configPath() path := cs.ConfigPath
file, err := os.Create( file, err := os.Create(
path, path,
) )
if err != nil { if err != nil {
log.Fatalf("Could not open config file") log.Fatalf("Could not open config file %s: %s", path, err)
} }
defer file.Close() defer file.Close()
file.Write(s) file.Write(s)
file.Close() file.Close()
log.Printf("Wrote configuration out to %s", path)
} }

19
main.go
View File

@ -39,20 +39,26 @@ type errorResponse struct {
} }
func main() { func main() {
cs := config.ConfigService{} log.Printf("Starting gropple %s - https://github.com/tardisx/gropple", versionInfo.CurrentVersion)
exists, err := cs.ConfigFileExists()
configService = &config.ConfigService{}
configService.DetermineConfigDir()
exists, err := configService.ConfigFileExists()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
if !exists { if !exists {
log.Print("No config file - creating default config") log.Print("No config file - creating default config")
cs.LoadDefaultConfig() configService.LoadDefaultConfig()
cs.WriteConfig() configService.WriteConfig()
log.Printf("Configuration written to %s", configService.ConfigPath)
} else { } else {
err := cs.LoadConfig() err := configService.LoadConfig()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Printf("Configuration loaded from %s", configService.ConfigPath)
} }
r := mux.NewRouter() r := mux.NewRouter()
@ -97,8 +103,7 @@ func main() {
} }
}() }()
log.Printf("starting gropple %s - https://github.com/tardisx/gropple", versionInfo.CurrentVersion) log.Printf("Visit %s for details on installing the bookmarklet and to check status", configService.Config.Server.Address)
log.Printf("go to %s for details on installing the bookmarklet and to check status", configService.Config.Server.Address)
log.Fatal(srv.ListenAndServe()) log.Fatal(srv.ListenAndServe())
} }

View File

@ -63,8 +63,6 @@ func (i *Info) canUpgrade() bool {
return false return false
} }
log.Printf("We are %s, github is %s", i.CurrentVersion, i.GithubVersion)
if !semver.IsValid(i.CurrentVersion) { if !semver.IsValid(i.CurrentVersion) {
log.Printf("current version %s is invalid", i.CurrentVersion) log.Printf("current version %s is invalid", i.CurrentVersion)
} }