mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
fix: handle partial seasons more reliably (#4116)
refactor: remove matchingOldSeason variable
This commit is contained in:
@@ -355,6 +355,7 @@ class AvailabilitySync {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
media.lastSeasonChange = new Date();
|
||||||
await mediaRepository.save(media);
|
await mediaRepository.save(media);
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
|
@@ -58,19 +58,16 @@ export class MediaRequestSubscriber
|
|||||||
// Find all seasons in the related media entity
|
// Find all seasons in the related media entity
|
||||||
// and see if they are available, then we can check
|
// and see if they are available, then we can check
|
||||||
// if the request contains the same seasons
|
// if the request contains the same seasons
|
||||||
|
const requestedSeasons =
|
||||||
|
entity.seasons?.map((entitySeason) => entitySeason.seasonNumber) ?? [];
|
||||||
const availableSeasons = entity.media.seasons.filter(
|
const availableSeasons = entity.media.seasons.filter(
|
||||||
(season) =>
|
(season) =>
|
||||||
season[entity.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE
|
season[entity.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE &&
|
||||||
|
requestedSeasons.includes(season.seasonNumber)
|
||||||
);
|
);
|
||||||
|
|
||||||
const isMediaAvailable =
|
const isMediaAvailable =
|
||||||
availableSeasons.length > 0 &&
|
availableSeasons.length > 0 &&
|
||||||
availableSeasons.every((availableSeason) =>
|
availableSeasons.length === requestedSeasons.length;
|
||||||
entity.seasons?.some(
|
|
||||||
(entitySeason) =>
|
|
||||||
entitySeason.seasonNumber === availableSeason.seasonNumber
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
entity.media[entity.is4k ? 'status4k' : 'status'] ===
|
entity.media[entity.is4k ? 'status4k' : 'status'] ===
|
||||||
|
@@ -31,7 +31,11 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updateRelatedMediaRequest(event: Media, is4k: boolean) {
|
private async updateRelatedMediaRequest(
|
||||||
|
event: Media,
|
||||||
|
databaseEvent: Media,
|
||||||
|
is4k: boolean
|
||||||
|
) {
|
||||||
const requestRepository = getRepository(MediaRequest);
|
const requestRepository = getRepository(MediaRequest);
|
||||||
const seasonRequestRepository = getRepository(SeasonRequest);
|
const seasonRequestRepository = getRepository(SeasonRequest);
|
||||||
|
|
||||||
@@ -67,17 +71,39 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
(mediaSeason) =>
|
(mediaSeason) =>
|
||||||
mediaSeason.seasonNumber === requestSeason.seasonNumber
|
mediaSeason.seasonNumber === requestSeason.seasonNumber
|
||||||
);
|
);
|
||||||
|
const matchingOldSeason = databaseEvent.seasons.find(
|
||||||
|
(oldSeason) =>
|
||||||
|
oldSeason.seasonNumber === requestSeason.seasonNumber
|
||||||
|
);
|
||||||
|
|
||||||
if (!matchingSeason) {
|
if (!matchingSeason) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
const currentSeasonStatus =
|
||||||
matchingSeason[request.is4k ? 'status4k' : 'status'] ===
|
matchingSeason[request.is4k ? 'status4k' : 'status'];
|
||||||
MediaStatus.AVAILABLE ||
|
const previousSeasonStatus =
|
||||||
matchingSeason[request.is4k ? 'status4k' : 'status'] ===
|
matchingOldSeason?.[request.is4k ? 'status4k' : 'status'];
|
||||||
MediaStatus.DELETED
|
|
||||||
);
|
const hasStatusChanged =
|
||||||
|
currentSeasonStatus !== previousSeasonStatus;
|
||||||
|
|
||||||
|
const shouldUpdate =
|
||||||
|
(hasStatusChanged ||
|
||||||
|
requestSeason.status === MediaRequestStatus.COMPLETED) &&
|
||||||
|
(currentSeasonStatus === MediaStatus.AVAILABLE ||
|
||||||
|
currentSeasonStatus === MediaStatus.DELETED);
|
||||||
|
|
||||||
|
if (shouldUpdate) {
|
||||||
|
// Handle season requests and mark them completed when
|
||||||
|
// that specific season becomes available
|
||||||
|
seasonRequestRepository.update(requestSeason.id, {
|
||||||
|
status: MediaRequestStatus.COMPLETED,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
shouldComplete = allSeasonsReady;
|
shouldComplete = allSeasonsReady;
|
||||||
@@ -90,38 +116,6 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await requestRepository.save(completedRequests);
|
await requestRepository.save(completedRequests);
|
||||||
|
|
||||||
// Handle season requests and mark them completed when
|
|
||||||
// that specific season becomes available
|
|
||||||
if (event.mediaType === 'tv') {
|
|
||||||
const seasonsToUpdate = relatedRequests.flatMap((request) => {
|
|
||||||
return request.seasons.filter((requestSeason) => {
|
|
||||||
const matchingSeason = event.seasons.find(
|
|
||||||
(mediaSeason) =>
|
|
||||||
mediaSeason.seasonNumber === requestSeason.seasonNumber
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!matchingSeason) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
matchingSeason[request.is4k ? 'status4k' : 'status'] ===
|
|
||||||
MediaStatus.AVAILABLE ||
|
|
||||||
matchingSeason[request.is4k ? 'status4k' : 'status'] ===
|
|
||||||
MediaStatus.DELETED
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
seasonsToUpdate.map((season) =>
|
|
||||||
seasonRequestRepository.update(season.id, {
|
|
||||||
status: MediaRequestStatus.COMPLETED,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +167,7 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
season[is4k ? 'status4k' : 'status'] !==
|
season[is4k ? 'status4k' : 'status'] !==
|
||||||
previousSeason[is4k ? 'status4k' : 'status']
|
previousSeason?.[is4k ? 'status4k' : 'status']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -184,7 +178,11 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
seasonStatusCheck(false))) &&
|
seasonStatusCheck(false))) &&
|
||||||
validStatuses.includes(event.entity.status)
|
validStatuses.includes(event.entity.status)
|
||||||
) {
|
) {
|
||||||
this.updateRelatedMediaRequest(event.entity as Media, false);
|
this.updateRelatedMediaRequest(
|
||||||
|
event.entity as Media,
|
||||||
|
event.databaseEntity as Media,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -192,7 +190,11 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
|
|||||||
(event.entity.mediaType === MediaType.TV && seasonStatusCheck(true))) &&
|
(event.entity.mediaType === MediaType.TV && seasonStatusCheck(true))) &&
|
||||||
validStatuses.includes(event.entity.status4k)
|
validStatuses.includes(event.entity.status4k)
|
||||||
) {
|
) {
|
||||||
this.updateRelatedMediaRequest(event.entity as Media, true);
|
this.updateRelatedMediaRequest(
|
||||||
|
event.entity as Media,
|
||||||
|
event.databaseEntity as Media,
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user