From 76cff9554001ca3727e2ba11b790e9bba27d6b77 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 17 May 2018 16:29:15 +0300 Subject: Move all cache to ~/.cache/gomuks Now `rm -rf ~/.cache/gomuks` has the same effect as `/clearcache` --- config/config.go | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 237 insertions(+), 23 deletions(-) (limited to 'config/config.go') diff --git a/config/config.go b/config/config.go index cf080ff..41cff41 100644 --- a/config/config.go +++ b/config/config.go @@ -17,55 +17,90 @@ package config import ( - "fmt" "io/ioutil" "os" "path/filepath" "gopkg.in/yaml.v2" "maunium.net/go/gomuks/debug" + "maunium.net/go/gomuks/matrix/rooms" + "maunium.net/go/gomuks/matrix/pushrules" + "encoding/json" + "strings" + "maunium.net/go/gomatrix" ) // Config contains the main config of gomuks. type Config struct { - UserID string `yaml:"mxid"` - HS string `yaml:"homeserver"` + UserID string `yaml:"mxid"` + AccessToken string `yaml:"access_token"` + HS string `yaml:"homeserver"` - Dir string `yaml:"-"` - HistoryDir string `yaml:"history_dir"` - MediaDir string `yaml:"media_dir"` - Session *Session `yaml:"-"` + Dir string `yaml:"-"` + CacheDir string `yaml:"cache_dir"` + HistoryDir string `yaml:"history_dir"` + MediaDir string `yaml:"media_dir"` + StateDir string `yaml:"state_dir"` + + AuthCache struct { + NextBatch string `yaml:"next_batch"` + FilterID string `yaml:"filter_id"` + InitialSyncDone bool `yaml:"initial_sync_done"` + } `yaml:"-"` + + Rooms map[string]*rooms.Room `yaml:"-"` + PushRules *pushrules.PushRuleset `yaml:"-"` + + nosave bool } // NewConfig creates a config that loads data from the given directory. func NewConfig(configDir, cacheDir string) *Config { return &Config{ Dir: configDir, + CacheDir: cacheDir, HistoryDir: filepath.Join(cacheDir, "history"), + StateDir: filepath.Join(cacheDir, "state"), MediaDir: filepath.Join(cacheDir, "media"), + + Rooms: make(map[string]*rooms.Room), } } // Clear clears the session cache and removes all history. func (config *Config) Clear() { - if config.Session != nil { - config.Session.Clear() - } os.RemoveAll(config.HistoryDir) + os.RemoveAll(config.StateDir) os.RemoveAll(config.MediaDir) + os.RemoveAll(config.CacheDir) + config.nosave = true } -func (config *Config) DeleteSession() { - if config.Session != nil { - os.Remove(config.Session.path) - config.Session = nil - } - os.RemoveAll(config.HistoryDir) - os.RemoveAll(config.MediaDir) +func (config *Config) CreateCacheDirs() { + os.MkdirAll(config.CacheDir, 0700) os.MkdirAll(config.HistoryDir, 0700) + os.MkdirAll(config.StateDir, 0700) os.MkdirAll(config.MediaDir, 0700) } +func (config *Config) DeleteSession() { + config.AuthCache.NextBatch = "" + config.AuthCache.InitialSyncDone = false + config.Rooms = make(map[string]*rooms.Room) + config.PushRules = nil + + config.Clear() + config.nosave = false + config.CreateCacheDirs() +} + +func (config *Config) LoadAll() { + config.Load() + config.LoadAuthCache() + config.LoadPushRules() + config.LoadRooms() +} + // Load loads the config from config.yaml in the directory given to the config struct. func (config *Config) Load() { os.MkdirAll(config.Dir, 0700) @@ -74,25 +109,34 @@ func (config *Config) Load() { data, err := ioutil.ReadFile(configPath) if err != nil { if os.IsNotExist(err) { - os.MkdirAll(config.HistoryDir, 0700) - os.MkdirAll(config.MediaDir, 0700) + config.CreateCacheDirs() return } - fmt.Println("Failed to read config from", configPath) + debug.Print("Failed to read config from", configPath) panic(err) } err = yaml.Unmarshal(data, &config) if err != nil { - fmt.Println("Failed to parse config at", configPath) + debug.Print("Failed to parse config at", configPath) panic(err) } - os.MkdirAll(config.HistoryDir, 0700) - os.MkdirAll(config.MediaDir, 0700) + config.CreateCacheDirs() +} + +func (config *Config) SaveAll() { + config.Save() + config.SaveAuthCache() + config.SavePushRules() + config.SaveRooms() } // Save saves this config to config.yaml in the directory given to the config struct. func (config *Config) Save() { + if config.nosave { + return + } + os.MkdirAll(config.Dir, 0700) data, err := yaml.Marshal(&config) if err != nil { @@ -107,3 +151,173 @@ func (config *Config) Save() { panic(err) } } + +func (config *Config) LoadAuthCache() { + os.MkdirAll(config.Dir, 0700) + + configPath := filepath.Join(config.CacheDir, "auth-cache.yaml") + data, err := ioutil.ReadFile(configPath) + if err != nil { + if os.IsNotExist(err) { + return + } + debug.Print("Failed to read auth cache from", configPath) + panic(err) + } + + err = yaml.Unmarshal(data, &config.AuthCache) + if err != nil { + debug.Print("Failed to parse auth cache at", configPath) + panic(err) + } +} + +func (config *Config) SaveAuthCache() { + if config.nosave { + return + } + + os.MkdirAll(config.CacheDir, 0700) + data, err := yaml.Marshal(&config.AuthCache) + if err != nil { + debug.Print("Failed to marshal auth cache") + panic(err) + } + + path := filepath.Join(config.CacheDir, "auth-cache.yaml") + err = ioutil.WriteFile(path, data, 0600) + if err != nil { + debug.Print("Failed to write auth cache to", path) + panic(err) + } +} + +func (config *Config) LoadPushRules() { + os.MkdirAll(config.CacheDir, 0700) + + pushRulesPath := filepath.Join(config.CacheDir, "pushrules.json") + data, err := ioutil.ReadFile(pushRulesPath) + if err != nil { + if os.IsNotExist(err) { + return + } + debug.Print("Failed to read push rules from", pushRulesPath) + return + } + + config.PushRules = &pushrules.PushRuleset{} + err = json.Unmarshal(data, &config.PushRules) + if err != nil { + debug.Print("Failed to parse push rules at", pushRulesPath) + return + } +} + +func (config *Config) SavePushRules() { + if config.nosave || config.PushRules == nil { + return + } + + os.MkdirAll(config.CacheDir, 0700) + data, err := json.Marshal(&config.PushRules) + if err != nil { + debug.Print("Failed to marshal push rules") + return + } + + path := filepath.Join(config.CacheDir, "pushrules.json") + err = ioutil.WriteFile(path, data, 0600) + if err != nil { + debug.Print("Failed to write config to", path) + return + } +} + +func (config *Config) LoadRooms() { + os.MkdirAll(config.StateDir, 0700) + + roomFiles, err := ioutil.ReadDir(config.StateDir) + if err != nil { + debug.Print("Failed to list rooms state caches in", config.StateDir) + panic(err) + } + + for _, roomFile := range roomFiles { + if roomFile.IsDir() || !strings.HasSuffix(roomFile.Name(), ".gmxstate") { + continue + } + path := filepath.Join(config.StateDir, roomFile.Name()) + room := &rooms.Room{} + err = room.Load(path) + if err != nil { + debug.Printf("Failed to load room state cache from %s: %v", path, err) + continue + } + config.Rooms[room.ID] = room + } +} + +func (config *Config) SaveRooms() { + if config.nosave { + return + } + + os.MkdirAll(config.StateDir, 0700) + for _, room := range config.Rooms { + path := config.getRoomCachePath(room) + err := room.Save(path) + if err != nil { + debug.Printf("Failed to save room state cache to file %s: %v", path, err) + } + } +} + +func (config *Config) GetUserID() string { + return config.UserID +} + +func (config *Config) SaveFilterID(_, filterID string) { + config.AuthCache.FilterID = filterID + config.SaveAuthCache() +} + +func (config *Config) LoadFilterID(_ string) string { + return config.AuthCache.FilterID +} + +func (config *Config) SaveNextBatch(_, nextBatch string) { + config.AuthCache.NextBatch = nextBatch + config.SaveAuthCache() +} + +func (config *Config) LoadNextBatch(_ string) string { + return config.AuthCache.NextBatch +} + +func (config *Config) GetRoom(roomID string) *rooms.Room { + room, _ := config.Rooms[roomID] + if room == nil { + room = rooms.NewRoom(roomID, config.UserID) + config.Rooms[room.ID] = room + } + return room +} + +func (config *Config) getRoomCachePath(room *rooms.Room) string { + return filepath.Join(config.StateDir, room.ID+".gmxstate") +} + +func (config *Config) PutRoom(room *rooms.Room) { + config.Rooms[room.ID] = room + room.Save(config.getRoomCachePath(room)) +} + +func (config *Config) SaveRoom(room *gomatrix.Room) { + gmxRoom := config.GetRoom(room.ID) + gmxRoom.Room = room + gmxRoom.Save(config.getRoomCachePath(gmxRoom)) +} + +func (config *Config) LoadRoom(roomID string) *gomatrix.Room { + return config.GetRoom(roomID).Room +} -- cgit v1.2.3