Пример #1
0
func (self *Themeset) Load() error {
	themeNames := make([]string, 0)

	//  build a unique list of theme names from all ThemeDirs
	for _, iconPath := range self.ThemeDirs {
		if themeDirs, err := filepath.Glob(path.Join(iconPath, `*`)); err == nil {
			for _, themeDir := range themeDirs {
				if stat, err := os.Stat(themeDir); err == nil && stat.IsDir() {
					name := path.Base(themeDir)

					if !sliceutil.ContainsString(themeNames, name) {
						themeNames = append(themeNames, name)
					}
				}
			}
		}
	}

	//  assemble and load all themes
	for _, themeName := range themeNames {
		theme := NewTheme(themeName)
		theme.ThemeDirs = self.ThemeDirs

		if err := theme.Refresh(); err == nil {
			self.Themes = append(self.Themes, theme)

			if _, ok := self.themeIndex[theme.InternalName]; !ok {
				self.themeIndex[theme.InternalName] = theme
			}
		} else {
			continue
		}
	}

	return nil
}
Пример #2
0
func (self *Server) setupTemplateHandler(method string, route *Route) {
	method = strings.ToUpper(method)
	endpointPath := route.Path

	if self.RoutePrefix != `` {
		endpointPath = fmt.Sprintf("%s/%s", self.RoutePrefix, endpointPath)
	}

	log.Debugf("Creating endpoint: %s %s", method, endpointPath)

	self.router.Handle(method, endpointPath, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		allParams := make(map[string]interface{})
		bindingData := make(map[string]interface{})

		//  evaluate all bindings that this route is attached to
		routeBindings := self.GetBindings(req, route)

		//  populate data values for evaluated bindings
		for _, binding := range routeBindings {
			for k, v := range binding.Params {
				allParams[k] = v
			}
		}

		payload := map[string]interface{}{
			`route`: map[string]interface{}{
				`index`:   route.Index,
				`pattern`: route.Path,
				`path`:    endpointPath,
			},
			`request`: map[string]interface{}{
				`method`: req.Method,
				`url`: map[string]interface{}{
					`full`:   req.URL.String(),
					`scheme`: req.URL.Scheme,
					`host`:   req.URL.Host,
					`path`:   req.URL.Path,
					`query`:  req.URL.Query(),
				},
				`headers`: req.Header,
				`protocol`: map[string]interface{}{
					`name`:  req.Proto,
					`major`: req.ProtoMajor,
					`minor`: req.ProtoMinor,
				},
				`length`: req.ContentLength,
				`remote`: map[string]interface{}{
					`address`: req.RemoteAddr,
				},
			},
			`params`: allParams,
		}

		for key, binding := range routeBindings {
			if data, err := binding.Evaluate(req, params); err == nil {
				bindingData[key] = data
			} else {
				log.Errorf("Binding '%s' failed to evaluate: %v", key, err)
			}
		}

		payload[`data`] = bindingData

		protectedKeys := make([]string, 0)

		for k, _ := range payload {
			protectedKeys = append(protectedKeys, k)
		}

		//  add global config payload keys
		for k, v := range self.Config.Options.Payload {
			if !sliceutil.ContainsString(protectedKeys, k) {
				payload[k] = v
			}
		}

		//  add external payload keys
		for k, v := range self.Payload {
			if !sliceutil.ContainsString(protectedKeys, k) {
				payload[k] = v
			}
		}

		// add global config headers
		for name, value := range self.Config.Options.Headers {
			w.Header().Set(name, value)
		}

		// add route config headers
		for name, value := range route.Headers {
			w.Header().Set(name, value)
		}

		if err := route.Render(w, payload); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})
}
Пример #3
0
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
}