diff --git a/modules/servers/tyr/glance.nix b/modules/servers/tyr/glance.nix index 9f1ac73..aa6b26d 100644 --- a/modules/servers/tyr/glance.nix +++ b/modules/servers/tyr/glance.nix @@ -295,12 +295,47 @@ "syncthing/syncthing" ]; } + { + type = "custom-api"; + title = "GitHub Notifications"; + url = "https://api.github.com/notifications?all=true&per_page=20"; + headers = { + Authorization = "Bearer \${GITHUB_TOKEN}"; + Accept = "application/vnd.github+json"; + }; + template = '' + + ''; + } ]; } ]; } { - name = "gaming"; + name = "Gaming"; columns = [ { size = "small"; @@ -362,6 +397,185 @@ } ]; } + { + name = "SelfHosted Services"; + columns = [ + { + size = "small"; + widgets = [ + { + type = "custom-api"; + title = "Audiobookshelf"; + title-url = "\${AUDIOBOOKSHELF_URL}"; + options = { + base-url = "\${AUDIOBOOKSHELF_URL}"; + api-key = "\${AUDIOBOOKSHELF_KEY}"; + }; + cache = "5m"; + template = '' + {{ $baseURL := .Options.StringOr "base-url" "" }} + {{ $apiKey := .Options.StringOr "api-key" "" }} + + {{ define "errorMsg" }} +
+
ERROR
+ + + +
+

{{ . }}

+ {{ end }} + + {{ $bearer := printf "Bearer %s" $apiKey }} + {{ $librariesRequestURL := concat $baseURL "/api/libraries" }} + {{ $librariesResponse := newRequest $librariesRequestURL + | withHeader "Content-Type" "application/json" + | withHeader "Authorization" $bearer + | getResponse }} + + {{ if $librariesResponse.JSON.Exists "libraries" }} + {{ $all_libraries := $librariesResponse.JSON.Array "libraries" }} + + {{ $books_count := 0 }} + {{ $books_duration := 0 }} + {{ $podcasts_count := 0 }} + {{ $podcasts_duration := 0 }} + + {{ range $library := $all_libraries }} + {{ $lib_id := $library.String "id" }} + {{ $lib_request_url := concat $baseURL "/api/libraries/" $lib_id "/stats"}} + {{ $lib_stats := newRequest $lib_request_url + | withHeader "Content-Type" "application/json" + | withHeader "Authorization" $bearer + | getResponse }} + {{ $lib_type := $library.String "mediaType" }} + {{ $lib_item_count := $lib_stats.JSON.Int "totalItems" }} + {{ $lib_total_duration := $lib_stats.JSON.Int "totalDuration" }} + {{ if eq $lib_type "book" }} + {{ $books_count = add $books_count $lib_item_count }} + {{ $books_duration = add $books_duration $lib_total_duration }} + {{ else if eq $lib_type "podcast" }} + {{ $podcasts_count = add $podcasts_count $lib_item_count }} + {{ $podcasts_duration = add $podcasts_duration $lib_total_duration }} + {{ end }} + {{ end }} + + {{ $books_duration = duration (concat (printf "%d" $books_duration) "s") }} + {{ $podcasts_duration = duration (concat (printf "%d" $podcasts_duration) "s") }} + +
+
+
+
{{ $books_count }}
+
Books
+
+
+
{{ $books_duration }}
+
Duration
+
+
+
{{ $podcasts_count }}
+
Podcasts
+
+
+
{{ $podcasts_duration }}
+
Duration
+
+
+
+ {{ else }} + {{ template "errorMsg" "Could not fetch data from API!" }} + {{ end }} + ''; + } + { + type = "custom-api"; + title = "Immich Stats"; + cache = "1d"; + url = "https://immich.cronyakatsuki.xyz/api/server/statistics"; + headers = { + x-api-key = "\${IMMICH_API_KEY}"; + Accept = "application/json"; + }; + template = '' +
+
+
{{ .JSON.Int "photos" | formatNumber }}
+
PHOTOS
+
+
+
{{ .JSON.Int "videos" | formatNumber }}
+
VIDEOS
+
+
+
{{ div (.JSON.Int "usage" | toFloat) 1073741824 | toInt | formatNumber }}GB
+
USAGE
+
+
+ ''; + } + { + type = "custom-api"; + title = "Jellyfin Stats"; + base-url = "\${JELLYFIN_URL}"; + options = { + url = "\${JELLYFIN_URL}"; + key = "\${JELLYFIN_KEY}"; + }; + template = '' + {{ $url := .Options.StringOr "url" "" }} + {{ $key := .Options.StringOr "key" "" }} + + {{- if or (eq $url "") (eq $key "") -}} + +

Error: The URL or API Key was not configured in the widget options.

+ + {{- else -}} + + {{- $requestUrl := printf "%s/emby/Items/Counts?api_key=%s" $url $key -}} + {{- $jellyfinData := newRequest $requestUrl | getResponse -}} + + {{- if eq $jellyfinData.Response.StatusCode 200 -}} +
+
+ +
+
{{ $jellyfinData.JSON.Int "MovieCount" | formatNumber }}
+
Movies
+
+ +
+
{{ $jellyfinData.JSON.Int "SeriesCount" | formatNumber }}
+
TV Shows
+
+ +
+
{{ $jellyfinData.JSON.Int "EpisodeCount" | formatNumber }}
+
Episodes
+
+ +
+
{{ $jellyfinData.JSON.Int "SongCount" | formatNumber }}
+
Songs
+
+ +
+
+ {{- else -}} +

Failed: {{ $jellyfinData.Response.Status }}

+ {{- end -}} + {{- end -}} + ''; + } + ]; + } + { + size = "full"; + widgets = [ + ]; + } + ]; + } ]; }; }; diff --git a/secrets/glance.age b/secrets/glance.age index 43efa98..3b62064 100644 Binary files a/secrets/glance.age and b/secrets/glance.age differ