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