Skip to content

Commit 3292f11

Browse files
authored
fix(MediaRequestSubscriber): use event manager to get fresh media state for MEDIA_AVAILABLE notifications (#1825)
* fix(MediaRequestSubscriber): use event manager to get fresh media state for MEDIA_AVAILABLE notifications * refactor(MediaRequestSubscriber): streamline media availability notifications
1 parent c86ee0d commit 3292f11

1 file changed

Lines changed: 119 additions & 76 deletions

File tree

server/subscriber/MediaRequestSubscriber.ts

Lines changed: 119 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -33,52 +33,93 @@ import { EventSubscriber } from 'typeorm';
3333
export class MediaRequestSubscriber
3434
implements EntitySubscriberInterface<MediaRequest>
3535
{
36-
private async notifyAvailableMovie(entity: MediaRequest) {
36+
private async notifyAvailableMovie(
37+
entity: MediaRequest,
38+
event?: UpdateEvent<MediaRequest>
39+
) {
40+
// Get fresh media state using event manager
41+
let latestMedia: Media | null = null;
42+
if (event?.manager) {
43+
latestMedia = await event.manager.findOne(Media, {
44+
where: { id: entity.media.id },
45+
});
46+
}
47+
if (!latestMedia) {
48+
const mediaRepository = getRepository(Media);
49+
latestMedia = await mediaRepository.findOne({
50+
where: { id: entity.media.id },
51+
});
52+
}
53+
54+
// Check availability using fresh media state
3755
if (
38-
entity.media[entity.is4k ? 'status4k' : 'status'] ===
39-
MediaStatus.AVAILABLE
56+
!latestMedia ||
57+
latestMedia[entity.is4k ? 'status4k' : 'status'] !== MediaStatus.AVAILABLE
4058
) {
41-
const tmdb = new TheMovieDb();
59+
return;
60+
}
4261

43-
try {
44-
const movie = await tmdb.getMovie({
45-
movieId: entity.media.tmdbId,
46-
});
62+
const tmdb = new TheMovieDb();
4763

48-
notificationManager.sendNotification(Notification.MEDIA_AVAILABLE, {
49-
event: `${entity.is4k ? '4K ' : ''}Movie Request Now Available`,
50-
notifyAdmin: false,
51-
notifySystem: true,
52-
notifyUser: entity.requestedBy,
53-
subject: `${movie.title}${
54-
movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : ''
55-
}`,
56-
message: truncate(movie.overview, {
57-
length: 500,
58-
separator: /\s/,
59-
omission: '…',
60-
}),
61-
media: entity.media,
62-
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
63-
request: entity,
64-
});
65-
} catch (e) {
66-
logger.error('Something went wrong sending media notification(s)', {
67-
label: 'Notifications',
68-
errorMessage: e.message,
69-
mediaId: entity.id,
70-
});
71-
}
64+
try {
65+
const movie = await tmdb.getMovie({
66+
movieId: entity.media.tmdbId,
67+
});
68+
69+
notificationManager.sendNotification(Notification.MEDIA_AVAILABLE, {
70+
event: `${entity.is4k ? '4K ' : ''}Movie Request Now Available`,
71+
notifyAdmin: false,
72+
notifySystem: true,
73+
notifyUser: entity.requestedBy,
74+
subject: `${movie.title}${
75+
movie.release_date ? ` (${movie.release_date.slice(0, 4)})` : ''
76+
}`,
77+
message: truncate(movie.overview, {
78+
length: 500,
79+
separator: /\s/,
80+
omission: '…',
81+
}),
82+
media: latestMedia,
83+
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
84+
request: entity,
85+
});
86+
} catch (e) {
87+
logger.error('Something went wrong sending media notification(s)', {
88+
label: 'Notifications',
89+
errorMessage: e.message,
90+
mediaId: entity.id,
91+
});
7292
}
7393
}
7494

75-
private async notifyAvailableSeries(entity: MediaRequest) {
76-
// Find all seasons in the related media entity
77-
// and see if they are available, then we can check
78-
// if the request contains the same seasons
95+
private async notifyAvailableSeries(
96+
entity: MediaRequest,
97+
event?: UpdateEvent<MediaRequest>
98+
) {
99+
// Get fresh media state with seasons using event manager
100+
let latestMedia: Media | null = null;
101+
if (event?.manager) {
102+
latestMedia = await event.manager.findOne(Media, {
103+
where: { id: entity.media.id },
104+
relations: { seasons: true },
105+
});
106+
}
107+
if (!latestMedia) {
108+
const mediaRepository = getRepository(Media);
109+
latestMedia = await mediaRepository.findOne({
110+
where: { id: entity.media.id },
111+
relations: { seasons: true },
112+
});
113+
}
114+
115+
if (!latestMedia) {
116+
return;
117+
}
118+
119+
// Check availability using fresh media state
79120
const requestedSeasons =
80121
entity.seasons?.map((entitySeason) => entitySeason.seasonNumber) ?? [];
81-
const availableSeasons = entity.media.seasons.filter(
122+
const availableSeasons = latestMedia.seasons.filter(
82123
(season) =>
83124
season[entity.is4k ? 'status4k' : 'status'] === MediaStatus.AVAILABLE &&
84125
requestedSeasons.includes(season.seasonNumber)
@@ -87,44 +128,46 @@ export class MediaRequestSubscriber
87128
availableSeasons.length > 0 &&
88129
availableSeasons.length === requestedSeasons.length;
89130

90-
if (isMediaAvailable) {
91-
const tmdb = new TheMovieDb();
131+
if (!isMediaAvailable) {
132+
return;
133+
}
92134

93-
try {
94-
const tv = await tmdb.getTvShow({ tvId: entity.media.tmdbId });
95-
96-
notificationManager.sendNotification(Notification.MEDIA_AVAILABLE, {
97-
event: `${entity.is4k ? '4K ' : ''}Series Request Now Available`,
98-
subject: `${tv.name}${
99-
tv.first_air_date ? ` (${tv.first_air_date.slice(0, 4)})` : ''
100-
}`,
101-
message: truncate(tv.overview, {
102-
length: 500,
103-
separator: /\s/,
104-
omission: '…',
105-
}),
106-
notifyAdmin: false,
107-
notifySystem: true,
108-
notifyUser: entity.requestedBy,
109-
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
110-
media: entity.media,
111-
extra: [
112-
{
113-
name: 'Requested Seasons',
114-
value: entity.seasons
115-
.map((season) => season.seasonNumber)
116-
.join(', '),
117-
},
118-
],
119-
request: entity,
120-
});
121-
} catch (e) {
122-
logger.error('Something went wrong sending media notification(s)', {
123-
label: 'Notifications',
124-
errorMessage: e.message,
125-
mediaId: entity.id,
126-
});
127-
}
135+
const tmdb = new TheMovieDb();
136+
137+
try {
138+
const tv = await tmdb.getTvShow({ tvId: entity.media.tmdbId });
139+
140+
notificationManager.sendNotification(Notification.MEDIA_AVAILABLE, {
141+
event: `${entity.is4k ? '4K ' : ''}Series Request Now Available`,
142+
subject: `${tv.name}${
143+
tv.first_air_date ? ` (${tv.first_air_date.slice(0, 4)})` : ''
144+
}`,
145+
message: truncate(tv.overview, {
146+
length: 500,
147+
separator: /\s/,
148+
omission: '…',
149+
}),
150+
notifyAdmin: false,
151+
notifySystem: true,
152+
notifyUser: entity.requestedBy,
153+
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
154+
media: latestMedia,
155+
extra: [
156+
{
157+
name: 'Requested Seasons',
158+
value: entity.seasons
159+
.map((season) => season.seasonNumber)
160+
.join(', '),
161+
},
162+
],
163+
request: entity,
164+
});
165+
} catch (e) {
166+
logger.error('Something went wrong sending media notification(s)', {
167+
label: 'Notifications',
168+
errorMessage: e.message,
169+
mediaId: entity.id,
170+
});
128171
}
129172
}
130173

@@ -782,10 +825,10 @@ export class MediaRequestSubscriber
782825

783826
if (event.entity.status === MediaRequestStatus.COMPLETED) {
784827
if (event.entity.media.mediaType === MediaType.MOVIE) {
785-
this.notifyAvailableMovie(event.entity as MediaRequest);
828+
this.notifyAvailableMovie(event.entity as MediaRequest, event);
786829
}
787830
if (event.entity.media.mediaType === MediaType.TV) {
788-
this.notifyAvailableSeries(event.entity as MediaRequest);
831+
this.notifyAvailableSeries(event.entity as MediaRequest, event);
789832
}
790833
}
791834
}

0 commit comments

Comments
 (0)