diff --git a/.gitignore b/.gitignore index 2cd84fc0..0b9ecea6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /assets +/config /build /playground /.idea diff --git a/docs/configuration.md b/docs/configuration.md index adb73c41..46e0de9e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -6,6 +6,7 @@ - [Environment variables](#environment-variables) - [Other ways of providing tokens/passwords/secrets](#other-ways-of-providing-tokenspasswordssecrets) - [Including other config files](#including-other-config-files) + - [Config schema](#config-schema) - [Server](#server) - [Document](#document) - [Branding](#branding) @@ -182,6 +183,10 @@ docker run --rm -v ./glance.yml:/app/config/glance.yml glanceapp/glance config:p This assumes that the config you want to print is in your current working directory and is named `glance.yml`. +## Config schema + +For property descriptions, validation and autocompletion of the config within your IDE, @not-first has kindly created a [schema](https://github.com/not-first/glance-schema). Massive thanks to them for this, go check it out and give them a star! + ## Server Server configuration is done through a top level `server` property. Example: @@ -997,6 +1002,7 @@ Preview: | search-engine | string | no | duckduckgo | | new-tab | boolean | no | false | | autofocus | boolean | no | false | +| target | string | no | _blank | | placeholder | string | no | Type here to search… | | bangs | array | no | | @@ -1018,6 +1024,9 @@ When set to `true`, swaps the shortcuts for showing results in the same or new t ##### `autofocus` When set to `true`, automatically focuses the search input on page load. +##### `target` +The target to use when opening the search results in a new tab. Possible values are `_blank`, `_self`, `_parent` and `_top`. + ##### `placeholder` When set, modifies the text displayed in the input field before typing. @@ -1623,7 +1632,7 @@ The title used to indicate the site. `url` -The public facing URL of a monitored service, the user will be redirected here. If `check-url` is not specified, this is used as the status check. +The URL of the monitored service, which must be reachable by Glance, and will be used as the link to go to when clicking on the title. If `check-url` is not specified, this is used as the status check. `check-url` diff --git a/docs/custom-api.md b/docs/custom-api.md index d42d1fc5..3a37df26 100644 --- a/docs/custom-api.md +++ b/docs/custom-api.md @@ -378,6 +378,7 @@ The following helper functions provided by Glance are available: - `offsetNow(offset string) time.Time`: Returns the current time with an offset. The offset can be positive or negative and must be in the format "3h" "-1h" or "2h30m10s". - `duration(str string) time.Duration`: Parses a string such as `1h`, `24h`, `5h30m`, etc into a `time.Duration`. - `parseTime(layout string, s string) time.Time`: Parses a string into time.Time. The layout must be provided in Go's [date format](https://pkg.go.dev/time#pkg-constants). You can alternatively use these values instead of the literal format: "unix", "RFC3339", "RFC3339Nano", "DateTime", "DateOnly". +- `parseLocalTime(layout string, s string) time.Time`: Same as the above, except in the absence of a timezone, it will use the local timezone instead of UTC. - `parseRelativeTime(layout string, s string) time.Time`: A shorthand for `{{ .String "date" | parseTime "rfc3339" | toRelativeTime }}`. - `add(a, b float) float`: Adds two numbers. - `sub(a, b float) float`: Subtracts two numbers. diff --git a/internal/glance/cli.go b/internal/glance/cli.go index 47bb2897..0a76e66c 100644 --- a/internal/glance/cli.go +++ b/internal/glance/cli.go @@ -136,7 +136,7 @@ func cliMountpointInfo(requestedPath string) int { fmt.Println("Path:", usage.Path) fmt.Println("FS type:", ternary(usage.Fstype == "", "unknown", usage.Fstype)) - fmt.Printf("Used percent: %.1f%%", usage.UsedPercent) + fmt.Printf("Used percent: %.1f%%\n", usage.UsedPercent) return 0 } diff --git a/internal/glance/config.go b/internal/glance/config.go index a63afff8..f48582f2 100644 --- a/internal/glance/config.go +++ b/internal/glance/config.go @@ -430,8 +430,32 @@ func isConfigStateValid(config *config) error { } if config.Server.AssetsPath != "" { - if _, err := os.Stat(config.Server.AssetsPath); os.IsNotExist(err) { - return fmt.Errorf("assets directory does not exist: %s", config.Server.AssetsPath) + if _, err := os.Stat(config.Server.AssetsPath); err == nil { + return nil + } + + workingDir, err := os.Getwd() + if err != nil { + return fmt.Errorf("directory does not exist: %v", err) + } + + // Try these paths in order: + possiblePaths := []string{ + config.Server.AssetsPath, // Original path + filepath.Join(workingDir, "config"), // Local config directory + filepath.Join(workingDir, config.Server.AssetsPath), // Relative to working dir + "/app/config", // Docker path + } + + for _, path := range possiblePaths { + if _, err := os.Stat(path); err == nil { + config.Server.AssetsPath = path + return nil + } + } + + if !strings.HasPrefix(config.Server.AssetsPath, "/app/") { + return fmt.Errorf("assets directory not found in any of the expected locations. Tried: %v", possiblePaths) } } diff --git a/internal/glance/glance.go b/internal/glance/glance.go index ab635361..8f9cda99 100644 --- a/internal/glance/glance.go +++ b/internal/glance/glance.go @@ -127,7 +127,7 @@ func (p *page) updateOutdatedWidgets() { } func (a *application) transformUserDefinedAssetPath(path string) string { - if strings.HasPrefix(path, "/assets/") { + if strings.HasPrefix(path, "/assets/") || strings.HasPrefix(path, "/config/") { return a.Config.Server.BaseURL + path } @@ -262,6 +262,7 @@ func (a *application) server() (func() error, func() error) { absAssetsPath, _ = filepath.Abs(a.Config.Server.AssetsPath) assetsFS := fileServerWithCache(http.Dir(a.Config.Server.AssetsPath), 2*time.Hour) mux.Handle("/assets/{path...}", http.StripPrefix("/assets/", assetsFS)) + mux.Handle("/config/{path...}", http.StripPrefix("/config/", assetsFS)) } server := http.Server{ diff --git a/internal/glance/static/js/main.js b/internal/glance/static/js/main.js index 41d2ae3a..dca713bb 100644 --- a/internal/glance/static/js/main.js +++ b/internal/glance/static/js/main.js @@ -104,6 +104,7 @@ function setupSearchBoxes() { for (let i = 0; i < searchWidgets.length; i++) { const widget = searchWidgets[i]; const defaultSearchUrl = widget.dataset.defaultSearchUrl; + const target = widget.dataset.target || "_blank"; const newTab = widget.dataset.newTab === "true"; const inputElement = widget.getElementsByClassName("search-input")[0]; const bangElement = widget.getElementsByClassName("search-bang")[0]; @@ -143,7 +144,7 @@ function setupSearchBoxes() { const url = searchUrlTemplate.replace("!QUERY!", encodeURIComponent(query)); if (newTab && !event.ctrlKey || !newTab && event.ctrlKey) { - window.open(url, '_blank').focus(); + window.open(url, target).focus(); } else { window.location.href = url; } diff --git a/internal/glance/templates/search.html b/internal/glance/templates/search.html index 6e8fc43d..ae981c63 100644 --- a/internal/glance/templates/search.html +++ b/internal/glance/templates/search.html @@ -3,7 +3,7 @@ {{ define "widget-content-classes" }}widget-content-frameless{{ end }} {{ define "widget-content" }} -