From 4fcf8fae763629a53eead9f7e655a145d5edcdcf Mon Sep 17 00:00:00 2001 From: Aleksi Lassila Date: Fri, 11 Aug 2023 22:45:53 +0300 Subject: [PATCH] add: Update checker fix: Jellyfin user id being hard coded --- README.md | 2 +- src/lib/apis/jellyfin/jellyfinApi.ts | 49 ++++++++++++++++--------- src/lib/components/UpdateChecker.svelte | 28 ++++++++++++++ src/lib/localstorage.ts | 15 ++++++++ src/lib/stores/settings.store.ts | 3 -- src/routes/+layout.svelte | 2 + 6 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 src/lib/components/UpdateChecker.svelte create mode 100644 src/lib/localstorage.ts diff --git a/README.md b/README.md index 9c43895..a172f9a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ TMDB Discovery: Local Library & Playback -- Steam Movies & TV shows (from Jellyfin library) +- Stream Movies & TV shows (from Jellyfin library) - Create requests for movies & TV shows in Radarr & Sonarr - Manage local library files - View Radarr & Sonarr stats (disk space, items, etc.) diff --git a/src/lib/apis/jellyfin/jellyfinApi.ts b/src/lib/apis/jellyfin/jellyfinApi.ts index cb40ed4..c3e7bbf 100644 --- a/src/lib/apis/jellyfin/jellyfinApi.ts +++ b/src/lib/apis/jellyfin/jellyfinApi.ts @@ -17,11 +17,26 @@ export const JellyfinApi = createClient({ } }); -export const getJellyfinContinueWatching = (): Promise => +let userId: string | undefined = undefined; +const getUserId = async () => { + if (userId) return userId; + + const user = JellyfinApi.get('/Users', { + params: {}, + headers: { + 'cache-control': 'max-age=3600' + } + }).then((r) => r.data?.[0]?.Id || ''); + + userId = await user; + return user; +}; + +export const getJellyfinContinueWatching = async (): Promise => JellyfinApi.get('/Users/{userId}/Items/Resume', { params: { path: { - userId: get(settings).jellyfin.userId + userId: await getUserId() }, query: { mediaTypes: ['Video'], @@ -30,21 +45,21 @@ export const getJellyfinContinueWatching = (): Promise => } }).then((r) => r.data?.Items || []); -export const getJellyfinNextUp = () => +export const getJellyfinNextUp = async () => JellyfinApi.get('/Shows/NextUp', { params: { query: { - userId: get(settings).jellyfin.userId, + userId: await getUserId(), fields: ['ProviderIds'] } } }).then((r) => r.data?.Items || []); -export const getJellyfinItems = () => +export const getJellyfinItems = async () => JellyfinApi.get('/Users/{userId}/Items', { params: { path: { - userId: get(settings).jellyfin.userId + userId: await getUserId() }, query: { hasTmdbId: true, @@ -59,7 +74,7 @@ export const getJellyfinItems = () => // JellyfinApi.get('/Users/{userId}/Items', { // params: { // path: { -// userId: get(settings).jellyfin.userId +// userId: env.PUBLIC_JELLYFIN_USER_ID || "" // }, // query: { // hasTmdbId: true, @@ -69,11 +84,11 @@ export const getJellyfinItems = () => // } // }).then((r) => r.data?.Items || []); -export const getJellyfinEpisodes = () => +export const getJellyfinEpisodes = async () => JellyfinApi.get('/Users/{userId}/Items', { params: { path: { - userId: get(settings).jellyfin.userId + userId: await getUserId() }, query: { recursive: true, @@ -91,12 +106,12 @@ export const getJellyfinEpisodesBySeries = (seriesId: string) => export const getJellyfinItemByTmdbId = (tmdbId: string) => getJellyfinItems().then((items) => items.find((i) => i.ProviderIds?.Tmdb == tmdbId)); -export const getJellyfinItem = (itemId: string) => +export const getJellyfinItem = async (itemId: string) => JellyfinApi.get('/Users/{userId}/Items/{itemId}', { params: { path: { itemId, - userId: get(settings).jellyfin.userId + userId: await getUserId() } } }).then((r) => r.data); @@ -104,7 +119,7 @@ export const getJellyfinItem = (itemId: string) => export const requestJellyfinItemByTmdbId = () => request((tmdbId: string) => getJellyfinItemByTmdbId(tmdbId)); -export const getJellyfinPlaybackInfo = ( +export const getJellyfinPlaybackInfo = async ( itemId: string, playbackProfile: DeviceProfile, startTimeTicks = 0 @@ -115,7 +130,7 @@ export const getJellyfinPlaybackInfo = ( itemId: itemId }, query: { - userId: get(settings).jellyfin.userId, + userId: await getUserId(), startTimeTicks, autoOpenLiveStream: true, maxStreamingBitrate: 140000000 @@ -184,11 +199,11 @@ export const reportJellyfinPlaybackStopped = ( } }); -export const setJellyfinItemWatched = (jellyfinId: string) => +export const setJellyfinItemWatched = async (jellyfinId: string) => JellyfinApi.post('/Users/{userId}/PlayedItems/{itemId}', { params: { path: { - userId: get(settings).jellyfin.userId, + userId: await getUserId(), itemId: jellyfinId }, query: { @@ -197,11 +212,11 @@ export const setJellyfinItemWatched = (jellyfinId: string) => } }); -export const setJellyfinItemUnwatched = (jellyfinId: string) => +export const setJellyfinItemUnwatched = async (jellyfinId: string) => JellyfinApi.del('/Users/{userId}/PlayedItems/{itemId}', { params: { path: { - userId: get(settings).jellyfin.userId, + userId: await getUserId(), itemId: jellyfinId } } diff --git a/src/lib/components/UpdateChecker.svelte b/src/lib/components/UpdateChecker.svelte new file mode 100644 index 0000000..8bd96d7 --- /dev/null +++ b/src/lib/components/UpdateChecker.svelte @@ -0,0 +1,28 @@ + + +{#await fetchLatestVersion() then latestVersion} + {#if latestVersion !== `v${version}` && latestVersion !== $skippedVersion && visible} +
+ New version is available! + (visible = false)} class="absolute right-8 inset-y-0"> + + +
+ {/if} +{/await} diff --git a/src/lib/localstorage.ts b/src/lib/localstorage.ts new file mode 100644 index 0000000..60ea610 --- /dev/null +++ b/src/lib/localstorage.ts @@ -0,0 +1,15 @@ +import { writable } from 'svelte/store'; + +function createLocalStorageStore(key: string) { + const store = writable(JSON.parse(localStorage.getItem(key) || 'null') || null); + + return { + subscribe: store.subscribe, + set: (value: any) => { + localStorage.setItem(key, JSON.stringify(value)); + store.set(value); + } + }; +} + +export const skippedVersion = createLocalStorageStore('skipped-version'); diff --git a/src/lib/stores/settings.store.ts b/src/lib/stores/settings.store.ts index bc9f275..414da4e 100644 --- a/src/lib/stores/settings.store.ts +++ b/src/lib/stores/settings.store.ts @@ -44,9 +44,6 @@ const defaultSettings: Settings = { qualityProfileId: 4, profileId: 4, rootFolderPath: '/movies' - }, - jellyfin: { - userId: '75dcb061c9404115a7acdc893ea6bbbc' } }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 1ea4015..cd3e75e 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -3,6 +3,7 @@ import DynamicModal from '$lib/components/Modal/DynamicModal.svelte'; import Navbar from '$lib/components/Navbar/Navbar.svelte'; import SetupRequired from '$lib/components/SetupRequired/SetupRequired.svelte'; + import UpdateChecker from '$lib/components/UpdateChecker.svelte'; import '../app.css'; import type { LayoutData } from './$types'; @@ -18,6 +19,7 @@ {#key $page.url.pathname} {/key} + {:else}