libremdb/fetchers/movie.js
2022-03-19 17:22:07 +05:30

238 lines
7.0 KiB
JavaScript

const cheerio = require('cheerio');
const axiosInstance = require('../utils/axiosInstance');
// cleans images links and adds custom quality(optional).
const cleanLink = (link, quality = null) => {
if (!link) return '';
let cleanedLink = link.match(
/https:\/\/m\.media-amazon\.com\/images\/M\/[^.]*/gm
)?.[0];
if (!cleanedLink) return '';
cleanedLink += quality ? `.UX${quality}.jpeg` : '.jpeg';
return cleanedLink;
};
const getMovie = async (title, quality = null) => {
try {
const res = await axiosInstance(`/title/${title}`);
const $ = cheerio.load(res.data);
// basic info
const name = $('h1').text();
const metadata = $('ul[data-testid=hero-title-block__metadata] li')
.map((i, el) =>
$(el).children().length ? $(el).children().first().text() : $(el).text()
)
.toArray();
const rating = $('[data-testid=hero-rating-bar__aggregate-rating__score]')
.children()
.first()
.text();
const numVotes = $('[data-testid=hero-rating-bar__aggregate-rating__score]')
.siblings()
.last()
.text();
const popularity = $('[data-testid="hero-rating-bar__popularity__score"]')
.first()
.text();
const plotBrief = $('span[data-testid=plot-xl]').contents().first().text();
let poster = $('[data-testid="hero-media__poster"] img').attr('src');
poster = cleanLink(poster, quality);
const reviewScores = [];
$(
'ul[data-testid="reviewContent-all-reviews"] li a span.three-Elements'
).each((i, el) =>
reviewScores.push([
$(el).children().first().text(),
$(el).children().last().text(),
])
);
// media
const images = $('section[data-testid="Photos"] .ipc-photo img')
.map((i, el) => {
let image = $(el).attr('src');
return cleanLink(image, quality);
})
.toArray();
const imagesLinkExternal = $('[data-testid=photos-title]').attr('href');
const videoThumbnail = $('.ipc-slate__slate-image img').attr('src');
const videoLinkExternal = $('.hero-media__slate-overlay').attr('href');
const videosLinkExternal = $('[data-testid=videos-title]').attr('href');
// cast
const actors = $(
'section[data-testid="title-cast"] div[data-testid=title-cast-item]'
)
.map((i, el) => {
const name = $(el)
.find('a[data-testid="title-cast-item__actor"]')
.text();
let avatar = $(el).find('img').attr('src');
avatar = cleanLink(avatar, quality);
const characterName = $(el)
.find('a[data-testid=cast-item-characters-link] span')
.first()
.text();
return { name, avatar, characterName };
})
.toArray();
const directors = $(
'section[data-testid=title-cast] ul li:nth-of-type(1) li'
)
.map((i, el) => $(el).find('a').text())
.toArray();
const writers = $('section[data-testid=title-cast] ul li:nth-of-type(2) li')
.map((i, el) => $(el).find('a').text())
.toArray();
// storyline
const plotExpanded = $(
'section[data-testid="Storyline"] [data-testid=storyline-plot-summary]'
)
.contents()
.first()
.text();
const tagline = $(
'section[data-testid="Storyline"] [data-testid=storyline-taglines] li'
)
.first()
.text();
const genres = $(
'section[data-testid="Storyline"] [data-testid=storyline-genres] li'
)
.map((i, el) => $(el).text())
.toArray();
const parentalGuidance = $(
'[data-testid="storyline-certificate"] li'
).text();
// details
const releaseDate = $(
'section[data-testid="Details"] li[data-testid="title-details-releasedate"] li'
).text();
const countries = $(
'section[data-testid="Details"] li[data-testid="title-details-origin"] li'
)
.map((i, el) => $(el).text())
.toArray();
const officialSite = $(
'section[data-testid="Details"] li[data-testid="title-details-officialsites"] li a'
)
.first()
.attr('href');
const languages = $(
'section[data-testid="Details"] li[data-testid="title-details-languages"] li'
)
.map((i, el) => $(el).text())
.toArray();
const alternateTitle = $(
'section[data-testid="Details"] li[data-testid="title-details-akas"] li'
)
.first()
.text();
const filmingLocations = $(
'section[data-testid="Details"] li[data-testid="title-details-filminglocations"] li'
)
.map((i, el) => $(el).text())
.toArray();
const companies = $(
'section[data-testid="Details"] li[data-testid="title-details-companies"] li'
)
.map((i, el) => $(el).text())
.toArray();
// technical specs
const runtime = $(
'section[data-testid="TechSpecs"] li[data-testid="title-techspec_runtime"] div'
).text();
const color = $(
'section[data-testid="TechSpecs"] li[data-testid="title-techspec_color"] div'
).text();
const aspectRatio = $(
'section[data-testid="TechSpecs"] li[data-testid="title-techspec_aspectratio"] div'
).text();
const sound = $(
'section[data-testid="TechSpecs"] li[data-testid="title-techspec_soundmix"] li'
)
.map((i, el) => $(el).text())
.toArray();
// boxoffice
const budget = $(
'section[data-testid="BoxOffice"] [data-testid="title-boxoffice-section"] li[data-testid="title-boxoffice-budget"] li'
).text();
const grossDomestic = $(
'section[data-testid="BoxOffice"] [data-testid="title-boxoffice-section"] li[data-testid="title-boxoffice-grossdomestic"] li'
).text();
const openingWeekendDomestic = $(
'section[data-testid="BoxOffice"] [data-testid="title-boxoffice-section"] li[data-testid="title-boxoffice-openingweekenddomestic"] li'
)
.map((i, el) => $(el).text())
.toArray();
const grossWorldwide = $(
'section[data-testid="BoxOffice"] [data-testid="title-boxoffice-section"] li[data-testid="title-boxoffice-cumulativeworldwidegross"] li'
).text();
// making data object
const data = {
basic: {
name,
poster,
metadata,
rating,
numVotes,
popularity,
genres,
plotBrief,
directors,
writers,
},
media: {
poster,
images,
imagesLinkExternal,
videoThumbnail,
videoLinkExternal,
videosLinkExternal,
},
topCast: { actors, directors, writers },
storyline: { plotExpanded, tagline, genres, parentalGuidance },
details: {
releaseDate,
countries,
officialSite,
languages,
alternateTitle,
filmingLocations,
companies,
},
technicalSpecs: {
runtime,
color,
aspectRatio,
sound,
},
boxoffice: {
budget,
openingWeekendDomestic,
grossDomestic,
grossWorldwide,
},
reviews: {
reviewScores,
},
};
// returning data
return data;
} catch (err) {
console.log(err.response);
throw err;
}
};
module.exports = getMovie;