func GenerateCommands(prefix string, config map[string]interface{}) (map[string]Command, error) { commands := make(map[string]Command) if cmdInterface, ok := config[`commands`]; ok { switch cmdInterface.(type) { case map[string]interface{}: for key, commandConfigI := range cmdInterface.(map[string]interface{}) { key = prefix + `:` + key log.Infof("CommandModule: initializing command '%s'", key) switch commandConfigI.(type) { case map[string]interface{}: commandConfig := commandConfigI.(map[string]interface{}) command := Command{ Key: key, } if v, ok := commandConfig[`shellwrap`]; ok { if s, err := stringutil.ToString(v); err == nil { command.ShellWrap = s } } if v, ok := commandConfig[`detach`]; ok { if s, err := stringutil.ToString(v); err == nil { command.Detach = (s == `true`) } } if v, ok := commandConfig[`command`]; ok { if s, err := stringutil.ToString(v); err == nil { command.CommandLine = s } } if err := command.Init(); err == nil { commands[key] = command } else { return commands, err } } } } } return commands, nil }
func coerceIntoType(in interface{}, typeName string) (interface{}, error) { // make sure `in' is a string, error out if not if inStr, err := stringutil.ToString(in); err == nil { switch typeName { case `bool`: if v, err := strconv.ParseBool(inStr); err == nil { return interface{}(v), nil } else { return nil, fmt.Errorf("Unable to convert '%s' into a boolean", inStr) } case `int`: if v, err := strconv.ParseInt(inStr, 10, 64); err == nil { return interface{}(v), nil } else { return nil, fmt.Errorf("Unable to convert '%s' into an integer", inStr) } case `float`: if v, err := strconv.ParseFloat(inStr, 64); err == nil { return interface{}(v), nil } else { return nil, fmt.Errorf("Unable to convert '%s' into a float", inStr) } case `str`: return interface{}(inStr), nil default: return in, fmt.Errorf("Unknown conversion type '%s'", typeName) } } else { return in, nil } }
func GetBaseFunctions() template.FuncMap { return template.FuncMap{ `autosize`: func(input float64, fixTo int) (string, error) { check := float64(input) i := 1 for i = 1; i < 9; i++ { if check < 1024.0 { break } else { check = (check / 1024.0) } } return (strconv.FormatFloat(check, 'f', fixTo, 64) + ` ` + util.SiSuffixes[i-1]), nil }, `length`: func(set []interface{}) int { return len(set) }, `str`: func(in ...interface{}) (string, error) { if len(in) > 0 { if in[0] != nil { return stringutil.ToString(in[0]) } } return ``, nil }, } }
func GetBaseFunctions() map[string]pongo2.FilterFunction { return map[string]pongo2.FilterFunction{ `autosize`: func(input *pongo2.Value, fixTo *pongo2.Value) (*pongo2.Value, *pongo2.Error) { check := input.Float() i := 1 for i = 1; i < 9; i++ { if check < 1024.0 { break } else { check = (check / 1024.0) } } return pongo2.AsValue((strconv.FormatFloat(check, 'f', fixTo.Integer(), 64) + ` ` + util.SiSuffixes[i-1])), nil }, `less`: func(first *pongo2.Value, second *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue(first.Float() - second.Float()), nil }, `str`: func(input *pongo2.Value, _ *pongo2.Value) (*pongo2.Value, *pongo2.Error) { if input.Len() > 0 { if v, err := stringutil.ToString(input.Interface()); err == nil { return pongo2.AsValue(v), nil } } return pongo2.AsValue(``), nil }, } }
func Join(input map[string]interface{}, innerJoiner string, outerJoiner string) string { parts := make([]string, 0) for key, value := range input { if v, err := stringutil.ToString(value); err == nil { parts = append(parts, key+innerJoiner+v) } } return strings.Join(parts, outerJoiner) }
// Take a deeply-nested map and return a flat (non-nested) map with keys whose intermediate tiers are joined with fieldJoiner // Additionally, values will be converted to strings and keys will be prefixed with the datatype of the value // func CoalesceMapTyped(data map[string]interface{}, fieldJoiner string, typePrefixSeparator string) (map[string]interface{}, []error) { errs := make([]error, 0) rv := make(map[string]interface{}) for k, v := range deepGetValues([]string{}, fieldJoiner, data) { if stringVal, err := stringutil.ToString(v); err == nil { rv[prepareCoalescedKey(k, v, typePrefixSeparator)] = stringVal } else { errs = append(errs, err) } } return rv, errs }
func (self *Server) GetBindings(method string, routePath string, req *http.Request) map[string]Binding { var httpMethod HttpMethod bindings := make(map[string]Binding) for key, binding := range self.Bindings { if binding.RouteMethods == MethodAny || binding.RouteMethods&httpMethod == httpMethod { for _, rx := range binding.Routes { if match := rx.FindStringSubmatch(routePath); match != nil { for i, matchGroupName := range rx.SubexpNames() { if matchGroupName != `` { newUrl := *binding.Resource // generate the final request path with params expanded from the 'resource' config newUrl.Path = strings.Replace(newUrl.Path, (ParamDelimPre + matchGroupName + ParamDelimPost), match[i], -1) // expand parameters from the 'params' config for qs, v := range newUrl.Query() { qsv := strings.Replace(v[0], (ParamDelimPre + matchGroupName + ParamDelimPost), match[i], -1) binding.ResourceParams[qs] = qsv binding.RouteParams[matchGroupName] = match[i] } // passthrough querystring parameters supplied in the reuquest itself as overrides for qs, v := range req.URL.Query() { if len(v) > 0 { binding.ResourceParams[qs] = v[0] binding.RouteParams[qs] = v[0] } } // build raw querystring newUrlValues := newUrl.Query() for k, v := range binding.ResourceParams { if str, err := stringutil.ToString(v); err == nil { if binding.EscapeParams { str = url.QueryEscape(str) } log.Debugf("Setting resource param %s='%s'", k, v) newUrlValues.Set(k, str) } } newUrl.RawQuery = newUrlValues.Encode() log.Debugf("Resource URL: %+v (%s)", newUrl, newUrlValues.Encode()) binding.Resource = &newUrl } } bindings[key] = binding break } } } else { log.Warnf("Binding '%s' did not match %s %s", key, method, routePath) } } // log.Debugf("Bindings for %s %s -> %v", method, routePath, bindings) return bindings }
func (self *SessionModule) LoadRoutes(router *httprouter.Router) error { router.GET(`/api/session/workspaces`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { if workspaces, err := self.GetAllWorkspaces(); err == nil { util.Respond(w, http.StatusOK, workspaces, nil) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.GET(`/api/session/workspaces/current`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { if workspaces, err := self.GetAllWorkspaces(); err == nil { for _, workspace := range workspaces { if workspace.IsCurrent { util.Respond(w, http.StatusOK, workspace, nil) return } } util.Respond(w, http.StatusNotFound, nil, fmt.Errorf("Current workspace not found")) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.GET(`/api/session/windows`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { if windows, err := self.GetAllWindows(); err == nil { for i, _ := range windows { windows[i].IconUri = fmt.Sprintf("/api/session/windows/%d/icon", windows[i].ID) } util.Respond(w, http.StatusOK, windows, nil) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.GET(`/api/session/windows/:id`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { if window, err := self.GetWindow(params.ByName(`id`)); err == nil { window.IconUri = fmt.Sprintf("/api/session/windows/%s/icon", params.ByName(`id`)) util.Respond(w, http.StatusOK, window, nil) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.GET(`/api/session/windows/:id/icon`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { var buffer bytes.Buffer width := uint(16) height := uint(16) if w := req.URL.Query().Get(`w`); w != `` { if value, err := stringutil.ConvertToInteger(w); err == nil { width = uint(value) } } if h := req.URL.Query().Get(`h`); h != `` { if value, err := stringutil.ConvertToInteger(h); err == nil { height = uint(value) } } if height != width { height = width } if err := self.WriteWindowIcon(params.ByName(`id`), width, height, &buffer); err == nil { w.Header().Set(`Content-Type`, `image/png`) w.Write(buffer.Bytes()) return } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.GET(`/api/session/windows/:id/image`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { var buffer bytes.Buffer if err := self.WriteWindowImage(params.ByName(`id`), &buffer); err == nil { w.Header().Set(`Content-Type`, `image/png`) w.Write(buffer.Bytes()) return } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.PUT(`/api/session/windows/:id/do/:action`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { var err error id := params.ByName(`id`) switch params.ByName(`action`) { case `maximize`: err = self.MaximizeWindow(id) case `max-x`: err = self.MaximizeWindowHorizontal(id) case `max-y`: err = self.MaximizeWindowVertical(id) case `minimize`: err = self.MinimizeWindow(id) case `restore`: err = self.RestoreWindow(id) case `hide`: err = self.HideWindow(id) case `show`: err = self.ShowWindow(id) case `raise`: err = self.RaiseWindow(id) default: util.Respond(w, http.StatusBadRequest, nil, fmt.Errorf("Unknown action '%s'", params.ByName(`action`))) return } if err == nil { util.Respond(w, http.StatusAccepted, nil, nil) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.PUT(`/api/session/windows/:id/move/:x/:y`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { id := params.ByName(`id`) var x, y int if value, err := stringutil.ConvertToInteger(params.ByName(`x`)); err == nil { x = int(value) } else { util.Respond(w, http.StatusBadRequest, nil, err) return } if value, err := stringutil.ConvertToInteger(params.ByName(`y`)); err == nil { y = int(value) } else { util.Respond(w, http.StatusBadRequest, nil, err) return } if err := self.MoveWindow(id, x, y); err == nil { util.Respond(w, http.StatusAccepted, nil, nil) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.PUT(`/api/session/windows/:id/resize/:x/:y`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { id := params.ByName(`id`) var width, height uint if value, err := stringutil.ConvertToInteger(params.ByName(`width`)); err == nil { width = uint(value) } else { util.Respond(w, http.StatusBadRequest, nil, err) return } if value, err := stringutil.ConvertToInteger(params.ByName(`height`)); err == nil { height = uint(value) } else { util.Respond(w, http.StatusBadRequest, nil, err) return } if err := self.ResizeWindow(id, width, height); err == nil { util.Respond(w, http.StatusAccepted, nil, nil) } else { util.Respond(w, http.StatusInternalServerError, nil, err) } }) router.GET(`/api/session/applications`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { keys := make([]string, 0) for key, _ := range self.Applications.Entries { keys = append(keys, key) } sort.Strings(keys) util.Respond(w, http.StatusOK, keys, nil) }) router.GET(`/api/session/applications/:name`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { key := params.ByName(`name`) if app, ok := self.Applications.Entries[key]; ok { util.Respond(w, http.StatusOK, app, nil) } else { util.Respond(w, http.StatusNotFound, nil, fmt.Errorf("Could not locate application '%s'", key)) } }) router.GET(`/api/session/icons/list/:type`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { var filterMinSize, filterMaxSize int rv := make([]string, 0) listType := params.ByName(`type`) // filters filterThemes := strings.Split(req.URL.Query().Get(`themes`), `,`) filterIconContextTypes := strings.Split(req.URL.Query().Get(`contexts`), `,`) filterIconFileTypes := strings.Split(req.URL.Query().Get(`filetypes`), `,`) filterMinSizeS := req.URL.Query().Get(`minsize`) filterMaxSizeS := req.URL.Query().Get(`maxsize`) filterIsScalable := req.URL.Query().Get(`scalable`) if filterMinSizeS != `` { if v, err := stringutil.ConvertToInteger(filterMinSizeS); err == nil { filterMinSize = int(v) } else { util.Respond(w, http.StatusBadRequest, nil, err) return } } if filterMaxSizeS != `` { if v, err := stringutil.ConvertToInteger(filterMaxSizeS); err == nil { filterMaxSize = int(v) } else { util.Respond(w, http.StatusBadRequest, nil, err) return } } for _, theme := range self.Themeset.Themes { if len(filterThemes) > 0 && filterThemes[0] != `` { if !sliceutil.ContainsString(filterThemes, strings.ToLower(theme.InternalName)) { inInherited := false for _, inheritedThemeName := range theme.Inherits { if sliceutil.ContainsString(filterThemes, strings.ToLower(inheritedThemeName)) { inInherited = true break } } if !inInherited { continue } } } switch listType { case `themes`: if !sliceutil.ContainsString(rv, theme.Name) { rv = append(rv, theme.InternalName) } default: for _, icon := range theme.Icons { // filter context types if len(filterIconContextTypes) > 0 && filterIconContextTypes[0] != `` { if !sliceutil.ContainsString(filterIconContextTypes, strings.ToLower(icon.Context.Name)) { continue } } // filter icon filetypes if len(filterIconFileTypes) > 0 && filterIconFileTypes[0] != `` { if !sliceutil.ContainsString(filterIconFileTypes, icon.Type) { continue } } // filter icon size contraints if filterMinSize > 0 && icon.Context.MinSize < filterMinSize { continue } if filterMaxSize > 0 && icon.Context.MaxSize > filterMaxSize { continue } // filter for scalable/non-scalable icons if filterIsScalable == `true` && icon.Context.Type != icons.IconContextScalable { continue } else if filterIsScalable == `false` && icon.Context.Type == icons.IconContextScalable { continue } var value string switch listType { case `names`: value = icon.Name case `contexts`: value = strings.ToLower(icon.Context.Name) case `display-names`: value = icon.DisplayName case `sizes`: if v, err := stringutil.ToString(icon.Context.Size); err == nil { value = v } default: util.Respond(w, http.StatusBadRequest, nil, fmt.Errorf("Unrecognized list type '%s'", listType)) return } if value != `` { if !sliceutil.ContainsString(rv, value) { rv = append(rv, value) } } } } } sort.Strings(rv) util.Respond(w, http.StatusOK, rv, nil) }) router.GET(`/api/session/icons/view/:name/size/:size`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { var iconSize int iconNames := strings.Split(params.ByName(`name`), `,`) iconSizeS := params.ByName(`size`) themeName := req.URL.Query().Get(`theme`) if themeName == `` { themeName = self.Themeset.DefaultTheme } if v, err := stringutil.ConvertToInteger(iconSizeS); err == nil { iconSize = int(v) var icon *icons.Icon switch req.URL.Query().Get(`mode`) { case `hicolor-first`: if hiColorIcon, ok := self.Themeset.FindIconViaTheme(`hicolor`, iconNames, iconSize); ok { icon = hiColorIcon } else if themeIcon, ok := self.Themeset.FindIconViaTheme(themeName, iconNames, iconSize); ok { icon = themeIcon } default: if themeIcon, ok := self.Themeset.FindIconViaTheme(themeName, iconNames, iconSize); ok { icon = themeIcon } } if icon != nil { var contentType string switch icon.Type { case `png`: contentType = `image/png` case `svg`: contentType = `image/svg+xml` default: util.Respond(w, http.StatusBadRequest, nil, fmt.Errorf("Unsupported icon type '%s'", icon.Type)) return } defer icon.Close() if data, err := ioutil.ReadAll(icon); err == nil { w.Header().Set(`Content-Type`, contentType) w.Write(data) } else { util.Respond(w, http.StatusBadRequest, nil, err) } } else { util.Respond(w, http.StatusNotFound, nil, fmt.Errorf("Could not locate icon")) } } else { util.Respond(w, http.StatusBadRequest, nil, err) } }) // router.GET(`/api/session/applications/find/:pattern`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { // }) router.PUT(`/api/session/applications/:name/launch`, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { if err := self.Applications.LaunchEntry(params.ByName(`name`)); err == nil { util.Respond(w, http.StatusAccepted, nil, nil) } else { util.Respond(w, http.StatusNotFound, nil, err) } }) return nil }