From f53a3bc10b9433fd9c80df765e9ec0326d27fbe0 Mon Sep 17 00:00:00 2001 From: Ryan Cohen Date: Tue, 16 Aug 2022 14:26:46 +0900 Subject: [PATCH] fix: add user setting for watchlist sync --- server/entity/UserSettings.ts | 3 ++ .../interfaces/api/userSettingsInterfaces.ts | 1 + server/lib/watchlistsync.ts | 7 +++- ...60627491586-AddWatchlistSyncUserSetting.ts | 33 +++++++++++++++++++ server/routes/user/usersettings.ts | 4 +++ .../UserGeneralSettings/index.tsx | 21 ++++++++++++ 6 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 server/migration/1660627491586-AddWatchlistSyncUserSetting.ts diff --git a/server/entity/UserSettings.ts b/server/entity/UserSettings.ts index fb738c59c..a3e6c7aa5 100644 --- a/server/entity/UserSettings.ts +++ b/server/entity/UserSettings.ts @@ -57,6 +57,9 @@ export class UserSettings { @Column({ nullable: true }) public telegramSendSilently?: boolean; + @Column({ nullable: true }) + public watchlistSync?: boolean; + @Column({ type: 'text', nullable: true, diff --git a/server/interfaces/api/userSettingsInterfaces.ts b/server/interfaces/api/userSettingsInterfaces.ts index de7888b24..9f8aa0bab 100644 --- a/server/interfaces/api/userSettingsInterfaces.ts +++ b/server/interfaces/api/userSettingsInterfaces.ts @@ -14,6 +14,7 @@ export interface UserSettingsGeneralResponse { globalMovieQuotaLimit?: number; globalTvQuotaLimit?: number; globalTvQuotaDays?: number; + watchlistSync?: boolean; } export type NotificationAgentTypes = Record; diff --git a/server/lib/watchlistsync.ts b/server/lib/watchlistsync.ts index e5e020823..3f74f4272 100644 --- a/server/lib/watchlistsync.ts +++ b/server/lib/watchlistsync.ts @@ -30,13 +30,18 @@ class WatchlistSync { private async syncUserWatchlist(user: User) { if (!user.plexToken) { - logger.debug('Skipping user watchlist sync for user without plex token', { + logger.warn('Skipping user watchlist sync for user without plex token', { label: 'Plex Watchlist Sync', userId: user.id, }); return; } + // Skip sync if user settings have it disabled + if (!user.settings?.watchlistSync) { + return; + } + const plexTvApi = new PlexTvAPI(user.plexToken); const response = await plexTvApi.getWatchlist({ size: 200 }); diff --git a/server/migration/1660627491586-AddWatchlistSyncUserSetting.ts b/server/migration/1660627491586-AddWatchlistSyncUserSetting.ts new file mode 100644 index 000000000..2067d1895 --- /dev/null +++ b/server/migration/1660627491586-AddWatchlistSyncUserSetting.ts @@ -0,0 +1,33 @@ +import type { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddWatchlistSyncUserSetting1660627491586 + implements MigrationInterface +{ + name = 'AddWatchlistSyncUserSetting1660627491586'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temporary_user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "notificationTypes" text, "discordId" varchar, "userId" integer, "region" varchar, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, "locale" varchar NOT NULL DEFAULT (''), "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, "watchlistSync" boolean, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "temporary_user_settings"("id", "notificationTypes", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey") SELECT "id", "notificationTypes", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey" FROM "user_settings"` + ); + await queryRunner.query(`DROP TABLE "user_settings"`); + await queryRunner.query( + `ALTER TABLE "temporary_user_settings" RENAME TO "user_settings"` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "user_settings" RENAME TO "temporary_user_settings"` + ); + await queryRunner.query( + `CREATE TABLE "user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "notificationTypes" text, "discordId" varchar, "userId" integer, "region" varchar, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, "locale" varchar NOT NULL DEFAULT (''), "pushbulletAccessToken" varchar, "pushoverApplicationToken" varchar, "pushoverUserKey" varchar, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)` + ); + await queryRunner.query( + `INSERT INTO "user_settings"("id", "notificationTypes", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey") SELECT "id", "notificationTypes", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently", "pgpKey", "locale", "pushbulletAccessToken", "pushoverApplicationToken", "pushoverUserKey" FROM "temporary_user_settings"` + ); + await queryRunner.query(`DROP TABLE "temporary_user_settings"`); + } +} diff --git a/server/routes/user/usersettings.ts b/server/routes/user/usersettings.ts index 84d95b399..2e5af2f7e 100644 --- a/server/routes/user/usersettings.ts +++ b/server/routes/user/usersettings.ts @@ -63,6 +63,7 @@ userSettingsRoutes.get<{ id: string }, UserSettingsGeneralResponse>( globalMovieQuotaLimit: defaultQuotas.movie.quotaLimit, globalTvQuotaDays: defaultQuotas.tv.quotaDays, globalTvQuotaLimit: defaultQuotas.tv.quotaLimit, + watchlistSync: user.settings?.watchlistSync, }); } catch (e) { next({ status: 500, message: e.message }); @@ -114,12 +115,14 @@ userSettingsRoutes.post< locale: req.body.locale, region: req.body.region, originalLanguage: req.body.originalLanguage, + watchlistSync: req.body.watchlistSync, }); } else { user.settings.discordId = req.body.discordId; user.settings.locale = req.body.locale; user.settings.region = req.body.region; user.settings.originalLanguage = req.body.originalLanguage; + user.settings.watchlistSync = req.body.watchlistSync; } await userRepository.save(user); @@ -130,6 +133,7 @@ userSettingsRoutes.post< locale: user.settings.locale, region: user.settings.region, originalLanguage: user.settings.originalLanguage, + watchlistSync: user.settings.watchlistSync, }); } catch (e) { next({ status: 500, message: e.message }); diff --git a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx index dd348ce76..1bcc998b5 100644 --- a/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx +++ b/src/components/UserProfile/UserSettings/UserGeneralSettings/index.tsx @@ -49,6 +49,8 @@ const messages = defineMessages({ discordIdTip: 'The multi-digit ID number associated with your Discord user account', validationDiscordId: 'You must provide a valid Discord user ID', + plexwatchlistsync: 'Plex Watchlist Auto-Request', + plexwatchlistsynctip: 'Automatically request Plex watchlist items.', }); const UserGeneralSettings = () => { @@ -122,6 +124,7 @@ const UserGeneralSettings = () => { movieQuotaDays: data?.movieQuotaDays, tvQuotaLimit: data?.tvQuotaLimit, tvQuotaDays: data?.tvQuotaDays, + watchlistSync: false, }} validationSchema={UserGeneralSettingsSchema} enableReinitialize @@ -409,6 +412,24 @@ const UserGeneralSettings = () => { )} +
+ +
+ { + setFieldValue('watchlistSync', !values.watchlistSync); + }} + /> +
+