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
	}
}
Beispiel #3
0
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
		},
	}
}
Beispiel #4
0
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
}