Refactoring where now we can search lists and lookup movies or shows by using the new tmdbMethod function which takes the api endpoint variable and type to return the appropriate tmdbMethod name for the matching api call to tmdb. Removed a lot of the globally defined variables.

This commit is contained in:
2018-02-07 13:42:46 +01:00
parent 7e874bbc9d
commit 6fd65fdb23

View File

@@ -1,33 +1,53 @@
const moviedb = require('moviedb'); const moviedb = require('moviedb');
const convertTmdbToSeasoned = require('src/tmdb/convertTmdbToSeasoned'); const convertTmdbToSeasoned = require('src/tmdb/convertTmdbToSeasoned');
var methodTypes = { 'movie': 'searchMovie', 'show': 'searchTv', 'multi': 'searchMulti', 'movieInfo': 'movieInfo',
'tvInfo': 'tvInfo', 'upcomingMovies': 'miscUpcomingMovies', 'discoverMovie': 'discoverMovie',
'discoverShow': 'discoverTv', 'popularMovies': 'miscPopularMovies', 'popularShows': 'miscPopularTvs',
'nowPlayingMovies': 'miscNowPlayingMovies', 'nowAiringShows': 'tvOnTheAir', 'movieSimilar': 'movieSimilar',
'showSimilar': 'tvSimilar' };
const TMDB_METHODS = {
const TYPE_LIST = ['upcoming', 'discover', 'popular', 'nowplaying', 'similar'] upcoming: { movie: 'miscUpcomingMovies' },
const TMDB_TYPE_LIST = { discover: { movie: 'discoverMovie', show: 'discoverTv' },
'upcomingmovie': 'miscUpcomingMovies', 'discovermovie': 'discoverMovie', popular: { movie: 'miscPopularMovies', show: 'miscPopularTvs' },
'discovershow': 'discoverTv', 'popularmovie': 'miscPopularMovies', nowplaying: { movie: 'miscNowPlayingMovies', show: 'tvOnTheAir' },
'popularshow': 'miscPopularTvs', 'nowplayingmovie': 'miscNowPlayingMovies', similar: { movie: 'movieSimilar', show: 'tvSimilar' },
'nowplayingshow': 'tvOnTheAir', 'similarmovie': 'movieSimilar', 'similarshow': 'tvSimilar', search: { movie: 'searchMovie', show: 'searchTv', multi: 'searchMulti' },
info: { movie: 'movieInfo', show: 'tvInfo' },
}; };
class TMDB { class TMDB {
constructor(cache, apiKey, tmdbLibrary) { constructor(cache, apiKey, tmdbLibrary) {
this.cache = cache this.cache = cache;
this.tmdbLibrary = tmdbLibrary || moviedb(apiKey); this.tmdbLibrary = tmdbLibrary || moviedb(apiKey);
this.cacheTags = { this.cacheTags = {
'search': 'se', search: 'se',
'info': 'i', info: 'i',
'upcoming': 'u', upcoming: 'u',
'discover': 'd', discover: 'd',
'popular': 'p', popular: 'p',
'nowplaying': 'n', nowplaying: 'n',
'similar': 'si', 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.');
}
});
} }
/** /**
@@ -36,78 +56,46 @@ class TMDB {
* @returns {Promise} dict with query results, current page and total_pages * @returns {Promise} dict with query results, current page and total_pages
*/ */
search(text, page = 1, type = 'multi') { search(text, page = 1, type = 'multi') {
const query = { 'query': text, 'page': page }; const query = { query: text, page };
const cacheKey = `${this.cacheTags.search}:${page}:${type}:${text}`; const cacheKey = `${this.cacheTags.search}:${page}:${type}:${text}`;
return Promise.resolve() return Promise.resolve()
.then(() => this.cache.get(cacheKey)) .then(() => this.cache.get(cacheKey))
.catch(() => this.tmdb(methodTypes[type], query)) .catch(() => this.tmdb(this.tmdbMethod('search', type), query))
.catch(() => { throw new Error('Could not search for movies/shows at tmdb.'); }) .catch(() => { throw new Error('Could not search for movies/shows at tmdb.'); })
.then((response) => this.cache.set(cacheKey, response)) .then(response => this.cache.set(cacheKey, response))
.then((response) => this.mapResults(response)) .then(response => this.mapResults(response, type))
.catch((error) => { throw new Error(error); }) .catch((error) => { throw new Error(error); })
.then(([mappedResults, pagenumber, totalpages, total_results]) => { .then(([mappedResults, pagenumber, totalpages, total_results]) => ({
return {'results': mappedResults, 'page': pagenumber, 'total_results': total_results, 'total_pages': totalpages} results: mappedResults, page: pagenumber, total_results, total_pages: totalpages,
}) }));
} }
/** /**
* Retrieve a specific movie by id from TMDB. * Fetches a given list from tmdb.
* @param {Number} identifier of the movie you want to retrieve * @param {listName} List we want to fetch.
* @returns {Promise} succeeds if movie was found * @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
*/ */
lookup(identifier, queryType = 'movie') { listSearch(listName, type = 'movie', id, page = '1') {
var type, tmdbType; const params = { id, page };
if (queryType === 'movie' || queryType === 'movieInfo') { type = 'movie', tmdbType = 'movieInfo' } const cacheKey = `${this.cacheTags[listName]}:${type}:${id}:${page}`;
else if (queryType === 'show' || queryType === 'tvInfo') { type = 'show', tmdbType = 'tvInfo' }
else {
return Promise.resolve()
.then(() => {
throw new Error('Invalid type declaration.')
})
}
const query = { id: identifier };
const cacheKey = `${this.cacheTags.lookup}:${type}:${identifier}`;
return Promise.resolve() return Promise.resolve()
.then(() => this.cache.get(cacheKey)) .then(() => this.cache.get(cacheKey))
.catch(() => this.tmdb(tmdbType, query)) .catch(() => this.tmdb(this.tmdbMethod(listName, type), params))
.catch(() => { throw new Error('Could not find a movie with that id.'); }) .then(response => this.cache.set(cacheKey, response))
.then((response) => this.cache.set(cacheKey, response)) .then(response => this.mapResults(response, type))
.then((response) => { .catch((error) => { throw new Error(error); })
try { .then(([mappedResults, pagenumber, totalpages, total_results]) => ({
return convertTmdbToSeasoned(response, type); results: mappedResults, page: pagenumber, total_pages: totalpages, total_results,
} catch (parseError) { }));
throw new Error('Could not parse movie.');
}
});
} }
/** static tmdbMethod(apiMethod, type) {
* Verifies that a list_name corresponds to a tmdb list and calls the tmdb const method = TMDB_METHODS[apiMethod][type];
* api with list name and paramters. if (method !== undefined) return method;
* @param {list_name} The name of a list we want to search for. throw new Error('Could not find tmdb api method.');
* @param {media_type} The type declared in listSearch.
* @param {params} Params is page and id given as parameters in listSearch.
* @returns {Promise} dict with raw tmdb results.
*/
searchTmdbList(list_name, media_type, params) {
return new Promise((resolve, reject) => {
if (TYPE_LIST.includes(list_name) && ['movie', 'show'].includes(media_type)) {
const searchQuery = list_name.toLowerCase() + media_type.toLowerCase();
const tmdbList = TMDB_TYPE_LIST[searchQuery]
return Promise.resolve()
.then(() => this.tmdb(tmdbList, params))
.then((response) => {
resolve(response)
})
.catch(() => {
return reject('Error while fetching from tmdb list.')
})
}
return reject('Did not find tmdb list matching query.')
})
} }
/** /**
@@ -116,39 +104,13 @@ class TMDB {
* @param {type} The type declared in listSearch. * @param {type} The type declared in listSearch.
* @returns {Promise} dict with tmdb results, mapped as movie/show objects. * @returns {Promise} dict with tmdb results, mapped as movie/show objects.
*/ */
mapResults(response, type) { static mapResults(response, type) {
return Promise.resolve() return Promise.resolve()
.then(() => { .then(() => {
const mappedResults = response.results.map((result) => { const mappedResults = response.results.map(result => convertTmdbToSeasoned(result, type));
return convertTmdbToSeasoned(result, type) return [mappedResults, response.page, response.total_pages, response.total_results];
})
return [mappedResults, response.page, response.total_pages, response.total_results]
})
.catch((error) => { throw new Error(error)})
}
/**
* Fetches a given list from tmdb.
* @param {list_name} List we want to fetch.
* @param {media_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(list_name, media_type='movie', id, page='1') {
const params = {'id': id, 'page': page}
const cacheKey = `${this.cacheTags[list_name]}:${media_type}:${id}:${page}`;
return Promise.resolve()
.then(() => this.cache.get(cacheKey))
.catch(() => this.searchTmdbList(list_name, media_type, params))
.then((response) => this.cache.set(cacheKey, response))
.then((response) => this.mapResults(response, media_type))
.catch((error) => { throw new Error(error); })
.then(([mappedResults, pagenumber, totalpages, total_results]) => {
return {'results': mappedResults, 'page': pagenumber, 'total_pages': totalpages, 'total_results': total_results}
}) })
.catch((error) => { throw new Error(error); });
} }
tmdb(method, argument) { tmdb(method, argument) {
@@ -157,7 +119,7 @@ class TMDB {
if (error) { if (error) {
return reject(error); return reject(error);
} }
resolve(reponse); return resolve(reponse);
}; };
if (!argument) { if (!argument) {
@@ -165,7 +127,7 @@ class TMDB {
} else { } else {
this.tmdbLibrary[method](argument, callback); this.tmdbLibrary[method](argument, callback);
} }
}) });
} }
} }