diff --git a/seasoned_api/src/tmdb/tmdb.js b/seasoned_api/src/tmdb/tmdb.js index 979dda1..4d95e96 100644 --- a/seasoned_api/src/tmdb/tmdb.js +++ b/seasoned_api/src/tmdb/tmdb.js @@ -2,6 +2,8 @@ const moviedb = require('km-moviedb'); const convertTmdbToMovie = require('src/tmdb/convertTmdbToMovie'); const convertTmdbToShow = require('src/tmdb/convertTmdbToShow'); const convertTmdbToPerson = require('src/tmdb/convertTmdbToPerson'); + +const { Credits } = require('src/tmdb/types'); // const { tmdbInfo } = require('src/tmdb/types') class TMDB { @@ -13,7 +15,8 @@ class TMDB { movieSearch: 'mos', showSearch: 'ss', personSearch: 'ps', - movieInfo: 'mi', + movieInfo: 'mi', + movieCredits: 'mc', showInfo: 'si', personInfo: 'pi', miscNowPlayingMovies: 'npm', @@ -106,6 +109,31 @@ class TMDB { .then(([movies, credits, releaseDates]) => this.cache.set(cacheKey, [movies, credits, releaseDates])) .then(([movies, credits, releaseDates]) => convertTmdbToMovie(movies, credits, releaseDates)) } + + tmdbCreditsError(error) { + if (error.status === 404) { + throw { + status: 404, + message: error.response.body.status_message + } + } + + throw { + status: 500, + message: 'An unexpected error occured while fetching credits from tmdb' + } + } + + movieCredits(identifier) { + const query = { id: identifier } + const cacheKey = `${this.cacheTags.movieCredits}:${identifier}` + + return this.cache.get(cacheKey) + .catch(() => this.tmdb('movieCredits', query)) + .catch(tmdbError => this.tmdbCreditsError(tmdbError)) + .then(credits => this.cache.set(cacheKey, credits, 1)) + .then(credits => Credits.convertFromTmdbResponse(credits)) + } /** * Retrieve a specific show by id from TMDB. diff --git a/seasoned_api/src/tmdb/types.js b/seasoned_api/src/tmdb/types.js index 5c8891e..08de9ab 100644 --- a/seasoned_api/src/tmdb/types.js +++ b/seasoned_api/src/tmdb/types.js @@ -1,5 +1,6 @@ import Movie from './types/movie.js' import Show from './types/show.js' import Person from './types/person.js' +import Credits from './types/credits.js' -module.exports = { Movie, Show, Person } +module.exports = { Movie, Show, Person, Credits } diff --git a/seasoned_api/src/tmdb/types/credits.js b/seasoned_api/src/tmdb/types/credits.js new file mode 100644 index 0000000..0e2213e --- /dev/null +++ b/seasoned_api/src/tmdb/types/credits.js @@ -0,0 +1,76 @@ +class Credits { + constructor(id, cast=[], crew=[]) { + this.id = id; + this.cast = cast; + this.crew = crew; + this.type = 'credits'; + } + + static convertFromTmdbResponse(response) { + console.log('this is our credits response', response) + const { id, cast, crew } = response; + + const allCast = cast.map(cast => + new CastMember(cast.character, cast.gender, cast.id, cast.name, cast.profile_path)) + const allCrew = crew.map(crew => + new CrewMember(crew.department, crew.gender, crew.id, crew.job, crew.name, crew.profile_path)) + + return new Credits(id, allCast, allCrew) + } + + createJsonResponse() { + return { + id: this.id, + cast: this.cast, + crew: this.crew + } + } +} + +class CastMember { + constructor(character, gender, id, name, profile_path) { + this.character = character; + this.gender = gender; + this.id = id; + this.name = name; + this.profile_path = profile_path; + this.type = 'cast member'; + } + + createJsonResponse() { + return { + character: this.character, + gender: this.gender, + id: this.id, + name: this.name, + profile_path: this.profile_path, + type: this.type + } + } +} + +class CrewMember { + constructor(department, gender, id, job, name, profile_path) { + this.department = department; + this.gender = gender; + this.id = id; + this.job = job; + this.name = name; + this.profile_path = profile_path; + this.type = 'crew member'; + } + + createJsonResponse() { + return { + department: this.department, + gender: this.gender, + id: this.id, + job: this.job, + name: this.name, + profile_path: this.profile_path, + type: this.type + } + } +} + +module.exports = Credits; diff --git a/seasoned_api/src/tmdb/types/movie.js b/seasoned_api/src/tmdb/types/movie.js index 1d443d2..d3e4a23 100644 --- a/seasoned_api/src/tmdb/types/movie.js +++ b/seasoned_api/src/tmdb/types/movie.js @@ -1,6 +1,7 @@ class Movie { - constructor(id, title, year=null, overview=null, poster=null, backdrop=null, rank=null, genres=null, status=null, - tagline=null, runtime=null, imdb_id=null) { + constructor(id, title, year=undefined, overview=undefined, poster=undefined, + backdrop=undefined, rank=undefined, genres=undefined, status=undefined, + tagline=undefined, runtime=undefined, imdb_id=undefined) { this.id = id; this.title = title; this.year = year; @@ -15,6 +16,24 @@ class Movie { this.imdb_id = imdb_id; this.type = 'movie'; } + + createJsonResponse() { + return { + id: this.id, + title: this.title, + year: this.year, + overview: this.overview, + poster: this.poster, + backdrop: this.backdrop, + rank: this.rank, + genres: this.genres, + status: this.status, + tagline: this.tagline, + runtime: this.runtime, + imdb_id: this.imdb_id, + type: this.type + } + } } module.exports = Movie; diff --git a/seasoned_api/src/tmdb/types/person.js b/seasoned_api/src/tmdb/types/person.js index 4c469fb..d051a2a 100644 --- a/seasoned_api/src/tmdb/types/person.js +++ b/seasoned_api/src/tmdb/types/person.js @@ -8,6 +8,18 @@ class Person { this.known_for = known_for; this.type = 'person'; } + + createJsonResponse() { + return { + id: this.id, + name: this.name, + poster: this.poster, + birthday: this.birthday, + deathday: this.deathday, + known_for: this.known_for, + type: this.type + } + } } module.exports = Person; diff --git a/seasoned_api/src/tmdb/types/show.js b/seasoned_api/src/tmdb/types/show.js index 5aaf8d1..d6b69d5 100644 --- a/seasoned_api/src/tmdb/types/show.js +++ b/seasoned_api/src/tmdb/types/show.js @@ -1,20 +1,40 @@ class Show { - constructor(id, title, year=null, seasons=null, episodes=null, overview=null, rank=null, genres=null, - poster=null, backdrop=null, status=null, runtime=null) { + constructor(id, title, year=null, overview=null, poster=null, backdrop=null, + seasons=null, episodes=null, rank=null, genres=null, status=null, + runtime=null) { this.id = id; this.title = title; this.year = year; - this.seasons = seasons; - this.episodes = episodes; this.overview = overview; - this.rank = rank; - this.genres = genres; this.poster = poster; this.backdrop = backdrop; + this.seasons = seasons; + this.episodes = episodes; + this.rank = rank; + this.genres = genres; this.status = status; this.runtime = runtime; this.type = 'show'; } + + createJsonResponse() { + return { + id: this.id, + title: this.title, + year: this.year, + overview: this.overview, + poster: this.poster, + backdrop: this.backdrop, + seasons: this.seasons, + episodes: this.episodes, + rank: this.rank, + genres: this.genres, + status: this.status, + runtime: this.runtime, + // imdb_id: this.imdb_id, + type: this.type + } + } } module.exports = Show; diff --git a/seasoned_api/src/webserver/controllers/movie/credits.js b/seasoned_api/src/webserver/controllers/movie/credits.js new file mode 100644 index 0000000..cd31924 --- /dev/null +++ b/seasoned_api/src/webserver/controllers/movie/credits.js @@ -0,0 +1,25 @@ +const configuration = require('src/config/configuration').getInstance(); +const Cache = require('src/tmdb/cache'); +const TMDB = require('src/tmdb/tmdb'); + +const cache = new Cache(); +const tmdb = new TMDB(cache, configuration.get('tmdb', 'apiKey')); + +const movieCreditsController = (req, res) => { + const movieId = req.params.id; + + tmdb.movieCredits(movieId) + .then(credits => res.send(credits.createJsonResponse())) + .catch(error => { + const { status, message } = error; + + if (status && message) { + res.status(error.status).send({ success: false, error: error.message }) + } else { + // TODO log unhandled errors + res.status(500).send({ message: 'An unexpected error occured while requesting movie credits' }) + } + }) +} + +module.exports = movieCreditsController; \ No newline at end of file