/**@module tmdb-js/sections/types */
// TMDb utilities
const tmdbUtils = require('../../../utils/tmdb_utils');
const sections = tmdbUtils.sections;
const Section = require('../section').Section;
/**
* A class that represents the search section in TMDb.
*/
exports.SearchSection = class extends Section {
/**
* Initializes this object.
* @param {string} apiKey A TMDb API key.
* @param {string} language The natural language of search queries. The default is "en-US".
*/
constructor(apiKey, language = "en-US") {
super(sections.SEARCH, undefined, apiKey, language);
}
/**
* Gets data from a company search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
*
* @returns {Promise<*>} A Promise of JSON data with search results of companies.
*/
async searchCompaniesAsync(searchTerm, startPage = 1, pageCount = 1) {
let companiesChild = this.createChild(searchType.COMPANIES);
return await searchPagesAsync(
companiesChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
false,
this._language);
}
/**
* Gets data from a collection search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
*
* @returns {Promise<*>} A Promise of JSON data with search results of collections.
*/
async searchCollectionsAsync(searchTerm, startPage = 1, pageCount = 1) {
let collectionsChild = this.createChild(searchType.COLLECTIONS);
return await searchPagesAsync(
collectionsChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
false,
this._language);
}
/**
* Gets data from a keyword search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
*
* @returns {Promise<*>} A Promise of JSON data with search results of keywords.
*/
async searchKeywordsAsync(searchTerm, startPage = 1, pageCount = 1) {
let keywordsChild = this.createChild(searchType.KEYWORDS);
return await searchPagesAsync(
keywordsChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
false,
this._language);
}
/**
* Gets data from a movie search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
* @param {Boolean} includeAdult
* true if adult content will be included. The default is true.
* @param {string} region The region.
* @param {Number} year The year.
* @param {Number} primaryReleaseYear The primary release year.
*
* @returns {Promise<*>} A Promise of JSON data with search results of movies.
*/
async searchMoviesAsync(searchTerm,
startPage = 1,
pageCount = 1,
includeAdult = true,
region = undefined,
year = undefined,
primaryReleaseYear = undefined) {
// Additional optional query info
let additionalInfo = {
"region": region,
"year": year,
"primary_release_year": primaryReleaseYear
};
let moviesChild = this.createChild(searchType.MOVIES);
return await searchPagesAsync(
moviesChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
includeAdult,
this._language,
additionalInfo);
}
/**
* Gets data from a multi search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
* @param {Boolean} includeAdult
* true if adult content will be included. The default is true.
*
* @returns {Promise<*>} A Promise of JSON data with multi-search results.
*/
async multiSearchAsync(searchTerm, startPage = 1, pageCount = 1, includeAdult = true) {
let multiChild = this.createChild(searchType.MULTI);
return await searchPagesAsync(
multiChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
includeAdult,
this._language);
}
/**
* Gets data from a people search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
* @param {Boolean} includeAdult
* true if adult content will be included. The default is true.
* @param {string} region The region.
*
* @returns {Promise<*>} A Promise of JSON data with search results of people.
*/
async searchPeopleAsync(searchTerm,
startPage = 1,
pageCount = 1,
includeAdult = true,
region = undefined) {
// Additional optional query info
let additionalInfo = {"region": region};
let peopleChild = this.createChild(searchType.PEOPLE);
return await searchPagesAsync(
peopleChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
includeAdult,
this._language,
additionalInfo);
}
/**
* Gets data from a TV show search in TMDb.
*
* @param {string} searchTerm The search term (query).
* @param {Number} startPage
* The first search result page to return data from. The default is 1.
* @param {Number} pageCount
* The number of search result pages to return data from. The default is 1.
* @param {Boolean} includeAdult
* true if adult content will be included. The default is true.
* @param {Number} firstAirDateYear The first air date year.
*
* @returns {Promise<*>} A Promise of JSON data with search results of TV shows.
*/
async searchTvShowsAsync(searchTerm,
startPage = 1,
pageCount = 1,
includeAdult = true,
firstAirDateYear = undefined) {
// Additional optional query info
let additionalInfo = {"first_air_date_year": firstAirDateYear};
let tvShowChild = this.createChild(searchType.TV_SHOWS);
return await searchPagesAsync(
tvShowChild.toString(),
searchTerm,
this._apiKey,
startPage,
pageCount,
includeAdult,
this._language,
additionalInfo);
}
}
/**
* All different search types on TMDb.
*/
const searchType = {
COMPANIES: 'company',
COLLECTIONS: 'collection',
KEYWORDS: 'keyword',
MOVIES: 'movie',
MULTI: 'multi',
PEOPLE: 'person',
TV_SHOWS: 'tv'
}
/**
* Gets search data from TMDb as a JSON object.
*
* @param {string} url The url.
* @param {string} searchTerm The search term (query).
* @param {string} apiKey The API key to the TMDb API.
* @param {Number} startPage
* The first search result page to return data from.
* @param {Number} pageCount
* The number of search result pages to return data from.
* @param {Boolean} includeAdult true if adult content will be included.
* @param {string} language
* The language of the search results. Default value is "en-US".
* @param {Object} additionalInfo
* Additional info to add to the search query.
*
* @returns {Promise<*>} A Promise of JSON data with search results.
*/
async function searchPagesAsync(url, searchTerm, apiKey, startPage,
pageCount, includeAdult = true, language = "en-US", additionalInfo = {}) {
// Throw an error if the page related parameters are invalid
if (startPage < 1 || pageCount < 1) {
throw "startPage and pageCount have to be larger or equal to 1.";
}
// Search the first page in order to get the total number of pages.
// Used to interrupt when there are no pages left to search.
let firstPage = await searchPageAsync(url,
searchTerm,
apiKey,
startPage,
includeAdult,
language,
additionalInfo);
// The page count is 1, no more pages should thus be searched
if (pageCount === 1)
return [firstPage];
// Update the page count, in case it exceeds the total number of pages
pageCount = Math.min(pageCount, firstPage["total_pages"] - startPage);
// Create one search promise per page
let promises = [];
for (let index = 1; index <= pageCount; index++) {
let page = startPage + index;
let promise = searchPageAsync(url,
searchTerm,
apiKey,
page,
includeAdult,
language,
additionalInfo);
promises.push(promise);
}
// Add the rest of the resulting pages to the first one
return await Promise
.all(promises)
.then(restOfPages => [firstPage, ...restOfPages]);
}
/**
* Gets search data from TMDb as a JSON object.
* @param {string} url The url path.
* @param {string} searchTerm The search term (query).
* @param {string} apiKey The API key to the TMDb API.
* @param {Number} page The search result page to return data from.
* @param {Boolean} includeAdult true if adult content will be included.
* @param {string} language
* The language of the search results. Default value is "en-US".
* @param {Object} additionalInfo
* Additional info to add to the search query.
*
* @returns {Promise<*>} A Promise of JSON data of the specified page.
*/
async function searchPageAsync(url,
searchTerm,
apiKey,
page = 1,
includeAdult = true,
language = "en-US",
additionalInfo = {}) {
let parameters = {
"api_key": apiKey,
"language": language,
"query": searchTerm,
"page": page,
"include_adult": includeAdult,
...additionalInfo
};
return await tmdbUtils.getDataAsync(url, parameters);
}