mirror of
https://github.com/prdlk/glance.git
synced 2026-08-02 17:31:40 +00:00
chore(config): remove unused widget config files
This commit is contained in:
@@ -1,16 +0,0 @@
|
|||||||
- type: extension
|
|
||||||
url: http://localhost:8181/graph/prnk28
|
|
||||||
allow-potentially-dangerous-html: true
|
|
||||||
parameters:
|
|
||||||
background-color: "#1d2025" # cell background
|
|
||||||
primary-color: "#f3afaf" # cell foreground
|
|
||||||
svg-height: 150 # height for graph svg
|
|
||||||
show-months: true # show months on the graph
|
|
||||||
show-weekdays: true # show weekdays on the graph
|
|
||||||
font-size: 9 # size of weekdays & months text on graph
|
|
||||||
|
|
||||||
# if true, it will transition the hue from background
|
|
||||||
# to primary color per the number of commits.
|
|
||||||
# otherwise it will just use the background hue for
|
|
||||||
# 0 commits and the foreground hue for all others
|
|
||||||
transition-hue: false
|
|
||||||
@@ -1,494 +0,0 @@
|
|||||||
- size: full
|
|
||||||
widgets:
|
|
||||||
- type: custom-api
|
|
||||||
title: Latest Movies
|
|
||||||
frameless: true
|
|
||||||
cache: 5m
|
|
||||||
options:
|
|
||||||
base-url: http://umbrel.tail51ffca.ts.net:8096
|
|
||||||
api-key: df9e869fec0b460bb6577302f5efd049
|
|
||||||
user-name: "prad"
|
|
||||||
library-name: "Movies"
|
|
||||||
mode: "latest"
|
|
||||||
item-count: "10"
|
|
||||||
small-column: false
|
|
||||||
show-thumbnail: true
|
|
||||||
thumbnail-aspect-ratio: "default"
|
|
||||||
template: |
|
|
||||||
{{/* Required config options */}}
|
|
||||||
{{ $baseURL := .Options.StringOr "base-url" "" }}
|
|
||||||
{{ $apiKey := .Options.StringOr "api-key" "" }}
|
|
||||||
{{ $userName := .Options.StringOr "user-name" "" }}
|
|
||||||
|
|
||||||
{{/* Required config options for "latest" mode */}}
|
|
||||||
{{ $libraryName := .Options.StringOr "library-name" "" }}
|
|
||||||
|
|
||||||
{{/* Optional config options */}}
|
|
||||||
{{ $mode := .Options.StringOr "mode" "latest" }}
|
|
||||||
{{ $itemCount := .Options.StringOr "item-count" "10" }}
|
|
||||||
{{ $mediaTypes := .Options.StringOr "media-types" "Movie,Episode,MusicAlbum" }}
|
|
||||||
{{ $thumbAspectRatio := .Options.StringOr "thumbnail-aspect-ratio" "" }}
|
|
||||||
{{ $isSmallColumn:= .Options.BoolOr "small-column" false }}
|
|
||||||
{{ $showThumbnail := .Options.BoolOr "show-thumbnail" false }}
|
|
||||||
{{ $showProgressBar := .Options.BoolOr "progress-bar" true }}
|
|
||||||
|
|
||||||
{{/* Error message template */}}
|
|
||||||
{{ define "errorMsg" }}
|
|
||||||
<div class="widget-error-header">
|
|
||||||
<div class="color-negative size-h3">ERROR</div>
|
|
||||||
<svg class="widget-error-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<p class="break-all">{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* Check required fields */}}
|
|
||||||
{{ if or (eq $baseURL "") (eq $apiKey "") (eq $userName "") (eq $mode "") (and (eq $mode "latest") (eq $libraryName "")) }}
|
|
||||||
{{ template "errorMsg" "Some required options are not set." }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Fetch user ID */}}
|
|
||||||
{{ $userID := "" }}
|
|
||||||
{{ $usersCall := newRequest (print $baseURL "/Users")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $user := $usersCall.JSON.Array "" }}
|
|
||||||
{{ if eq ($user.String "Name") $userName }}
|
|
||||||
{{ $userID = $user.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq $userID "" }}
|
|
||||||
{{ template "errorMsg" (printf "User '%s' not found." $userName) }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{ $items := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
|
|
||||||
{{/* Fetch library ID */}}
|
|
||||||
{{ $libraryID := "" }}
|
|
||||||
{{ $userViewsCall := newRequest (print $baseURL "/UserViews")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "userId" $userID
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $item := $userViewsCall.JSON.Array "Items" }}
|
|
||||||
{{ if eq ($item.String "Name") $libraryName }}
|
|
||||||
{{ $libraryID = $item.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq $libraryID "" }}
|
|
||||||
{{ template "errorMsg" (printf "Library '%s' not found." $libraryName) }}
|
|
||||||
{{ else }}
|
|
||||||
{{/* Fetch latest items */}}
|
|
||||||
{{ $latestCall := newRequest (print $baseURL "/Users/" $userID "/Items/Latest")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "ParentId" $libraryID
|
|
||||||
| withParameter "IncludeItemTypes" $mediaTypes
|
|
||||||
| withParameter "GroupItems" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $latestCall.JSON.Array "" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
|
|
||||||
{{/* Fetch next up items */}}
|
|
||||||
{{ $nextUpCall := newRequest (print $baseURL "/Shows/NextUp")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "UserId" $userID
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "EnableResumable" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $nextUpCall.JSON.Array "Items" }}
|
|
||||||
|
|
||||||
{{ else }}
|
|
||||||
{{ template "errorMsg" "Unknown mode, expected 'latest' or 'nextup'" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq (len $items) 0 }}
|
|
||||||
<p>No items found, start streaming something!</p>
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Display the item carousel */}}
|
|
||||||
<div class="carousel-container show-right-cutoff">
|
|
||||||
<div class="cards-horizontal carousel-items-container">
|
|
||||||
{{ range $n, $item := $items }}
|
|
||||||
{{/* Common item variables */}}
|
|
||||||
{{ $mediaType := $item.String "Type" }}
|
|
||||||
{{ $title := $item.String "Name" }}
|
|
||||||
{{ $itemID := $item.String "Id" }}
|
|
||||||
|
|
||||||
{{/* Media type specific variables */}}
|
|
||||||
{{ $seriesTitle := "" }}
|
|
||||||
{{ $artist := "" }}
|
|
||||||
{{ $seriesID := "" }}
|
|
||||||
{{ $season := "" }}
|
|
||||||
{{ $episode := "" }}
|
|
||||||
{{ $playPercentage := "" }}
|
|
||||||
{{ $unwatchedEpisodeCount := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mediaType "Movie" }}
|
|
||||||
{{ else if eq $mediaType "Series" }}
|
|
||||||
{{ $unwatchedEpisodeCount = $item.Int "UserData.UnplayedItemCount" }}
|
|
||||||
{{ else if eq $mediaType "Episode" }}
|
|
||||||
{{ $unwatchedEpisodeCount = 1 }}
|
|
||||||
{{ $seriesTitle = $item.String "SeriesName" }}
|
|
||||||
{{ $seriesID = $item.String "SeriesId" }}
|
|
||||||
{{ $season = $item.Int "ParentIndexNumber" }}
|
|
||||||
{{ $episode = $item.Int "IndexNumber" }}
|
|
||||||
|
|
||||||
{{ if $item.Exists "UserData.PlayedPercentage" }}
|
|
||||||
{{ $playPercentage = $item.String "UserData.PlayedPercentage" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* For latest always refer to the series not individual episodes */}}
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ $itemID = $seriesID }}
|
|
||||||
{{ $title = $seriesTitle }}
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
{{ $artist = $item.String "AlbumArtist" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ $linkURL := print $baseURL "/web/#/details?id=" $itemID }}
|
|
||||||
{{ $thumbURL := "" }}
|
|
||||||
{{ if not (eq $playPercentage "") }}
|
|
||||||
{{/* $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey "&percentPlayed=" $playPercentage */}}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<a class="card widget-content-frame" href="{{ $linkURL | safeURL }}">
|
|
||||||
{{ if $showThumbnail }}
|
|
||||||
<div style="position: relative;">
|
|
||||||
<img src="{{ $thumbURL | safeURL }}"
|
|
||||||
alt="{{ $title }} thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
class="media-server-thumbnail shrink-0"
|
|
||||||
style="
|
|
||||||
object-fit: fill;
|
|
||||||
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
{{ if eq $thumbAspectRatio "square" }}aspect-ratio: 1;
|
|
||||||
{{ else if eq $thumbAspectRatio "portrait" }}aspect-ratio: 2/3;
|
|
||||||
{{ else if eq $thumbAspectRatio "landscape" }}aspect-ratio: 16/9;
|
|
||||||
{{ else }}aspect-ratio: initial;
|
|
||||||
{{ end }}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{ if and ($showProgressBar) (not (eq $playPercentage "")) }}
|
|
||||||
<div style="
|
|
||||||
position: absolute;
|
|
||||||
bottom: 8px;
|
|
||||||
left: 8px;
|
|
||||||
right: 8px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
">
|
|
||||||
<div style="
|
|
||||||
width: {{ print $playPercentage "%" }};
|
|
||||||
height: 100%;
|
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
|
||||||
background-color: var(--color-primary)
|
|
||||||
"></div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<div class="grow padding-inline-widget margin-top-10 margin-bottom-10">
|
|
||||||
<ul class="flex flex-column justify-evenly margin-bottom-3 {{ if $isSmallColumn }}size-h6{{ end }}" style="height: 100%;">
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ if or (eq $mediaType "Series") (eq $mediaType "Episode") }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">{{ $unwatchedEpisodeCount }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary text-truncate">{{ $artist }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">S{{ $season }}E{{ $episode }}</li>
|
|
||||||
<li class="text-truncate">{{ $seriesTitle }}</li>
|
|
||||||
</ul>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
- type: custom-api
|
|
||||||
title: Up Next Movies
|
|
||||||
frameless: true
|
|
||||||
cache: 5m
|
|
||||||
options:
|
|
||||||
base-url: http://umbrel.tail51ffca.ts.net:8096
|
|
||||||
api-key: df9e869fec0b460bb6577302f5efd049
|
|
||||||
user-name: "prad"
|
|
||||||
library-name: "Movies"
|
|
||||||
mode: "nextup"
|
|
||||||
item-count: "10"
|
|
||||||
small-column: false
|
|
||||||
show-thumbnail: true
|
|
||||||
thumbnail-aspect-ratio: "default"
|
|
||||||
template: |
|
|
||||||
{{/* Required config options */}}
|
|
||||||
{{ $baseURL := .Options.StringOr "base-url" "" }}
|
|
||||||
{{ $apiKey := .Options.StringOr "api-key" "" }}
|
|
||||||
{{ $userName := .Options.StringOr "user-name" "" }}
|
|
||||||
|
|
||||||
{{/* Required config options for "latest" mode */}}
|
|
||||||
{{ $libraryName := .Options.StringOr "library-name" "" }}
|
|
||||||
|
|
||||||
{{/* Optional config options */}}
|
|
||||||
{{ $mode := .Options.StringOr "mode" "latest" }}
|
|
||||||
{{ $itemCount := .Options.StringOr "item-count" "10" }}
|
|
||||||
{{ $mediaTypes := .Options.StringOr "media-types" "Movie,Episode,MusicAlbum" }}
|
|
||||||
{{ $thumbAspectRatio := .Options.StringOr "thumbnail-aspect-ratio" "" }}
|
|
||||||
{{ $isSmallColumn:= .Options.BoolOr "small-column" false }}
|
|
||||||
{{ $showThumbnail := .Options.BoolOr "show-thumbnail" false }}
|
|
||||||
{{ $showProgressBar := .Options.BoolOr "progress-bar" true }}
|
|
||||||
|
|
||||||
{{/* Error message template */}}
|
|
||||||
{{ define "errorMsg" }}
|
|
||||||
<div class="widget-error-header">
|
|
||||||
<div class="color-negative size-h3">ERROR</div>
|
|
||||||
<svg class="widget-error-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<p class="break-all">{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* Check required fields */}}
|
|
||||||
{{ if or (eq $baseURL "") (eq $apiKey "") (eq $userName "") (eq $mode "") (and (eq $mode "latest") (eq $libraryName "")) }}
|
|
||||||
{{ template "errorMsg" "Some required options are not set." }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Fetch user ID */}}
|
|
||||||
{{ $userID := "" }}
|
|
||||||
{{ $usersCall := newRequest (print $baseURL "/Users")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $user := $usersCall.JSON.Array "" }}
|
|
||||||
{{ if eq ($user.String "Name") $userName }}
|
|
||||||
{{ $userID = $user.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq $userID "" }}
|
|
||||||
{{ template "errorMsg" (printf "User '%s' not found." $userName) }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{ $items := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
|
|
||||||
{{/* Fetch library ID */}}
|
|
||||||
{{ $libraryID := "" }}
|
|
||||||
{{ $userViewsCall := newRequest (print $baseURL "/UserViews")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "userId" $userID
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $item := $userViewsCall.JSON.Array "Items" }}
|
|
||||||
{{ if eq ($item.String "Name") $libraryName }}
|
|
||||||
{{ $libraryID = $item.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq $libraryID "" }}
|
|
||||||
{{ template "errorMsg" (printf "Library '%s' not found." $libraryName) }}
|
|
||||||
{{ else }}
|
|
||||||
{{/* Fetch latest items */}}
|
|
||||||
{{ $latestCall := newRequest (print $baseURL "/Users/" $userID "/Items/Latest")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "ParentId" $libraryID
|
|
||||||
| withParameter "IncludeItemTypes" $mediaTypes
|
|
||||||
| withParameter "GroupItems" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $latestCall.JSON.Array "" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
|
|
||||||
{{/* Fetch next up items */}}
|
|
||||||
{{ $nextUpCall := newRequest (print $baseURL "/Shows/NextUp")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "UserId" $userID
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "EnableResumable" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $nextUpCall.JSON.Array "Items" }}
|
|
||||||
|
|
||||||
{{ else }}
|
|
||||||
{{ template "errorMsg" "Unknown mode, expected 'latest' or 'nextup'" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq (len $items) 0 }}
|
|
||||||
<p>No items found, start streaming something!</p>
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Display the item carousel */}}
|
|
||||||
<div class="carousel-container show-right-cutoff">
|
|
||||||
<div class="cards-horizontal carousel-items-container">
|
|
||||||
{{ range $n, $item := $items }}
|
|
||||||
{{/* Common item variables */}}
|
|
||||||
{{ $mediaType := $item.String "Type" }}
|
|
||||||
{{ $title := $item.String "Name" }}
|
|
||||||
{{ $itemID := $item.String "Id" }}
|
|
||||||
|
|
||||||
{{/* Media type specific variables */}}
|
|
||||||
{{ $seriesTitle := "" }}
|
|
||||||
{{ $artist := "" }}
|
|
||||||
{{ $seriesID := "" }}
|
|
||||||
{{ $season := "" }}
|
|
||||||
{{ $episode := "" }}
|
|
||||||
{{ $playPercentage := "" }}
|
|
||||||
{{ $unwatchedEpisodeCount := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mediaType "Movie" }}
|
|
||||||
{{ else if eq $mediaType "Series" }}
|
|
||||||
{{ $unwatchedEpisodeCount = $item.Int "UserData.UnplayedItemCount" }}
|
|
||||||
{{ else if eq $mediaType "Episode" }}
|
|
||||||
{{ $unwatchedEpisodeCount = 1 }}
|
|
||||||
{{ $seriesTitle = $item.String "SeriesName" }}
|
|
||||||
{{ $seriesID = $item.String "SeriesId" }}
|
|
||||||
{{ $season = $item.Int "ParentIndexNumber" }}
|
|
||||||
{{ $episode = $item.Int "IndexNumber" }}
|
|
||||||
|
|
||||||
{{ if $item.Exists "UserData.PlayedPercentage" }}
|
|
||||||
{{ $playPercentage = $item.String "UserData.PlayedPercentage" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* For latest always refer to the series not individual episodes */}}
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ $itemID = $seriesID }}
|
|
||||||
{{ $title = $seriesTitle }}
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
{{ $artist = $item.String "AlbumArtist" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ $linkURL := print $baseURL "/web/#/details?id=" $itemID }}
|
|
||||||
{{ $thumbURL := "" }}
|
|
||||||
{{ if not (eq $playPercentage "") }}
|
|
||||||
{{/* $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey "&percentPlayed=" $playPercentage */}}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<a class="card widget-content-frame" href="{{ $linkURL | safeURL }}">
|
|
||||||
{{ if $showThumbnail }}
|
|
||||||
<div style="position: relative;">
|
|
||||||
<img src="{{ $thumbURL | safeURL }}"
|
|
||||||
alt="{{ $title }} thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
class="media-server-thumbnail shrink-0"
|
|
||||||
style="
|
|
||||||
object-fit: fill;
|
|
||||||
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
{{ if eq $thumbAspectRatio "square" }}aspect-ratio: 1;
|
|
||||||
{{ else if eq $thumbAspectRatio "portrait" }}aspect-ratio: 2/3;
|
|
||||||
{{ else if eq $thumbAspectRatio "landscape" }}aspect-ratio: 16/9;
|
|
||||||
{{ else }}aspect-ratio: initial;
|
|
||||||
{{ end }}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{ if and ($showProgressBar) (not (eq $playPercentage "")) }}
|
|
||||||
<div style="
|
|
||||||
position: absolute;
|
|
||||||
bottom: 8px;
|
|
||||||
left: 8px;
|
|
||||||
right: 8px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
">
|
|
||||||
<div style="
|
|
||||||
width: {{ print $playPercentage "%" }};
|
|
||||||
height: 100%;
|
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
|
||||||
background-color: var(--color-primary)
|
|
||||||
"></div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<div class="grow padding-inline-widget margin-top-10 margin-bottom-10">
|
|
||||||
<ul class="flex flex-column justify-evenly margin-bottom-3 {{ if $isSmallColumn }}size-h6{{ end }}" style="height: 100%;">
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ if or (eq $mediaType "Series") (eq $mediaType "Episode") }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">{{ $unwatchedEpisodeCount }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary text-truncate">{{ $artist }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">S{{ $season }}E{{ $episode }}</li>
|
|
||||||
<li class="text-truncate">{{ $seriesTitle }}</li>
|
|
||||||
</ul>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,494 +0,0 @@
|
|||||||
- size: full
|
|
||||||
widgets:
|
|
||||||
- type: custom-api
|
|
||||||
title: Latest TV
|
|
||||||
frameless: true
|
|
||||||
cache: 5m
|
|
||||||
options:
|
|
||||||
base-url: http://umbrel.tail51ffca.ts.net:8096
|
|
||||||
api-key: df9e869fec0b460bb6577302f5efd049
|
|
||||||
user-name: "prad"
|
|
||||||
library-name: "TV"
|
|
||||||
mode: "latest"
|
|
||||||
item-count: "10"
|
|
||||||
small-column: false
|
|
||||||
show-thumbnail: true
|
|
||||||
thumbnail-aspect-ratio: "default"
|
|
||||||
template: |
|
|
||||||
{{/* Required config options */}}
|
|
||||||
{{ $baseURL := .Options.StringOr "base-url" "" }}
|
|
||||||
{{ $apiKey := .Options.StringOr "api-key" "" }}
|
|
||||||
{{ $userName := .Options.StringOr "user-name" "" }}
|
|
||||||
|
|
||||||
{{/* Required config options for "latest" mode */}}
|
|
||||||
{{ $libraryName := .Options.StringOr "library-name" "" }}
|
|
||||||
|
|
||||||
{{/* Optional config options */}}
|
|
||||||
{{ $mode := .Options.StringOr "mode" "latest" }}
|
|
||||||
{{ $itemCount := .Options.StringOr "item-count" "10" }}
|
|
||||||
{{ $mediaTypes := .Options.StringOr "media-types" "Movie,Episode,MusicAlbum" }}
|
|
||||||
{{ $thumbAspectRatio := .Options.StringOr "thumbnail-aspect-ratio" "" }}
|
|
||||||
{{ $isSmallColumn:= .Options.BoolOr "small-column" false }}
|
|
||||||
{{ $showThumbnail := .Options.BoolOr "show-thumbnail" false }}
|
|
||||||
{{ $showProgressBar := .Options.BoolOr "progress-bar" true }}
|
|
||||||
|
|
||||||
{{/* Error message template */}}
|
|
||||||
{{ define "errorMsg" }}
|
|
||||||
<div class="widget-error-header">
|
|
||||||
<div class="color-negative size-h3">ERROR</div>
|
|
||||||
<svg class="widget-error-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<p class="break-all">{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* Check required fields */}}
|
|
||||||
{{ if or (eq $baseURL "") (eq $apiKey "") (eq $userName "") (eq $mode "") (and (eq $mode "latest") (eq $libraryName "")) }}
|
|
||||||
{{ template "errorMsg" "Some required options are not set." }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Fetch user ID */}}
|
|
||||||
{{ $userID := "" }}
|
|
||||||
{{ $usersCall := newRequest (print $baseURL "/Users")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $user := $usersCall.JSON.Array "" }}
|
|
||||||
{{ if eq ($user.String "Name") $userName }}
|
|
||||||
{{ $userID = $user.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq $userID "" }}
|
|
||||||
{{ template "errorMsg" (printf "User '%s' not found." $userName) }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{ $items := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
|
|
||||||
{{/* Fetch library ID */}}
|
|
||||||
{{ $libraryID := "" }}
|
|
||||||
{{ $userViewsCall := newRequest (print $baseURL "/UserViews")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "userId" $userID
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $item := $userViewsCall.JSON.Array "Items" }}
|
|
||||||
{{ if eq ($item.String "Name") $libraryName }}
|
|
||||||
{{ $libraryID = $item.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq $libraryID "" }}
|
|
||||||
{{ template "errorMsg" (printf "Library '%s' not found." $libraryName) }}
|
|
||||||
{{ else }}
|
|
||||||
{{/* Fetch latest items */}}
|
|
||||||
{{ $latestCall := newRequest (print $baseURL "/Users/" $userID "/Items/Latest")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "ParentId" $libraryID
|
|
||||||
| withParameter "IncludeItemTypes" $mediaTypes
|
|
||||||
| withParameter "GroupItems" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $latestCall.JSON.Array "" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
|
|
||||||
{{/* Fetch next up items */}}
|
|
||||||
{{ $nextUpCall := newRequest (print $baseURL "/Shows/NextUp")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "UserId" $userID
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "EnableResumable" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $nextUpCall.JSON.Array "Items" }}
|
|
||||||
|
|
||||||
{{ else }}
|
|
||||||
{{ template "errorMsg" "Unknown mode, expected 'latest' or 'nextup'" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq (len $items) 0 }}
|
|
||||||
<p>No items found, start streaming something!</p>
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Display the item carousel */}}
|
|
||||||
<div class="carousel-container show-right-cutoff">
|
|
||||||
<div class="cards-horizontal carousel-items-container">
|
|
||||||
{{ range $n, $item := $items }}
|
|
||||||
{{/* Common item variables */}}
|
|
||||||
{{ $mediaType := $item.String "Type" }}
|
|
||||||
{{ $title := $item.String "Name" }}
|
|
||||||
{{ $itemID := $item.String "Id" }}
|
|
||||||
|
|
||||||
{{/* Media type specific variables */}}
|
|
||||||
{{ $seriesTitle := "" }}
|
|
||||||
{{ $artist := "" }}
|
|
||||||
{{ $seriesID := "" }}
|
|
||||||
{{ $season := "" }}
|
|
||||||
{{ $episode := "" }}
|
|
||||||
{{ $playPercentage := "" }}
|
|
||||||
{{ $unwatchedEpisodeCount := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mediaType "Movie" }}
|
|
||||||
{{ else if eq $mediaType "Series" }}
|
|
||||||
{{ $unwatchedEpisodeCount = $item.Int "UserData.UnplayedItemCount" }}
|
|
||||||
{{ else if eq $mediaType "Episode" }}
|
|
||||||
{{ $unwatchedEpisodeCount = 1 }}
|
|
||||||
{{ $seriesTitle = $item.String "SeriesName" }}
|
|
||||||
{{ $seriesID = $item.String "SeriesId" }}
|
|
||||||
{{ $season = $item.Int "ParentIndexNumber" }}
|
|
||||||
{{ $episode = $item.Int "IndexNumber" }}
|
|
||||||
|
|
||||||
{{ if $item.Exists "UserData.PlayedPercentage" }}
|
|
||||||
{{ $playPercentage = $item.String "UserData.PlayedPercentage" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* For latest always refer to the series not individual episodes */}}
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ $itemID = $seriesID }}
|
|
||||||
{{ $title = $seriesTitle }}
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
{{ $artist = $item.String "AlbumArtist" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ $linkURL := print $baseURL "/web/#/details?id=" $itemID }}
|
|
||||||
{{ $thumbURL := "" }}
|
|
||||||
{{ if not (eq $playPercentage "") }}
|
|
||||||
{{/* $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey "&percentPlayed=" $playPercentage */}}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<a class="card widget-content-frame" href="{{ $linkURL | safeURL }}">
|
|
||||||
{{ if $showThumbnail }}
|
|
||||||
<div style="position: relative;">
|
|
||||||
<img src="{{ $thumbURL | safeURL }}"
|
|
||||||
alt="{{ $title }} thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
class="media-server-thumbnail shrink-0"
|
|
||||||
style="
|
|
||||||
object-fit: fill;
|
|
||||||
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
{{ if eq $thumbAspectRatio "square" }}aspect-ratio: 1;
|
|
||||||
{{ else if eq $thumbAspectRatio "portrait" }}aspect-ratio: 2/3;
|
|
||||||
{{ else if eq $thumbAspectRatio "landscape" }}aspect-ratio: 16/9;
|
|
||||||
{{ else }}aspect-ratio: initial;
|
|
||||||
{{ end }}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{ if and ($showProgressBar) (not (eq $playPercentage "")) }}
|
|
||||||
<div style="
|
|
||||||
position: absolute;
|
|
||||||
bottom: 8px;
|
|
||||||
left: 8px;
|
|
||||||
right: 8px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
">
|
|
||||||
<div style="
|
|
||||||
width: {{ print $playPercentage "%" }};
|
|
||||||
height: 100%;
|
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
|
||||||
background-color: var(--color-primary)
|
|
||||||
"></div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<div class="grow padding-inline-widget margin-top-10 margin-bottom-10">
|
|
||||||
<ul class="flex flex-column justify-evenly margin-bottom-3 {{ if $isSmallColumn }}size-h6{{ end }}" style="height: 100%;">
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ if or (eq $mediaType "Series") (eq $mediaType "Episode") }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">{{ $unwatchedEpisodeCount }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary text-truncate">{{ $artist }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">S{{ $season }}E{{ $episode }}</li>
|
|
||||||
<li class="text-truncate">{{ $seriesTitle }}</li>
|
|
||||||
</ul>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
- type: custom-api
|
|
||||||
title: Up Next TV
|
|
||||||
frameless: true
|
|
||||||
cache: 5m
|
|
||||||
options:
|
|
||||||
base-url: http://umbrel.tail51ffca.ts.net:8096
|
|
||||||
api-key: df9e869fec0b460bb6577302f5efd049
|
|
||||||
user-name: "prad"
|
|
||||||
library-name: "TV"
|
|
||||||
mode: "nextup"
|
|
||||||
item-count: "10"
|
|
||||||
small-column: false
|
|
||||||
show-thumbnail: true
|
|
||||||
thumbnail-aspect-ratio: "default"
|
|
||||||
template: |
|
|
||||||
{{/* Required config options */}}
|
|
||||||
{{ $baseURL := .Options.StringOr "base-url" "" }}
|
|
||||||
{{ $apiKey := .Options.StringOr "api-key" "" }}
|
|
||||||
{{ $userName := .Options.StringOr "user-name" "" }}
|
|
||||||
|
|
||||||
{{/* Required config options for "latest" mode */}}
|
|
||||||
{{ $libraryName := .Options.StringOr "library-name" "" }}
|
|
||||||
|
|
||||||
{{/* Optional config options */}}
|
|
||||||
{{ $mode := .Options.StringOr "mode" "latest" }}
|
|
||||||
{{ $itemCount := .Options.StringOr "item-count" "10" }}
|
|
||||||
{{ $mediaTypes := .Options.StringOr "media-types" "Movie,Episode,MusicAlbum" }}
|
|
||||||
{{ $thumbAspectRatio := .Options.StringOr "thumbnail-aspect-ratio" "" }}
|
|
||||||
{{ $isSmallColumn:= .Options.BoolOr "small-column" false }}
|
|
||||||
{{ $showThumbnail := .Options.BoolOr "show-thumbnail" false }}
|
|
||||||
{{ $showProgressBar := .Options.BoolOr "progress-bar" true }}
|
|
||||||
|
|
||||||
{{/* Error message template */}}
|
|
||||||
{{ define "errorMsg" }}
|
|
||||||
<div class="widget-error-header">
|
|
||||||
<div class="color-negative size-h3">ERROR</div>
|
|
||||||
<svg class="widget-error-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<p class="break-all">{{ . }}</p>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* Check required fields */}}
|
|
||||||
{{ if or (eq $baseURL "") (eq $apiKey "") (eq $userName "") (eq $mode "") (and (eq $mode "latest") (eq $libraryName "")) }}
|
|
||||||
{{ template "errorMsg" "Some required options are not set." }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Fetch user ID */}}
|
|
||||||
{{ $userID := "" }}
|
|
||||||
{{ $usersCall := newRequest (print $baseURL "/Users")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $user := $usersCall.JSON.Array "" }}
|
|
||||||
{{ if eq ($user.String "Name") $userName }}
|
|
||||||
{{ $userID = $user.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ if eq $userID "" }}
|
|
||||||
{{ template "errorMsg" (printf "User '%s' not found." $userName) }}
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{ $items := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
|
|
||||||
{{/* Fetch library ID */}}
|
|
||||||
{{ $libraryID := "" }}
|
|
||||||
{{ $userViewsCall := newRequest (print $baseURL "/UserViews")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "userId" $userID
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
|
|
||||||
{{ range $i, $item := $userViewsCall.JSON.Array "Items" }}
|
|
||||||
{{ if eq ($item.String "Name") $libraryName }}
|
|
||||||
{{ $libraryID = $item.String "Id" }}
|
|
||||||
{{ break }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq $libraryID "" }}
|
|
||||||
{{ template "errorMsg" (printf "Library '%s' not found." $libraryName) }}
|
|
||||||
{{ else }}
|
|
||||||
{{/* Fetch latest items */}}
|
|
||||||
{{ $latestCall := newRequest (print $baseURL "/Users/" $userID "/Items/Latest")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "ParentId" $libraryID
|
|
||||||
| withParameter "IncludeItemTypes" $mediaTypes
|
|
||||||
| withParameter "GroupItems" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $latestCall.JSON.Array "" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
|
|
||||||
{{/* Fetch next up items */}}
|
|
||||||
{{ $nextUpCall := newRequest (print $baseURL "/Shows/NextUp")
|
|
||||||
| withParameter "api_key" $apiKey
|
|
||||||
| withParameter "UserId" $userID
|
|
||||||
| withParameter "Limit" $itemCount
|
|
||||||
| withParameter "EnableResumable" "true"
|
|
||||||
| withHeader "Accept" "application/json"
|
|
||||||
| getResponse }}
|
|
||||||
{{ $items = $nextUpCall.JSON.Array "Items" }}
|
|
||||||
|
|
||||||
{{ else }}
|
|
||||||
{{ template "errorMsg" "Unknown mode, expected 'latest' or 'nextup'" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if eq (len $items) 0 }}
|
|
||||||
<p>No items found, start streaming something!</p>
|
|
||||||
{{ else }}
|
|
||||||
|
|
||||||
{{/* Display the item carousel */}}
|
|
||||||
<div class="carousel-container show-right-cutoff">
|
|
||||||
<div class="cards-horizontal carousel-items-container">
|
|
||||||
{{ range $n, $item := $items }}
|
|
||||||
{{/* Common item variables */}}
|
|
||||||
{{ $mediaType := $item.String "Type" }}
|
|
||||||
{{ $title := $item.String "Name" }}
|
|
||||||
{{ $itemID := $item.String "Id" }}
|
|
||||||
|
|
||||||
{{/* Media type specific variables */}}
|
|
||||||
{{ $seriesTitle := "" }}
|
|
||||||
{{ $artist := "" }}
|
|
||||||
{{ $seriesID := "" }}
|
|
||||||
{{ $season := "" }}
|
|
||||||
{{ $episode := "" }}
|
|
||||||
{{ $playPercentage := "" }}
|
|
||||||
{{ $unwatchedEpisodeCount := "" }}
|
|
||||||
|
|
||||||
{{ if eq $mediaType "Movie" }}
|
|
||||||
{{ else if eq $mediaType "Series" }}
|
|
||||||
{{ $unwatchedEpisodeCount = $item.Int "UserData.UnplayedItemCount" }}
|
|
||||||
{{ else if eq $mediaType "Episode" }}
|
|
||||||
{{ $unwatchedEpisodeCount = 1 }}
|
|
||||||
{{ $seriesTitle = $item.String "SeriesName" }}
|
|
||||||
{{ $seriesID = $item.String "SeriesId" }}
|
|
||||||
{{ $season = $item.Int "ParentIndexNumber" }}
|
|
||||||
{{ $episode = $item.Int "IndexNumber" }}
|
|
||||||
|
|
||||||
{{ if $item.Exists "UserData.PlayedPercentage" }}
|
|
||||||
{{ $playPercentage = $item.String "UserData.PlayedPercentage" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{/* For latest always refer to the series not individual episodes */}}
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ $itemID = $seriesID }}
|
|
||||||
{{ $title = $seriesTitle }}
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
{{ $artist = $item.String "AlbumArtist" }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ $linkURL := print $baseURL "/web/#/details?id=" $itemID }}
|
|
||||||
{{ $thumbURL := "" }}
|
|
||||||
{{ if not (eq $playPercentage "") }}
|
|
||||||
{{/* $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey "&percentPlayed=" $playPercentage */}}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $thumbURL = concat $baseURL "/Items/" $itemID "/Images/Primary?api_key=" $apiKey }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<a class="card widget-content-frame" href="{{ $linkURL | safeURL }}">
|
|
||||||
{{ if $showThumbnail }}
|
|
||||||
<div style="position: relative;">
|
|
||||||
<img src="{{ $thumbURL | safeURL }}"
|
|
||||||
alt="{{ $title }} thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
class="media-server-thumbnail shrink-0"
|
|
||||||
style="
|
|
||||||
object-fit: fill;
|
|
||||||
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
{{ if eq $thumbAspectRatio "square" }}aspect-ratio: 1;
|
|
||||||
{{ else if eq $thumbAspectRatio "portrait" }}aspect-ratio: 2/3;
|
|
||||||
{{ else if eq $thumbAspectRatio "landscape" }}aspect-ratio: 16/9;
|
|
||||||
{{ else }}aspect-ratio: initial;
|
|
||||||
{{ end }}
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
|
|
||||||
{{ if and ($showProgressBar) (not (eq $playPercentage "")) }}
|
|
||||||
<div style="
|
|
||||||
position: absolute;
|
|
||||||
bottom: 8px;
|
|
||||||
left: 8px;
|
|
||||||
right: 8px;
|
|
||||||
height: 6px;
|
|
||||||
border-radius: var(--border-radius);
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
">
|
|
||||||
<div style="
|
|
||||||
width: {{ print $playPercentage "%" }};
|
|
||||||
height: 100%;
|
|
||||||
border-radius: var(--border-radius) 0 0 var(--border-radius);
|
|
||||||
background-color: var(--color-primary)
|
|
||||||
"></div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<div class="grow padding-inline-widget margin-top-10 margin-bottom-10">
|
|
||||||
<ul class="flex flex-column justify-evenly margin-bottom-3 {{ if $isSmallColumn }}size-h6{{ end }}" style="height: 100%;">
|
|
||||||
{{ if eq $mode "latest" }}
|
|
||||||
{{ if or (eq $mediaType "Series") (eq $mediaType "Episode") }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">{{ $unwatchedEpisodeCount }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else if eq $mediaType "MusicAlbum" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary text-truncate">{{ $artist }}</li>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
{{ else if eq $mode "nextup" }}
|
|
||||||
<ul class="list-horizontal-text flex-nowrap">
|
|
||||||
<li class="color-primary shrink-0">S{{ $season }}E{{ $episode }}</li>
|
|
||||||
<li class="text-truncate">{{ $seriesTitle }}</li>
|
|
||||||
</ul>
|
|
||||||
<li class="text-truncate">{{ $title }}</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# Masthead + markets ticker — the newspaper banner
|
|
||||||
- type: html
|
|
||||||
source: |
|
|
||||||
<div class="masthead">
|
|
||||||
<div class="masthead-rule"></div>
|
|
||||||
<div class="masthead-title">The Daily Glance</div>
|
|
||||||
<div class="masthead-sub">Tech · Markets · Crypto</div>
|
|
||||||
<div class="masthead-rule"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
- type: markets
|
|
||||||
hide-header: true
|
|
||||||
markets:
|
|
||||||
- symbol: BTC-USD
|
|
||||||
name: Bitcoin
|
|
||||||
- symbol: ETH-USD
|
|
||||||
name: Ethereum
|
|
||||||
- symbol: MAGS
|
|
||||||
name: Mag7
|
|
||||||
- symbol: QQQ
|
|
||||||
name: Nasdaq
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
- type: custom-api
|
|
||||||
title: Personal Events
|
|
||||||
cache: 15m
|
|
||||||
url: http://glances-ical-api:8076/events
|
|
||||||
parameters:
|
|
||||||
url: https://calendar.google.com/calendar/ical/prnk28%40gmail.com/public/basic.ics
|
|
||||||
limit: 5
|
|
||||||
template: |
|
|
||||||
{{ $events := .JSON.Array "events" }}
|
|
||||||
{{ $count := len $events }}
|
|
||||||
{{ $limit := 3 }} <!-- how many upcoming to show before collapse -->
|
|
||||||
|
|
||||||
{{ if eq $count 0 }}
|
|
||||||
<div style="padding:8px 10px; border-radius:10px; background:var(--surface-2);">
|
|
||||||
No entries found.
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<!-- 1) Ongoing first (never collapsible) -->
|
|
||||||
<ul class="list list-gap-10">
|
|
||||||
{{ range $i, $e := $events }}
|
|
||||||
{{ $ongoing := $e.Bool "ongoing" }}
|
|
||||||
{{ if $ongoing }}
|
|
||||||
{{ $start := $e.String "start" | parseTime "rfc3339" }}
|
|
||||||
{{ $end := $e.String "end" | parseTime "rfc3339" }}
|
|
||||||
{{ $name := $e.String "name" }}
|
|
||||||
{{ $url := $e.String "url" }}
|
|
||||||
<li>
|
|
||||||
<div class="flex items-center justify-between gap-10">
|
|
||||||
<!-- Left: name (highlight) + absolute date -->
|
|
||||||
<div>
|
|
||||||
{{ if $url }}
|
|
||||||
<a class="size-h3 color-highlight block text-truncate" href="{{ $url }}" target="_blank" rel="noreferrer" title="{{ $name }}">{{ $name }}</a>
|
|
||||||
{{ else }}
|
|
||||||
<span class="size-h3 color-highlight block text-truncate" title="{{ $name }}">{{ $name }}</span>
|
|
||||||
{{ end }}
|
|
||||||
<div style="font-size:.85em;">{{ $start | formatTime "Mon, 02 Jan 2006" }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- Right: relative time until END -->
|
|
||||||
<div class="size-h3 color-primary" style="white-space:nowrap;">
|
|
||||||
ends <span {{ $end | toRelativeTime }}></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- 2) Upcoming, collapsible after $limit -->
|
|
||||||
{{ $shown := 0 }}
|
|
||||||
<ul class="list list-gap-10 collapsible-container" data-collapse-after="{{ $limit }}">
|
|
||||||
{{ range $i, $e := $events }}
|
|
||||||
{{ $ongoing := $e.Bool "ongoing" }}
|
|
||||||
{{ if not $ongoing }}
|
|
||||||
{{ $start := $e.String "start" | parseTime "rfc3339" }}
|
|
||||||
{{ $name := $e.String "name" }}
|
|
||||||
{{ $url := $e.String "url" }}
|
|
||||||
<li {{ if ge $shown $limit }}class="collapsible-item"{{ end }}>
|
|
||||||
<div class="flex items-center justify-between gap-10">
|
|
||||||
<!-- Left: name (highlight) + absolute date -->
|
|
||||||
<div>
|
|
||||||
{{ if $url }}
|
|
||||||
<a class="size-h3 color-highlight block text-truncate" href="{{ $url }}" target="_blank" rel="noreferrer" title="{{ $name }}">{{ $name }}</a>
|
|
||||||
{{ else }}
|
|
||||||
<span class="size-h3 color-highlight block text-truncate" title="{{ $name }}">{{ $name }}</span>
|
|
||||||
{{ end }}
|
|
||||||
<div style="font-size:.85em;">{{ $start | formatTime "Mon, 02 Jan 2006" }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- Right: relative time until START -->
|
|
||||||
<div class="size-h3 color-primary" style="white-space:nowrap;" {{ $start | toRelativeTime }}></div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{ $shown = add $shown 1 }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
- type: custom-api
|
|
||||||
title: Work Schedule
|
|
||||||
cache: 15m
|
|
||||||
url: http://glances-ical-api:8076/events
|
|
||||||
parameters:
|
|
||||||
url: https://calendar.google.com/calendar/ical/prad%40sonr.io/public/basic.ics
|
|
||||||
limit: 5
|
|
||||||
template: |
|
|
||||||
{{ $events := .JSON.Array "events" }}
|
|
||||||
{{ $count := len $events }}
|
|
||||||
{{ $limit := 3 }} <!-- how many upcoming to show before collapse -->
|
|
||||||
|
|
||||||
{{ if eq $count 0 }}
|
|
||||||
<div style="padding:8px 10px; border-radius:10px; background:var(--surface-2);">
|
|
||||||
No entries found.
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<!-- 1) Ongoing first (never collapsible) -->
|
|
||||||
<ul class="list list-gap-10">
|
|
||||||
{{ range $i, $e := $events }}
|
|
||||||
{{ $ongoing := $e.Bool "ongoing" }}
|
|
||||||
{{ if $ongoing }}
|
|
||||||
{{ $start := $e.String "start" | parseTime "rfc3339" }}
|
|
||||||
{{ $end := $e.String "end" | parseTime "rfc3339" }}
|
|
||||||
{{ $name := $e.String "name" }}
|
|
||||||
{{ $url := $e.String "url" }}
|
|
||||||
<li>
|
|
||||||
<div class="flex items-center justify-between gap-10">
|
|
||||||
<!-- Left: name (highlight) + absolute date -->
|
|
||||||
<div>
|
|
||||||
{{ if $url }}
|
|
||||||
<a class="size-h3 color-highlight block text-truncate" href="{{ $url }}" target="_blank" rel="noreferrer" title="{{ $name }}">{{ $name }}</a>
|
|
||||||
{{ else }}
|
|
||||||
<span class="size-h3 color-highlight block text-truncate" title="{{ $name }}">{{ $name }}</span>
|
|
||||||
{{ end }}
|
|
||||||
<div style="font-size:.85em;">{{ $start | formatTime "Mon, 02 Jan 2006" }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- Right: relative time until END -->
|
|
||||||
<div class="size-h3 color-primary" style="white-space:nowrap;">
|
|
||||||
ends <span {{ $end | toRelativeTime }}></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<!-- 2) Upcoming, collapsible after $limit -->
|
|
||||||
{{ $shown := 0 }}
|
|
||||||
<ul class="list list-gap-10 collapsible-container" data-collapse-after="{{ $limit }}">
|
|
||||||
{{ range $i, $e := $events }}
|
|
||||||
{{ $ongoing := $e.Bool "ongoing" }}
|
|
||||||
{{ if not $ongoing }}
|
|
||||||
{{ $start := $e.String "start" | parseTime "rfc3339" }}
|
|
||||||
{{ $name := $e.String "name" }}
|
|
||||||
{{ $url := $e.String "url" }}
|
|
||||||
<li {{ if ge $shown $limit }}class="collapsible-item"{{ end }}>
|
|
||||||
<div class="flex items-center justify-between gap-10">
|
|
||||||
<!-- Left: name (highlight) + absolute date -->
|
|
||||||
<div>
|
|
||||||
{{ if $url }}
|
|
||||||
<a class="size-h3 color-highlight block text-truncate" href="{{ $url }}" target="_blank" rel="noreferrer" title="{{ $name }}">{{ $name }}</a>
|
|
||||||
{{ else }}
|
|
||||||
<span class="size-h3 color-highlight block text-truncate" title="{{ $name }}">{{ $name }}</span>
|
|
||||||
{{ end }}
|
|
||||||
<div style="font-size:.85em;">{{ $start | formatTime "Mon, 02 Jan 2006" }}</div>
|
|
||||||
</div>
|
|
||||||
<!-- Right: relative time until START -->
|
|
||||||
<div class="size-h3 color-primary" style="white-space:nowrap;" {{ $start | toRelativeTime }}></div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{ $shown = add $shown 1 }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# Macro rates box (St. Louis Fed / FRED). One shared template, three series.
|
|
||||||
# ponytail: template was copy-pasted 4x across the config — collapsed to one anchor.
|
|
||||||
define:
|
|
||||||
fred-template: &fred-template |
|
|
||||||
{{ $latest := .JSON.Float "observations.0.value" }}
|
|
||||||
{{ $previous := .JSON.Float "observations.1.value" }}
|
|
||||||
{{ $lastObserve := .JSON.String "observations.0.date" }}
|
|
||||||
{{ $change := sub $latest $previous }}
|
|
||||||
<div class="flex justify-between items-center gap-15">
|
|
||||||
<div class="min-width-0">
|
|
||||||
<a class="size-h3 block color-highlight" href="https://fred.stlouisfed.org/" target="_blank" rel="noreferrer">
|
|
||||||
{{ .JSON.String "observations.0.value" }}%
|
|
||||||
</a>
|
|
||||||
<div class="text-truncate">St. Louis Federal Reserve</div>
|
|
||||||
</div>
|
|
||||||
<div class="shrink-0">
|
|
||||||
<div class="size-h3 text-right {{ if lt $change 0.0 }}color-positive{{ else if gt $change 0.0 }}color-negative{{ end }}">
|
|
||||||
{{ printf "%+.2f" $change }}%
|
|
||||||
</div>
|
|
||||||
<div class="text-right" title="As of {{ $lastObserve }}" {{ $lastObserve | parseRelativeTime "DateOnly" }}></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
- type: custom-api
|
|
||||||
title: Secured Financing Rate
|
|
||||||
cache: 12h
|
|
||||||
url: https://api.stlouisfed.org/fred/series/observations?series_id=SOFR&api_key=${FRED_API_KEY}&file_type=json&sort_order=desc&limit=2
|
|
||||||
template: *fred-template
|
|
||||||
|
|
||||||
- type: custom-api
|
|
||||||
title: Federal Funds Rate
|
|
||||||
cache: 12h
|
|
||||||
url: https://api.stlouisfed.org/fred/series/observations?series_id=FEDFUNDS&api_key=${FRED_API_KEY}&file_type=json&sort_order=desc&limit=2
|
|
||||||
template: *fred-template
|
|
||||||
|
|
||||||
- type: custom-api
|
|
||||||
title: Real GDP
|
|
||||||
cache: 12h
|
|
||||||
url: https://api.stlouisfed.org/fred/series/observations?series_id=A191RL1Q225SBEA&api_key=${FRED_API_KEY}&file_type=json&sort_order=desc&limit=2
|
|
||||||
template: *fred-template
|
|
||||||
Reference in New Issue
Block a user