fix: handle partial seasons more reliably (#4116)

refactor: remove matchingOldSeason variable
This commit is contained in:
Brandon Cohen
2025-04-18 18:20:30 -05:00
committed by GitHub
parent 064ae92134
commit 8cd53cdc3c
3 changed files with 50 additions and 50 deletions

View File

@@ -355,6 +355,7 @@ class AvailabilitySync {
);
}
media.lastSeasonChange = new Date();
await mediaRepository.save(media);
logger.info(

View File

@@ -58,19 +58,16 @@ export class MediaRequestSubscriber
// Find all seasons in the related media entity
// and see if they are available, then we can check
// if the request contains the same seasons
const requestedSeasons =
entity.seasons?.map((entitySeason) => entitySeason.seasonNumber) ?? [];
const availableSeasons = entity.media.seasons.filter(
(season) =>
season[entity.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE
season[entity.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE &&
requestedSeasons.includes(season.seasonNumber)
);
const isMediaAvailable =
availableSeasons.length > 0 &&
availableSeasons.every((availableSeason) =>
entity.seasons?.some(
(entitySeason) =>
entitySeason.seasonNumber === availableSeason.seasonNumber
)
);
availableSeasons.length === requestedSeasons.length;
if (
entity.media[entity.is4k ? 'status4k' : 'status'] ===

View File

@@ -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 seasonRequestRepository = getRepository(SeasonRequest);
@@ -67,17 +71,39 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
(mediaSeason) =>
mediaSeason.seasonNumber === requestSeason.seasonNumber
);
const matchingOldSeason = databaseEvent.seasons.find(
(oldSeason) =>
oldSeason.seasonNumber === requestSeason.seasonNumber
);
if (!matchingSeason) {
return false;
}
return (
matchingSeason[request.is4k ? 'status4k' : 'status'] ===
MediaStatus.AVAILABLE ||
matchingSeason[request.is4k ? 'status4k' : 'status'] ===
MediaStatus.DELETED
);
const currentSeasonStatus =
matchingSeason[request.is4k ? 'status4k' : 'status'];
const previousSeasonStatus =
matchingOldSeason?.[request.is4k ? 'status4k' : 'status'];
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;
@@ -90,38 +116,6 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
});
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 (
season[is4k ? 'status4k' : 'status'] !==
previousSeason[is4k ? 'status4k' : 'status']
previousSeason?.[is4k ? 'status4k' : 'status']
);
});
};
@@ -184,7 +178,11 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
seasonStatusCheck(false))) &&
validStatuses.includes(event.entity.status)
) {
this.updateRelatedMediaRequest(event.entity as Media, false);
this.updateRelatedMediaRequest(
event.entity as Media,
event.databaseEntity as Media,
false
);
}
if (
@@ -192,7 +190,11 @@ export class MediaSubscriber implements EntitySubscriberInterface<Media> {
(event.entity.mediaType === MediaType.TV && seasonStatusCheck(true))) &&
validStatuses.includes(event.entity.status4k)
) {
this.updateRelatedMediaRequest(event.entity as Media, true);
this.updateRelatedMediaRequest(
event.entity as Media,
event.databaseEntity as Media,
true
);
}
}