From dd9744850695f896432247201b02b117662cd031 Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 14:26:35 +0300 Subject: [PATCH 01/17] docs: update readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8aff3198..3518fd13 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,11 @@ services: Plex Rewind is available in the Community Apps store for Unraid. Search for "Plex Rewind" and install it from grtgbln's repository. -As noted in the installation instructions, you will need to download a copy of "settings.json" into the associated settings path **before** running the application. To download the file, you can open a terminal, enter the directory and run `curl -o settings.json https://raw.githubusercontent.com/RaunoT/plex-rewind/main/config/settings.example.json`. +As noted in the installation instructions, you will need to download a copy of `settings.json` into the associated settings path **before** running the application. To download the file, you can open a terminal, enter the directory and run the following command: + +```sh +curl -o settings.json https://raw.githubusercontent.com/RaunoT/plex-rewind/main/config/settings.example.json +``` ## Updating From 0d868a5e1db6a137e1e811c39cb4dc81467ab5ad Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 15:09:09 +0300 Subject: [PATCH 02/17] docs: fix issue templates labels --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- .github/ISSUE_TEMPLATE/enhancement.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index b728bad3..58e931d7 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,6 +1,6 @@ name: 🐛 Bug report description: Report a problem -labels: ['type:bug', 'awaiting-triage'] +labels: ['type:bug', 'awaiting triage'] body: - type: input id: version diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 9fe230f3..42c6bc0d 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -1,6 +1,6 @@ name: ✨ Feature request description: Suggest an enhancement, improvement or idea -labels: ['type:enhancement', 'awaiting-triage'] +labels: ['type:enhancement', 'awaiting triage'] body: - type: textarea id: description From 7439407557f6248dae112f724d5736d8e90a90b4 Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 16:28:51 +0300 Subject: [PATCH 03/17] feat(#193): allow using tmdb posters as default for tv/movies --- config/settings.example.json | 3 ++- src/actions/update-feature-settings.ts | 2 ++ .../features/_components/FeaturesSettingsForm.tsx | 14 ++++++++++++++ src/styles/globals.css | 8 ++++++-- src/types/index.d.ts | 1 + src/utils/constants.ts | 1 + src/utils/getMediaAdditionalData.ts | 3 ++- 7 files changed, 28 insertions(+), 4 deletions(-) diff --git a/config/settings.example.json b/config/settings.example.json index 66230a7c..e39d76d8 100644 --- a/config/settings.example.json +++ b/config/settings.example.json @@ -22,7 +22,8 @@ "activeDashboardTotalStatistics": ["size", "duration", "count", "requests"], "dashboardDefaultPeriod": "custom", "dashboardCustomPeriod": "30", - "googleAnalyticsId": "" + "googleAnalyticsId": "", + "isPostersTmdbOnly": false }, "test": false } diff --git a/src/actions/update-feature-settings.ts b/src/actions/update-feature-settings.ts index c0b20ea5..1e0d4a4d 100644 --- a/src/actions/update-feature-settings.ts +++ b/src/actions/update-feature-settings.ts @@ -30,6 +30,7 @@ const schema = z.object({ }, ), googleAnalyticsId: z.string(), + isPostersTmdbOnly: z.boolean(), }) export async function saveFeaturesSettings( @@ -50,6 +51,7 @@ export async function saveFeaturesSettings( dashboardDefaultPeriod: formData.get('dashboardDefaultPeriod') as string, dashboardCustomPeriod: formData.get('dashboardCustomPeriod') as string, googleAnalyticsId: formData.get('googleAnalyticsId') as string, + isPostersTmdbOnly: formData.get('isPostersTmdbOnly') === 'on', } // Save settings diff --git a/src/app/settings/features/_components/FeaturesSettingsForm.tsx b/src/app/settings/features/_components/FeaturesSettingsForm.tsx index 64197409..c9d17cdd 100644 --- a/src/app/settings/features/_components/FeaturesSettingsForm.tsx +++ b/src/app/settings/features/_components/FeaturesSettingsForm.tsx @@ -39,6 +39,20 @@ export default function FeaturesSettingsForm({ settings, libraries }: Props) { + +
+ + TMDB only posters + + Ignore Plex posters for tv/movies. +
By default, TMDB is a fallback. +
+
+

Rewind

diff --git a/src/styles/globals.css b/src/styles/globals.css index 4ceac104..3576091a 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -142,18 +142,22 @@ } .label { - @apply shrink-0 text-xs text-neutral-300 peer-focus-within:text-white sm:w-48 sm:text-right sm:text-sm; + @apply text-xs text-neutral-300 peer-focus-within:text-white sm:w-48 sm:shrink-0 sm:text-right sm:text-sm; &--start { @apply mt-0.5 self-start; } + + > small { + @apply block text-xs text-neutral-400; + } } .switch { @apply flex w-fit items-center justify-end gap-2 sm:flex-row-reverse; .indicator { - @apply relative h-6 w-12 cursor-pointer rounded-full bg-neutral-500; + @apply relative h-6 w-12 shrink-0 cursor-pointer rounded-full bg-neutral-500; &::after { @apply absolute inset-y-0 left-0.5 my-auto size-5 rounded-full bg-white transition content-['']; diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 3b238754..d6a68879 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -141,6 +141,7 @@ export type FeaturesSettings = { dashboardDefaultPeriod: string dashboardCustomPeriod: string googleAnalyticsId: string + isPostersTmdbOnly: boolean } export type Settings = { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 6dd816e3..9f5b29b3 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -90,6 +90,7 @@ export const DEFAULT_SETTINGS: Settings = { dashboardDefaultPeriod: 'custom', dashboardCustomPeriod: '30', googleAnalyticsId: '', + isPostersTmdbOnly: false, }, test: false, } diff --git a/src/utils/getMediaAdditionalData.ts b/src/utils/getMediaAdditionalData.ts index 6a6164d0..5ecd7b7f 100644 --- a/src/utils/getMediaAdditionalData.ts +++ b/src/utils/getMediaAdditionalData.ts @@ -44,9 +44,10 @@ export default async function getMediaAdditionalData( const settings = await getSettings() const tautulliUrl = settings.connection.tautulliUrl + const isPostersTmdbOnly = settings.features.isPostersTmdbOnly // Test if thumb exists, if not, fetch from TMDB - if (!poster && tautulliUrl) { + if ((!poster || isPostersTmdbOnly) && tautulliUrl) { const tmdbImage = await fetchTmdb<{ poster_path: string }>( `${type}/${tmdbId}`, ) From c214bf1814d5cc845e084cab961bd991026f943c Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 16:46:27 +0300 Subject: [PATCH 04/17] feat(#194): add option to toggle rewind libraries size and count card --- config/settings.example.json | 3 ++- src/actions/update-feature-settings.ts | 3 +++ src/app/rewind/_components/RewindStories.tsx | 4 +++- .../features/_components/FeaturesSettingsForm.tsx | 14 ++++++++++++++ src/types/index.d.ts | 1 + src/utils/constants.ts | 1 + 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/config/settings.example.json b/config/settings.example.json index e39d76d8..dde2d88f 100644 --- a/config/settings.example.json +++ b/config/settings.example.json @@ -23,7 +23,8 @@ "dashboardDefaultPeriod": "custom", "dashboardCustomPeriod": "30", "googleAnalyticsId": "", - "isPostersTmdbOnly": false + "isPostersTmdbOnly": false, + "isRewindLibrariesSizeAndCountActive": true }, "test": false } diff --git a/src/actions/update-feature-settings.ts b/src/actions/update-feature-settings.ts index 1e0d4a4d..a7ac1180 100644 --- a/src/actions/update-feature-settings.ts +++ b/src/actions/update-feature-settings.ts @@ -31,6 +31,7 @@ const schema = z.object({ ), googleAnalyticsId: z.string(), isPostersTmdbOnly: z.boolean(), + isRewindLibrariesSizeAndCountActive: z.boolean(), }) export async function saveFeaturesSettings( @@ -52,6 +53,8 @@ export async function saveFeaturesSettings( dashboardCustomPeriod: formData.get('dashboardCustomPeriod') as string, googleAnalyticsId: formData.get('googleAnalyticsId') as string, isPostersTmdbOnly: formData.get('isPostersTmdbOnly') === 'on', + isRewindLibrariesSizeAndCountActive: + formData.get('isRewindLibrariesSizeAndCountActive') === 'on', } // Save settings diff --git a/src/app/rewind/_components/RewindStories.tsx b/src/app/rewind/_components/RewindStories.tsx index 7023a37d..ade54837 100644 --- a/src/app/rewind/_components/RewindStories.tsx +++ b/src/app/rewind/_components/RewindStories.tsx @@ -50,10 +50,12 @@ export default function RewindStories({ userRewind, settings }: Props) { const isOverseerrActive = settings.connection.overseerrUrl && settings.connection.overseerrApiKey + const isRewindLibrariesSizeAndCountActive = + settings.features.isRewindLibrariesSizeAndCountActive const stories = [ createStory(StoryWelcome, 5000), createStory(StoryTotal, 8000), - ...(userRewind.libraries_total_size + ...(userRewind.libraries_total_size && isRewindLibrariesSizeAndCountActive ? [createStory(StoryLibraries, 9000)] : []), ...(isOverseerrActive diff --git a/src/app/settings/features/_components/FeaturesSettingsForm.tsx b/src/app/settings/features/_components/FeaturesSettingsForm.tsx index c9d17cdd..1274af1a 100644 --- a/src/app/settings/features/_components/FeaturesSettingsForm.tsx +++ b/src/app/settings/features/_components/FeaturesSettingsForm.tsx @@ -64,6 +64,20 @@ export default function FeaturesSettingsForm({ settings, libraries }: Props) {
Enabled + +
+ + Libraries size & count card + + Disable, if you don't want to rely on Tautulli for these + stats. + + +

Dashboard

diff --git a/src/types/index.d.ts b/src/types/index.d.ts index d6a68879..90f72ba0 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -142,6 +142,7 @@ export type FeaturesSettings = { dashboardCustomPeriod: string googleAnalyticsId: string isPostersTmdbOnly: boolean + isRewindLibrariesSizeAndCountActive: boolean } export type Settings = { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 9f5b29b3..40ce7c51 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -91,6 +91,7 @@ export const DEFAULT_SETTINGS: Settings = { dashboardCustomPeriod: '30', googleAnalyticsId: '', isPostersTmdbOnly: false, + isRewindLibrariesSizeAndCountActive: true, }, test: false, } From 8b7470358bd3d769ea5576f61b726240c169b04d Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 20:47:01 +0300 Subject: [PATCH 05/17] perf: improve cache --- src/lib/auth.ts | 1 + src/utils/fetchTmdb.ts | 7 ++++++- src/utils/getSettings.ts | 28 +++++++++++----------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/lib/auth.ts b/src/lib/auth.ts index cedebb9a..102729b4 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -66,6 +66,7 @@ export const authOptions: AuthOptions = { { user_id: userData.id, }, + true, ) const userExists = diff --git a/src/utils/fetchTmdb.ts b/src/utils/fetchTmdb.ts index b1bccba5..557df0e9 100644 --- a/src/utils/fetchTmdb.ts +++ b/src/utils/fetchTmdb.ts @@ -10,6 +10,7 @@ type QueryParams = { export default async function fetchTmdb( endpoint: string, params?: QueryParams, + cache: boolean = true, ): Promise { const settings = await getSettings() const apiKey = settings.connection.tmdbApiKey @@ -22,7 +23,11 @@ export default async function fetchTmdb( const apiUrl = `https://api.themoviedb.org/3/${endpoint}?api_key=${apiKey}&${qs.stringify( params, )}` - const res = await fetch(apiUrl) + const res = await fetch(apiUrl, { + next: { + revalidate: cache ? 3600 : 0, + }, + }) if (!res.ok) { console.error(`TMDB API request failed: ${res.status} ${res.statusText}`) diff --git a/src/utils/getSettings.ts b/src/utils/getSettings.ts index 4c8484fa..42e48afe 100644 --- a/src/utils/getSettings.ts +++ b/src/utils/getSettings.ts @@ -40,16 +40,7 @@ export default async function getSettings(): Promise { } if (updated) { - try { - await fs.writeFile( - SETTINGS_PATH, - JSON.stringify(settings, null, 2), - 'utf8', - ) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (error: any) { - throw new Error('Unable to write updated settings to the file!') - } + await writeSettings(settings as Settings) } return settings as Settings @@ -58,16 +49,19 @@ export default async function getSettings(): Promise { // If reading fails because the file does not exist, create the file with default settings if (error.code === 'ENOENT') { console.warn('Settings file not found. Creating a new one.') - - await fs.writeFile( - SETTINGS_PATH, - JSON.stringify(DEFAULT_SETTINGS, null, 2), - 'utf8', - ) - + await writeSettings(DEFAULT_SETTINGS) return DEFAULT_SETTINGS } else { throw new Error('Unable to read the settings file!') } } } + +async function writeSettings(settings: Settings): Promise { + try { + await fs.writeFile(SETTINGS_PATH, JSON.stringify(settings, null, 2), 'utf8') + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (error: any) { + throw new Error('Unable to write settings to the file!') + } +} From 8494dd4dceecbbeef1241b6ec8a4469513e274b2 Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 20:51:56 +0300 Subject: [PATCH 06/17] docs: update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3518fd13..3d075c25 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ services: container_name: plex-rewind environment: - NEXTAUTH_SECRET= # (required) used to encrypt auth JWT token, generate one with `openssl rand -base64 32` - - NEXTAUTH_URL=http://localhost:8383 # change to your domain if you are exposing the app to the internet - - NEXT_PUBLIC_SITE_URL=http://localhost:8383 # change to your domain if you are exposing the app to the internet - - NEXT_PUBLIC_STATISTICS_START_DATE=2018-01-01 # starting date for "all time" option (YYYY-MM-DD) + - NEXTAUTH_URL=http://localhost:8383 # (required) change to your domain if you are exposing the app to the internet + - NEXT_PUBLIC_SITE_URL=http://localhost:8383 # (required) change to your domain if you are exposing the app to the internet + - NEXT_PUBLIC_STATISTICS_START_DATE=2018-01-01 # (optional) starting date for "all time" option (YYYY-MM-DD) volumes: - ./config:/app/config ports: From 321d4f06ba1d3cc71b3d70aa1f81e96c65365b3a Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Sun, 28 Jul 2024 20:57:08 +0300 Subject: [PATCH 07/17] style: update copy --- src/app/settings/features/_components/FeaturesSettingsForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/settings/features/_components/FeaturesSettingsForm.tsx b/src/app/settings/features/_components/FeaturesSettingsForm.tsx index 1274af1a..a47b7a95 100644 --- a/src/app/settings/features/_components/FeaturesSettingsForm.tsx +++ b/src/app/settings/features/_components/FeaturesSettingsForm.tsx @@ -73,7 +73,7 @@ export default function FeaturesSettingsForm({ settings, libraries }: Props) { Libraries size & count card - Disable, if you don't want to rely on Tautulli for these + Disable if you don't want to rely on Tautulli for these stats. From acece3f6bb9b69831bea97d58cd6a65a96808231 Mon Sep 17 00:00:00 2001 From: Rauno Tegelmann Date: Tue, 30 Jul 2024 10:26:32 +0300 Subject: [PATCH 08/17] fix: use global tmdb api key, users no longer need to apply their own --- config/settings.example.json | 3 +-- src/actions/update-connection-settings.ts | 6 ++---- .../_components/ConnectionSettingsForm.tsx | 13 ------------- src/types/index.d.ts | 1 - src/utils/constants.ts | 3 ++- src/utils/fetchTmdb.ts | 11 ++--------- 6 files changed, 7 insertions(+), 30 deletions(-) diff --git a/config/settings.example.json b/config/settings.example.json index dde2d88f..1ed782fd 100644 --- a/config/settings.example.json +++ b/config/settings.example.json @@ -3,8 +3,7 @@ "tautulliUrl": "", "tautulliApiKey": "", "overseerrUrl": "", - "overseerrApiKey": "", - "tmdbApiKey": "" + "overseerrApiKey": "" }, "features": { "isRewindActive": true, diff --git a/src/actions/update-connection-settings.ts b/src/actions/update-connection-settings.ts index c5a4f0f1..e2d93aaa 100644 --- a/src/actions/update-connection-settings.ts +++ b/src/actions/update-connection-settings.ts @@ -1,7 +1,7 @@ 'use server' import { SettingsFormInitialState } from '@/types' -import { SETTINGS_PATH } from '@/utils/constants' +import { SETTINGS_PATH, TMDB_API_KEY } from '@/utils/constants' import getSettings from '@/utils/getSettings' import { promises as fs } from 'fs' import { revalidatePath } from 'next/cache' @@ -12,7 +12,6 @@ const schema = z.object({ tautulliApiKey: z.string(), overseerrUrl: z.string().url().optional().or(z.literal('')), overseerrApiKey: z.string().optional(), - tmdbApiKey: z.string().optional(), }) export async function saveConnectionSettings( @@ -24,7 +23,6 @@ export async function saveConnectionSettings( tautulliApiKey: formData.get('tautulliApiKey') as string, overseerrUrl: formData.get('overseerrUrl') as string, overseerrApiKey: formData.get('overseerrApiKey') as string, - tmdbApiKey: formData.get('tmdbApiKey') as string, } try { @@ -85,7 +83,7 @@ export async function saveConnectionSettings( // Test TMDB try { const res = await fetch( - `https://api.themoviedb.org/3/authentication?api_key=${data.tmdbApiKey}`, + `https://api.themoviedb.org/3/authentication?api_key=${TMDB_API_KEY}`, { cache: 'no-store', }, diff --git a/src/app/settings/connection/_components/ConnectionSettingsForm.tsx b/src/app/settings/connection/_components/ConnectionSettingsForm.tsx index 727cea43..3de15de8 100644 --- a/src/app/settings/connection/_components/ConnectionSettingsForm.tsx +++ b/src/app/settings/connection/_components/ConnectionSettingsForm.tsx @@ -37,19 +37,6 @@ export default function ConnectionSettingsForm({ settings }: Props) { API key
-
-

TMDB

- -

Overseerr

+
+

Plex

+ +

Overseerr