Renamed apiv1 lib to xaapiv1.
[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 // FolderChangeArg argument structure used by FolderChange
14 type FolderChangeArg struct {
15         ID           string
16         Label        string
17         RelativePath string
18         SyncThingID  string
19 }
20
21 // FolderLoadFromStConfig Load/Retrieve folder config from syncthing database
22 /*
23 func (s *SyncThing) FolderLoadFromStConfig(f *[]xsapiv1.FolderConfig) error {
24
25         defaultSdk := "" // cannot know which was the default sdk
26
27         stCfg, err := s.ConfigGet()
28         if err != nil {
29                 return err
30         }
31         if len(stCfg.Devices) < 1 {
32                 return fmt.Errorf("Cannot load syncthing config: no device defined")
33         }
34         devID := stCfg.Devices[0].DeviceID.String()
35         if devID == s.MyID {
36                 if len(stCfg.Devices) < 2 {
37                         return fmt.Errorf("Cannot load syncthing config: no valid device found")
38                 }
39                 devID = stCfg.Devices[1].DeviceID.String()
40         }
41
42         for _, stFld := range stCfg.Folders {
43                 *f = append(*f, xsapiv1.FolderConfig{
44                         ID:            stFld.ID,
45                         Label:         stFld.Label,
46                         ClientPath:    strings.TrimRight(stFld.Path, "/"),
47                         Type:          xsapiv1.TypeCloudSync,
48                         Status:        StatusDisable,
49                         DefaultSdk:    defaultSdk,
50                         RootPath:      "",
51                         DataCloudSync: xsapiv1.CloudSyncConfig{SyncThingID: devID},
52                 })
53         }
54
55         return nil
56 }
57 */
58
59 // FolderChange is called when configuration has changed
60 func (s *SyncThing) FolderChange(f FolderChangeArg) (string, error) {
61
62         // Get current config
63         stCfg, err := s.ConfigGet()
64         if err != nil {
65                 s.log.Errorln(err)
66                 return "", err
67         }
68
69         stClientID := f.SyncThingID
70         // Add new Device if needed
71         var devID protocol.DeviceID
72         if err := devID.UnmarshalText([]byte(stClientID)); err != nil {
73                 s.log.Errorf("not a valid device id (err %v)", err)
74                 return "", err
75         }
76
77         newDevice := stconfig.DeviceConfiguration{
78                 DeviceID:  devID,
79                 Name:      stClientID,
80                 Addresses: []string{"dynamic"},
81         }
82
83         var found = false
84         for _, device := range stCfg.Devices {
85                 if device.DeviceID == devID {
86                         found = true
87                         break
88                 }
89         }
90         if !found {
91                 stCfg.Devices = append(stCfg.Devices, newDevice)
92         }
93
94         // Add or update Folder settings
95         var label, id string
96         if label = f.Label; label == "" {
97                 label = strings.Split(id, "/")[0]
98         }
99         if id = f.ID; id == "" {
100                 id = stClientID[0:15] + "_" + label
101         }
102
103         // Resolve local path
104         pathCli, err := common.ResolveEnvVar(f.RelativePath)
105         if err != nil {
106                 pathCli = f.RelativePath
107         }
108
109         folder := stconfig.FolderConfiguration{
110                 ID:            id,
111                 Label:         label,
112                 Path:          pathCli,
113                 AutoNormalize: true,
114         }
115
116         /* TODO - add it ?
117         if s.conf.FileConf.SThgConf.RescanIntervalS > 0 {
118                 folder.RescanIntervalS = s.conf.FileConf.SThgConf.RescanIntervalS
119         }
120         */
121
122         folder.Devices = append(folder.Devices, stconfig.FolderDeviceConfiguration{
123                 DeviceID: newDevice.DeviceID,
124         })
125
126         found = false
127         var fld stconfig.FolderConfiguration
128         for _, fld = range stCfg.Folders {
129                 if folder.ID == fld.ID {
130                         fld = folder
131                         found = true
132                         break
133                 }
134         }
135         if !found {
136                 stCfg.Folders = append(stCfg.Folders, folder)
137                 fld = stCfg.Folders[0]
138         }
139
140         err = s.ConfigSet(stCfg)
141
142         return id, err
143 }
144
145 // FolderDelete is called to delete a folder config
146 func (s *SyncThing) FolderDelete(id string) error {
147         // Get current config
148         stCfg, err := s.ConfigGet()
149         if err != nil {
150                 s.log.Errorln(err)
151                 return err
152         }
153
154         for i, fld := range stCfg.Folders {
155                 if id == fld.ID {
156                         stCfg.Folders = append(stCfg.Folders[:i], stCfg.Folders[i+1:]...)
157                         err = s.ConfigSet(stCfg)
158                         if err != nil {
159                                 s.log.Errorln(err)
160                                 return err
161                         }
162                 }
163         }
164
165         return nil
166 }
167
168 // FolderConfigGet Returns the configuration of a specific folder
169 func (s *SyncThing) FolderConfigGet(folderID string) (stconfig.FolderConfiguration, error) {
170         fc := stconfig.FolderConfiguration{}
171         if folderID == "" {
172                 return fc, fmt.Errorf("folderID not set")
173         }
174         cfg, err := s.ConfigGet()
175         if err != nil {
176                 return fc, err
177         }
178         for _, f := range cfg.Folders {
179                 if f.ID == folderID {
180                         fc = f
181                         return fc, nil
182                 }
183         }
184         return fc, fmt.Errorf("id not found")
185 }
186
187 // FolderStatus Returns all information about the current
188 func (s *SyncThing) FolderStatus(folderID string) (*FolderStatus, error) {
189         var data []byte
190         var res FolderStatus
191         if folderID == "" {
192                 return nil, fmt.Errorf("folderID not set")
193         }
194         if err := s.client.HTTPGet("db/status?folder="+folderID, &data); err != nil {
195                 return nil, err
196         }
197         if err := json.Unmarshal(data, &res); err != nil {
198                 return nil, err
199         }
200         return &res, nil
201 }
202
203 // IsFolderInSync Returns true when folder is in sync
204 func (s *SyncThing) IsFolderInSync(folderID string) (bool, error) {
205         sts, err := s.FolderStatus(folderID)
206         if err != nil {
207                 return false, err
208         }
209         return sts.NeedBytes == 0 && sts.State == "idle", nil
210 }
211
212 // FolderScan Request immediate folder scan.
213 // Scan all folders if folderID param is empty
214 func (s *SyncThing) FolderScan(folderID string, subpath string) error {
215         url := "db/scan"
216         if folderID != "" {
217                 url += "?folder=" + folderID
218
219                 if subpath != "" {
220                         url += "&sub=" + subpath
221                 }
222         }
223         return s.client.HTTPPost(url, "")
224 }