Add folder synchronization status.
[src/xds/xds-server.git] / lib / syncthing / folder-st.go
index ffcd284..da27062 100644 (file)
@@ -6,6 +6,7 @@ import (
 
        "github.com/iotbzh/xds-server/lib/folder"
        "github.com/iotbzh/xds-server/lib/xdsconfig"
+       uuid "github.com/satori/go.uuid"
        "github.com/syncthing/syncthing/lib/config"
 )
 
@@ -13,10 +14,13 @@ import (
 
 // STFolder .
 type STFolder struct {
-       globalConfig *xdsconfig.Config
-       st           *SyncThing
-       fConfig      folder.FolderConfig
-       stfConfig    config.FolderConfiguration
+       globalConfig      *xdsconfig.Config
+       st                *SyncThing
+       fConfig           folder.FolderConfig
+       stfConfig         config.FolderConfiguration
+       eventIDs          []int
+       eventChangeCB     *folder.EventCB
+       eventChangeCBData *folder.EventCBData
 }
 
 // NewFolderST Create a new instance of STFolder
@@ -27,6 +31,15 @@ func (s *SyncThing) NewFolderST(gc *xdsconfig.Config) *STFolder {
        }
 }
 
+// NewUID Get a UUID
+func (f *STFolder) NewUID(suffix string) string {
+       i := len(f.st.MyID)
+       if i > 15 {
+               i = 15
+       }
+       return uuid.NewV1().String()[:14] + f.st.MyID[:i] + "_" + suffix
+}
+
 // Add a new folder
 func (f *STFolder) Add(cfg folder.FolderConfig) (*folder.FolderConfig, error) {
 
@@ -59,6 +72,16 @@ func (f *STFolder) Add(cfg folder.FolderConfig) (*folder.FolderConfig, error) {
                        return nil, err
                }
 
+               // Register to events to update folder status
+               for _, evName := range []string{EventStateChanged, EventFolderPaused} {
+                       evID, err := f.st.Events.Register(evName, f.cbEventState, id, nil)
+                       if err != nil {
+                               return nil, err
+                       }
+                       f.eventIDs = append(f.eventIDs, evID)
+               }
+
+               f.fConfig.IsInSync = false // will be updated later by events
                f.fConfig.Status = folder.StatusEnable
        }
 
@@ -86,6 +109,20 @@ func (f *STFolder) Remove() error {
        return f.st.FolderDelete(f.stfConfig.ID)
 }
 
+// RegisterEventChange requests registration for folder event change
+func (f *STFolder) RegisterEventChange(cb *folder.EventCB, data *folder.EventCBData) error {
+       f.eventChangeCB = cb
+       f.eventChangeCBData = data
+       return nil
+}
+
+// UnRegisterEventChange remove registered callback
+func (f *STFolder) UnRegisterEventChange() error {
+       f.eventChangeCB = nil
+       f.eventChangeCBData = nil
+       return nil
+}
+
 // Sync Force folder files synchronization
 func (f *STFolder) Sync() error {
        return f.st.FolderScan(f.stfConfig.ID, "")
@@ -93,5 +130,41 @@ func (f *STFolder) Sync() error {
 
 // IsInSync Check if folder files are in-sync
 func (f *STFolder) IsInSync() (bool, error) {
-       return f.st.IsFolderInSync(f.stfConfig.ID)
+       sts, err := f.st.IsFolderInSync(f.stfConfig.ID)
+       if err != nil {
+               return false, err
+       }
+       f.fConfig.IsInSync = sts
+       return sts, nil
+}
+
+// callback use to update IsInSync status
+func (f *STFolder) cbEventState(ev Event, data *EventsCBData) {
+       prevSync := f.fConfig.IsInSync
+       prevStatus := f.fConfig.Status
+
+       switch ev.Type {
+
+       case EventStateChanged:
+               to := ev.Data["to"]
+               switch to {
+               case "scanning", "syncing":
+                       f.fConfig.Status = folder.StatusSyncing
+               case "idle":
+                       f.fConfig.Status = folder.StatusEnable
+               }
+               f.fConfig.IsInSync = (to == "idle")
+
+       case EventFolderPaused:
+               if f.fConfig.Status == folder.StatusEnable {
+                       f.fConfig.Status = folder.StatusPause
+               }
+               f.fConfig.IsInSync = false
+       }
+
+       if f.eventChangeCB != nil &&
+               (prevSync != f.fConfig.IsInSync || prevStatus != f.fConfig.Status) {
+               cpConf := f.fConfig
+               (*f.eventChangeCB)(&cpConf, f.eventChangeCBData)
+       }
 }