mirror of
https://gitlab.com/upRootNutrition/dotfiles.git
synced 2025-06-16 10:05:13 -05:00
326 lines
14 KiB
Nix
Executable file
326 lines
14 KiB
Nix
Executable file
''
|
|
{{ $mediaServer := .Options.StringOr "media-server" "" }}
|
|
{{ $baseURL := .Options.StringOr "base-url" "" }}
|
|
{{ $apiKey := .Options.StringOr "api-key" "" }}
|
|
{{ $userName := .Options.StringOr "user-name" "" }}
|
|
|
|
{{ 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 }}
|
|
|
|
{{ if or
|
|
(eq $mediaServer "")
|
|
(eq $baseURL "")
|
|
(eq $apiKey "")
|
|
(and (eq $mediaServer "jellyfin") (eq $userName ""))
|
|
}}
|
|
{{ template "errorMsg" "Some required options are not set" }}
|
|
{{ else }}
|
|
|
|
{{ $historyLength := .Options.StringOr "history-length" "10" }}
|
|
{{ $mediaTypes := .Options.StringOr "media-types" "" }}
|
|
{{ if eq $mediaServer "tautulli" }}
|
|
{{ $mediaTypes = .Options.StringOr "media-types" "movie,episode,track" }}
|
|
{{ else if or (eq $mediaServer "jellyfin") (eq $mediaServer "emby") }}
|
|
{{ $mediaTypes = .Options.StringOr "media-types" "Movie,Episode,Audio" }}
|
|
{{ end }}
|
|
{{ $isSmallColumn := .Options.BoolOr "small-column" false }}
|
|
{{ $isCompact := .Options.BoolOr "compact" true }}
|
|
{{ $showThumbnail := .Options.BoolOr "show-thumbnail" false }}
|
|
{{ $thumbAspectRatio := .Options.StringOr "thumbnail-aspect-ratio" "" }}
|
|
{{ $showUser := .Options.BoolOr "show-user" true }}
|
|
{{ $timeAbsolute := .Options.BoolOr "time-absolute" false }}
|
|
{{ $timeFormat := .Options.StringOr "time-format" "Jan 02 15:04" }}
|
|
|
|
{{ $userID := "" }}
|
|
{{ $historyRequestURL := "" }}
|
|
{{ $usersRequestURL := "" }}
|
|
{{ $historyCall := "" }}
|
|
{{ $usersCall := "" }}
|
|
{{ $history := "" }}
|
|
{{ $users := "" }}
|
|
|
|
{{ if eq $mediaServer "plex" }}
|
|
{{ $historyRequestURL = concat $baseURL "/status/sessions/history/all" }}
|
|
{{ $historyCall = newRequest $historyRequestURL
|
|
| withParameter "limit" $historyLength
|
|
| withParameter "sort" "viewedAt:desc"
|
|
| withHeader "Accept" "application/json"
|
|
| withHeader "X-Plex-Token" $apiKey
|
|
| getResponse }}
|
|
|
|
{{ if $historyCall.JSON.Exists "MediaContainer" }}
|
|
{{ $history = $historyCall.JSON.Array "MediaContainer.Metadata" }}
|
|
{{ else }}
|
|
{{ template "errorMsg" (concat "Could not fetch " $mediaServer " API.") }}
|
|
{{ end }}
|
|
|
|
{{ $usersRequestURL = concat $baseURL "/accounts" }}
|
|
{{ $usersCall = newRequest $usersRequestURL
|
|
| withHeader "Accept" "application/json"
|
|
| withHeader "X-Plex-Token" $apiKey
|
|
| getResponse }}
|
|
{{ $users = $usersCall.JSON.Array "MediaContainer.Account" }}
|
|
|
|
{{ else if eq $mediaServer "tautulli" }}
|
|
{{ $historyRequestURL = concat $baseURL "/api/v2" }}
|
|
{{ $historyCall = newRequest $historyRequestURL
|
|
| withParameter "apikey" $apiKey
|
|
| withParameter "cmd" "get_history"
|
|
| withParameter "length" $historyLength
|
|
| withParameter "media_type" $mediaTypes
|
|
| withHeader "Accept" "application/json"
|
|
| getResponse }}
|
|
|
|
{{ if eq $historyCall.Response.StatusCode 200 }}
|
|
{{ $history = $historyCall.JSON.Array "response.data.data" }}
|
|
{{ else }}
|
|
{{ template "errorMsg" (concat "Could not fetch " $mediaServer " API.") }}
|
|
{{ end }}
|
|
|
|
{{ else if or (eq $mediaServer "jellyfin") (eq $mediaServer "emby") }}
|
|
{{ $usersRequestURL = concat $baseURL "/Users" }}
|
|
{{ $usersCall = newRequest $usersRequestURL
|
|
| withParameter "api_key" $apiKey
|
|
| withHeader "Accept" "application/json"
|
|
| getResponse }}
|
|
|
|
{{ $usersList := $usersCall.JSON.Array "" }}
|
|
{{ range $i, $user := $usersList }}
|
|
{{ if eq ($user.String "Name") $userName }}
|
|
{{ $userID = $user.String "Id" }}
|
|
{{ break }}
|
|
{{ end }}
|
|
{{ end }}
|
|
{{ if eq $userID "" }}
|
|
{{ template "errorMsg" (concat "User '" $userName "' not found.") }}
|
|
{{ end }}
|
|
|
|
{{ $historyRequestURL = concat $baseURL "/Users/" $userID "/Items" }}
|
|
{{ $historyCall = newRequest $historyRequestURL
|
|
| withParameter "api_key" $apiKey
|
|
| withParameter "Limit" $historyLength
|
|
| withParameter "IncludeItemTypes" $mediaTypes
|
|
| withParameter "Recursive" "true"
|
|
| withParameter "isPlayed" "true"
|
|
| withParameter "sortBy" "DatePlayed"
|
|
| withParameter "sortOrder" "Descending"
|
|
| withParameter "Fields" "UserDataLastPlayedDate"
|
|
| withHeader "Accept" "application/json"
|
|
| getResponse }}
|
|
|
|
{{ $history = $historyCall.JSON.Array "Items" }}
|
|
{{ end }}
|
|
|
|
{{ if and (eq $historyCall.Response.StatusCode 200) (eq (len $history) 0) }}
|
|
<p>Nothing has been played. Start streaming something!</p>
|
|
{{ else }}
|
|
<div class="carousel-container show-right-cutoff">
|
|
<div class="cards-horizontal carousel-items-container">
|
|
{{ range $n, $item := $history }}
|
|
{{ $mediaType := "" }}
|
|
{{ $isMovie := false }}
|
|
{{ $isShows := false }}
|
|
{{ $isMusic := false }}
|
|
{{ $title := "" }}
|
|
{{ $showTitle := "" }}
|
|
{{ $showSeason := "" }}
|
|
{{ $showEpisode := "" }}
|
|
{{ $artist := "" }}
|
|
{{ $albumTitle := "" }}
|
|
{{ $thumbURL := "" }}
|
|
{{ $playedAt := "" }}
|
|
|
|
{{ if eq $mediaServer "plex" }}
|
|
{{ $userID = $item.Int "accountID" }}
|
|
{{ range $n, $u := $users }}
|
|
{{ if eq $userID ($u.Int "id") }}
|
|
{{ $userName = $u.String "name" }}
|
|
{{ break }}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{ $mediaType = $item.String "type" }}
|
|
{{ $isMovie = eq $mediaType "movie" }}
|
|
{{ $isShows = eq $mediaType "episode" }}
|
|
{{ $isMusic = eq $mediaType "track" }}
|
|
|
|
{{ $title = $item.String "title" }}
|
|
{{ if $isShows }}
|
|
{{ $showTitle = $item.String "grandparentTitle" }}
|
|
{{ $showSeason = $item.String "parentIndex" }}
|
|
{{ $showEpisode = $item.String "index" }}
|
|
{{ else if $isMusic }}
|
|
{{ $artist = $item.String "grandparentTitle" }}
|
|
{{ $albumTitle = $item.String "parentTitle" }}
|
|
{{ end }}
|
|
|
|
{{ $thumbID := $item.String "thumb" }}
|
|
{{ if or $isShows $isMusic}}
|
|
{{ $thumbID = $item.String "parentThumb" }}
|
|
{{ end }}
|
|
{{ $thumbURL = concat $baseURL $thumbID "?X-Plex-Token=" $apiKey }}
|
|
|
|
{{ $time := $item.String "viewedAt" }}
|
|
{{ if $timeAbsolute }}
|
|
{{ $playedAt = $time | parseLocalTime "unix" | formatTime $timeFormat }}
|
|
{{ else }}
|
|
{{ $playedAt = $time | parseRelativeTime "unix" }}
|
|
{{ end }}
|
|
|
|
{{ else if eq $mediaServer "tautulli" }}
|
|
{{ $userName = $item.String "user" }}
|
|
{{ $mediaType = $item.String "media_type" }}
|
|
{{ $isMovie = eq $mediaType "movie" }}
|
|
{{ $isShows = eq $mediaType "episode" }}
|
|
{{ $isMusic = eq $mediaType "track" }}
|
|
|
|
{{ $title = $item.String "title" }}
|
|
{{ if $isShows }}
|
|
{{ $showTitle = $item.String "grandparent_title" }}
|
|
{{ $showSeason = $item.String "parent_media_index" }}
|
|
{{ $showEpisode = $item.String "media_index" }}
|
|
{{ else if $isMusic }}
|
|
{{ $artist = $item.String "grandparent_title" }}
|
|
{{ $albumTitle = $item.String "parent_title" }}
|
|
{{ end }}
|
|
|
|
{{ $thumbID := $item.String "thumb" }}
|
|
{{ $thumbURL = concat $baseURL "/api/v2?apikey=" $apiKey "&cmd=pms_image_proxy&img=" $thumbID }}
|
|
|
|
{{ $time := $item.String "date" }}
|
|
{{ if $timeAbsolute }}
|
|
{{ $playedAt = $time | parseLocalTime "unix" | formatTime $timeFormat }}
|
|
{{ else }}
|
|
{{ $playedAt = $time | parseRelativeTime "unix" }}
|
|
{{ end }}
|
|
|
|
{{ else if or (eq $mediaServer "jellyfin") (eq $mediaServer "emby") }}
|
|
{{ $mediaType = $item.String "Type" }}
|
|
{{ $isMovie = eq $mediaType "Movie" }}
|
|
{{ $isShows = eq $mediaType "Episode" }}
|
|
{{ $isMusic = eq $mediaType "Audio" }}
|
|
|
|
{{ $title = $item.String "Name" }}
|
|
{{ if $isShows }}
|
|
{{ $showTitle = $item.String "SeriesName" }}
|
|
{{ $showSeason = $item.String "ParentIndexNumber" }}
|
|
{{ $showEpisode = $item.String "IndexNumber" }}
|
|
{{ else if $isMusic }}
|
|
{{ $artist = $item.String "AlbumArtist" }}
|
|
{{ $albumTitle = $item.String "Album" }}
|
|
{{ end }}
|
|
|
|
{{ $thumbID := $item.String "Id" }}
|
|
{{ if $isShows }}
|
|
{{ $thumbID = $item.String "SeasonId" }}
|
|
{{ end }}
|
|
{{ $thumbURL = concat $baseURL "/Items/" $thumbID "/Images/Primary?api_key=" $apiKey }}
|
|
|
|
{{ $time := $item.String "UserData.LastPlayedDate" }}
|
|
{{ if $timeAbsolute }}
|
|
{{ $playedAt = $time | parseLocalTime "rfc3339" | formatTime $timeFormat }}
|
|
{{ else }}
|
|
{{ $playedAt = $time | parseRelativeTime "rfc3339" }}
|
|
{{ end }}
|
|
{{ end }}
|
|
|
|
{{ $showInfoFormat := concat "Season " $showSeason " Episode " $showEpisode}}
|
|
{{ if $isCompact }}
|
|
{{ $showInfoFormat = concat "S" $showSeason "E" $showEpisode}}
|
|
{{ end }}
|
|
|
|
<div class="card widget-content-frame">
|
|
{{ if $showThumbnail }}
|
|
<img src="{{ $thumbURL | safeURL }}"
|
|
alt="{{ $title }} thumbnail"
|
|
loading="lazy"
|
|
class="media-server-thumbnail shrink-0"
|
|
style="
|
|
object-fit: cover;
|
|
border-radius: var(--border-radius) var(--border-radius) 0 0;
|
|
{{ if eq $thumbAspectRatio "square" }}
|
|
aspect-ratio: 1;
|
|
{{ else if eq $thumbAspectRatio "portrait" }}
|
|
aspect-ratio: 3/4;
|
|
{{ else if eq $thumbAspectRatio "landscape" }}
|
|
aspect-ratio: 4/3;
|
|
{{ else }}
|
|
aspect-ratio: initial;
|
|
{{ end }}
|
|
"
|
|
/>
|
|
{{ 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 $isCompact }}
|
|
<ul class="list-horizontal-text flex-nowrap">
|
|
{{ if $showUser }}
|
|
<li class="color-primary text-truncate">{{ $userName }}</li>
|
|
{{ end }}
|
|
|
|
{{ if $timeAbsolute }}
|
|
<li class="text-truncate">{{ $playedAt }}</li>
|
|
{{ else }}
|
|
<li class="shrink-0">
|
|
<span {{ $playedAt }}></span>
|
|
{{ if not $showUser }}
|
|
<span> ago</span>
|
|
{{ end }}
|
|
</li>
|
|
{{ end }}
|
|
</ul>
|
|
|
|
{{ if $isShows }}
|
|
<ul class="list-horizontal-text flex-nowrap">
|
|
<li class="text-truncate">{{ $showInfoFormat }}</li>
|
|
<li class="text-truncate">{{ $showTitle }}</li>
|
|
</ul>
|
|
{{ else if $isMusic }}
|
|
<ul class="list-horizontal-text flex-nowrap">
|
|
<li class="text-truncate">{{ $artist }}</li>
|
|
<li class="text-truncate">{{ $albumTitle }}</li>
|
|
</ul>
|
|
{{ end }}
|
|
|
|
<li class="text-truncate">{{ $title }}</li>
|
|
{{ else }}
|
|
{{ if $showUser }}
|
|
<li class="color-primary text-truncate">{{ $userName }}</li>
|
|
{{ end }}
|
|
|
|
{{ if $timeAbsolute }}
|
|
<li class="text-truncate">{{ $playedAt }}</li>
|
|
{{ else }}
|
|
<li class="text-truncate">
|
|
<span {{ $playedAt }}></span>
|
|
<span> ago</span>
|
|
</li>
|
|
{{ end }}
|
|
|
|
{{ if $isShows }}
|
|
<li class="text-truncate">{{ $showTitle }}</li>
|
|
<li class="text-truncate">{{ $showInfoFormat }}</li>
|
|
{{ else if $isMusic }}
|
|
<li class="text-truncate">{{ $artist }}</li>
|
|
<li class="text-truncate">{{ $albumTitle }}</li>
|
|
{{ end }}
|
|
|
|
<li class="text-truncate">{{ $title }}</li>
|
|
{{ end }}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
{{ end }}
|
|
''
|