diff options
Diffstat (limited to 'lib/syncthing')
-rw-r--r-- | lib/syncthing/st.go | 76 | ||||
-rw-r--r-- | lib/syncthing/stfolder.go | 116 |
2 files changed, 192 insertions, 0 deletions
diff --git a/lib/syncthing/st.go b/lib/syncthing/st.go new file mode 100644 index 0000000..7d07b70 --- /dev/null +++ b/lib/syncthing/st.go @@ -0,0 +1,76 @@ +package st + +import ( + "encoding/json" + + "strings" + + "fmt" + + "github.com/Sirupsen/logrus" + "github.com/iotbzh/xds-server/lib/common" + "github.com/syncthing/syncthing/lib/config" +) + +// SyncThing . +type SyncThing struct { + BaseURL string + client *common.HTTPClient + log *logrus.Logger +} + +// NewSyncThing creates a new instance of Syncthing +func NewSyncThing(url string, apikey string, log *logrus.Logger) *SyncThing { + cl, err := common.HTTPNewClient(url, + common.HTTPClientConfig{ + URLPrefix: "/rest", + HeaderClientKeyName: "X-Syncthing-ID", + }) + if err != nil { + msg := ": " + err.Error() + if strings.Contains(err.Error(), "connection refused") { + msg = fmt.Sprintf("(url: %s)", url) + } + log.Debugf("ERROR: cannot connect to Syncthing %s", msg) + return nil + } + + s := SyncThing{ + BaseURL: url, + client: cl, + log: log, + } + + return &s +} + +// IDGet returns the Syncthing ID of Syncthing instance running locally +func (s *SyncThing) IDGet() (string, error) { + var data []byte + if err := s.client.HTTPGet("system/status", &data); err != nil { + return "", err + } + status := make(map[string]interface{}) + json.Unmarshal(data, &status) + return status["myID"].(string), nil +} + +// ConfigGet returns the current Syncthing configuration +func (s *SyncThing) ConfigGet() (config.Configuration, error) { + var data []byte + config := config.Configuration{} + if err := s.client.HTTPGet("system/config", &data); err != nil { + return config, err + } + err := json.Unmarshal(data, &config) + return config, err +} + +// ConfigSet set Syncthing configuration +func (s *SyncThing) ConfigSet(cfg config.Configuration) error { + body, err := json.Marshal(cfg) + if err != nil { + return err + } + return s.client.HTTPPost("system/config", string(body)) +} diff --git a/lib/syncthing/stfolder.go b/lib/syncthing/stfolder.go new file mode 100644 index 0000000..d79e579 --- /dev/null +++ b/lib/syncthing/stfolder.go @@ -0,0 +1,116 @@ +package st + +import ( + "path/filepath" + "strings" + + "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/protocol" +) + +// FIXME remove and use an interface on xdsconfig.FolderConfig +type FolderChangeArg struct { + ID string + Label string + RelativePath string + SyncThingID string + ShareRootDir string +} + +// FolderChange is called when configuration has changed +func (s *SyncThing) FolderChange(f FolderChangeArg) error { + + // Get current config + stCfg, err := s.ConfigGet() + if err != nil { + s.log.Errorln(err) + return err + } + + // Add new Device if needed + var devID protocol.DeviceID + if err := devID.UnmarshalText([]byte(f.SyncThingID)); err != nil { + s.log.Errorf("not a valid device id (err %v)\n", err) + return err + } + + newDevice := config.DeviceConfiguration{ + DeviceID: devID, + Name: f.SyncThingID, + Addresses: []string{"dynamic"}, + } + + var found = false + for _, device := range stCfg.Devices { + if device.DeviceID == devID { + found = true + break + } + } + if !found { + stCfg.Devices = append(stCfg.Devices, newDevice) + } + + // Add or update Folder settings + var label, id string + if label = f.Label; label == "" { + label = strings.Split(id, "/")[0] + } + if id = f.ID; id == "" { + id = f.SyncThingID[0:15] + "_" + label + } + + folder := config.FolderConfiguration{ + ID: id, + Label: label, + RawPath: filepath.Join(f.ShareRootDir, f.RelativePath), + } + + folder.Devices = append(folder.Devices, config.FolderDeviceConfiguration{ + DeviceID: newDevice.DeviceID, + }) + + found = false + var fld config.FolderConfiguration + for _, fld = range stCfg.Folders { + if folder.ID == fld.ID { + fld = folder + found = true + break + } + } + if !found { + stCfg.Folders = append(stCfg.Folders, folder) + fld = stCfg.Folders[0] + } + + err = s.ConfigSet(stCfg) + if err != nil { + s.log.Errorln(err) + } + + return nil +} + +// FolderDelete is called to delete a folder config +func (s *SyncThing) FolderDelete(id string) error { + // Get current config + stCfg, err := s.ConfigGet() + if err != nil { + s.log.Errorln(err) + return err + } + + for i, fld := range stCfg.Folders { + if id == fld.ID { + stCfg.Folders = append(stCfg.Folders[:i], stCfg.Folders[i+1:]...) + err = s.ConfigSet(stCfg) + if err != nil { + s.log.Errorln(err) + return err + } + } + } + + return nil +} |