// 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, ¤tMap) 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 }