Skip to content

Commit dc3fa8f

Browse files
committed
feat(graphql-api): Added find related movies
1 parent e1dbde0 commit dc3fa8f

File tree

6 files changed

+154
-37
lines changed

6 files changed

+154
-37
lines changed

apps/graphql-api/src/app.module.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ConfigService } from './shared/config/config.service'
77
import { ModelsModule } from './shared/models/models.module'
88
import { TorrentModule } from './shared/torrent/torrent.module'
99
import { PubSubModule } from './shared/pub-sub/pub-sub.module'
10+
import { TraktModule } from './shared/trakt/trakt.module'
1011

1112
import { StatusModule } from './status/status.module'
1213
import { CalendarModule } from './calendar/calendar.module'
@@ -29,6 +30,7 @@ import { WatchModule } from './watch/watch.module'
2930
ConfigModule,
3031
TorrentModule,
3132
PubSubModule,
33+
TraktModule,
3234

3335
// GraphQL
3436
StatusModule,
@@ -60,12 +62,17 @@ import { WatchModule } from './watch/watch.module'
6062
}),
6163

6264
// Enable Graphql
63-
GraphQLModule.forRoot({
64-
debug: true,
65-
playground: true,
66-
installSubscriptionHandlers: true,
67-
autoSchemaFile: 'schema.gql',
68-
introspection: true
65+
GraphQLModule.forRootAsync({
66+
imports: [ConfigModule],
67+
inject: [ConfigService],
68+
useFactory: (configService: ConfigService) => ({
69+
debug: configService.isDevelopment,
70+
tracing: configService.isDevelopment,
71+
playground: true,
72+
installSubscriptionHandlers: true,
73+
autoSchemaFile: 'schema.gql',
74+
introspection: true,
75+
})
6976
})
7077
]
7178
})

apps/graphql-api/src/movies/movies.resolver.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ import { Movie } from '@pct-org/mongo-models'
55
import { MovieArgs } from './dto/movie.args'
66
import { MoviesArgs } from './dto/movies.args'
77
import { MoviesService } from './movies.service'
8+
import { TraktService } from '../shared/trakt/trakt.service'
89

910
@Resolver(of => Movie)
1011
export class MoviesResolver {
1112

12-
constructor(private readonly moviesService: MoviesService) {}
13+
constructor(
14+
private readonly moviesService: MoviesService,
15+
private readonly traktService: TraktService
16+
) {}
1317

1418
@Query(returns => Movie)
1519
movie(@Args() movieArgs: MovieArgs): Promise<Movie> {
@@ -21,4 +25,11 @@ export class MoviesResolver {
2125
return this.moviesService.findAll(moviesArgs)
2226
}
2327

28+
@Query(returns => [Movie])
29+
relatedMovies(
30+
@Args({ name: '_id', description: 'Id of the movie to find related movies for.' }) _id: string
31+
): Promise<Movie[]> {
32+
return this.traktService.findRelatedMovies(_id)
33+
}
34+
2435
}

apps/graphql-api/src/movies/movies.service.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { InjectModel } from '@nestjs/mongoose'
33
import { Model } from 'mongoose'
44
import { Movie } from '@pct-org/mongo-models'
55

6-
import { MovieArgs } from './dto/movie.args'
76
import { MoviesArgs } from './dto/movies.args'
87
import { ContentService } from '../shared/content/content.service'
98

@@ -34,6 +33,20 @@ export class MoviesService extends ContentService {
3433
)
3534
}
3635

36+
findAllWithIDS(ids: string[], lean = true): Promise<Movie[]> {
37+
return this.movieModel.find(
38+
{
39+
_id: {
40+
$in: ids
41+
}
42+
},
43+
{},
44+
{
45+
lean
46+
}
47+
)
48+
}
49+
3750
updateOne(movie: Movie): Promise<Movie> {
3851
return this.movieModel.findOneAndUpdate({
3952
_id: movie._id
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Module, Global } from '@nestjs/common'
2+
3+
import { ShowsService } from '../../shows/shows.service'
4+
import { MoviesService } from '../../movies/movies.service'
5+
import { TraktService } from './trakt.service'
6+
7+
@Global()
8+
@Module({
9+
providers: [
10+
TraktService,
11+
ShowsService,
12+
MoviesService
13+
],
14+
exports: [
15+
TraktService
16+
]
17+
})
18+
export class TraktModule {
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { Injectable } from '@nestjs/common'
2+
import * as Trakt from 'trakt.tv'
3+
import { Show, Movie } from '@pct-org/mongo-models'
4+
5+
import { ConfigService } from '../config/config.service'
6+
import { ShowsService } from '../../shows/shows.service'
7+
import { MoviesService } from '../../movies/movies.service'
8+
9+
@Injectable()
10+
export class TraktService {
11+
12+
private readonly trakt
13+
14+
constructor(
15+
private readonly configService: ConfigService,
16+
private readonly showsService: ShowsService,
17+
private readonly moviesService: MoviesService
18+
) {
19+
const clientId = this.configService.get(ConfigService.TRAKT_KEY)
20+
21+
if (clientId) {
22+
try {
23+
this.trakt = new Trakt({
24+
client_id: this.configService.get(ConfigService.TRAKT_KEY)
25+
})
26+
} catch (err) {
27+
// Do nothing
28+
}
29+
}
30+
}
31+
32+
async mostWatchedWeeklyShows(): Promise<Show[]> {
33+
// Trakt is not setup
34+
if (!this.trakt) {
35+
return []
36+
}
37+
38+
let showIds = []
39+
40+
try {
41+
const traktMostWatched = await this.trakt.shows.watched({
42+
period: 'weekly',
43+
limit: 20
44+
})
45+
46+
showIds = traktMostWatched.map((item) => item.show.ids.imdb)
47+
} catch (e) {
48+
}
49+
50+
if (showIds.length === 0) {
51+
return []
52+
}
53+
54+
const shows = await this.showsService.findAllWithIDS(showIds)
55+
56+
return shows.sort((showA, showB) =>
57+
showIds.indexOf(showA._id) - showIds.indexOf(showB._id)
58+
)
59+
}
60+
61+
async findRelatedMovies(movieImdbId): Promise<Movie[]> {
62+
// Trakt is not setup
63+
if (!this.trakt) {
64+
return []
65+
}
66+
67+
let movieIds = []
68+
69+
try {
70+
const traktRelatedMovies = await this.trakt.movies.related({
71+
id: movieImdbId,
72+
limit: 30
73+
})
74+
75+
movieIds = traktRelatedMovies.map((item) => item.ids.imdb)
76+
} catch (e) {
77+
}
78+
79+
if (movieIds.length === 0) {
80+
return []
81+
}
82+
83+
const movies = await this.moviesService.findAllWithIDS(movieIds)
84+
85+
return this.sortItemsOnIds(movies, movieIds)
86+
}
87+
88+
private sortItemsOnIds(items, ids) {
89+
return items.sort((itemA, itemB) =>
90+
ids.indexOf(itemA._id) - ids.indexOf(itemB._id)
91+
)
92+
}
93+
}

apps/graphql-api/src/shows/shows.resolver.ts

+3-29
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
11
import { Args, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'
22
import { Show, Season } from '@pct-org/mongo-models'
3-
import * as Trakt from 'trakt.tv'
43

54
import { ShowArgs } from './dto/show.args'
65
import { ShowsArgs } from './dto/shows.args'
76
import { ShowsService } from './shows.service'
87

9-
import { ConfigService } from '../shared/config/config.service'
108
import { SeasonsService } from '../seasons/seasons.service'
119
import { DownloadsService } from '../downloads/downloads.service'
10+
import { TraktService } from '../shared/trakt/trakt.service'
1211

1312
@Resolver(of => Show)
1413
export class ShowsResolver {
1514

16-
private readonly trakt
17-
1815
constructor(
1916
private readonly showsService: ShowsService,
2017
private readonly seasonsService: SeasonsService,
2118
private readonly downloadsService: DownloadsService,
22-
private readonly configService: ConfigService
19+
private readonly traktService: TraktService
2320
) {
24-
this.trakt = new Trakt({
25-
// eslint-disable-next-line @typescript-eslint/camelcase
26-
client_id: this.configService.get(ConfigService.TRAKT_KEY)
27-
})
2821
}
2922

3023
/**
@@ -60,26 +53,7 @@ export class ShowsResolver {
6053
*/
6154
@Query(returns => [Show], { description: 'Get most watched shows.' })
6255
async mostWatchedShows(): Promise<Show[]> {
63-
let showIds = []
64-
65-
try {
66-
const traktMostWatched = await this.trakt.shows.watched({
67-
period: 'weekly'
68-
})
69-
70-
showIds = traktMostWatched.map((item) => item.show.ids.imdb)
71-
} catch (e) {
72-
}
73-
74-
if (showIds.length === 0) {
75-
return []
76-
}
77-
78-
const shows = await this.showsService.findAllWithIDS(showIds)
79-
80-
return shows.sort((showA, showB) =>
81-
showIds.indexOf(showA._id) - showIds.indexOf(showB._id),
82-
)
56+
return this.traktService.mostWatchedWeeklyShows()
8357
}
8458

8559
/**

0 commit comments

Comments
 (0)