136 lines
5.2 KiB
JavaScript
136 lines
5.2 KiB
JavaScript
const moviedb = require('moviedb');
|
|
const convertTmdbToSeasoned = require('src/tmdb/convertTmdbToSeasoned');
|
|
|
|
const TMDB_METHODS = {
|
|
upcoming: { movie: 'miscUpcomingMovies' },
|
|
discover: { movie: 'discoverMovie', show: 'discoverTv' },
|
|
popular: { movie: 'miscPopularMovies', show: 'miscPopularTvs' },
|
|
nowplaying: { movie: 'miscNowPlayingMovies', show: 'tvOnTheAir' },
|
|
similar: { movie: 'movieSimilar', show: 'tvSimilar' },
|
|
search: { movie: 'searchMovie', show: 'searchTv', multi: 'searchMulti' },
|
|
info: { movie: 'movieInfo', show: 'tvInfo' },
|
|
};
|
|
|
|
class TMDB {
|
|
constructor(cache, apiKey, tmdbLibrary) {
|
|
this.cache = cache;
|
|
this.tmdbLibrary = tmdbLibrary || moviedb(apiKey);
|
|
this.cacheTags = {
|
|
search: 'se',
|
|
info: 'i',
|
|
upcoming: 'u',
|
|
discover: 'd',
|
|
popular: 'p',
|
|
nowplaying: 'n',
|
|
similar: 'si',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Retrieve a specific movie by id from TMDB.
|
|
* @param {Number} identifier of the movie you want to retrieve
|
|
* @returns {Promise} succeeds if movie was found
|
|
*/
|
|
lookup(identifier, type = 'movie') {
|
|
const query = { id: identifier };
|
|
const cacheKey = `${this.cacheTags.info}:${type}:${identifier}`;
|
|
return Promise.resolve()
|
|
.then(() => this.cache.get(cacheKey))
|
|
.catch(() => this.tmdb(this.tmdbMethod('info', type), query))
|
|
.catch(() => { throw new Error('Could not find a movie with that id.'); })
|
|
.then(response => this.cache.set(cacheKey, response))
|
|
.then((response) => {
|
|
try {
|
|
return convertTmdbToSeasoned(response, type);
|
|
} catch (parseError) {
|
|
console.error(parseError);
|
|
throw new Error('Could not parse movie.');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Retrive list of of items from TMDB matching the query and/or type given.
|
|
* @param {queryText, page, type} the page number to specify in the request for discover,
|
|
* @returns {Promise} dict with query results, current page and total_pages
|
|
*/
|
|
search(text, page = 1, type = 'multi') {
|
|
const query = { query: text, page };
|
|
const cacheKey = `${this.cacheTags.search}:${page}:${type}:${text}`;
|
|
return Promise.resolve()
|
|
.then(() => this.cache.get(cacheKey))
|
|
.catch(() => this.tmdb(this.tmdbMethod('search', type), query))
|
|
.catch(() => { throw new Error('Could not search for movies/shows at tmdb.'); })
|
|
.then(response => this.cache.set(cacheKey, response))
|
|
.then(response => this.mapResults(response))
|
|
.catch((error) => { throw new Error(error); })
|
|
.then(([mappedResults, pagenumber, totalpages, total_results]) => ({
|
|
results: mappedResults, page: pagenumber, total_results, total_pages: totalpages,
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Fetches a given list from tmdb.
|
|
* @param {listName} List we want to fetch.
|
|
* @param {type} The to specify in the request for discover (default 'movie').
|
|
* @param {id} When finding similar a id can be added to query
|
|
* @param {page} Page number we want to fetch.
|
|
* @returns {Promise} dict with query results, current page and total_pages
|
|
*/
|
|
listSearch(listName, type = 'movie', id, page = '1') {
|
|
const params = { id, page };
|
|
const cacheKey = `${this.cacheTags[listName]}:${type}:${id}:${page}`;
|
|
return Promise.resolve()
|
|
.then(() => this.cache.get(cacheKey))
|
|
.catch(() => this.tmdb(this.tmdbMethod(listName, type), params))
|
|
.then(response => this.cache.set(cacheKey, response))
|
|
.then(response => this.mapResults(response, type))
|
|
.catch((error) => { throw new Error(error); })
|
|
.then(([mappedResults, pagenumber, totalpages, total_results]) => ({
|
|
results: mappedResults, page: pagenumber, total_pages: totalpages, total_results,
|
|
}));
|
|
}
|
|
|
|
tmdbMethod(apiMethod, type) {
|
|
const method = TMDB_METHODS[apiMethod][type];
|
|
if (method !== undefined) return method;
|
|
throw new Error('Could not find tmdb api method.');
|
|
}
|
|
|
|
/**
|
|
* Maps our response from tmdb api to a movie/show object.
|
|
* @param {response} JSON response from tmdb.
|
|
* @param {type} The type declared in listSearch.
|
|
* @returns {Promise} dict with tmdb results, mapped as movie/show objects.
|
|
*/
|
|
mapResults(response, type) {
|
|
return Promise.resolve()
|
|
.then(() => {
|
|
const mappedResults = response.results.filter((element) => {
|
|
return (element.type === 'movie' || element.type === 'tv');
|
|
}).map((element) => convertTmdbToSeasoned(element, type));
|
|
return [mappedResults, response.page, response.total_pages, response.total_results];
|
|
})
|
|
.catch((error) => { throw new Error(error); });
|
|
}
|
|
|
|
tmdb(method, argument) {
|
|
return new Promise((resolve, reject) => {
|
|
const callback = (error, reponse) => {
|
|
if (error) {
|
|
return reject(error);
|
|
}
|
|
return resolve(reponse);
|
|
};
|
|
|
|
if (!argument) {
|
|
this.tmdbLibrary[method](callback);
|
|
} else {
|
|
this.tmdbLibrary[method](argument, callback);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = TMDB;
|