package shareEntry import ( "encoding/json" "errors" "path/filepath" "sync" "imuslab.com/arozos/mod/database" ) /* Share Entry This module is designed to isolate the entry operatiosn with the handle operations so as to reduce the complexity of recursive import during development */ type ShareEntryTable struct { FileToUrlMap *sync.Map UrlToFileMap *sync.Map Database *database.Database } type ShareOption struct { UUID string FileRealPath string Owner string Accessibles []string //Use to store username or group names if permission is groups or users Permission string //Access permission, allow {anyone / signedin / samegroup / groups / users} AllowLivePreview bool } func NewShareEntryTable(db *database.Database) *ShareEntryTable { //Create the share table if not exists db.NewTable("share") FileToUrlMap := sync.Map{} UrlToFileMap := sync.Map{} //Load the old share links entries, _ := db.ListTable("share") for _, keypairs := range entries { shareObject := new(ShareOption) json.Unmarshal(keypairs[1], &shareObject) if shareObject != nil { //Append this to the maps FileToUrlMap.Store(shareObject.FileRealPath, shareObject) UrlToFileMap.Store(shareObject.UUID, shareObject) } } return &ShareEntryTable{ FileToUrlMap: &FileToUrlMap, UrlToFileMap: &UrlToFileMap, Database: db, } } //Delete the share on this vpath func (s *ShareEntryTable) DeleteShare(rpath string) error { //Check if the share already exists. If yes, use the previous link val, ok := s.FileToUrlMap.Load(rpath) if ok { //Exists. Send back the old share url uuid := val.(*ShareOption).UUID //Remove this from the database err := s.Database.Delete("share", uuid) if err != nil { return err } //Remove this form the current sync map s.UrlToFileMap.Delete(uuid) s.FileToUrlMap.Delete(rpath) return nil } else { //Already deleted from buffered record. return nil } } func (s *ShareEntryTable) GetShareUUIDFromPath(rpath string) string { targetShareObject := s.GetShareObjectFromRealPath(rpath) if (targetShareObject) != nil { return targetShareObject.UUID } return "" } func (s *ShareEntryTable) GetShareObjectFromRealPath(rpath string) *ShareOption { rpath = filepath.ToSlash(filepath.Clean(rpath)) var targetShareOption *ShareOption s.FileToUrlMap.Range(func(k, v interface{}) bool { filePath := k.(string) shareObject := v.(*ShareOption) if filepath.ToSlash(filepath.Clean(filePath)) == rpath { targetShareOption = shareObject } return true }) return targetShareOption } func (s *ShareEntryTable) GetShareObjectFromUUID(uuid string) *ShareOption { var targetShareOption *ShareOption s.UrlToFileMap.Range(func(k, v interface{}) bool { thisUuid := k.(string) shareObject := v.(*ShareOption) if thisUuid == uuid { targetShareOption = shareObject } return true }) return targetShareOption } func (s *ShareEntryTable) FileIsShared(rpath string) bool { shareUUID := s.GetShareUUIDFromPath(rpath) return shareUUID != "" } func (s *ShareEntryTable) RemoveShareByRealpath(rpath string) error { so, ok := s.FileToUrlMap.Load(rpath) if ok { shareUUID := so.(*ShareOption).UUID s.UrlToFileMap.Delete(shareUUID) s.FileToUrlMap.Delete(rpath) s.Database.Delete("share", shareUUID) } else { return errors.New("Share with given realpath not exists") } return nil } func (s *ShareEntryTable) RemoveShareByUUID(uuid string) error { so, ok := s.UrlToFileMap.Load(uuid) if ok { s.FileToUrlMap.Delete(so.(*ShareOption).FileRealPath) s.UrlToFileMap.Delete(uuid) s.Database.Delete("share", uuid) } else { return errors.New("Share with given uuid not exists") } return nil }