Implement loading and storing config to / from file
This commit is contained in:
@@ -1,25 +1,212 @@
|
||||
package configloader
|
||||
|
||||
import (
|
||||
"os"
|
||||
"encoding/json"
|
||||
"path/filepath"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type MDWebDavUploaderConfig struct {
|
||||
InstanceLink string `json:"instance"`
|
||||
Mail string `json:"mail"`
|
||||
WebDavAuthToken string `json:"token"`
|
||||
InstitutionId int `json:"institution_id"`
|
||||
Parser string `json:"parser"`
|
||||
MetadataFolder string `json:"metadata_folder"`
|
||||
MediaFolder string `json:"media_folder"`
|
||||
PublishOnImport bool `json:"visible"`
|
||||
InstanceLink string `json:"instance"`
|
||||
Mail string `json:"mail"`
|
||||
WebDavAuthToken string `json:"token"`
|
||||
InstitutionId int `json:"institution_id"`
|
||||
Parser string `json:"parser"`
|
||||
MetadataFolder string `json:"metadata_folder"`
|
||||
MediaFolder string `json:"media_folder"`
|
||||
PublishOnImport bool `json:"visible"`
|
||||
Settings map[string]string `json:"settings"`
|
||||
}
|
||||
|
||||
// Returns a uniform filepath for the configuration of this tool.
|
||||
// Returns the file path of the configuration file within the supplied
|
||||
// directory. Moved to a dedicated function to provide a consistent
|
||||
// filename.
|
||||
func getConfigFileNameByDir(folder string) string {
|
||||
return filepath.Join(folder, "config.json")
|
||||
}
|
||||
|
||||
// Returns a uniform directory for the configuration of this tool.
|
||||
// To be compatible across operating systems, this will be a JSON
|
||||
// file in the same directory as the current programm.
|
||||
func getConfigFilepath() string {
|
||||
func getConfigFilepath() (string, error) {
|
||||
|
||||
// Get the OS-dependent configuration directory.
|
||||
generalConfigDir, dirErr := os.UserConfigDir()
|
||||
if dirErr != nil {
|
||||
return "", dirErr
|
||||
}
|
||||
|
||||
// Select a subdirectory of that directory to store application-specific
|
||||
// settings in. Attempt to create it and return the config filepath as
|
||||
// a file in that directory.
|
||||
configDir := filepath.Join(generalConfigDir, "museum-digital-uploader")
|
||||
generateConfigDirErr := os.Mkdir(configDir, 0700)
|
||||
|
||||
// The config directory could be created, return path of the configuration
|
||||
// file in it.
|
||||
if generateConfigDirErr == nil {
|
||||
return getConfigFileNameByDir(configDir), nil // Use this to create files
|
||||
}
|
||||
|
||||
// There has been an error creating the config directory.
|
||||
// This may be either that the directory already exists, which is alright
|
||||
// (and even expected on most runs). Or it might be, that the path is
|
||||
// already occupied with a file. Or something else. In those cases,
|
||||
// the error should be returned.
|
||||
|
||||
// If the path is already occupied, inspect it more closely.
|
||||
if os.IsExist(generateConfigDirErr) {
|
||||
|
||||
info, err := os.Stat(configDir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// The directory already exists and is a directory. This is fine,
|
||||
// so we return the config filename in the existing config directory.
|
||||
if info.IsDir() {
|
||||
return getConfigFileNameByDir(configDir), nil // Use this to create files
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return "", generateConfigDirErr
|
||||
|
||||
}
|
||||
|
||||
// Wrapper around getConfigFilepath() allowing for an override for testing.
|
||||
func getConfigFilepathOrOverride(overridePath string) (string, error) {
|
||||
|
||||
// Override path is not validated, as it should only be used
|
||||
// in test settings
|
||||
if overridePath != "" {
|
||||
return overridePath, nil
|
||||
}
|
||||
|
||||
configFilePath, err := getConfigFilepath()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return configFilePath, nil
|
||||
|
||||
}
|
||||
|
||||
// Validates each of the values of MDWebDavUploaderConfig.
|
||||
func ValidateConfig(conf MDWebDavUploaderConfig) (MDWebDavUploaderConfig, error) {
|
||||
|
||||
// Validate and clean instance link
|
||||
instanceLink, instanceErr := ValidateInstanceLink(conf.InstanceLink)
|
||||
if instanceErr != nil {
|
||||
return conf, instanceErr
|
||||
}
|
||||
conf.InstanceLink = instanceLink
|
||||
|
||||
// Validate and clean mail
|
||||
mailLink, mailErr := ValidateMail(conf.Mail)
|
||||
if mailErr != nil {
|
||||
return conf, mailErr
|
||||
}
|
||||
conf.Mail = mailLink
|
||||
|
||||
// Validate and clean institution ID
|
||||
institutionIdLink, institutionIdErr := ValidateInstitutionId(conf.InstitutionId, conf.InstanceLink)
|
||||
if institutionIdErr != nil {
|
||||
return conf, institutionIdErr
|
||||
}
|
||||
conf.InstitutionId = institutionIdLink
|
||||
|
||||
// Validate and clean parser
|
||||
parserLink, parserErr := ValidateParser(conf.Parser)
|
||||
if parserErr != nil {
|
||||
return conf, parserErr
|
||||
}
|
||||
conf.Parser = parserLink
|
||||
|
||||
// Validate and clean metadata folder
|
||||
metadataFolder, mFolderErr := ValidateUploadDir(conf.MetadataFolder)
|
||||
if mFolderErr != nil {
|
||||
return conf, mFolderErr
|
||||
}
|
||||
conf.MetadataFolder = metadataFolder
|
||||
|
||||
// Validate and clean media folder
|
||||
mediaFolder, mediaFolderErr := ValidateUploadDir(conf.MediaFolder)
|
||||
if mediaFolderErr != nil {
|
||||
return conf, mediaFolderErr
|
||||
}
|
||||
conf.MediaFolder = mediaFolder
|
||||
|
||||
return conf, nil
|
||||
|
||||
}
|
||||
|
||||
// Loads configuration from the configuration file (located using
|
||||
// getConfigFilepath()).
|
||||
func LoadFromFile() MDWebDavUploaderConfig {
|
||||
// The function parameter overridePath is only useful for test settings.
|
||||
// Outside those, set an empty string to use the default config path.
|
||||
// Output parameters:
|
||||
// 1: Config
|
||||
// 2: Requirement for a re-run of the setup
|
||||
// 3: Error
|
||||
func LoadFromFile(overridePath string) (MDWebDavUploaderConfig, bool, error) {
|
||||
|
||||
// Get config file path
|
||||
configFile, configFileErr := getConfigFilepathOrOverride(overridePath)
|
||||
if configFileErr != nil {
|
||||
return MDWebDavUploaderConfig{}, false, configFileErr
|
||||
}
|
||||
|
||||
// Read the file
|
||||
configFileBytes, ioErr := ioutil.ReadFile(configFile)
|
||||
if ioErr != nil {
|
||||
return MDWebDavUploaderConfig{}, true, ioErr
|
||||
}
|
||||
|
||||
// Parse the file into a configuration struct
|
||||
var data MDWebDavUploaderConfig
|
||||
unmarshalErr := json.Unmarshal(configFileBytes, &data)
|
||||
|
||||
if unmarshalErr != nil {
|
||||
return MDWebDavUploaderConfig{}, true, ioErr
|
||||
}
|
||||
|
||||
// Validate data - the configuration file may have been altered externally
|
||||
config, validationErr := ValidateConfig(data)
|
||||
if validationErr != nil {
|
||||
return MDWebDavUploaderConfig{}, true, validationErr
|
||||
}
|
||||
|
||||
// Config could be parsed
|
||||
return config, false, nil
|
||||
|
||||
}
|
||||
|
||||
// Stores a config from MDWebDavUploaderConfig to the config file.
|
||||
// As with LoadFromFile(), it is possible to provide an overridePath for testing.
|
||||
func StoreConfigToFile(conf MDWebDavUploaderConfig, overridePath string) error {
|
||||
|
||||
config, validationErr := ValidateConfig(conf)
|
||||
if validationErr != nil {
|
||||
return validationErr
|
||||
}
|
||||
|
||||
configFilePath, configFileErr := getConfigFilepathOrOverride(overridePath)
|
||||
if configFileErr != nil {
|
||||
return configFileErr
|
||||
}
|
||||
|
||||
configJson, encodeErr := json.Marshal(config)
|
||||
if encodeErr != nil {
|
||||
return encodeErr
|
||||
}
|
||||
|
||||
writeErr := ioutil.WriteFile(configFilePath, configJson, 0644)
|
||||
if writeErr != nil {
|
||||
return writeErr
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user