Optimize mncvision.id grabber connection.

Currently while fetching guide for every channels, there will be one additional
connection used to set the language cookie. This optimization change this behaviour
by setting the language cookie once and then use those cookie for the rest of the
channels unless there's change in channel language.

Assume there are 10 channels and each channel only use one connection. Before the
optimization the connections made are 20 (1 for guide fetch, 1 for set language,
then multiplied by 10), and after the optimization the connections made are 11
(1 for set language, 1 for guide fetch multiplied by 10).

Signed-off-by: Toha <tohenk@yahoo.com>
This commit is contained in:
Toha
2023-11-21 22:42:02 +07:00
parent 35272ea0a4
commit f0cadf182e
7 changed files with 459 additions and 1425 deletions
+32 -53
View File
@@ -10,13 +10,17 @@ dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.extend(customParseFormat)
const languages = { en: 'english', id: 'indonesia' }
const cookies = {}
const timeout = 30000
module.exports = {
site: 'mncvision.id',
days: 2,
url: 'https://www.mncvision.id/schedule/table',
request: {
method: 'POST',
data: function ({ channel, date }) {
data({ channel, date }) {
const formData = new URLSearchParams()
formData.append('search_model', 'channel')
formData.append('af0rmelement', 'aformelement')
@@ -26,32 +30,33 @@ module.exports = {
return formData
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
async headers({ channel }) {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
if (channel && !cookies[channel.lang]) {
cookies[channel.lang] = await loadLangCookies(channel)
if (cookies[channel.lang]) {
headers.Cookie = cookies[channel.lang]
}
}
return headers
},
jar: null
},
async parser({ content, date, headers, channel }) {
async parser({ content, headers, date, channel}) {
const programs = []
const cookies = parseCookies(headers)
if (!cookies) return programs
let items = parseItems(content)
if (!items.length) return programs
const pages = parsePages(content)
for (let url of pages) {
items = items.concat(parseItems(await loadNextPage(url, cookies)))
if (!cookies[channel.lang]) {
cookies[channel.lang] = parseCookies(headers)
}
const langCookies = await loadLangCookies(channel)
if (!langCookies) return programs
const [$, items] = parseItems(content)
for (const item of items) {
const $item = cheerio.load(item)
const $item = $(item)
const start = parseStart($item, date)
const duration = parseDuration($item)
const stop = start.add(duration, 'm')
const description = await loadDescription($item, langCookies)
const description = await loadDescription($item, cookies[channel.lang])
programs.push({
title: parseTitle($item),
season: parseSeason($item),
@@ -78,7 +83,7 @@ module.exports = {
const $item = $(item)
return {
lang: lang,
lang,
site_id: $item.attr('value'),
name: $item.text().split(' - ')[0].trim()
}
@@ -103,7 +108,7 @@ function parseEpisode($item) {
}
function parseDuration($item) {
let duration = $item('td:nth-child(3)').text()
let duration = $item.find('td:nth-child(3)').text()
const match = duration.match(/(\d{2}):(\d{2})/)
const hours = parseInt(match[1])
const minutes = parseInt(match[2])
@@ -112,67 +117,41 @@ function parseDuration($item) {
}
function parseStart($item, date) {
let time = $item('td:nth-child(1)').text()
let time = $item.find('td:nth-child(1)').text()
time = `${date.format('DD/MM/YYYY')} ${time}`
return dayjs.tz(time, 'DD/MM/YYYY HH:mm', 'Asia/Jakarta')
}
function parseTitle($item) {
return $item('td:nth-child(2) > a').text()
return $item.find('td:nth-child(2) > a').text()
}
function parseItems(content) {
const $ = cheerio.load(content)
return $('tr[valign="top"]').toArray()
}
function parsePages(content) {
const $ = cheerio.load(content)
const links = $('#schedule > div.schedule_search_result_container > div.box.well > a')
.map((i, el) => {
return $(el).attr('href')
})
.get()
return _.uniq(links)
}
function loadNextPage(url, cookies) {
return axios
.get(url, { headers: { Cookie: cookies }, timeout: 30000 })
.then(r => r.data)
.catch(err => {
console.log(err.message)
return null
})
return [$, $('tr[valign="top"]').toArray()]
}
function loadLangCookies(channel) {
const languages = {
en: 'english',
id: 'indonesia'
}
const url = `https://www.mncvision.id/language_switcher/setlang/${languages[channel.lang]}/`
return axios
.get(url, { timeout: 30000 })
.get(url, { timeout })
.then(r => parseCookies(r.headers))
.catch(error => console.log(error.message))
.catch(error => console.error(error.message))
}
async function loadDescription($item, cookies) {
const url = $item('a').attr('href')
const url = $item.find('a').attr('href')
if (!url) return null
const content = await axios
.get(url, {
headers: { 'X-Requested-With': 'XMLHttpRequest', Cookie: cookies },
timeout: 30000
timeout
})
.then(r => r.data)
.catch(error => console.log(error.message))
.catch(error => console.error(error.message))
if (!content) return null
const $page = cheerio.load(content)