138 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			5.0 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
 | 
						|
   * @param {String} type filter results by type (default movie).
 | 
						|
   * @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(TMDB_METHODS['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 search results from TMDB.
 | 
						|
   * @param {String} text query you want to search for
 | 
						|
   * @param {Number} page representing pagination of results
 | 
						|
   * @param {String} type filter results by type (default multi)
 | 
						|
   * @returns {Promise} dict with query results, current page and total_pages
 | 
						|
   */
 | 
						|
   search(text, page = 1, type = 'multi') {
 | 
						|
      const query = { query: text, page: page };
 | 
						|
      const cacheKey = `${this.cacheTags.search}:${page}:${type}:${text}`;
 | 
						|
      return Promise.resolve()
 | 
						|
         .then(() => this.cache.get(cacheKey))
 | 
						|
         .catch(() => this.tmdb(TMDB_METHODS['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));
 | 
						|
   }
 | 
						|
 | 
						|
   /**
 | 
						|
   * Fetches a given list from tmdb.
 | 
						|
   * @param {String} listName Name of list
 | 
						|
   * @param {String} type filter results by type (default movie)
 | 
						|
   * @param {Number} page representing pagination of results
 | 
						|
   * @returns {Promise} dict with query results, current page and total_pages
 | 
						|
   */
 | 
						|
   listSearch(listName, type = 'movie', page = '1') {
 | 
						|
      const query = { page: page };
 | 
						|
      console.log(query);
 | 
						|
      const cacheKey = `${this.cacheTags[listName]}:${type}:${page}`;
 | 
						|
      return Promise.resolve()
 | 
						|
         .then(() => this.cache.get(cacheKey))
 | 
						|
         .catch(() => this.tmdb(TMDB_METHODS[listName][type], query))
 | 
						|
         .catch(() => { throw new Error('Error fetching list from tmdb.'); })
 | 
						|
         .then(response => this.cache.set(cacheKey, response))
 | 
						|
         .then(response => this.mapResults(response, type));
 | 
						|
   }
 | 
						|
 | 
						|
   /**
 | 
						|
   * Maps our response from tmdb api to a movie/show object.
 | 
						|
   * @param {String} response from tmdb.
 | 
						|
   * @param {String} The type declared in listSearch.
 | 
						|
   * @returns {Promise} dict with tmdb results, mapped as movie/show objects.
 | 
						|
   */
 | 
						|
   mapResults(response, type) {
 | 
						|
      console.log(response.page);
 | 
						|
      return Promise.resolve()
 | 
						|
         .then(() => {
 | 
						|
            const mappedResults = response.results.filter((element) => {
 | 
						|
               return (element.media_type === 'movie' || element.media_type === 'tv' || element.media_type === undefined);
 | 
						|
            }).map((element) => convertTmdbToSeasoned(element, type));
 | 
						|
            return { 
 | 
						|
               results: mappedResults,
 | 
						|
               page: response.page,
 | 
						|
               total_pages: response.total_pages,
 | 
						|
               total_results: response.total_results
 | 
						|
            }
 | 
						|
         })
 | 
						|
         .catch((error) => { throw new Error(error); });
 | 
						|
   }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Wraps moviedb library to support Promises.
 | 
						|
   * @param {String} method function name in the library
 | 
						|
   * @param {Object} argument argument to function being called
 | 
						|
   * @returns {Promise} succeeds if callback succeeds
 | 
						|
   */
 | 
						|
   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;
 |