Skip to content

Commit 6a4d0f6

Browse files
committed
feat(season-helper): Added format and enhance
1 parent 2b482cf commit 6a4d0f6

File tree

2 files changed

+175
-11
lines changed

2 files changed

+175
-11
lines changed

libs/scraper/helpers/season/src/season-helper.module.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { Module } from '@nestjs/common'
22
import { EpisodeHelperModule } from '@pct-org/scraper/helpers/episode'
3+
import { TmdbModule } from '@pct-org/services/tmdb'
34

45
import { SeasonHelperService } from './season-helper.service'
56

67
@Module({
78
imports: [
9+
TmdbModule,
810
EpisodeHelperModule,
911
],
1012
providers: [

libs/scraper/helpers/season/src/season-helper.service.ts

+173-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { Inject, Injectable, Logger } from '@nestjs/common'
2-
import { ScrapedShowTorrent } from '@pct-org/scraper/providers/base'
2+
import { ScrapedShowTorrents } from '@pct-org/scraper/providers/base'
33
import { InjectModel } from '@nestjs/mongoose'
4-
import { SeasonModel, Season } from '@pct-org/mongo-models'
5-
import { TraktSeason } from '@pct-org/services/trakt'
4+
import { SeasonModel, Season, Show, Episode } from '@pct-org/mongo-models'
65
import { EpisodeHelperService } from '@pct-org/scraper/helpers/episode'
6+
import { TYPE_SEASON } from '@pct-org/constants/item-types'
7+
import { defaultEpisodeImages, defaultSeasonImages } from '@pct-org/constants/default-image-sizes'
8+
import { TmdbService } from '@pct-org/services/tmdb'
9+
import * as pMap from 'p-map'
710

811
@Injectable()
912
export class SeasonHelperService {
@@ -14,29 +17,120 @@ export class SeasonHelperService {
1417
@Inject()
1518
private readonly episodeHelperService: EpisodeHelperService
1619

20+
@Inject()
21+
private readonly tmdbService: TmdbService
22+
1723
protected readonly logger = new Logger('SeasonHelper')
1824

19-
public formatTraktSeasons(traktSeasons: TraktSeason[], torrents: ScrapedShowTorrent[]): Season[] {
20-
const formattedSeasons = []
25+
public formatTraktSeasons(show: Show, torrents: ScrapedShowTorrents): Season[] {
26+
const formattedSeasons: Season[] = []
27+
let traktSeasons = show._traktSeasons
2128
let seasonNumbers: any[] = Object.keys(torrents)
2229

2330
// If we don't have any episodes for specials then also remove it from trakt
2431
if (!seasonNumbers.includes('0') && !seasonNumbers.includes(0)) {
2532
traktSeasons = traktSeasons.filter((traktSeason) => traktSeason.number !== 0)
2633
}
2734

28-
// TODO:: Format the trakt seasons here
35+
traktSeasons.forEach((traktSeason) => {
36+
const formattedEpisodes = traktSeason.episodes.map((traktEpisode) => (
37+
this.episodeHelperService.formatTraktEpisode(
38+
show,
39+
traktEpisode,
40+
torrents?.[traktEpisode.season]?.[traktEpisode.number] ?? []
41+
)
42+
))
43+
44+
// Remove it from the episodes seasons
45+
seasonNumbers = seasonNumbers.filter((season) => parseInt(season, 10) !== traktSeason.number)
46+
47+
let seasonFirstAired = Number(new Date(traktSeason?.first_aired)) ?? 0
48+
49+
// If it's null then use the one from the first episode
50+
if (seasonFirstAired === 0 && formattedEpisodes.length > 0) {
51+
const firstEpisode = formattedEpisodes[0]
2952

30-
return []
53+
seasonFirstAired = firstEpisode.firstAired
54+
}
55+
56+
formattedSeasons.push({
57+
_id: `${show._id}-${traktSeason.number}`,
58+
tmdbId: traktSeason.ids.tmdb,
59+
showImdbId: show._id,
60+
61+
firstAired: seasonFirstAired,
62+
number: traktSeason.number,
63+
synopsis: null,
64+
title: traktSeason.title,
65+
type: TYPE_SEASON,
66+
images: defaultSeasonImages,
67+
createdAt: Number(new Date()),
68+
updatedAt: Number(new Date()),
69+
70+
episodes: this.sortItems(formattedEpisodes) as Episode[],
71+
72+
_traktSeason: true
73+
})
74+
})
75+
76+
// If we still have some seasons left add them with what we can
77+
if (seasonNumbers.length > 0) {
78+
// TODO:: Maybe check the titles and check if they match the
79+
// name of the show then _traktSeason can be true
80+
// Also rename trakt season then to a better name
81+
seasonNumbers.forEach((seasonNr) => {
82+
const formattedEpisodes: Episode[] = []
83+
84+
Object.keys(torrents[seasonNr]).map((episodeNr) => {
85+
formattedEpisodes.push(this.episodeHelperService.formatUnknownEpisode(
86+
show,
87+
parseInt(seasonNr, 10),
88+
parseInt(episodeNr, 10),
89+
torrents[seasonNr][episodeNr]
90+
))
91+
})
92+
93+
formattedSeasons.push({
94+
_id: `${show._id}-${seasonNr}`,
95+
tmdbId: null,
96+
showImdbId: show._id,
97+
98+
firstAired: Number(new Date()),
99+
number: parseInt(seasonNr, 10),
100+
synopsis: null,
101+
title: `Season ${seasonNr}`,
102+
type: TYPE_SEASON,
103+
images: defaultSeasonImages,
104+
createdAt: Number(new Date()),
105+
updatedAt: Number(new Date()),
106+
107+
episodes: this.sortItems(formattedEpisodes) as Episode[],
108+
109+
_traktSeason: false
110+
})
111+
})
112+
}
113+
114+
return this.sortItems(formattedSeasons) as Season[]
31115
}
32116

33-
public async enhanceSeasons(seasons: Season[]): Promise<Season[]> {
34-
// TODO:: Enhance the seasons here
35-
return seasons
117+
public async enhanceSeasons(show: Show, seasons: Season[]): Promise<Season[]> {
118+
const enhancedSeasons: (boolean | Season)[] = await pMap(
119+
seasons,
120+
(season) => {
121+
return this.enhanceSeason(show, season)
122+
},
123+
{
124+
concurrency: 1
125+
}
126+
)
127+
128+
// Remove all the falsy seasons
129+
return enhancedSeasons.filter(Boolean) as Season[]
36130
}
37131

38132
public async addSeasonsToDatabase(seasons: Season[]): Promise<void> {
39-
await Promise.all(seasons.map(this.addSeasonToDatabase))
133+
await Promise.all(seasons.map((season) => this.addSeasonToDatabase(season)))
40134
}
41135

42136
public async updateSeasonsInDatabase(seasons: Season[]): Promise<void> {
@@ -71,4 +165,72 @@ export class SeasonHelperService {
71165
await this.episodeHelperService.updateEpisodesInDatabase(episodes)
72166
}
73167

168+
private async enhanceSeason(show: Show, season: Season): Promise<Season | boolean> {
169+
try {
170+
const tmdbSeason = await this.tmdbService.getSeasonInfo(show, season)
171+
172+
// Also enhance all the episodes
173+
season.episodes.map((episode) => {
174+
const tmdbEpisode = tmdbSeason.episodes.find((tmdbEpisode) => (
175+
tmdbEpisode.episodeNumber === episode.number
176+
))
177+
178+
// If we have a matching episode then enhance it
179+
if (tmdbEpisode) {
180+
return {
181+
...episode,
182+
183+
title: episode.title !== `Episode ${episode.number}`
184+
? episode.title
185+
: tmdbEpisode.name,
186+
synopsis: episode.synopsis || tmdbEpisode.overview,
187+
firstAired: tmdbEpisode.airDate && episode.firstAired === 0
188+
? new Date(tmdbEpisode.airDate).getTime()
189+
: episode.firstAired,
190+
images: {
191+
...episode.images,
192+
193+
poster: tmdbEpisode.stillPath
194+
? this.tmdbService.formatImage(tmdbEpisode.stillPath)
195+
: defaultEpisodeImages.poster
196+
}
197+
}
198+
}
199+
200+
return episode
201+
})
202+
203+
return {
204+
...season,
205+
206+
title: season.title !== `Season ${season.number}`
207+
? season.title
208+
: tmdbSeason.name,
209+
synopsis: season.synopsis || tmdbSeason.overview,
210+
firstAired: tmdbSeason.airDate && season.firstAired === 0
211+
? new Date(tmdbSeason.airDate).getTime()
212+
: season.firstAired,
213+
images: {
214+
...season.images,
215+
216+
poster: tmdbSeason.posterPath
217+
? this.tmdbService.formatImage(tmdbSeason.posterPath)
218+
: defaultSeasonImages.poster
219+
}
220+
}
221+
} catch (err) {
222+
// If it was not a trakt season don't return it at all
223+
if (!season._traktSeason) {
224+
return false
225+
}
226+
}
227+
228+
// We ware not able to enhance it, return trakt season
229+
return season
230+
}
231+
232+
private sortItems(items: Episode[] | Season[]): Episode[] | Season[] {
233+
return items.sort((a, b) => a.number - b.number)
234+
}
235+
74236
}

0 commit comments

Comments
 (0)