Use go module as dependency tool instead of glide
[src/xds/xds-server.git] / lib / syncthing / stfolder.go
1 /*
2  * Copyright (C) 2017-2018 "IoT.bzh"
3  * Author Sebastien Douheret <sebastien@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package st
19
20 import (
21         "encoding/json"
22         "fmt"
23         "path/filepath"
24         "strings"
25
26         "gerrit.automotivelinux.org/gerrit/src/xds/xds-server.git/lib/xsapiv1"
27         stconfig "github.com/syncthing/syncthing/lib/config"
28         "github.com/syncthing/syncthing/lib/protocol"
29 )
30
31 // FolderLoadFromStConfig Load/Retrieve folder config from syncthing database
32 func (s *SyncThing) FolderLoadFromStConfig(f *[]xsapiv1.FolderConfig) error {
33
34         defaultSdk := "" // cannot know which was the default sdk
35
36         stCfg, err := s.ConfigGet()
37         if err != nil {
38                 return err
39         }
40         if len(stCfg.Devices) < 1 {
41                 return fmt.Errorf("Cannot load syncthing config: no device defined")
42         }
43         devID := stCfg.Devices[0].DeviceID.String()
44         if devID == s.MyID {
45                 if len(stCfg.Devices) < 2 {
46                         return fmt.Errorf("Cannot load syncthing config: no valid device found")
47                 }
48                 devID = stCfg.Devices[1].DeviceID.String()
49         }
50
51         for _, stFld := range stCfg.Folders {
52                 cliPath := strings.TrimPrefix(stFld.Path, s.conf.FileConf.ShareRootDir)
53                 if cliPath == "" {
54                         cliPath = stFld.Path
55                 }
56                 *f = append(*f, xsapiv1.FolderConfig{
57                         ID:            stFld.ID,
58                         Label:         stFld.Label,
59                         ClientPath:    strings.TrimRight(cliPath, "/"),
60                         Type:          xsapiv1.TypeCloudSync,
61                         Status:        xsapiv1.StatusDisable,
62                         DefaultSdk:    defaultSdk,
63                         RootPath:      s.conf.FileConf.ShareRootDir,
64                         DataCloudSync: xsapiv1.CloudSyncConfig{SyncThingID: devID},
65                 })
66         }
67
68         return nil
69 }
70
71 // FolderChange is called when configuration has changed
72 func (s *SyncThing) FolderChange(f xsapiv1.FolderConfig) (string, error) {
73         var label, id string
74
75         if id = f.ID; id == "" {
76                 s.log.Errorf("Try to create Syncthing folder with null ID: %v", f)
77                 return "", fmt.Errorf("Cannot create Syncthing folder (ID must be set")
78         }
79
80         // Get current config
81         stCfg, err := s.ConfigGet()
82         if err != nil {
83                 s.log.Errorln(err)
84                 return "", err
85         }
86
87         stClientID := f.DataCloudSync.SyncThingID
88         // Add new Device if needed
89         var devID protocol.DeviceID
90         if err := devID.UnmarshalText([]byte(stClientID)); err != nil {
91                 s.log.Errorf("not a valid device id (err %v)", err)
92                 return "", err
93         }
94
95         newDevice := stconfig.DeviceConfiguration{
96                 DeviceID:  devID,
97                 Name:      stClientID,
98                 Addresses: []string{"dynamic"},
99         }
100
101         var found = false
102         for _, device := range stCfg.Devices {
103                 if device.DeviceID == devID {
104                         found = true
105                         break
106                 }
107         }
108         if !found {
109                 stCfg.Devices = append(stCfg.Devices, newDevice)
110         }
111
112         // Add or update Folder settings
113         if label = f.Label; label == "" {
114                 label = strings.Split(id, "/")[0]
115         }
116
117         folder := stconfig.FolderConfiguration{
118                 ID:    id,
119                 Label: label,
120                 Path:  filepath.Join(s.conf.FileConf.ShareRootDir, f.ClientPath),
121         }
122
123         if s.conf.FileConf.SThgConf.RescanIntervalS > 0 {
124                 folder.RescanIntervalS = s.conf.FileConf.SThgConf.RescanIntervalS
125         }
126
127         folder.Devices = append(folder.Devices, stconfig.FolderDeviceConfiguration{
128                 DeviceID: newDevice.DeviceID,
129         })
130
131         found = false
132         var fld stconfig.FolderConfiguration
133         for _, fld = range stCfg.Folders {
134                 if folder.ID == fld.ID {
135                         fld = folder
136                         found = true
137                         break
138                 }
139         }
140         if !found {
141                 stCfg.Folders = append(stCfg.Folders, folder)
142                 fld = stCfg.Folders[0]
143         }
144
145         err = s.ConfigSet(stCfg)
146         if err != nil {
147                 s.log.Errorln(err)
148         }
149
150         return id, nil
151 }
152
153 // FolderDelete is called to delete a folder config
154 func (s *SyncThing) FolderDelete(id string) error {
155         // Get current config
156         stCfg, err := s.ConfigGet()
157         if err != nil {
158                 s.log.Errorln(err)
159                 return err
160         }
161
162         for i, fld := range stCfg.Folders {
163                 if id == fld.ID {
164                         stCfg.Folders = append(stCfg.Folders[:i], stCfg.Folders[i+1:]...)
165                         err = s.ConfigSet(stCfg)
166                         if err != nil {
167                                 s.log.Errorln(err)
168                                 return err
169                         }
170                 }
171         }
172
173         return nil
174 }
175
176 // FolderConfigGet Returns the configuration of a specific folder
177 func (s *SyncThing) FolderConfigGet(folderID string) (stconfig.FolderConfiguration, error) {
178         fc := stconfig.FolderConfiguration{}
179         if folderID == "" {
180                 return fc, fmt.Errorf("folderID not set")
181         }
182         cfg, err := s.ConfigGet()
183         if err != nil {
184                 return fc, err
185         }
186         for _, f := range cfg.Folders {
187                 if f.ID == folderID {
188                         fc = f
189                         return fc, nil
190                 }
191         }
192         return fc, fmt.Errorf("id not found")
193 }
194
195 // FolderStatus Returns all information about the current
196 func (s *SyncThing) FolderStatus(folderID string) (*FolderStatus, error) {
197         var data []byte
198         var res FolderStatus
199         if folderID == "" {
200                 return nil, fmt.Errorf("folderID not set")
201         }
202         if err := s.client.HTTPGet("db/status?folder="+folderID, &data); err != nil {
203                 return nil, err
204         }
205         if err := json.Unmarshal(data, &res); err != nil {
206                 return nil, err
207         }
208         return &res, nil
209 }
210
211 // IsFolderInSync Returns true when folder is in sync
212 func (s *SyncThing) IsFolderInSync(folderID string) (bool, error) {
213         sts, err := s.FolderStatus(folderID)
214         if err != nil {
215                 return false, err
216         }
217         return sts.NeedBytes == 0 && sts.State == "idle", nil
218 }
219
220 // FolderScan Request immediate folder scan.
221 // Scan all folders if folderID param is empty
222 func (s *SyncThing) FolderScan(folderID string, subpath string) error {
223         url := "db/scan"
224         if folderID != "" {
225                 url += "?folder=" + folderID
226
227                 if subpath != "" {
228                         url += "&sub=" + subpath
229                 }
230         }
231         return s.client.HTTPPost(url, "")
232 }