diff --git a/Dockerfile b/Dockerfile index 0c4cc63..4d8cd87 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24.2-alpine3.21 AS builder +FROM golang:1.23.6-alpine3.21 AS builder WORKDIR /app COPY . /app diff --git a/README.md b/README.md index ca16c49..cf64d2f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@
What if you could see everything at a...
Install • Configuration • Discord • Sponsor
-Community widgets • Preconfigured pages • Themes
+Install • Configuration • Preconfigured pages • Themes • Discord
 @@ -195,7 +194,6 @@ services: glance: container_name: glance image: glanceapp/glance - restart: unless-stopped volumes: - ./config:/app/config ports: @@ -266,31 +264,59 @@ Glance can also be installed through the following 3rd party channels:{{ .JSON.String "text" }}
-{{ (.Subrequest "another-one").JSON.String "text" }}
-``` - -The subrequests support all the same properties as the main request, except for `subrequests` itself, so you can use `headers`, `parameters`, etc. - -`(.Subrequest "key")` can be a little cumbersome to write, so you can define a variable to make it easier: - -```yaml - template: | - {{ $anotherOne := .Subrequest "another-one" }} -{{ $anotherOne.JSON.String "text" }}
-``` - -You can also access the `.Response` property of a subrequest as you would with the main request: - -```yaml - template: | - {{ $anotherOne := .Subrequest "another-one" }} -{{ $anotherOne.Response.StatusCode }}
-``` - -> [!NOTE] -> -> Setting this property will override any query parameters that are already in the URL. - -```yaml -parameters: - param1: value1 - param2: - - item1 - - item2 -``` - ### Extension Display a widget provided by an external source (3rd party). If you want to learn more about developing extensions, checkout the [extensions documentation](extensions.md) (WIP). @@ -1417,7 +1330,6 @@ Display a widget provided by an external source (3rd party). If you want to lear | url | string | yes | | | fallback-content-type | string | no | | | allow-potentially-dangerous-html | boolean | no | false | -| headers | key & value | no | | | parameters | key & value | no | | ##### `url` @@ -1426,14 +1338,6 @@ The URL of the extension. **Note that the query gets stripped from this URL and ##### `fallback-content-type` Optionally specify the fallback content type of the extension if the URL does not return a valid `Widget-Content-Type` header. Currently the only supported value for this property is `html`. -##### `headers` -Optionally specify the headers that will be sent with the request. Example: - -```yaml -headers: - x-api-key: ${SECRET_KEY} -``` - ##### `allow-potentially-dangerous-html` Whether to allow the extension to display HTML. @@ -1950,7 +1854,7 @@ Whether to hide the swap usage. | Name | Type | Required | Default | | ---- | ---- | -------- | ------- | | cpu-temp-sensor | string | no | | -| hide-mountpoints-by-default | boolean | no | false | +| hide-mointpoints-by-default | boolean | no | false | | mountpoints | map\[string\]object | no | | ###### `cpu-temp-sensor` diff --git a/docs/custom-api.md b/docs/custom-api.md index d42d1fc..91c501b 100644 --- a/docs/custom-api.md +++ b/docs/custom-api.md @@ -226,10 +226,10 @@ JSON response: } ``` -Calculations can be performed on either ints or floats. If both numbers are ints, an int will be returned, otherwise a float will be returned. If you try to divide by zero, 0 will be returned. If you provide non-numeric values, `NaN` will be returned. +Calculations can be performed, however all numbers must be converted to floats first if they are not already: ```html -{{ .String "name" }} is {{ .Int "age" }} years old
-{{ end }} -``` - -Output: - -```html -Steve is 30 years old
-Alex is 25 years old
-John is 35 years old
-``` - -For other ways of selecting data from a JSON Lines response, have a look at the docs for [tidwall/gjson](https://github.com/tidwall/gjson/tree/master?tab=readme-ov-file#json-lines). For example, to get an array of all names, you can use the following: - -```html -{{ range .JSON.Array "..#.name" }} -{{ .String "" }}
-{{ end }} -``` - -Output: - -```html -Steve
-Alex
-John
-``` - ## Functions The following functions are available on the `JSON` object: @@ -373,31 +273,12 @@ The following helper functions provided by Glance are available: - `toFloat(i int) float`: Converts an integer to a float. - `toInt(f float) int`: Converts a float to an integer. -- `toRelativeTime(t time.Time) template.HTMLAttr`: Converts Time to a relative time such as 2h, 1d, etc which dynamically updates. **NOTE:** the value of this function should be used as an attribute in an HTML tag, e.g. ``. -- `now() time.Time`: Returns the current time. -- `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". -- `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. - `mul(a, b float) float`: Multiplies two numbers. - `div(a, b float) float`: Divides two numbers. - `formatApproxNumber(n int) string`: Formats a number to be more human-readable, e.g. 1000 -> 1k. - `formatNumber(n float|int) string`: Formats a number with commas, e.g. 1000 -> 1,000. -- `trimPrefix(prefix string, str string) string`: Trims the prefix from a string. -- `trimSuffix(suffix string, str string) string`: Trims the suffix from a string. -- `trimSpace(str string) string`: Trims whitespace from a string on both ends. -- `replaceAll(old string, new string, str string) string`: Replaces all occurrences of a string in a string. -- `replaceMatches(pattern string, replacement string, str string) string`: Replaces all occurrences of a regular expression in a string. -- `findMatch(pattern string, str string) string`: Finds the first match of a regular expression in a string. -- `findSubmatch(pattern string, str string) string`: Finds the first submatch of a regular expression in a string. -- `sortByString(key string, order string, arr []JSON): []JSON`: Sorts an array of JSON objects by a string key in either ascending or descending order. -- `sortByInt(key string, order string, arr []JSON): []JSON`: Sorts an array of JSON objects by an integer key in either ascending or descending order. -- `sortByFloat(key string, order string, arr []JSON): []JSON`: Sorts an array of JSON objects by a float key in either ascending or descending order. -- `sortByTime(key string, layout string, order string, arr []JSON): []JSON`: Sorts an array of JSON objects by a time key in either ascending or descending order. The format must be provided in Go's [date format](https://pkg.go.dev/time#pkg-constants). -- `concat(strings ...string) string`: Concatenates multiple strings together. -- `unique(key string, arr []JSON) []JSON`: Returns a unique array of JSON objects based on the given key. The following helper functions provided by Go's `text/template` are available: diff --git a/docs/extensions.md b/docs/extensions.md index b6719c1..b1fa4fa 100644 --- a/docs/extensions.md +++ b/docs/extensions.md @@ -26,9 +26,6 @@ If you know how to setup an HTTP server and a bit of HTML and CSS you're ready t ### `Widget-Title` Used to specify the title of the widget. If not provided, the widget's title will be "Extension". -### `Widget-Title-URL` -Used to specify the URL that will be opened when the widget's title is clicked. If the user has specified a `title-url` in their config, it will take precedence over this header. - ### `Widget-Content-Type` Used to specify the content type that will be returned by the extension. If not provided, the content will be shown as plain text. diff --git a/docs/images/themes/dracula.png b/docs/images/themes/dracula.png deleted file mode 100644 index 8dba452..0000000 Binary files a/docs/images/themes/dracula.png and /dev/null differ diff --git a/docs/themes.md b/docs/themes.md index fdc10b2..285b032 100644 --- a/docs/themes.md +++ b/docs/themes.md @@ -82,17 +82,6 @@ theme: negative-color: 209 88 54 ``` -### Dracula - -```yaml -theme: - background-color: 231 15 21 - primary-color: 265 89 79 - contrast-multiplier: 1.2 - positive-color: 135 94 66 - negative-color: 0 100 67 -``` - ## Light ### Catppuccin Latte diff --git a/go.mod b/go.mod index 4c19477..0ded337 100644 --- a/go.mod +++ b/go.mod @@ -1,32 +1,32 @@ module github.com/glanceapp/glance -go 1.24.2 +go 1.23.6 require ( - github.com/fsnotify/fsnotify v1.9.0 + github.com/fsnotify/fsnotify v1.8.0 github.com/mmcdole/gofeed v1.3.0 - github.com/shirou/gopsutil/v4 v4.25.3 + github.com/shirou/gopsutil/v4 v4.25.1 github.com/tidwall/gjson v1.18.0 - golang.org/x/text v0.24.0 + golang.org/x/text v0.22.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/PuerkitoBio/goquery v1.10.2 // indirect + github.com/PuerkitoBio/goquery v1.10.1 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect github.com/ebitengine/purego v0.8.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect + github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect github.com/mmcdole/goxpp v1.1.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - github.com/tklauser/go-sysconf v0.3.15 // indirect - github.com/tklauser/numcpus v0.10.0 // indirect + github.com/tklauser/go-sysconf v0.3.14 // indirect + github.com/tklauser/numcpus v0.9.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - golang.org/x/net v0.39.0 // indirect - golang.org/x/sys v0.32.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.30.0 // indirect ) diff --git a/go.sum b/go.sum index 9a79559..97af31d 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU= github.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY= -github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8= -github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -11,21 +9,16 @@ github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= -github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc= -github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= github.com/mmcdole/gofeed v1.3.0 h1:5yn+HeqlcvjMeAI4gu6T+crm7d0anY85+M+v6fIFNG4= github.com/mmcdole/gofeed v1.3.0/go.mod h1:9TGv2LcJhdXePDzxiuMnukhV2/zb6VtnZt1mS+SjkLE= github.com/mmcdole/goxpp v1.1.1 h1:RGIX+D6iQRIunGHrKqnA2+700XMCnNv0bAOOv5MUhx8= @@ -41,8 +34,6 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= -github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE= -github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -56,12 +47,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= -github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= -github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= -github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -87,8 +74,6 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -112,8 +97,6 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -134,8 +117,6 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/internal/glance/cli.go b/internal/glance/cli.go index f5a16fb..e231706 100644 --- a/internal/glance/cli.go +++ b/internal/glance/cli.go @@ -5,39 +5,23 @@ import ( "fmt" "os" "strings" - - "github.com/shirou/gopsutil/v4/disk" - "github.com/shirou/gopsutil/v4/sensors" ) type cliIntent uint8 const ( - cliIntentVersionPrint cliIntent = iota - cliIntentServe - cliIntentConfigValidate - cliIntentConfigPrint - cliIntentDiagnose - cliIntentSensorsPrint - cliIntentMountpointInfo + cliIntentServe cliIntent = iota + cliIntentConfigValidate = iota + cliIntentConfigPrint = iota + cliIntentDiagnose = iota ) type cliOptions struct { intent cliIntent configPath string - args []string } func parseCliOptions() (*cliOptions, error) { - var args []string - - args = os.Args[1:] - if len(args) == 1 && (args[0] == "--version" || args[0] == "-v" || args[0] == "version") { - return &cliOptions{ - intent: cliIntentVersionPrint, - }, nil - } - flags := flag.NewFlagSet("", flag.ExitOnError) flags.Usage = func() { fmt.Println("Usage: glance [options] command") @@ -48,8 +32,6 @@ func parseCliOptions() (*cliOptions, error) { fmt.Println("\nCommands:") fmt.Println(" config:validate Validate the config file") fmt.Println(" config:print Print the parsed config file with embedded includes") - fmt.Println(" sensors:print List all sensors") - fmt.Println(" mountpoint:info Print information about a given mountpoint path") fmt.Println(" diagnose Run diagnostic checks") } configPath := flags.String("config", "glance.yml", "Set config path") @@ -59,7 +41,7 @@ func parseCliOptions() (*cliOptions, error) { } var intent cliIntent - args = flags.Args() + var args = flags.Args() unknownCommandErr := fmt.Errorf("unknown command: %s", strings.Join(args, " ")) if len(args) == 0 { @@ -69,19 +51,11 @@ func parseCliOptions() (*cliOptions, error) { intent = cliIntentConfigValidate } else if args[0] == "config:print" { intent = cliIntentConfigPrint - } else if args[0] == "sensors:print" { - intent = cliIntentSensorsPrint } else if args[0] == "diagnose" { intent = cliIntentDiagnose } else { return nil, unknownCommandErr } - } else if len(args) == 2 { - if args[0] == "mountpoint:info" { - intent = cliIntentMountpointInfo - } else { - return nil, unknownCommandErr - } } else { return nil, unknownCommandErr } @@ -89,51 +63,5 @@ func parseCliOptions() (*cliOptions, error) { return &cliOptions{ intent: intent, configPath: *configPath, - args: args, }, nil } - -func cliSensorsPrint() int { - tempSensors, err := sensors.SensorsTemperatures() - if err != nil { - fmt.Printf("Failed to retrieve list of sensors: %v\n", err) - if warns, ok := err.(*sensors.Warnings); ok { - for _, w := range warns.List { - fmt.Printf(" - %v\n", w) - } - } - - return 1 - } - - if len(tempSensors) == 0 { - fmt.Println("No sensors found") - return 0 - } - - for _, sensor := range tempSensors { - fmt.Printf("%s: %.1f°C\n", sensor.SensorKey, sensor.Temperature) - } - - return 0 -} - -func cliMountpointInfo(requestedPath string) int { - usage, err := disk.Usage(requestedPath) - if err != nil { - fmt.Printf("Failed to retrieve info for path %s: %v\n", requestedPath, err) - if warns, ok := err.(*disk.Warnings); ok { - for _, w := range warns.List { - fmt.Printf(" - %v\n", w) - } - } - - return 1 - } - - fmt.Println("Path:", usage.Path) - fmt.Println("FS type:", ternary(usage.Fstype == "", "unknown", usage.Fstype)) - fmt.Printf("Used percent: %.1f%%\n", usage.UsedPercent) - - return 0 -} diff --git a/internal/glance/config-fields.go b/internal/glance/config-fields.go index e2ece3f..f3c836e 100644 --- a/internal/glance/config-fields.go +++ b/internal/glance/config-fields.go @@ -219,58 +219,3 @@ func (p *proxyOptionsField) UnmarshalYAML(node *yaml.Node) error { return nil } - -type queryParametersField map[string][]string - -func (q *queryParametersField) UnmarshalYAML(node *yaml.Node) error { - var decoded map[string]any - - if err := node.Decode(&decoded); err != nil { - return err - } - - *q = make(queryParametersField) - - // TODO: refactor the duplication in the switch cases if any more types get added - for key, value := range decoded { - switch v := value.(type) { - case string: - (*q)[key] = []string{v} - case int, int8, int16, int32, int64, float32, float64: - (*q)[key] = []string{fmt.Sprintf("%v", v)} - case bool: - (*q)[key] = []string{fmt.Sprintf("%t", v)} - case []string: - (*q)[key] = append((*q)[key], v...) - case []any: - for _, item := range v { - switch item := item.(type) { - case string: - (*q)[key] = append((*q)[key], item) - case int, int8, int16, int32, int64, float32, float64: - (*q)[key] = append((*q)[key], fmt.Sprintf("%v", item)) - case bool: - (*q)[key] = append((*q)[key], fmt.Sprintf("%t", item)) - default: - return fmt.Errorf("invalid query parameter value type: %T", item) - } - } - default: - return fmt.Errorf("invalid query parameter value type: %T", value) - } - } - - return nil -} - -func (q *queryParametersField) toQueryString() string { - query := url.Values{} - - for key, values := range *q { - for _, value := range values { - query.Add(key, value) - } - } - - return query.Encode() -} diff --git a/internal/glance/diagnose.go b/internal/glance/diagnose.go index 1ee1bc3..892aa5f 100644 --- a/internal/glance/diagnose.go +++ b/internal/glance/diagnose.go @@ -81,9 +81,7 @@ var diagnosticSteps = []diagnosticStep{ { name: "fetch data from Yahoo finance API", fn: func() (string, error) { - return testHttpRequestWithHeaders("GET", "https://query1.finance.yahoo.com/v8/finance/chart/NVDA", map[string]string{ - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0", - }, 200) + return testHttpRequest("GET", "https://query1.finance.yahoo.com/v8/finance/chart/NVDA", 200) }, }, { @@ -105,7 +103,7 @@ func runDiagnostic() { fmt.Println("Glance version: " + buildVersion) fmt.Println("Go version: " + runtime.Version()) fmt.Printf("Platform: %s / %s / %d CPUs\n", runtime.GOOS, runtime.GOARCH, runtime.NumCPU()) - fmt.Println("In Docker container: " + ternary(isRunningInsideDockerContainer(), "yes", "no")) + fmt.Println("In Docker container: " + boolToString(isRunningInsideDockerContainer(), "yes", "no")) fmt.Printf("\nChecking network connectivity, this may take up to %d seconds...\n\n", int(httpTestRequestTimeout.Seconds())) @@ -131,7 +129,7 @@ func runDiagnostic() { fmt.Printf( "%s %s %s| %dms\n", - ternary(step.err == nil, "✓ Can", "✗ Can't"), + boolToString(step.err == nil, "✓ Can", "✗ Can't"), step.name, extraInfo, step.elapsed.Milliseconds(), diff --git a/internal/glance/main.go b/internal/glance/main.go index 67a980c..baac315 100644 --- a/internal/glance/main.go +++ b/internal/glance/main.go @@ -18,8 +18,6 @@ func Main() int { } switch options.intent { - case cliIntentVersionPrint: - fmt.Println(buildVersion) case cliIntentServe: // remove in v0.10.0 if serveUpdateNoticeIfConfigLocationNotMigrated(options.configPath) { @@ -49,10 +47,6 @@ func Main() int { } fmt.Println(string(contents)) - case cliIntentSensorsPrint: - return cliSensorsPrint() - case cliIntentMountpointInfo: - return cliMountpointInfo(options.args[1]) case cliIntentDiagnose: runDiagnostic() } diff --git a/internal/glance/static/js/main.js b/internal/glance/static/js/main.js index 41d2ae3..dcd8946 100644 --- a/internal/glance/static/js/main.js +++ b/internal/glance/static/js/main.js @@ -649,7 +649,7 @@ function setupTruncatedElementTitles() { for (let i = 0; i < elements.length; i++) { const element = elements[i]; - if (element.getAttribute("title") === null) element.title = element.textContent; + if (element.title === "") element.title = element.textContent; } } diff --git a/internal/glance/static/main.css b/internal/glance/static/main.css index 2975a73..f686c59 100644 --- a/internal/glance/static/main.css +++ b/internal/glance/static/main.css @@ -552,10 +552,6 @@ kbd:active { z-index: 1; } -.summary::-webkit-details-marker { - display: none; -} - .details[open] .summary { margin-bottom: .8rem; } @@ -1132,7 +1128,7 @@ details[open] .summary::after { .calendar-date { padding: 0.4rem 0; - color: var(--color-text-base); + color: var(--color-text-paragraph); position: relative; border-radius: var(--border-radius); background: none; @@ -1839,7 +1835,7 @@ details[open] .summary::after { transform: translateY(calc(100% - var(--mobile-navigation-height))); left: var(--content-bounds-padding); right: var(--content-bounds-padding); - z-index: 11; + z-index: 10; background-color: var(--color-widget-background); border: 1px solid var(--color-widget-content-border); border-bottom: 0; @@ -1985,7 +1981,7 @@ details[open] .summary::after { @media (max-width: 550px) { :root { - font-size: 9.4px; + font-size: 9px; --widget-gap: 15px; --widget-content-vertical-padding: 10px; --widget-content-horizontal-padding: 10px; @@ -2038,7 +2034,6 @@ details[open] .summary::after { .color-primary { color: var(--color-primary); } .cursor-help { cursor: help; } -.rounded { border-radius: var(--border-radius); } .break-all { word-break: break-all; } .text-left { text-align: left; } .text-right { text-align: right; } diff --git a/internal/glance/templates.go b/internal/glance/templates.go index 699772d..ed83842 100644 --- a/internal/glance/templates.go +++ b/internal/glance/templates.go @@ -27,10 +27,9 @@ var globalTemplateFunctions = template.FuncMap{ "formatPrice": func(price float64) string { return intl.Sprintf("%.2f", price) }, - "formatPriceWithPrecision": func(precision int, price float64) string { - return intl.Sprintf("%."+strconv.Itoa(precision)+"f", price) + "dynamicRelativeTimeAttrs": func(t interface{ Unix() int64 }) template.HTMLAttr { + return template.HTMLAttr(`data-dynamic-relative-time="` + strconv.FormatInt(t.Unix(), 10) + `"`) }, - "dynamicRelativeTimeAttrs": dynamicRelativeTimeAttrs, "formatServerMegabytes": func(mb uint64) template.HTML { var value string var label string @@ -82,7 +81,3 @@ func formatApproxNumber(count int) string { return strconv.FormatFloat(float64(count)/1_000_000, 'f', 1, 64) + "m" } - -func dynamicRelativeTimeAttrs(t interface{ Unix() int64 }) template.HTMLAttr { - return template.HTMLAttr(`data-dynamic-relative-time="` + strconv.FormatInt(t.Unix(), 10) + `"`) -} diff --git a/internal/glance/templates/docker-containers.html b/internal/glance/templates/docker-containers.html index d84e9a6..66c79fd 100644 --- a/internal/glance/templates/docker-containers.html +++ b/internal/glance/templates/docker-containers.html @@ -1,10 +1,10 @@ {{ template "widget-base.html" . }} {{- define "widget-content" }} -