seekia/internal/globalSettings/globalSettings.go

162 lines
3.6 KiB
Go

// globalSettings provides functions to manage global settings, which are the same for all users.
package globalSettings
import goFilepath "path/filepath"
import "os"
import "encoding/json"
import "errors"
import "sync"
func InitializeGlobalSettingsDatastore()error{
localFileDirectory, err := os.UserConfigDir()
if (err != nil) { return err }
globalSettingsFolderpath := goFilepath.Join(localFileDirectory, "SeekiaData", "GlobalSettings")
// We create the GlobalSettings folder
file, err := os.Open(globalSettingsFolderpath)
if (err != nil){
isNotExistErr := os.IsNotExist(err)
if (isNotExistErr == false) {
return err
}
// Folder does not exist
err = os.Mkdir(globalSettingsFolderpath, os.ModePerm)
if (err != nil) { return err }
}
file.Close()
getCurrentSettingsMap := func()(map[string]string, error){
globalSettingsFilepath := goFilepath.Join(globalSettingsFolderpath, "GlobalSettings.json")
fileBytes, err := os.ReadFile(globalSettingsFilepath)
if (err != nil){
isNotExistError := os.IsNotExist(err)
if (isNotExistError == false){
return nil, err
}
emptyMap := make(map[string]string)
return emptyMap, nil
}
currentMap := make(map[string]string)
err = json.Unmarshal(fileBytes, &currentMap)
if (err != nil) {
return nil, errors.New("Stored globalSettings map is corrupted: " + err.Error())
}
return currentMap, nil
}
currentGlobalSettingsMap, err := getCurrentSettingsMap()
if (err != nil) { return err }
settingsMap = currentGlobalSettingsMap
return nil
}
// This will be locked whenever we are writing the map/local file
var updatingSettingsMutex sync.Mutex
var settingsMapMutex sync.RWMutex
var settingsMap map[string]string
//Outputs:
// -bool: Setting exists
// -string: Setting value
// -error
func GetSetting(settingName string)(bool, string, error){
if (settingsMap == nil){
return false, "", errors.New("GetSetting called when global settings map is not initialized.")
}
settingsMapMutex.RLock()
settingString, exists := settingsMap[settingName]
settingsMapMutex.RUnlock()
if (exists == false){
return false, "", nil
}
return true, settingString, nil
}
func SetSetting(settingName string, content string) error{
if (settingName == ""){
return errors.New("globalSettings SetSetting called with empty settingName.")
}
if (content == ""){
return errors.New("globalSettings SetSetting called with empty content.")
}
updatingSettingsMutex.Lock()
defer updatingSettingsMutex.Unlock()
settingsMapMutex.Lock()
settingsMap[settingName] = content
settingsMapMutex.Unlock()
overwriteSettingsFile()
return nil
}
func DeleteSetting(settingName string) error {
if (settingName == ""){
return errors.New("globalSettings DeleteSetting called with empty settingName.")
}
updatingSettingsMutex.Lock()
defer updatingSettingsMutex.Unlock()
settingsMapMutex.Lock()
delete(settingsMap, settingName)
settingsMapMutex.Unlock()
err := overwriteSettingsFile()
if (err != nil) { return err }
return nil
}
func overwriteSettingsFile()error{
jsonFileContents, err := json.MarshalIndent(settingsMap, "", "\t")
if (err != nil) { return err }
fileContentsString := string(jsonFileContents)
localFileDirectory, err := os.UserConfigDir()
if (err != nil) { return err }
globalSettingsFilepath := goFilepath.Join(localFileDirectory, "SeekiaData", "GlobalSettings", "GlobalSettings.json")
newFile, err := os.Create(globalSettingsFilepath)
if (err != nil) { return err }
_, err = newFile.WriteString(fileContentsString)
if (err != nil) {
newFile.Close()
return err
}
newFile.Close()
return nil
}