9 "github.com/iotbzh/xds-server/lib/folder"
10 "github.com/iotbzh/xds-server/lib/xdsconfig"
11 uuid "github.com/satori/go.uuid"
12 "github.com/syncthing/syncthing/lib/config"
15 // IFOLDER interface implementation for syncthing
18 type STFolder struct {
19 globalConfig *xdsconfig.Config
21 fConfig folder.FolderConfig
22 stfConfig config.FolderConfiguration
24 eventChangeCB *folder.EventCB
25 eventChangeCBData *folder.EventCBData
28 // NewFolderST Create a new instance of STFolder
29 func (s *SyncThing) NewFolderST(gc *xdsconfig.Config) *STFolder {
37 func (f *STFolder) NewUID(suffix string) string {
42 return uuid.NewV1().String()[:14] + f.st.MyID[:i] + "_" + suffix
46 func (f *STFolder) Add(cfg folder.FolderConfig) (*folder.FolderConfig, error) {
49 if cfg.DataCloudSync.SyncThingID == "" {
50 return nil, fmt.Errorf("device id not set (SyncThingID field)")
53 // rootPath should not be empty
54 if cfg.RootPath == "" {
55 cfg.RootPath = f.globalConfig.FileConf.ShareRootDir
60 f.fConfig.DataCloudSync.BuilderSThgID = f.st.MyID // FIXME - should be removed after local ST config rework
62 // Update Syncthing folder
63 // (expect if status is ErrorConfig)
64 // TODO: add cache to avoid multiple requests on startup
65 if f.fConfig.Status != folder.StatusErrorConfig {
66 id, err := f.st.FolderChange(f.fConfig)
71 f.stfConfig, err = f.st.FolderConfigGet(id)
73 f.fConfig.Status = folder.StatusErrorConfig
77 // Register to events to update folder status
78 for _, evName := range []string{EventStateChanged, EventFolderPaused} {
79 evID, err := f.st.Events.Register(evName, f.cbEventState, id, nil)
83 f.eventIDs = append(f.eventIDs, evID)
86 f.fConfig.IsInSync = false // will be updated later by events
87 f.fConfig.Status = folder.StatusEnable
90 return &f.fConfig, nil
93 // GetConfig Get public part of folder config
94 func (f *STFolder) GetConfig() folder.FolderConfig {
98 // GetFullPath returns the full path of a directory (from server POV)
99 func (f *STFolder) GetFullPath(dir string) string {
103 if filepath.IsAbs(dir) {
104 return filepath.Join(f.fConfig.RootPath, dir)
106 return filepath.Join(f.fConfig.RootPath, f.fConfig.ClientPath, dir)
109 // ConvPathCli2Svr Convert path from Client to Server
110 func (f *STFolder) ConvPathCli2Svr(s string) string {
111 if f.fConfig.ClientPath != "" && f.fConfig.RootPath != "" {
112 return strings.Replace(s,
113 f.fConfig.ClientPath,
114 f.fConfig.RootPath+"/"+f.fConfig.ClientPath,
120 // ConvPathSvr2Cli Convert path from Server to Client
121 func (f *STFolder) ConvPathSvr2Cli(s string) string {
122 if f.fConfig.ClientPath != "" && f.fConfig.RootPath != "" {
123 return strings.Replace(s,
124 f.fConfig.RootPath+"/"+f.fConfig.ClientPath,
125 f.fConfig.ClientPath,
132 func (f *STFolder) Remove() error {
133 err := f.st.FolderDelete(f.stfConfig.ID)
135 // Delete folder on server side
136 err2 := os.RemoveAll(f.GetFullPath(""))
144 // RegisterEventChange requests registration for folder event change
145 func (f *STFolder) RegisterEventChange(cb *folder.EventCB, data *folder.EventCBData) error {
147 f.eventChangeCBData = data
151 // UnRegisterEventChange remove registered callback
152 func (f *STFolder) UnRegisterEventChange() error {
153 f.eventChangeCB = nil
154 f.eventChangeCBData = nil
158 // Sync Force folder files synchronization
159 func (f *STFolder) Sync() error {
160 return f.st.FolderScan(f.stfConfig.ID, "")
163 // IsInSync Check if folder files are in-sync
164 func (f *STFolder) IsInSync() (bool, error) {
165 sts, err := f.st.IsFolderInSync(f.stfConfig.ID)
169 f.fConfig.IsInSync = sts
173 // callback use to update IsInSync status
174 func (f *STFolder) cbEventState(ev Event, data *EventsCBData) {
175 prevSync := f.fConfig.IsInSync
176 prevStatus := f.fConfig.Status
180 case EventStateChanged:
183 case "scanning", "syncing":
184 f.fConfig.Status = folder.StatusSyncing
186 f.fConfig.Status = folder.StatusEnable
188 f.fConfig.IsInSync = (to == "idle")
190 case EventFolderPaused:
191 if f.fConfig.Status == folder.StatusEnable {
192 f.fConfig.Status = folder.StatusPause
194 f.fConfig.IsInSync = false
197 if f.eventChangeCB != nil &&
198 (prevSync != f.fConfig.IsInSync || prevStatus != f.fConfig.Status) {
200 (*f.eventChangeCB)(&cpConf, f.eventChangeCBData)