mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2026-01-11 17:16:50 -05:00
Compare commits
1 Commits
renovate/r
...
pr-2273
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb672ec3c4 |
@@ -45,12 +45,12 @@ The documentation linked above is for running the **latest Jellyseerr** release.
|
||||
> [!WARNING]
|
||||
> If you are migrating from **Overseerr** to **Seerr** for beta testing, **do not follow the Jellyseerr latest setup guide**.
|
||||
|
||||
Instead, follow the dedicated migration guide (with `:develop` tag):
|
||||
Instead, follow the dedicated migration guide:
|
||||
https://github.com/seerr-team/seerr/blob/develop/docs/migration-guide.mdx
|
||||
|
||||
> [!CAUTION]
|
||||
> **DO NOT run Jellyseerr (latest) using an existing Overseerr database. This includes third-party images with `seerr:latest` (as it points to jellyseerr 2.7.3 and not seerr.**
|
||||
> Doing so **may cause database corruption and/or irreversible data loss and/or weird unintended behaviour**.
|
||||
> [!DANGER]
|
||||
> **DO NOT run Jellyseerr (latest) using an existing Overseerr database.**
|
||||
> Doing so **will cause database corruption and/or irreversible data loss**.
|
||||
|
||||
For migration assistance, beta testing questions, or troubleshooting, please join our **Discord** and ask for support there.
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
"eslint-plugin-no-relative-import-paths": "1.6.1",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "4.6.2",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"husky": "8.0.3",
|
||||
"lint-staged": "13.1.2",
|
||||
"nodemon": "3.1.11",
|
||||
|
||||
3259
pnpm-lock.yaml
generated
3259
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,9 @@ const migrationArrTags = async (settings: any): Promise<AllSettings> => {
|
||||
}
|
||||
|
||||
const userRepository = getRepository(User);
|
||||
const users = await userRepository.find();
|
||||
const users = await userRepository.find({
|
||||
select: ['id'],
|
||||
});
|
||||
|
||||
let errorOccurred = false;
|
||||
|
||||
@@ -28,26 +30,15 @@ const migrationArrTags = async (settings: any): Promise<AllSettings> => {
|
||||
});
|
||||
const radarrTags = await radarr.getTags();
|
||||
for (const user of users) {
|
||||
const userTag = radarrTags.find(
|
||||
(v) =>
|
||||
v.label.startsWith(user.id + ' - ') ||
|
||||
v.label.startsWith(user.id + '-')
|
||||
const userTag = radarrTags.find((v) =>
|
||||
v.label.startsWith(user.id + ' - ')
|
||||
);
|
||||
if (!userTag) {
|
||||
continue;
|
||||
}
|
||||
await radarr.renameTag({
|
||||
id: userTag.id,
|
||||
label:
|
||||
user.id +
|
||||
'-' +
|
||||
user.displayName
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^a-z0-9-]/gi, '')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, ''),
|
||||
label: userTag.label.replace(`${user.id} - `, `${user.id}-`),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -70,26 +61,15 @@ const migrationArrTags = async (settings: any): Promise<AllSettings> => {
|
||||
});
|
||||
const sonarrTags = await sonarr.getTags();
|
||||
for (const user of users) {
|
||||
const userTag = sonarrTags.find(
|
||||
(v) =>
|
||||
v.label.startsWith(user.id + ' - ') ||
|
||||
v.label.startsWith(user.id + '-')
|
||||
const userTag = sonarrTags.find((v) =>
|
||||
v.label.startsWith(user.id + ' - ')
|
||||
);
|
||||
if (!userTag) {
|
||||
continue;
|
||||
}
|
||||
await sonarr.renameTag({
|
||||
id: userTag.id,
|
||||
label:
|
||||
user.id +
|
||||
'-' +
|
||||
user.displayName
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^a-z0-9-]/gi, '')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, ''),
|
||||
label: userTag.label.replace(`${user.id} - `, `${user.id}-`),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,15 +6,6 @@ export class AddUniqueConstraintToPushSubscription1765233385034
|
||||
name = 'AddUniqueConstraintToPushSubscription1765233385034';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
DELETE FROM "user_push_subscription"
|
||||
WHERE id NOT IN (
|
||||
SELECT MAX(id)
|
||||
FROM "user_push_subscription"
|
||||
GROUP BY "endpoint", "userId"
|
||||
)
|
||||
`);
|
||||
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user_push_subscription" ADD CONSTRAINT "UQ_6427d07d9a171a3a1ab87480005" UNIQUE ("endpoint", "userId")`
|
||||
);
|
||||
|
||||
@@ -6,15 +6,6 @@ export class AddUniqueConstraintToPushSubscription1765233385034
|
||||
name = 'AddUniqueConstraintToPushSubscription1765233385034';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
DELETE FROM "user_push_subscription"
|
||||
WHERE id NOT IN (
|
||||
SELECT MAX(id)
|
||||
FROM "user_push_subscription"
|
||||
GROUP BY "endpoint", "userId"
|
||||
)
|
||||
`);
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE UNIQUE INDEX "UQ_6427d07d9a171a3a1ab87480005" ON "user_push_subscription" ("endpoint", "userId")`
|
||||
);
|
||||
|
||||
@@ -29,16 +29,6 @@ import type {
|
||||
} from 'typeorm';
|
||||
import { EventSubscriber } from 'typeorm';
|
||||
|
||||
const sanitizeDisplayName = (displayName: string): string => {
|
||||
return displayName
|
||||
.normalize('NFD')
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^a-z0-9-]/gi, '')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, '');
|
||||
};
|
||||
|
||||
@EventSubscriber()
|
||||
export class MediaRequestSubscriber
|
||||
implements EntitySubscriberInterface<MediaRequest>
|
||||
@@ -320,15 +310,11 @@ export class MediaRequestSubscriber
|
||||
mediaId: entity.media.id,
|
||||
userId: entity.requestedBy.id,
|
||||
newTag:
|
||||
entity.requestedBy.id +
|
||||
'-' +
|
||||
sanitizeDisplayName(entity.requestedBy.displayName),
|
||||
entity.requestedBy.id + '-' + entity.requestedBy.displayName,
|
||||
});
|
||||
userTag = await radarr.createTag({
|
||||
label:
|
||||
entity.requestedBy.id +
|
||||
'-' +
|
||||
sanitizeDisplayName(entity.requestedBy.displayName),
|
||||
entity.requestedBy.id + '-' + entity.requestedBy.displayName,
|
||||
});
|
||||
}
|
||||
if (userTag.id) {
|
||||
@@ -645,15 +631,11 @@ export class MediaRequestSubscriber
|
||||
mediaId: entity.media.id,
|
||||
userId: entity.requestedBy.id,
|
||||
newTag:
|
||||
entity.requestedBy.id +
|
||||
'-' +
|
||||
sanitizeDisplayName(entity.requestedBy.displayName),
|
||||
entity.requestedBy.id + '-' + entity.requestedBy.displayName,
|
||||
});
|
||||
userTag = await sonarr.createTag({
|
||||
label:
|
||||
entity.requestedBy.id +
|
||||
'-' +
|
||||
sanitizeDisplayName(entity.requestedBy.displayName),
|
||||
entity.requestedBy.id + '-' + entity.requestedBy.displayName,
|
||||
});
|
||||
}
|
||||
if (userTag.id) {
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
} from '@server/constants/media';
|
||||
import { MediaServerType } from '@server/constants/server';
|
||||
import type { MediaWatchDataResponse } from '@server/interfaces/api/mediaInterfaces';
|
||||
import type { DownloadingItem } from '@server/lib/downloadtracker';
|
||||
import type { RadarrSettings, SonarrSettings } from '@server/lib/settings';
|
||||
import type { MovieDetails } from '@server/models/Movie';
|
||||
import type { TvDetails } from '@server/models/Tv';
|
||||
@@ -34,17 +33,6 @@ import Link from 'next/link';
|
||||
import { useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const filterDuplicateDownloads = (
|
||||
items: DownloadingItem[] = []
|
||||
): DownloadingItem[] => {
|
||||
const seen = new Set<string>();
|
||||
return items.filter((item) => {
|
||||
if (seen.has(item.downloadId)) return false;
|
||||
seen.add(item.downloadId);
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
const messages = defineMessages('components.ManageSlideOver', {
|
||||
manageModalTitle: 'Manage {mediaType}',
|
||||
manageModalIssues: 'Open Issues',
|
||||
@@ -242,30 +230,26 @@ const ManageSlideOver = ({
|
||||
</h3>
|
||||
<div className="overflow-hidden rounded-md border border-gray-700 shadow">
|
||||
<ul>
|
||||
{filterDuplicateDownloads(data.mediaInfo?.downloadStatus).map(
|
||||
(status, index) => (
|
||||
<Tooltip
|
||||
key={`dl-status-${status.externalId}-${index}`}
|
||||
content={status.title}
|
||||
>
|
||||
<li className="border-b border-gray-700 last:border-b-0">
|
||||
<DownloadBlock downloadItem={status} />
|
||||
</li>
|
||||
</Tooltip>
|
||||
)
|
||||
)}
|
||||
{filterDuplicateDownloads(data.mediaInfo?.downloadStatus4k).map(
|
||||
(status, index) => (
|
||||
<Tooltip
|
||||
key={`dl-status-4k-${status.externalId}-${index}`}
|
||||
content={status.title}
|
||||
>
|
||||
<li className="border-b border-gray-700 last:border-b-0">
|
||||
<DownloadBlock downloadItem={status} is4k />
|
||||
</li>
|
||||
</Tooltip>
|
||||
)
|
||||
)}
|
||||
{data.mediaInfo?.downloadStatus?.map((status, index) => (
|
||||
<Tooltip
|
||||
key={`dl-status-${status.externalId}-${index}`}
|
||||
content={status.title}
|
||||
>
|
||||
<li className="border-b border-gray-700 last:border-b-0">
|
||||
<DownloadBlock downloadItem={status} />
|
||||
</li>
|
||||
</Tooltip>
|
||||
))}
|
||||
{data.mediaInfo?.downloadStatus4k?.map((status, index) => (
|
||||
<Tooltip
|
||||
key={`dl-status-${status.externalId}-${index}`}
|
||||
content={status.title}
|
||||
>
|
||||
<li className="border-b border-gray-700 last:border-b-0">
|
||||
<DownloadBlock downloadItem={status} is4k />
|
||||
</li>
|
||||
</Tooltip>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user