From 98c4db3b190367e734841c9b569e0f3eac1e0ba1 Mon Sep 17 00:00:00 2001 From: gauthier-th Date: Tue, 30 Sep 2025 10:54:07 +0200 Subject: [PATCH] fix(api): add a migration script to rename *arr tags with spaces This PR adds a migration script that will run at the startup of the app to remove the spaces from the *arr tags of Jellyseerr. fix #1897 re #1913 re https://github.com/Radarr/Radarr/issues/11251 --- server/api/servarr/base.ts | 19 ++++ server/lib/settings/index.ts | 10 ++ .../migrations/0007_migrate_arr_tags.ts | 91 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 server/lib/settings/migrations/0007_migrate_arr_tags.ts diff --git a/server/api/servarr/base.ts b/server/api/servarr/base.ts index c49b93610..5343898f5 100644 --- a/server/api/servarr/base.ts +++ b/server/api/servarr/base.ts @@ -198,6 +198,25 @@ class ServarrBase extends ExternalAPI { } }; + public renameTag = async ({ + id, + label, + }: { + id: number; + label: string; + }): Promise => { + try { + const response = await this.axios.put(`/tag/${id}`, { + id, + label, + }); + + return response.data; + } catch (e) { + throw new Error(`[${this.apiName}] Failed to rename tag: ${e.message}`); + } + }; + async refreshMonitoredDownloads(): Promise { await this.runCommand('RefreshMonitoredDownloads', {}); } diff --git a/server/lib/settings/index.ts b/server/lib/settings/index.ts index ce3e4b240..73bc951b7 100644 --- a/server/lib/settings/index.ts +++ b/server/lib/settings/index.ts @@ -363,6 +363,7 @@ export interface AllSettings { jobs: Record; network: NetworkSettings; metadataSettings: MetadataSettings; + migrations: string[]; } const SETTINGS_PATH = process.env.CONFIG_DIRECTORY @@ -593,6 +594,7 @@ class Settings { forceMaxTtl: -1, }, }, + migrations: [], }; if (initialSettings) { this.data = merge(this.data, initialSettings); @@ -722,6 +724,14 @@ class Settings { this.data.network = data; } + get migrations(): string[] { + return this.data.migrations; + } + + set migrations(data: string[]) { + this.data.migrations = data; + } + get clientId(): string { return this.data.clientId; } diff --git a/server/lib/settings/migrations/0007_migrate_arr_tags.ts b/server/lib/settings/migrations/0007_migrate_arr_tags.ts new file mode 100644 index 000000000..7c6f2c452 --- /dev/null +++ b/server/lib/settings/migrations/0007_migrate_arr_tags.ts @@ -0,0 +1,91 @@ +import RadarrAPI from '@server/api/servarr/radarr'; +import SonarrAPI from '@server/api/servarr/sonarr'; +import { getRepository } from '@server/datasource'; +import { User } from '@server/entity/User'; +import type { AllSettings } from '@server/lib/settings'; + +const migrationArrTags = async (settings: any): Promise => { + if ( + Array.isArray(settings.migrations) && + settings.migrations.includes('0007_migrate_arr_tags') + ) { + return settings; + } + + const userRepository = getRepository(User); + const users = await userRepository.find({ + select: ['id'], + }); + + let errorOccurred = false; + + for (const radarrSettings of settings.radarr || []) { + if (!radarrSettings.tagRequests) { + continue; + } + try { + const radarr = new RadarrAPI({ + apiKey: radarrSettings.apiKey, + url: RadarrAPI.buildUrl(radarrSettings, '/api/v3'), + }); + const radarrTags = await radarr.getTags(); + for (const user of users) { + const userTag = radarrTags.find((v) => + v.label.startsWith(user.id + ' - ') + ); + if (!userTag) { + continue; + } + await radarr.renameTag({ + id: userTag.id, + label: userTag.label.replace(`${user.id} - `, `${user.id}-`), + }); + } + } catch { + console.error( + `Unable to rename Radarr tags to the new format. Please check your Radarr connection settings for the instance "${radarrSettings.name}".` + ); + errorOccurred = true; + } + } + + for (const sonarrSettings of settings.sonarr || []) { + if (!sonarrSettings.tagRequests) { + continue; + } + try { + const sonarr = new SonarrAPI({ + apiKey: sonarrSettings.apiKey, + url: SonarrAPI.buildUrl(sonarrSettings, '/api/v3'), + }); + const sonarrTags = await sonarr.getTags(); + for (const user of users) { + const userTag = sonarrTags.find((v) => + v.label.startsWith(user.id + ' - ') + ); + if (!userTag) { + continue; + } + await sonarr.renameTag({ + id: userTag.id, + label: userTag.label.replace(`${user.id} - `, `${user.id}-`), + }); + } + } catch { + console.error( + `Unable to rename Sonarr tags to the new format. Please check your Sonarr connection settings for the instance "${sonarrSettings.name}".` + ); + errorOccurred = true; + } + } + + if (!errorOccurred) { + if (!Array.isArray(settings.migrations)) { + settings.migrations = []; + } + settings.migrations.push('0007_migrate_arr_tags'); + } + return settings; +}; + +export default migrationArrTags;