4 st "github.com/iotbzh/xds-agent/lib/syncthing"
7 // IPROJECT interface implementation for syncthing projects
10 type STProject struct {
13 folder *XdsFolderConfig
17 // NewProjectST Create a new instance of STProject
18 func NewProjectST(ctx *Context, svr *XdsServer) *STProject {
22 folder: &XdsFolderConfig{},
28 func (p *STProject) Add(cfg ProjectConfig) (*ProjectConfig, error) {
31 // Add project/folder into XDS Server
32 err = p.server.FolderAdd(p.server.ProjectToFolder(cfg), p.folder)
36 svrPrj := p.GetProject()
38 // Declare project into local Syncthing
39 id, err := p.SThg.FolderChange(st.FolderChangeArg{
42 RelativePath: cfg.ClientPath,
43 SyncThingID: p.server.ServerConfig.Builder.SyncThingID,
49 locPrj, err := p.SThg.FolderConfigGet(id)
51 svrPrj.Status = StatusErrorConfig
54 if svrPrj.ID != locPrj.ID {
55 p.Log.Errorf("Project ID in XDSServer and local ST differ: %s != %s", svrPrj.ID, locPrj.ID)
58 // Use Update function to setup remains fields
59 return p.UpdateProject(*svrPrj)
63 func (p *STProject) Delete() error {
64 errSvr := p.server.FolderDelete(p.folder.ID)
65 errLoc := p.SThg.FolderDelete(p.folder.ID)
72 // GetProject Get public part of project config
73 func (p *STProject) GetProject() *ProjectConfig {
74 prj := p.server.FolderToProject(*p.folder)
75 prj.ServerID = p.server.ID
79 // UpdateProject Update project config
80 func (p *STProject) UpdateProject(prj ProjectConfig) (*ProjectConfig, error) {
82 p.folder = p.server.ProjectToFolder(prj)
83 svrPrj := p.GetProject()
85 // Register events to update folder status
86 // Register to XDS Server events
87 p.server.EventOn("event:FolderStateChanged", p._cbServerFolderChanged)
88 if err := p.server.EventRegister("FolderStateChanged", svrPrj.ID); err != nil {
89 p.Log.Warningf("XDS Server EventRegister failed: %v", err)
93 // Register to Local Syncthing events
94 for _, evName := range []string{st.EventStateChanged, st.EventFolderPaused} {
95 evID, err := p.SThg.Events.Register(evName, p._cbLocalSTEvents, svrPrj.ID, nil)
99 p.eventIDs = append(p.eventIDs, evID)
105 // GetServer Get the XdsServer that holds this project
106 func (p *STProject) GetServer() *XdsServer {
110 // Sync Force project files synchronization
111 func (p *STProject) Sync() error {
112 if err := p.server.FolderSync(p.folder.ID); err != nil {
115 return p.SThg.FolderScan(p.folder.ID, "")
118 // IsInSync Check if project files are in-sync
119 func (p *STProject) IsInSync() (bool, error) {
120 // Should be up-to-date by callbacks (see below)
121 return p.folder.IsInSync, nil
128 // callback use to update (XDS Server) folder IsInSync status
130 func (p *STProject) _cbServerFolderChanged(data interface{}) {
131 evt := data.(XdsEventFolderChange)
133 // Only process event that concerns this project/folder ID
134 if p.folder.ID != evt.Folder.ID {
138 if evt.Folder.IsInSync != p.folder.DataCloudSync.STSvrIsInSync ||
139 evt.Folder.Status != p.folder.DataCloudSync.STSvrStatus {
141 p.folder.DataCloudSync.STSvrIsInSync = evt.Folder.IsInSync
142 p.folder.DataCloudSync.STSvrStatus = evt.Folder.Status
144 if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil {
145 p.Log.Warningf("Cannot notify project change: %v", err)
150 // callback use to update IsInSync status
151 func (p *STProject) _cbLocalSTEvents(ev st.Event, data *st.EventsCBData) {
153 inSync := p.folder.DataCloudSync.STLocIsInSync
154 sts := p.folder.DataCloudSync.STLocStatus
160 case st.EventStateChanged:
163 case "scanning", "syncing":
168 inSync = (to == "idle")
170 case st.EventFolderPaused:
171 if sts == StatusEnable {
177 if prevSync != inSync || prevStatus != sts {
179 p.folder.DataCloudSync.STLocIsInSync = inSync
180 p.folder.DataCloudSync.STLocStatus = sts
182 if err := p.events.Emit(EVTProjectChange, p.server.FolderToProject(*p.folder)); err != nil {
183 p.Log.Warningf("Cannot notify project change: %v", err)