Compare commits

...

3 Commits

Author SHA1 Message Date
fallenbagel
57d583e1bd refactor(jellyfin-scanner): extend BaseScanner for jellyfin scanner (#2226)
* refactor(jellyfin-scanner): extend BaseScanner for jellyfin scanner

Refactors JellyfinScanner to extend BaseScanner class to align the jellyfin scanner architecture
with the plex scanner and reduce code duplication.

* fix(jellyfin-scanner): add imdbId handling back to fix a regression from original behaviour

* fix: add imdbId assignment for existing media entries

* fix: include imdbId in processed 4k media items and improve 4k detection

* fix(jellyfin-scanner): filter seasons based on settings for special episodes (regression)
2025-12-29 20:05:47 +08:00
samohtxotom
8bbe7864af chore(metadata-settings): add autoDismiss to toast notifications (#2254) 2025-12-27 06:27:12 +08:00
Gauthier
66b4e2c871 chore(issuetemplate): add a checkbox to search for existing issues (#2255) 2025-12-27 06:26:16 +08:00
5 changed files with 339 additions and 594 deletions

View File

@@ -91,6 +91,14 @@ body:
attributes:
label: Additional Context
description: Please provide any additional information that may be relevant or helpful.
- type: checkboxes
id: search-existing
attributes:
label: Search Existing Issues
description: Have you searched existing issues to see if this bug has already been reported?
options:
- label: Yes, I have searched existing issues.
required: true
- type: checkboxes
id: terms
attributes:

View File

@@ -27,6 +27,14 @@ body:
attributes:
label: Additional Context
description: Provide any additional information or screenshots that may be relevant or helpful.
- type: checkboxes
id: search-existing
attributes:
label: Search Existing Issues
description: Have you searched existing issues to see if this feature has already been requested?
options:
- label: Yes, I have searched existing issues.
required: true
- type: checkboxes
id: terms
attributes:

View File

@@ -34,6 +34,8 @@ interface ProcessOptions {
is4k?: boolean;
mediaAddedAt?: Date;
ratingKey?: string;
jellyfinMediaId?: string;
imdbId?: string;
serviceId?: number;
externalServiceId?: number;
externalServiceSlug?: string;
@@ -95,6 +97,8 @@ class BaseScanner<T> {
is4k = false,
mediaAddedAt,
ratingKey,
jellyfinMediaId,
imdbId,
serviceId,
externalServiceId,
externalServiceSlug,
@@ -133,6 +137,21 @@ class BaseScanner<T> {
changedExisting = true;
}
if (
jellyfinMediaId &&
existing[is4k ? 'jellyfinMediaId4k' : 'jellyfinMediaId'] !==
jellyfinMediaId
) {
existing[is4k ? 'jellyfinMediaId4k' : 'jellyfinMediaId'] =
jellyfinMediaId;
changedExisting = true;
}
if (imdbId && !existing.imdbId) {
existing.imdbId = imdbId;
changedExisting = true;
}
if (
serviceId !== undefined &&
existing[is4k ? 'serviceId4k' : 'serviceId'] !== serviceId
@@ -173,6 +192,7 @@ class BaseScanner<T> {
} else {
const newMedia = new Media();
newMedia.tmdbId = tmdbId;
newMedia.imdbId = imdbId;
newMedia.status =
!is4k && !processing
@@ -203,6 +223,13 @@ class BaseScanner<T> {
newMedia.ratingKey4k =
is4k && this.enable4kMovie ? ratingKey : undefined;
}
if (jellyfinMediaId) {
newMedia.jellyfinMediaId = !is4k ? jellyfinMediaId : undefined;
newMedia.jellyfinMediaId4k =
is4k && this.enable4kMovie ? jellyfinMediaId : undefined;
}
await mediaRepository.save(newMedia);
this.log(`Saved new media: ${title}`);
}
@@ -221,11 +248,12 @@ class BaseScanner<T> {
*/
protected async processShow(
tmdbId: number,
tvdbId: number,
tvdbId: number | undefined,
seasons: ProcessableSeason[],
{
mediaAddedAt,
ratingKey,
jellyfinMediaId,
serviceId,
externalServiceId,
externalServiceSlug,
@@ -257,7 +285,7 @@ class BaseScanner<T> {
(es) => es.seasonNumber === season.seasonNumber
);
// We update the rating keys in the seasons loop because we need episode counts
// We update the rating keys and jellyfinMediaId in the seasons loop because we need episode counts
if (media && season.episodes > 0 && media.ratingKey !== ratingKey) {
media.ratingKey = ratingKey;
}
@@ -271,6 +299,23 @@ class BaseScanner<T> {
media.ratingKey4k = ratingKey;
}
if (
media &&
season.episodes > 0 &&
media.jellyfinMediaId !== jellyfinMediaId
) {
media.jellyfinMediaId = jellyfinMediaId;
}
if (
media &&
season.episodes4k > 0 &&
this.enable4kShow &&
media.jellyfinMediaId4k !== jellyfinMediaId
) {
media.jellyfinMediaId4k = jellyfinMediaId;
}
if (existingSeason) {
// Here we update seasons if they already exist.
// If the season is already marked as available, we
@@ -491,6 +536,22 @@ class BaseScanner<T> {
)
? ratingKey
: undefined,
jellyfinMediaId: newSeasons.some(
(sn) =>
sn.status === MediaStatus.PARTIALLY_AVAILABLE ||
sn.status === MediaStatus.AVAILABLE
)
? jellyfinMediaId
: undefined,
jellyfinMediaId4k:
this.enable4kShow &&
newSeasons.some(
(sn) =>
sn.status4k === MediaStatus.PARTIALLY_AVAILABLE ||
sn.status4k === MediaStatus.AVAILABLE
)
? jellyfinMediaId
: undefined,
status: isAllStandardSeasons
? MediaStatus.AVAILABLE
: newSeasons.some(

File diff suppressed because it is too large Load Diff

View File

@@ -320,12 +320,14 @@ const SettingsMetadata = () => {
addToast(intl.formatMessage(messages.metadataSettingsSaved), {
appearance: 'success',
autoDismiss: true,
});
} catch (e) {
addToast(
intl.formatMessage(messages.failedToSaveMetadataSettings),
{
appearance: 'error',
autoDismiss: true,
}
);
}
@@ -422,6 +424,7 @@ const SettingsMetadata = () => {
),
{
appearance: 'success',
autoDismiss: true,
}
);
}