// Place your settings in this file to overwrite default and user settings.
{
- // Configure glob patterns for excluding files and folders.
- "files.exclude": {
- ".tmp": true,
- ".git": true,
- "glide.lock": true,
- "vendor": true,
- "debug": true,
- "bin": true,
- "tools": true,
- "webapp/dist": true,
- "webapp/node_modules": true
- },
- // Specify paths/files to ignore. (Supports Globs)
- "cSpell.ignorePaths": [
- "**/node_modules/**",
- "**/vscode-extension/**",
- "**/.git/**",
- "**/vendor/**",
- ".vscode",
- "typings"
- ],
- // Words to add to dictionary for a workspace.
- "cSpell.words": [
- "apiv",
- "gonic",
- "devel",
- "csrffound",
- "Syncthing",
- "STID",
- "ISTCONFIG",
- "socketio",
- "ldflags",
- "SThg",
- "Intf",
- "dismissible",
- "rpath",
- "WSID",
- "sess",
- "IXDS",
- "xdsconfig",
- "xdsserver",
- "mfolder",
- "inotify",
- "Inot",
- "pname",
- "pkill",
- "sdkid",
- "CLOUDSYNC",
- "xdsagent",
- "gdbserver",
- "golib",
- "eows",
- "mfolders",
- "IFOLDER",
- "flds",
- "dflt",
- "stconfig"
- ]
+ // Configure glob patterns for excluding files and folders.
+ "files.exclude": {
+ ".tmp": true,
+ ".git": true,
+ "glide.lock": true,
+ "vendor": true,
+ "debug": true,
+ "bin": true,
+ "tools": true,
+ "webapp/dist": true,
+ "webapp/node_modules": true
+ },
+ // Specify paths/files to ignore. (Supports Globs)
+ "cSpell.ignorePaths": [
+ "**/node_modules/**",
+ "**/vscode-extension/**",
+ "**/.git/**",
+ "**/vendor/**",
+ ".vscode",
+ "typings"
+ ],
+ // Words to add to dictionary for a workspace.
+ "cSpell.words": [
+ "apiv", "gonic", "devel", "csrffound", "Syncthing", "STID",
+ "ISTCONFIG", "socketio", "ldflags", "SThg", "Intf", "dismissible",
+ "rpath", "WSID", "sess", "IXDS", "xdsconfig", "xdsserver", "mfolder",
+ "inotify", "Inot", "pname", "pkill", "sdkid", "CLOUDSYNC", "xdsagent",
+ "gdbserver", "golib", "eows", "mfolders", "IFOLDER", "flds", "dflt",
+ "stconfig", "reflectme", "franciscocpg"
+ ]
}
- golib/eows
- package: github.com/kr/pty
version: ^1.0.0
+- package: github.com/franciscocpg/reflectme
+ version: ^0.1.9
s.apiRouter.GET("/folders", s.getFolders)
s.apiRouter.GET("/folders/:id", s.getFolder)
+ s.apiRouter.PUT("/folders/:id", s.updateFolder)
s.apiRouter.POST("/folders", s.addFolder)
s.apiRouter.POST("/folders/sync/:id", s.syncFolder)
s.apiRouter.DELETE("/folders/:id", s.delFolder)
import (
"net/http"
+ "strings"
"time"
"github.com/iotbzh/xds-server/lib/folder"
}
// EventEvent Event send in WS when an internal event (eg. Syncthing event is received)
-const EventEventAll = "event:all"
-const EventEventType = "event:" // following by event type
+const (
+ // EventTypePrefix Used as event prefix
+ EventTypePrefix = "event:" // following by event type
+
+ // Supported Events type
+ EVTAll = EventTypePrefix + "all"
+ EVTFolderChange = EventTypePrefix + "folder-change" // type EventMsg with Data type apiv1.???
+ EVTFolderStateChange = EventTypePrefix + "folder-state-change" // type EventMsg with Data type apiv1.???
+)
// eventsList Registering for events that will be send over a WS
func (s *APIService) eventsList(c *gin.Context) {
return
}
- evType := "FolderStateChanged"
+ evType := strings.TrimPrefix(EVTFolderStateChange, EventTypePrefix)
if args.Name != evType {
common.APIError(c, "Unsupported event name")
return
Data: ev.Data,
}
- if err := (*so).Emit(EventEventAll, msg); err != nil {
+ if err := (*so).Emit(EVTAll, msg); err != nil {
s.log.Errorf("WS Emit Event : %v", err)
}
- if err := (*so).Emit(EventEventType+ev.Type, msg); err != nil {
+ if err := (*so).Emit(EventTypePrefix+ev.Type, msg); err != nil {
s.log.Errorf("WS Emit Event : %v", err)
}
}
}
s.log.Debugf("WS Emit %s - Status=%10s, IsInSync=%6v, ID=%s",
- EventEventType+evType, cfg.Status, cfg.IsInSync, cfg.ID)
+ EventTypePrefix+evType, cfg.Status, cfg.IsInSync, cfg.ID)
- if err := (*so).Emit(EventEventType+evType, msg); err != nil {
+ if err := (*so).Emit(EventTypePrefix+evType, msg); err != nil {
s.log.Errorf("WS Emit Folder StateChanged event : %v", err)
}
}
}
c.JSON(http.StatusOK, delEntry)
}
+
+// updateFolder update some field of a folder
+func (s *APIService) updateFolder(c *gin.Context) {
+ id, err := s.mfolders.ResolveID(c.Param("id"))
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+
+ s.log.Debugln("Update folder id ", id)
+
+ var cfgArg folder.FolderConfig
+ if c.BindJSON(&cfgArg) != nil {
+ common.APIError(c, "Invalid arguments")
+ return
+ }
+
+ upFld, err := s.mfolders.Update(id, cfgArg)
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+ c.JSON(http.StatusOK, upFld)
+}
ConvPathCli2Svr(s string) string // Convert path from Client to Server
ConvPathSvr2Cli(s string) string // Convert path from Server to Client
Remove() error // Remove a folder
+ Update(cfg FolderConfig) (*FolderConfig, error) // Update a new folder
RegisterEventChange(cb *EventCB, data *EventCBData) error // Request events registration (sent through WS)
UnRegisterEventChange() error // Un-register events
Sync() error // Force folder files synchronization
Status string `json:"status"`
IsInSync bool `json:"isInSync"`
DefaultSdk string `json:"defaultSdk"`
+ ClientData string `json:"clientData"` // free form field that can used by client
// Not exported fields from REST API point of view
RootPath string `json:"-"`
DataCloudSync CloudSyncConfig `json:"dataCloudSync,omitempty"`
}
+// FolderConfigUpdatableFields List fields that can be updated using Update function
+var FolderConfigUpdatableFields = []string{
+ "Label", "DefaultSdk", "ClientData",
+}
+
// PathMapConfig Path mapping specific data
type PathMapConfig struct {
ServerPath string `json:"serverPath"`
return nil
}
+// Update update some fields of a folder
+func (f *PathMap) Update(cfg FolderConfig) (*FolderConfig, error) {
+ if f.config.ID != cfg.ID {
+ return nil, fmt.Errorf("Invalid id")
+ }
+ f.config = cfg
+ return &f.config, nil
+}
+
// RegisterEventChange requests registration for folder change event
func (f *PathMap) RegisterEventChange(cb *EventCB, data *EventCBData) error {
return nil
return nil
}
+// Update update some fields of a folder
+func (f *STFolderDisable) Update(cfg FolderConfig) (*FolderConfig, error) {
+ return nil, nil
+}
+
// RegisterEventChange requests registration for folder change event
func (f *STFolderDisable) RegisterEventChange(cb *EventCB, data *EventCBData) error {
return nil
"time"
"github.com/Sirupsen/logrus"
+ "github.com/franciscocpg/reflectme"
common "github.com/iotbzh/xds-common/golib"
"github.com/iotbzh/xds-server/lib/folder"
"github.com/iotbzh/xds-server/lib/syncthing"
return fld, err
}
+// Update Update a specific folder
+func (f *Folders) Update(id string, cfg folder.FolderConfig) (*folder.FolderConfig, error) {
+ fcMutex.Lock()
+ defer fcMutex.Unlock()
+
+ fc, exist := f.folders[id]
+ if !exist {
+ return nil, fmt.Errorf("unknown id")
+ }
+
+ // Copy current in a new object to change nothing in case of an error rises
+ newCfg := folder.FolderConfig{}
+ reflectme.Copy((*fc).GetConfig(), &newCfg)
+
+ // Only update some fields
+ dirty := false
+ for _, fieldName := range folder.FolderConfigUpdatableFields {
+ valNew, err := reflectme.GetField(cfg, fieldName)
+ if err == nil {
+ valCur, err := reflectme.GetField(newCfg, fieldName)
+ if err == nil && valNew != valCur {
+ err = reflectme.SetField(&newCfg, fieldName, valNew)
+ if err != nil {
+ return nil, err
+ }
+ dirty = true
+ }
+ }
+ }
+
+ if !dirty {
+ return &newCfg, nil
+ }
+
+ fld, err := (*fc).Update(newCfg)
+ if err != nil {
+ return fld, err
+ }
+
+ // Save config on disk
+ err = f.SaveConfig()
+
+ // Send event to notified changes
+ // TODO emit folder change event
+
+ return fld, err
+}
+
// RegisterEventChange requests registration for folder event change
func (f *Folders) RegisterEventChange(id string, cb *folder.EventCB, data *folder.EventCBData) error {
return err2
}
+// Update update some fields of a folder
+func (f *STFolder) Update(cfg folder.FolderConfig) (*folder.FolderConfig, error) {
+ if f.fConfig.ID != cfg.ID {
+ return nil, fmt.Errorf("Invalid id")
+ }
+ f.fConfig = cfg
+ return &f.fConfig, nil
+}
+
// RegisterEventChange requests registration for folder event change
func (f *STFolder) RegisterEventChange(cb *folder.EventCB, data *folder.EventCBData) error {
f.eventChangeCB = cb