func CreateRectangleFromString(spec string) (*Rectangle, error) { coords := strings.SplitN(spec, `,`, 4) if len(coords) == 4 { rect := &Rectangle{} if x0, err := stringutil.ConvertToInteger(coords[0]); err == nil { rect.TopLeft.X = int(x0) } else { return nil, fmt.Errorf("Invalid x0 coordinate: %v", err) } if y0, err := stringutil.ConvertToInteger(coords[1]); err == nil { rect.TopLeft.Y = int(y0) } else { return nil, fmt.Errorf("Invalid y0 coordinate: %v", err) } if x1, err := stringutil.ConvertToInteger(coords[2]); err == nil { rect.BottomRight.X = int(x1) } else { return nil, fmt.Errorf("Invalid x1 coordinate: %v", err) } if y1, err := stringutil.ConvertToInteger(coords[3]); err == nil { rect.BottomRight.Y = int(y1) } else { return nil, fmt.Errorf("Invalid y1 coordinate: %v", err) } return rect, nil } return nil, fmt.Errorf("Expected 4 values, got %d", len(coords)) }
func CreatePointsFromString(spec string) []Point { points := make([]Point, 0) pairs := strings.Split(spec, `|`) for _, pair := range pairs { p := strings.SplitN(pair, `,`, 2) if len(p) == 2 { if x, err := stringutil.ConvertToInteger(p[0]); err == nil { if y, err := stringutil.ConvertToInteger(p[1]); err == nil { points = append(points, Point{ X: int(x), Y: int(y), }) } } } } return points }
func (self *Theme) generateThemeDefinition() error { for _, themeDir := range self.ThemeDirs { // glob for all sub-subdirs in a candidate directory: <base>/<name>/*/* // e.g.: /usr/share/icons/hicolor/apps/16 // candidateDir := path.Join(themeDir, self.InternalName) if files, err := filepath.Glob(path.Join(candidateDir, `*/*`)); err == nil { for _, filename := range files { // verify we have a directory if stat, err := os.Stat(filename); err == nil && stat.IsDir() { themeSubdir := strings.TrimPrefix(strings.TrimPrefix(filename, candidateDir), `/`) self.Directories = append(self.Directories, themeSubdir) // try to figure out the context of this subdirectory if parts := strings.SplitN(themeSubdir, `/`, 2); len(parts) == 2 { sizeParts := strings.Split(parts[1], `x`) context := IconContext{ Subdirectory: themeSubdir, Threshold: DEFAULT_ICON_CONTEXT_THRESHOLD, } if sizeParts[0] == `scalable` { context.Type = IconContextScalable context.Size = DEFAULT_ICON_CONTEXT_SCALABLE_SIZE context.MinSize = DEFAULT_ICON_CONTEXT_SCALABLE_MIN context.MaxSize = DEFAULT_ICON_CONTEXT_SCALABLE_MAX } else if v, err := stringutil.ConvertToInteger(sizeParts[0]); err == nil { context.Type = IconContextFixed context.Size = int(v) } self.Contexts[themeSubdir] = context } } } } } // if we got to this point and still don't have any directories in our list, // give up. we really, really tried.... if len(self.Directories) == 0 { return fmt.Errorf("Unable to generate theme definition") } // we're here! set spec defaults self.Inherits = []string{DEFAULT_ICONTHEME_INHERIT} return nil }
func (self *SoundctlModule) getNamedOutput(backendName string, outputName string) (types.IOutput, error) { if backend, ok := self.Backends[backendName]; ok { outputs := backend.GetOutputs() if outputName == `current` { if output, err := backend.GetCurrentOutput(); err == nil { return output, nil } else { return output, err } } else if i, err := stringutil.ConvertToInteger(outputName); err == nil && int(i) < len(outputs) { return outputs[i], nil } else { if output, ok := backend.GetOutputByName(outputName); ok { return output, nil } } return nil, fmt.Errorf("Unable to locate output '%s' on backend '%s'", outputName, backendName) } else { return nil, fmt.Errorf("Unable to locate backend '%s'", backendName) } }
func (self *Theme) refreshThemeDefinition() error { for _, themeDir := range self.ThemeDirs { themeIndexFilename := path.Join(themeDir, self.InternalName, self.IndexFile) if themeIndex, err := ini.LoadFile(themeIndexFilename); err == nil { if config, ok := themeIndex[`Icon Theme`]; ok { if v, ok := config[`Name`]; ok { self.Name = v } self.Inherits = strings.Split(config[`Inherits`], `,`) if len(self.Inherits) == 0 { self.Inherits = []string{DEFAULT_ICONTHEME_INHERIT} } self.Comment = config[`Comment`] self.Example = config[`Example`] if v, ok := config[`Hidden`]; ok { self.Hidden = (v == `true`) } if v, ok := config[`Directories`]; ok { self.Directories = strings.Split(v, `,`) for _, directory := range self.Directories { if contextConfig, ok := themeIndex[directory]; ok { context := IconContext{ Subdirectory: directory, } if v, err := stringutil.ConvertToInteger(contextConfig[`Size`]); err == nil { context.Size = int(v) } if v, ok := contextConfig[`Context`]; ok { context.Name = v } context.MinSize = context.Size context.MaxSize = context.Size context.Threshold = DEFAULT_ICON_CONTEXT_THRESHOLD switch strings.ToLower(contextConfig[`Type`]) { case `fixed`: context.Type = IconContextFixed if minSize, ok := contextConfig[`MinSize`]; ok { if v, err := stringutil.ConvertToInteger(minSize); err == nil { context.MinSize = int(v) } } if maxSize, ok := contextConfig[`MaxSize`]; ok { if v, err := stringutil.ConvertToInteger(maxSize); err == nil { context.MaxSize = int(v) } } case `scalable`: context.Type = IconContextScalable default: context.Type = IconContextThreshold if threshold, ok := contextConfig[`Threshold`]; ok { if v, err := stringutil.ConvertToInteger(threshold); err == nil { context.Threshold = int(v) } } } self.Contexts[directory] = context } } } } else { return fmt.Errorf("Cannot load theme at %s: missing [Icon Theme] section", themeIndexFilename) } self.loadedDef = true break } } if !self.loadedDef { if err := self.generateThemeDefinition(); err != nil { return fmt.Errorf("Unable to find a theme definition file for '%s' in any directories", self.InternalName) } } return nil }
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 }