diff --git a/config/backup.yml b/config/backup.yml deleted file mode 100644 index 6afc61e..0000000 --- a/config/backup.yml +++ /dev/null @@ -1,1580 +0,0 @@ -- name: Home - columns: - - size: small - widgets: - - type: calendar - first-day-of-week: sunday - - type: clock # Added Clock widget - hour-format: 12h # Assuming 12h based on weather widget preference - timezones: - - timezone: America/Los_Angeles # San Francisco uses this timezone - label: San Francisco - - timezone: America/New_York - label: New York - - timezone: Europe/London - label: London - - timezone: Europe/Amsterdam - label: Amsterdam - - timezone: Asia/Kolkata # New Delhi uses this timezone - label: New Delhi - - timezone: Asia/Tokyo - label: Tokyo - - type: custom-api - title: Astronomy Picture of the Day - cache: 1d - url: https://api.nasa.gov/planetary/apod?api_key=${NASA_API_KEY} - headers: - Accept: application/json - template: | - {{- if eq (.JSON.String "media_type") "image" -}} -
- -

- - {{ .JSON.String "title" }} - -

- - - {{ .JSON.String - - -
- - Show Explanation - -

- {{ .JSON.String "explanation" }} -

-
-
- {{- else -}} -

- No image available today. -

- {{- end }} - - - size: full - widgets: - - type: search - search-engine: google - bangs: # Added bangs section - - title: YouTube - shortcut: "!yt" - url: https://www.youtube.com/results?search_query={QUERY} - - title: Wikipedia - shortcut: "!w" - url: https://en.wikipedia.org/wiki/Special:Search?search={QUERY} - - title: Amazon - shortcut: "!a" - url: https://www.amazon.com/s?k={QUERY} - - title: Reddit - shortcut: "!r" - url: https://www.reddit.com/search/?q={QUERY} - - title: GitHub - shortcut: "!gh" - url: https://github.com/search?q={QUERY} - - type: bookmarks # Rewritten Quick Links widget - title: Quick Links - groups: - - links: - - title: Google - url: https://www.google.com/ - icon: si:google - - title: GMail - url: https://mail.google.com/ - icon: si:gmail - - title: GDrive - url: https://drive.google.com/ - icon: si:googledrive - - links: - - title: GCal - url: https://calendar.google.com/ - icon: si:googlecalendar - - title: Youtube - url: https://www.youtube.com/ - icon: si:youtube - - title: Amazon - url: https://www.amazon.com/ - icon: si:amazon - - links: - - title: Github - url: https://github.com/ - icon: si:github - - title: LinkedIn - url: https://www.linkedin.com/ - icon: si:linkedin - - title: Plex - url: "${PLEX_URL}/web/index.html#!/" - icon: si:plex - - links: - - title: MCSManager - url: http://panel.sirblob.co/ - icon: mdi:server - - title: Gitea - url: https://git.sirblob.co/ - icon: si:gitea - - title: Coder - url: "${CODER_APP_URL}" - icon: mdi:code-braces - - title: Yamtrack - url: https://tbd.sirblob.co/ - icon: mdi:bug - - links: - - title: qBittorrent - url: https://torr.sirblob.co/ - icon: si:qbittorrent - - title: Excalidraw - url: https://draw.sirblob.co/ - icon: mdi:draw - - title: Immich - url: https://immich.sirblob.co/ - icon: si:immich - - links: - - title: Canvas - url: https://canvas.gmu.edu/ - icon: si:instructure # Instructure is the company behind Canvas - - title: Mason360 - url: https://mason360.gmu.edu/ - icon: mdi:school # Using a generic school icon - - title: Nginx Proxy Manager # Added NPM - url: https://npm.sirblob.co/ - icon: si:nginxproxymanager - - title: OpenWeb (AI Chat) - url: https://openweb.sirblob.co/ - icon: mdi:chat - - title: Sea (Anime) - url: https://sea.sirblob.co/ - icon: mdi:television - - - type: monitor - cache: 1m - title: My Services - sites: - - title: Plex - url: "${PLEX_URL}/web/index.html#!/" - icon: si:plex - - title: Immich - url: https://immich.sirblob.co - icon: si:immich - - title: MCSManager - url: http://panel.sirblob.co/ - icon: mdi:server - - title: Coder - url: "${CODER_APP_URL}" - icon: mdi:code-braces - - title: Yamtrack - url: https://tbd.sirblob.co/ - icon: mdi:bug - - title: Excalidraw - url: https://draw.sirblob.co/ - icon: mdi:draw - - title: qBittorrent - url: https://torr.sirblob.co/ - icon: si:qbittorrent - - title: Gitea - url: https://git.sirblob.co/ - icon: si:gitea - - title: Nginx Proxy Manager # Added NPM - url: https://npm.sirblob.co/ - icon: si:nginxproxymanager - - title: OpenWeb (AI Chat) - url: https://openweb.sirblob.co/ - icon: mdi:chat - - title: Sea (Anime) - url: https://sea.sirblob.co/ - icon: mdi:television - - - type: group - widgets: - - type: custom-api - title: mason.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/mason.sirblob.co - template: &minecraft-widget-template | -
-
- {{ if .JSON.Bool "online" }} - - {{ else }} - - - - {{ end }} -
-
- - {{ .JSON.String "host" }} - {{ if .JSON.Bool "online" }} - - {{ else }} - - {{ end }} - - -
-
- - type: custom-api - title: cobble.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/cobble.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: cgc.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/cgc.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: presto.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/presto.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: event.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/event.sirblob.co - template: *minecraft-widget-template - - - type: custom-api - title: LeetCode Daily Question - cache: 6h - url: https://leetcode.com/graphql - method: POST - headers: - Accept: application/json - body-type: json - body: - query: | - query questionOfToday { - activeDailyCodingChallengeQuestion { - link - question { - questionId - title - difficulty - topicTags { - name - slug - } - } - } - } - operationName: questionOfToday - template: | -
- -

- - {{ .JSON.String "data.activeDailyCodingChallengeQuestion.question.questionId" }} - {{ .JSON.String "data.activeDailyCodingChallengeQuestion.question.title" }} - -

-

Difficulty: {{ .JSON.String "data.activeDailyCodingChallengeQuestion.question.difficulty" }}

-

Topics:

-
- {{ if .JSON.Exists "data.activeDailyCodingChallengeQuestion.question.topicTags" }} - {{ range .JSON.Array "data.activeDailyCodingChallengeQuestion.question.topicTags" }} - {{ .String "name" }} - {{ end }} - {{ else }} - None - {{ end }} -
- {{ if .JSON.Bool "data.activeDailyCodingChallengeQuestion.question.paidOnly" }} -

This is a Premium question

- {{ end }} -
- - - size: small - widgets: - - type: weather - location: Great Falls, Virginia, United States - units: imperial - hour-format: 12h - - - type: custom-api - title: Air Quality - cache: 10m - url: https://api.waqi.info/feed/geo:38.9979;-77.2894/?token=${AIR_TOKEN} - template: | - {{ $aqi := printf "%03s" (.JSON.String "data.aqi") }} - {{ $aqiraw := .JSON.String "data.aqi" }} - {{ $updated := .JSON.String "data.time.iso" }} - {{ $humidity := .JSON.String "data.iaqi.h.v" }} - {{ $ozone := .JSON.String "data.iaqi.o3.v" }} - {{ $pm25 := .JSON.String "data.iaqi.pm25.v" }} - {{ $pressure := .JSON.String "data.iaqi.p.v" }} - -
-
- {{ if le $aqi "050" }} -
Good air quality
- {{ else if le $aqi "100" }} -
Moderate air quality
- {{ else }} -
Bad air quality
- {{ end }} -
-
- -
AQI: {{ $aqiraw }}
-
- -
-
- -
-
{{ $humidity }}%
-
HUMIDITY
-
- -
-
{{ $ozone }} μg/m³
-
OZONE
-
- -
-
{{ $pm25 }} μg/m³
-
PM2.5
-
- -
-
{{ $pressure }} hPa
-
PRESSURE
-
- -
- -
Last Updated at {{ slice $updated 11 16 }}
-
- - - type: custom-api - title: GitHub Repositories - url: https://api.github.com/users/SirBlobby/repos - cache: 30m - parameters: - affiliation: owner - sort: updated - visibility: all - headers: - Accept: application/vnd.github.v3+json - User-Agent: Glance-Dashboard - template: | -
- -
- -- name: Media - columns: - - size: small # Added new small column on the left - widgets: - - type: hacker-news # Added Hacker News widget - limit: 15 - collapse-after: 5 - - size: full # Existing full column is now second - widgets: - - type: custom-api - title: Epic Games - cache: 1h - url: https://store-site-backend-static.ak.epicgames.com/freeGamesPromotions?locale=en&country=US&allowCountries=US - template: | -
- {{ if eq .Response.StatusCode 200 }} -
- {{ range .JSON.Array "data.Catalog.searchStore.elements" }} - {{ $price := .String "price.totalPrice.discountPrice" }} - {{ $hasPromo := gt (len (.Array "promotions.promotionalOffers")) 0 }} - {{ if and $hasPromo (eq $price "0") }} - {{ $gamePage := .String "productSlug" }} - {{ if gt (len (.Array "offerMappings")) 0 }} - {{ $gamePage = .String "offerMappings.0.pageSlug" }} - {{end }} - - {{ $title := .String "title" }} - {{ range .Array "keyImages" }} - {{ if eq (.String "type") "OfferImageWide" }} - {{ $title }} - {{ end }} - {{ end }} -
- {{ $title }}
- - {{ if $hasPromo }} - {{ $promotions := .Array "promotionalOffers" }} - {{ if gt (len $promotions) 0 }} - {{ $firstPromo := index $promotions 0 }} - {{ $offers := $firstPromo.Array "promotionalOffers" }} - {{ if gt (len $offers) 0 }} - {{ $firstOffer := index $offers 0 }} - Free until {{ slice ($firstOffer.String "endDate") 0 10 }} - {{ else }} - Free this week! - {{ end }} - {{ else }} - Free this week! - {{ end }} - {{ end }} - -
-
- {{ end }} - {{ end }} -
- {{ else }} -

Error fetching Epic Games data.

- {{ end }} -
- - - type: videos - title: For You - style: grid-cards - collapse-after-rows: 2 - channels: - - UCwWhs_6x42TyRM4Wstoq8HA - - UCLuYADJ6hESLHX87JnsGbjA - - UC-gW4TeZAlKm7UATp24JsWQ - - UCETqJYEne9Tks-eZYIrFZvg - - UCOT2iLov0V7Re7ku_3UBtcQ - - UCFe2Kq8Hg15UomoVYdmRg_Q - - - type: videos - title: Engineering - style: grid-cards - collapse-after-rows: 2 - channels: - - UCUyeluBRhGPCW4rPe_UvBZQ - - UCFhXFikryT4aFcLkLw2LBLA - - UCsBjURrPoezykLs9EqgamOA - - UCHnyfMqiRRG1u-2MsSQLbXA - - UC6biysICWOJ-C3P4Tyeggzg - -- name: Services - columns: - - size: full - widgets: - - type: monitor - cache: 1m - title: My Services - sites: - - title: Plex - url: "${PLEX_URL}/web/index.html#!/" - icon: si:plex - - title: Immich - url: https://immich.sirblob.co - icon: si:immich - - title: MCSManager - url: http://panel.sirblob.co/ - icon: mdi:server - - title: Coder - url: "${CODER_APP_URL}" - icon: mdi:code-braces - - title: Excalidraw - url: https://draw.sirblob.co/ - icon: mdi:draw - - title: qBittorrent - url: https://torr.sirblob.co/ - icon: si:qbittorrent - - title: Gitea - url: https://git.sirblob.co/ - icon: si:gitea - - title: Nginx Proxy Manager # Added NPM - url: https://npm.sirblob.co/ - icon: si:nginxproxymanager - - - type: custom-api - title: Immich stats - cache: 10m - url: https://immich.sirblob.co/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: group - widgets: - - type: custom-api - title: mason.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/mason.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: cobble.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/cobble.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: cgc.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/cgc.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: presto.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/presto.sirblob.co - template: *minecraft-widget-template - - type: custom-api - title: create.sirblob.co - cache: 30s - url: https://api.mcstatus.io/v2/status/java/create.sirblob.co - template: *minecraft-widget-template - - - type: custom-api - title: qBittorrent - cache: 10s - options: - view: "detailed" # "basic" or "detailed" - mode: "default" # "default" or "upload" - subrequests: - transfer: - url: http://${QBITTORRENT_IP}/api/v2/transfer/info - seeding: - url: http://${QBITTORRENT_IP}/api/v2/torrents/info - parameters: - filter: seeding - leeching: - url: http://${QBITTORRENT_IP}/api/v2/torrents/info - parameters: - filter: downloading - template: | - {{ $transfer := .Subrequest "transfer" }} - {{ $seeding := .Subrequest "seeding" }} - {{ $leeching := .Subrequest "leeching" }} - - {{ if and (eq $transfer.Response.StatusCode 200) (eq $seeding.Response.StatusCode 200) (eq $leeching.Response.StatusCode 200) }} - - {{ $isDetailed := eq (.Options.StringOr "view" "detailed") "detailed" }} - {{ $mode := .Options.StringOr "mode" "default" }} - - {{ if $isDetailed }} - -
-
-
- {{ $dlSpeed := $transfer.JSON.Float "dl_info_speed" }} - {{ if eq $mode "upload" }} -
{{ printf "%.1f MB/s" (div $dlSpeed 1000000.0) }}
- {{ else }} - {{ if lt $dlSpeed 1048576.0 }} -
{{ printf "%.0f KiB/s" (div $dlSpeed 1024.0) }}
- {{ else }} -
{{ printf "%.1f MiB/s" (div $dlSpeed 1048576.0) }}
- {{ end }} - {{ end }} -
DOWNLOADING
-
- - {{ if eq $mode "upload" }} -
- {{ $ulSpeed := $transfer.JSON.Float "up_info_speed" }} -
{{ printf "%.1f MB/s" (div $ulSpeed 1000000.0) }}
-
UPLOADING
-
- {{ end }} - -
-
{{ len ($seeding.JSON.Array "") }}
-
SEEDING
-
- - {{ if eq $mode "default" }} -
-
{{ len ($leeching.JSON.Array "") }}
-
LEECHING
-
- {{ end }} -
- - - {{ $downloadingTorrents := $leeching.JSON.Array "" }} - {{ if gt (len $downloadingTorrents) 0 }} -
- -
- {{ end }} - - - {{ if eq $mode "upload" }} - {{ $seedingTorrents := $seeding.JSON.Array "" }} - {{ if gt (len $seedingTorrents) 0 }} -
- -
- {{ end }} - {{ end }} - -
- - {{ else }} - -
-
- {{ $dlSpeed := $transfer.JSON.Float "dl_info_speed" }} -
{{ printf "%.1f MB/s" (div $dlSpeed 1000000.0) }}
-
DOWNLOADING
-
- {{ if eq $mode "upload" }} -
- {{ $ulSpeed := $transfer.JSON.Float "up_info_speed" }} -
{{ printf "%.1f MB/s" (div $ulSpeed 1000000.0) }}
-
UPLOADING
-
- {{ end }} -
-
{{ len ($seeding.JSON.Array "") }}
-
SEEDING
-
- {{ if eq $mode "default" }} -
-
{{ len ($leeching.JSON.Array "") }}
-
LEECHING
-
- {{ end }} -
- {{ end }} - - {{ else }} -
-

Error fetching qBittorrent data.

-

Check URL and authentication bypass settings.

-
- {{ end }} - - - type: custom-api - title: Plex Now Playing - cache: 1m - options: - media-server: "plex" - base-url: ${PLEX_URL} - api-key: ${PLEX_TOKEN} - small-column: false - compact: false - play-state: "indicator" - show-thumbnail: true - full-thumbnail: false - show-paused: false - show-progress-bar: false - show-progress-info: true - time-format: "15:04" - template: | - {{ $mediaServer := .Options.StringOr "media-server" "" }} - {{ $baseURL := .Options.StringOr "base-url" "" }} - {{ $apiKey := .Options.StringOr "api-key" "" }} - - {{ define "errorMsg" }} -
-
ERROR
- - - -
-

{{ . }}

- {{ end }} - - {{ if or - (eq $mediaServer "") - (eq $baseURL "") - (eq $apiKey "") - }} - {{ template "errorMsg" "Some required options are not set" }} - {{ else }} - - {{ $isSmallColumn := .Options.BoolOr "small-column" false }} - {{ $isCompact := .Options.BoolOr "compact" true }} - {{ $playState := .Options.StringOr "play-state" "indicator" }} - {{ $showThumbnail := .Options.BoolOr "show-thumbnail" false }} - {{ $fullThumbnail := .Options.BoolOr "full-thumbnail" false }} - {{ $showPaused := .Options.BoolOr "show-paused" false }} - {{ $showProgressBar := .Options.BoolOr "show-progress-bar" false }} - {{ $showProgressInfo := .Options.BoolOr "show-progress-info" true }} - {{ $timeFormat := .Options.StringOr "time-format" "15:04" }} - - {{ $userID := "" }} - {{ $sessionsRequestURL := "" }} - {{ $sessionsCall := "" }} - {{ $sessions := "" }} - {{ $activeSessions := 0 }} - - {{ if eq $mediaServer "plex" }} - {{ $sessionsRequestURL = concat $baseURL "/status/sessions" }} - {{ $sessionsCall = newRequest $sessionsRequestURL - | withHeader "Accept" "application/json" - | withHeader "X-Plex-Token" $apiKey - | getResponse }} - - {{ if $sessionsCall.JSON.Exists "MediaContainer" }} - {{ $sessions = $sessionsCall.JSON.Array "MediaContainer.Metadata" }} - {{ $activeSessions = len $sessions }} - {{ else }} - {{ template "errorMsg" (concat "Could not fetch " $mediaServer " API.") }} - {{ end }} - - {{ else if eq $mediaServer "tautulli" }} - {{ $sessionsRequestURL = concat $baseURL "/api/v2" }} - {{ $sessionsCall = newRequest $sessionsRequestURL - | withParameter "apikey" $apiKey - | withParameter "cmd" "get_activity" - | withHeader "Accept" "application/json" - | getResponse }} - - {{ if eq $sessionsCall.Response.StatusCode 200 }} - {{ $sessions = $sessionsCall.JSON.Array "response.data.sessions" }} - {{ $activeSessions = len $sessions }} - {{ else }} - {{ template "errorMsg" (concat "Could not fetch " $mediaServer " API.") }} - {{ end }} - - {{ else if or (eq $mediaServer "jellyfin") (eq $mediaServer "emby") }} - {{ $sessionsRequestURL = concat $baseURL "/Sessions" }} - {{ $sessionsCall = newRequest $sessionsRequestURL - | withParameter "api_key" $apiKey - | withParameter "activeWithinSeconds" "30" - | withHeader "Accept" "application/json" - | getResponse }} - - {{ if eq $sessionsCall.Response.StatusCode 200 }} - {{ $sessions = $sessionsCall.JSON.Array "" }} - {{ if eq $mediaServer "emby" }} - {{ range $session := $sessions }} - {{ if $session.Bool "PlayState.CanSeek" }} - {{ $activeSessions = 1 }} - {{ break }} - {{ end }} - {{ end }} - {{ else }} - {{ $activeSessions = len $sessions }} - {{ end }} - {{ else }} - {{ template "errorMsg" (concat "Could not fetch " $mediaServer " API.") }} - {{ end }} - {{ end }} - - {{ if and (eq $sessionsCall.Response.StatusCode 200) (eq $activeSessions 0) }} -

Nothing is playing right now.

- {{ else if $sessionsCall.JSON.Exists "MediaContainer" }} - - - -
- {{ range $i, $session := $sessions }} - {{ $isClient := true }} - {{ $isPlaying := false }} - {{ $state := "playing" }} - {{ $isMovie := false }} - {{ $isShows := false }} - {{ $isMusic := false }} - {{ $userName := "" }} - {{ $title := "" }} - {{ $showTitle := "" }} - {{ $showSeason := "" }} - {{ $showEpisode := "" }} - {{ $artist := "" }} - {{ $albumTitle := "" }} - {{ $thumbURL := "" }} - {{ $now := now | formatTime "15:04:05" | parseLocalTime "15:04:05" }} - {{ $duration := 0 }} - {{ $offset := 0 }} - {{ $remainingSeconds := 0 }} - - {{ if eq $mediaServer "plex" }} - {{ $isPlaying = eq ($session.String "Player.state") "playing" }} - {{ if not $isPlaying }} - {{ $state = "paused"}} - {{ end }} - - {{ $mediaType := $session.String "type" }} - {{ $isMovie = eq $mediaType "movie" }} - {{ $isShows = eq $mediaType "episode" }} - {{ $isMusic = eq $mediaType "track" }} - - {{ $userName = $session.String "User.title" }} - {{ $title = $session.String "title" }} - {{ $showTitle = $session.String "grandparentTitle" }} - {{ $showSeason = $session.String "parentIndex" }} - {{ $showEpisode = $session.String "index" }} - {{ $artist = $session.String "grandparentTitle" }} - {{ $albumTitle = $session.String "parentTitle" }} - - {{ $thumbID := $session.String "thumb" }} - {{ if or $isShows $isMusic }} - {{ $thumbID = $session.String "parentThumb" }} - {{ end }} - {{ $thumbURL = concat $baseURL $thumbID "?X-Plex-Token=" $apiKey }} - - {{ $duration = $session.Float "duration" }} - {{ $offset = $session.Float "viewOffset" }} - {{ $remainingSeconds = div (sub $duration $offset) 1000 | toInt }} - {{ else if eq $mediaServer "tautulli" }} - {{ $isPlaying = eq ($session.String "state") "playing" }} - {{ if not $isPlaying }} - {{ $state = "paused"}} - {{ end }} - - {{ $mediaType := $session.String "media_type" }} - {{ $isMovie = eq $mediaType "movie" }} - {{ $isShows = eq $mediaType "episode" }} - {{ $isMusic = eq $mediaType "track" }} - - {{ $userName = $session.String "user" }} - {{ $title = $session.String "title" }} - {{ $showTitle = $session.String "grandparent_title" }} - {{ $showSeason = $session.String "parent_media_index" }} - {{ $showEpisode = $session.String "media_index" }} - {{ $artist = $session.String "grandparent_title" }} - {{ $albumTitle = $session.String "parent_title" }} - - {{ $thumbID := $session.String "thumb" }} - {{ if or $isShows $isMusic }} - {{ $thumbID = $session.String "parent_thumb" }} - {{ end }} - {{ $thumbURL = concat $baseURL "/api/v2?apikey=" $apiKey "&cmd=pms_image_proxy&img=" $thumbID }} - - {{ $duration = $session.Float "duration" }} - {{ $offset = $session.Float "view_offset" }} - {{ $remainingSeconds = div (sub $duration $offset) 1000 | toInt }} - {{ else if or (eq $mediaServer "jellyfin") (eq $mediaServer "emby") }} - {{ if eq $mediaServer "emby" }} - {{ $isClient = $session.Bool "PlayState.CanSeek" }} - {{ end }} - {{ $isPlaying = and ($session.Exists "NowPlayingItem") (not ($session.Bool "PlayState.IsPaused")) }} - {{ if not $isPlaying }} - {{ $state = "paused"}} - {{ end }} - - {{ $mediaType := $session.String "NowPlayingItem.Type" }} - {{ $isMovie = eq $mediaType "Movie" }} - {{ $isShows = eq $mediaType "Episode" }} - {{ $isMusic = eq $mediaType "Audio" }} - - {{ $userName = $session.String "UserName" }} - {{ $title = $session.String "NowPlayingItem.Name" }} - {{ $showTitle = $session.String "NowPlayingItem.SeriesName" }} - {{ $showSeason = $session.String "NowPlayingItem.ParentIndexNumber" }} - {{ $showEpisode = $session.String "NowPlayingItem.IndexNumber" }} - {{ $artist = $session.String "NowPlayingItem.AlbumArtist" }} - {{ $albumTitle = $session.String "NowPlayingItem.Album" }} - - {{ $thumbID := $session.String "NowPlayingItem.Id" }} - {{ if $isShows }} - {{ $thumbID = $session.String "NowPlayingItem.ParentId" }} - {{ end }} - {{ $thumbURL = concat $baseURL "/Items/" $thumbID "/Images/Primary?api_key=" $apiKey }} - - {{ $duration = $session.Float "NowPlayingItem.RunTimeTicks" }} - {{ $offset = $session.Float "PlayState.PositionTicks" }} - {{ $remainingSeconds = div (sub $duration $offset) 10000000 | toInt }} - {{ end }} - - {{ $progress := mul 100 (div $offset $duration) | toInt }} - {{ $endTime := $now.Add (duration (printf "%ds" $remainingSeconds)) | formatTime $timeFormat }} - - {{ $showInfoFormat := concat "Season " $showSeason " Episode " $showEpisode}} - {{ if $isCompact }} - {{ $showInfoFormat = concat "S" $showSeason "E" $showEpisode}} - {{ end }} - - {{ if and $isClient (or $isPlaying $showPaused) }} -
-
- {{ $userName }} - {{ if eq $playState "text" }} - - [{{ $state }}] - - {{ else if eq $playState "indicator" }} - -
- {{ end }} -
- -
- -
- {{ if $showThumbnail }} - {{ $title }} thumbnail - {{ end }} -
    - {{ if $isCompact }} - {{ if $isShows }} -
      -
    • {{ concat "S" $showSeason "E" $showEpisode }}
    • -
    • {{ $showTitle }}
    • -
    - {{ else if $isMusic }} -
      -
    • {{ $artist }}
    • -
    • {{ $albumTitle }}
    • -
    - {{ end }} -
  • {{ $title }}
  • - {{ else }} - {{ if $isShows }} -
  • {{ $showTitle }}
  • -
  • {{ concat "S" $showSeason "E" $showEpisode }}
  • - {{ else if $isMusic }} -
  • {{ $artist }}
  • -
  • {{ $albumTitle }}
  • - {{ end }} -
  • {{ $title }}
  • - {{ end }} - -
  • - {{ if and $isPlaying $showProgressBar }} -
    -
    -
    -
    -
    - {{ if $showProgressInfo }} -

    - {{ if and (not $isCompact) (not $isSmallColumn) }} - ends at - {{ end }} - {{ $endTime }} -

    - {{ end }} -
    - {{ end }} -
  • -
-
-
- {{ end }} - {{ end }} -
- {{ end }} - {{ end }} - - - type: custom-api - title: Media Server History - frameless: true - cache: 5m - options: - media-server: "plex" - base-url: ${PLEX_URL} - api-key: ${PLEX_TOKEN} - history-length: "10" - small-column: false - compact: true - show-thumbnail: true - thumbnail-aspect-ratio: "default" - show-user: true - time-absolute: false - time-format: "Jan 02 15:04" - template: | - {{ $mediaServer := .Options.StringOr "media-server" "" }} - {{ $baseURL := .Options.StringOr "base-url" "" }} - {{ $apiKey := .Options.StringOr "api-key" "" }} - {{ $userName := .Options.StringOr "user-name" "" }} - - {{ define "errorMsg" }} -
-
ERROR
- - - -
-

{{ . }}

- {{ 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) }} -

Nothing has been played. Start streaming something!

- {{ else if $historyCall.JSON.Exists "MediaContainer" }} - - {{ end }} - {{ end }} - diff --git a/config/home.yml b/config/home.yml index cc6c7b1..08eb782 100644 --- a/config/home.yml +++ b/config/home.yml @@ -83,10 +83,11 @@ - title: GitHub shortcut: "!gh" url: https://github.com/search?q={QUERY} - - type: bookmarks # Rewritten Quick Links widget + - type: bookmarks title: Quick Links groups: - - links: + - title: Google Services + links: - title: Google url: https://www.google.com/ icon: si:google @@ -96,65 +97,68 @@ - title: GDrive url: https://drive.google.com/ icon: si:googledrive - - links: - title: GCal url: https://calendar.google.com/ icon: si:googlecalendar - title: Youtube url: https://www.youtube.com/ icon: si:youtube - - title: Amazon - url: https://www.amazon.com/ - icon: si:amazon - - links: + - title: Development + links: - title: Github url: https://github.com/ icon: si:github - - title: LinkedIn - url: https://www.linkedin.com/ - icon: si:linkedin - - title: Plex - url: "${PLEX_URL}/web/index.html#!/" - icon: si:plex - - links: - - title: MCSManager - url: http://panel.sirblob.co/ - icon: mdi:server - title: Gitea url: https://git.sirblob.co/ icon: si:gitea - title: Coder url: "${CODER_APP_URL}" icon: mdi:code-braces - - title: Yamtrack - url: https://tbd.sirblob.co/ - icon: mdi:bug - - links: - - title: qBittorrent - url: https://torr.sirblob.co/ - icon: si:qbittorrent - - title: Excalidraw - url: https://draw.sirblob.co/ - icon: mdi:draw + - title: Media & Entertainment + links: + - title: Plex + url: "${PLEX_URL}/web/index.html#!/" + icon: si:plex - title: Immich url: https://immich.sirblob.co/ icon: si:immich - - links: - - title: Canvas - url: https://canvas.gmu.edu/ - icon: si:instructure # Instructure is the company behind Canvas - - title: Mason360 - url: https://mason360.gmu.edu/ - icon: mdi:school # Using a generic school icon - - title: Nginx Proxy Manager # Added NPM - url: https://npm.sirblob.co/ - icon: si:nginxproxymanager - - title: OpenWeb (AI Chat) - url: https://openweb.sirblob.co/ - icon: mdi:chat - title: Sea (Anime) url: https://sea.sirblob.co/ icon: mdi:television + - title: qBittorrent + url: https://torr.sirblob.co/ + icon: si:qbittorrent + - title: Tools & Apps + links: + - title: OpenWeb (AI Chat) + url: https://openweb.sirblob.co/ + icon: mdi:chat + - title: Excalidraw + url: https://draw.sirblob.co/ + icon: mdi:draw + - title: Yamtrack + url: https://tbd.sirblob.co/ + icon: mdi:bug + - title: Amazon + url: https://www.amazon.com/ + icon: si:amazon + - title: LinkedIn + url: https://www.linkedin.com/ + icon: si:linkedin + - title: School & Infrastructure + links: + - title: Canvas + url: https://canvas.gmu.edu/ + icon: si:instructure + - title: Mason360 + url: https://mason360.gmu.edu/ + icon: mdi:school + - title: MCSManager + url: http://panel.sirblob.co/ + icon: mdi:server + - title: Nginx Proxy Manager + url: https://npm.sirblob.co/ + icon: si:nginxproxymanager - type: monitor cache: 1m @@ -187,10 +191,10 @@ - title: Nginx Proxy Manager # Added NPM url: https://npm.sirblob.co/ icon: si:nginxproxymanager - - title: OpenWeb (AI Chat) + - title: OpenWeb url: https://openweb.sirblob.co/ icon: mdi:chat - - title: Sea (Anime) + - title: SeaAnime url: https://sea.sirblob.co/ icon: mdi:television diff --git a/config/services.yml b/config/services.yml index d622384..54d271f 100644 --- a/config/services.yml +++ b/config/services.yml @@ -33,10 +33,10 @@ - title: Nginx Proxy Manager # Added NPM url: https://npm.sirblob.co/ icon: si:nginxproxymanager - - title: OpenWeb (AI Chat) + - title: OpenWeb url: https://openweb.sirblob.co/ icon: mdi:chat - - title: Sea (Anime) + - title: SeaAnime url: https://sea.sirblob.co/ icon: mdi:television