package storage import ( "cwtch.im/cwtch/event" "cwtch.im/cwtch/model" "encoding/json" ) type profileStore struct { fs FileStore profile *model.Profile eventManager *event.Manager queue *event.Queue } // ProfileStore is an interface to managing the storage of Cwtch Profiles type ProfileStore interface { Save() error Init(name string) Load() error Shutdown() GetProfileCopy() *model.Profile } // NewProfileStore returns a profile store backed by a filestore listening for events and saving them func NewProfileStore(eventManager *event.Manager, filename string, password string) (ProfileStore, error) { ps := &profileStore{fs: NewFileStore(filename, password), profile: nil, eventManager: eventManager} err := ps.Load() if err == nil { ps.queue = event.NewEventQueue(100) go ps.eventHandler() ps.eventManager.Subscribe(event.BlockPeer, ps.queue.EventChannel) } return ps, err } func (ps *profileStore) Init(name string) { ps.profile = model.GenerateNewProfile(name) ps.Save() } func (ps *profileStore) Save() error { bytes, _ := json.Marshal(ps.profile) return ps.fs.Save(bytes) } // Load instantiates a cwtchPeer from the file store func (ps *profileStore) Load() error { decrypted, err := ps.fs.Load() if err != nil { return err } cp := new(model.Profile) err = json.Unmarshal(decrypted, &cp) if err == nil { ps.profile = cp return nil } return err } func (ps *profileStore) GetProfileCopy() *model.Profile { return ps.profile.GetCopy() } func (ps *profileStore) eventHandler() { for { ev := ps.queue.Next() switch ev.EventType { case event.BlockPeer: contact, exists := ps.profile.GetContact(ev.Data["Onion"]) if exists { contact.Blocked = true } default: return } ps.Save() } } func (ps *profileStore) Shutdown() { ps.queue.Shutdown() }