a5312eb4ed9174fef0ccd2afa0357e341920bf1a
[src/xds/xds-agent.git] / lib / syncthing / stfolder.go
1 package st
2
3 import (
4         "encoding/json"
5         "fmt"
6         "strings"
7
8         common "github.com/iotbzh/xds-common/golib"
9         stconfig "github.com/syncthing/syncthing/lib/config"
10         "github.com/syncthing/syncthing/lib/protocol"
11 )
12
13 // FIXME remove and use an interface on xdsconfig.FolderConfig
14 type FolderChangeArg struct {
15         ID           string
16         Label        string
17         RelativePath string
18         SyncThingID  string
19         ShareRootDir string
20 }
21
22 // FolderChange is called when configuration has changed
23 func (s *SyncThing) FolderChange(f FolderChangeArg) (string, error) {
24
25         // Get current config
26         stCfg, err := s.ConfigGet()
27         if err != nil {
28                 s.log.Errorln(err)
29                 return "", err
30         }
31
32         // Add new Device if needed
33         var devID protocol.DeviceID
34         if err := devID.UnmarshalText([]byte(f.SyncThingID)); err != nil {
35                 s.log.Errorf("not a valid device id (err %v)", err)
36                 return "", err
37         }
38
39         newDevice := stconfig.DeviceConfiguration{
40                 DeviceID:  devID,
41                 Name:      f.SyncThingID,
42                 Addresses: []string{"dynamic"},
43         }
44
45         var found = false
46         for _, device := range stCfg.Devices {
47                 if device.DeviceID == devID {
48                         found = true
49                         break
50                 }
51         }
52         if !found {
53                 stCfg.Devices = append(stCfg.Devices, newDevice)
54         }
55
56         // Add or update Folder settings
57         var label, id string
58         if label = f.Label; label == "" {
59                 label = strings.Split(id, "/")[0]
60         }
61         if id = f.ID; id == "" {
62                 id = f.SyncThingID[0:15] + "_" + label
63         }
64
65         // Resolve local path
66         pathCli, err := common.ResolveEnvVar(f.RelativePath)
67         if err != nil {
68                 pathCli = f.RelativePath
69         }
70         // SEB still need ShareRootDir ? a sup
71         // pathCli := filepath.Join(f.ShareRootDir, f.RelativePath)
72
73         folder := stconfig.FolderConfiguration{
74                 ID:            id,
75                 Label:         label,
76                 RawPath:       pathCli,
77                 AutoNormalize: true,
78         }
79
80         /* TODO - add it ?
81         if s.conf.FileConf.SThgConf.RescanIntervalS > 0 {
82                 folder.RescanIntervalS = s.conf.FileConf.SThgConf.RescanIntervalS
83         }
84         */
85
86         folder.Devices = append(folder.Devices, stconfig.FolderDeviceConfiguration{
87                 DeviceID: newDevice.DeviceID,
88         })
89
90         found = false
91         var fld stconfig.FolderConfiguration
92         for _, fld = range stCfg.Folders {
93                 if folder.ID == fld.ID {
94                         fld = folder
95                         found = true
96                         break
97                 }
98         }
99         if !found {
100                 stCfg.Folders = append(stCfg.Folders, folder)
101                 fld = stCfg.Folders[0]
102         }
103
104         err = s.ConfigSet(stCfg)
105         if err != nil {
106                 s.log.Errorln(err)
107         }
108
109         return id, nil
110 }
111
112 // FolderDelete is called to delete a folder config
113 func (s *SyncThing) FolderDelete(id string) error {
114         // Get current config
115         stCfg, err := s.ConfigGet()
116         if err != nil {
117                 s.log.Errorln(err)
118                 return err
119         }
120
121         for i, fld := range stCfg.Folders {
122                 if id == fld.ID {
123                         stCfg.Folders = append(stCfg.Folders[:i], stCfg.Folders[i+1:]...)
124                         err = s.ConfigSet(stCfg)
125                         if err != nil {
126                                 s.log.Errorln(err)
127                                 return err
128                         }
129                 }
130         }
131
132         return nil
133 }
134
135 // FolderConfigGet Returns the configuration of a specific folder
136 func (s *SyncThing) FolderConfigGet(folderID string) (stconfig.FolderConfiguration, error) {
137         fc := stconfig.FolderConfiguration{}
138         if folderID == "" {
139                 return fc, fmt.Errorf("folderID not set")
140         }
141         cfg, err := s.ConfigGet()
142         if err != nil {
143                 return fc, err
144         }
145         for _, f := range cfg.Folders {
146                 if f.ID == folderID {
147                         fc = f
148                         return fc, nil
149                 }
150         }
151         return fc, fmt.Errorf("id not found")
152 }
153
154 // FolderStatus Returns all information about the current
155 func (s *SyncThing) FolderStatus(folderID string) (*FolderStatus, error) {
156         var data []byte
157         var res FolderStatus
158         if folderID == "" {
159                 return nil, fmt.Errorf("folderID not set")
160         }
161         if err := s.client.HTTPGet("db/status?folder="+folderID, &data); err != nil {
162                 return nil, err
163         }
164         if err := json.Unmarshal(data, &res); err != nil {
165                 return nil, err
166         }
167         return &res, nil
168 }
169
170 // IsFolderInSync Returns true when folder is in sync
171 func (s *SyncThing) IsFolderInSync(folderID string) (bool, error) {
172         sts, err := s.FolderStatus(folderID)
173         if err != nil {
174                 return false, err
175         }
176         return sts.NeedBytes == 0 && sts.State == "idle", nil
177 }
178
179 // FolderScan Request immediate folder scan.
180 // Scan all folders if folderID param is empty
181 func (s *SyncThing) FolderScan(folderID string, subpath string) error {
182         url := "db/scan"
183         if folderID != "" {
184                 url += "?folder=" + folderID
185
186                 if subpath != "" {
187                         url += "&sub=" + subpath
188                 }
189         }
190         return s.client.HTTPPost(url, "")
191 }