diff --git a/sites/mncvision.id/__data__/content.html b/sites/mncvision.id/__data__/content.html
new file mode 100644
index 00000000..319e0fae
--- /dev/null
+++ b/sites/mncvision.id/__data__/content.html
@@ -0,0 +1,808 @@
+
+
+
+
+
+
+
+
+
+
+
+
05 Oct 2022, 12:00 AM
00:00 - 00:06 [duration:00:06]
+
+
+ When children begin to disappear, a group of young kids have to face their biggest fears when they square off against a murderous, evil clown.
+
+
+

+
+
+ Channel 38
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sites/mncvision.id/__data__/program_id.html b/sites/mncvision.id/__data__/program_id.html
new file mode 100644
index 00000000..ea6cdbf5
--- /dev/null
+++ b/sites/mncvision.id/__data__/program_id.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
05 Oct 2022, 12:00 AM
00:00 - 00:06 [durasi:00:06]
+
+
+ Ketika anak-anak mulai menghilang, sekelompok anak kecil harus menghadapi ketakutan terbesar mereka ketika mereka melawan sesosok badut pembunuh yang jahat.
+
+
+

+
+
+ Channel 38
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sites/mncvision.id/mncvision.id.config.js b/sites/mncvision.id/mncvision.id.config.js
index 07111aec..0067336a 100644
--- a/sites/mncvision.id/mncvision.id.config.js
+++ b/sites/mncvision.id/mncvision.id.config.js
@@ -1,4 +1,4 @@
-const FormData = require('form-data')
+const _ = require('lodash')
const axios = require('axios')
const cheerio = require('cheerio')
const dayjs = require('dayjs')
@@ -16,8 +16,7 @@ module.exports = {
request: {
method: 'POST',
data: function ({ channel, date }) {
- const formData = new FormData()
- formData.setBoundary('X-EPG-BOUNDARY')
+ const formData = new URLSearchParams()
formData.append('search_model', 'channel')
formData.append('af0rmelement', 'aformelement')
formData.append('fdate', date.format('YYYY-MM-DD'))
@@ -27,29 +26,36 @@ module.exports = {
return formData
},
headers: {
- 'Content-Type': 'multipart/form-data; boundary=X-EPG-BOUNDARY'
- }
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ jar: null
},
async parser({ content, date, headers, channel }) {
const programs = []
+ const cookies = parseCookies(headers)
+ if (!cookies) return programs
let items = parseItems(content)
if (!items.length) return programs
const pages = parsePages(content)
- const cookies = headers && headers['set-cookie'] ? headers['set-cookie'].join(';') : ''
for (let url of pages) {
items = items.concat(parseItems(await loadNextPage(url, cookies)))
}
const langCookies = await loadLangCookies(channel)
+ if (!langCookies) return programs
for (const item of items) {
- const start = parseStart(item, date)
- const duration = parseDuration(item)
+ const $item = cheerio.load(item)
+ const start = parseStart($item, date)
+ const duration = parseDuration($item)
const stop = start.add(duration, 'm')
+ const description = await loadDescription($item, langCookies)
programs.push({
- title: parseTitle(item),
- description: await loadDescription(item, langCookies),
+ title: parseTitle($item),
+ season: parseSeason($item),
+ episode: parseEpisode($item),
+ description,
start,
stop
})
@@ -61,7 +67,7 @@ module.exports = {
const data = await axios
.get('https://www.mncvision.id/schedule')
.then(response => response.data)
- .catch(console.log)
+ .catch(console.error)
const $ = cheerio.load(data)
const items = $('select[name="fchannel"] option').toArray()
@@ -79,46 +85,22 @@ module.exports = {
}
}
-async function loadNextPage(url, cookies) {
- return axios
- .get(url, {
- headers: {
- Cookie: cookies
- }
- })
- .then(r => r.data)
- .catch(console.log)
+function parseSeason($item) {
+ const title = parseTitle($item)
+ const [_, season] = title.match(/ S(\d+)/) || [null, null]
+
+ return season ? parseInt(season) : null
}
-async function loadLangCookies(channel) {
- const lang = channel.lang === 'en' ? 'english' : 'indonesia'
- const url = `https://www.mncvision.id/language_switcher/setlang/${lang}/`
+function parseEpisode($item) {
+ const title = parseTitle($item)
+ const [_, episode] = title.match(/ Ep (\d+)/) || [null, null]
- return axios
- .get(url)
- .then(r => r.headers['set-cookie'].join(';'))
- .catch(console.error)
+ return episode ? parseInt(episode) : null
}
-async function loadDescription(item, cookies) {
- const $item = cheerio.load(item)
- const progUrl = $item('a').attr('href')
- if (!progUrl) return null
- const data = await axios
- .get(progUrl, { headers: { 'X-Requested-With': 'XMLHttpRequest', Cookie: cookies } })
- .then(r => r.data)
- .catch(console.log)
- if (!data) return null
- const $page = cheerio.load(data)
- const description = $page('.synopsis').text().trim()
- if (description === '-') return null
-
- return description
-}
-
-function parseDuration(item) {
- const $ = cheerio.load(item)
- let duration = $('td:nth-child(3)').text()
+function parseDuration($item) {
+ let duration = $item('td:nth-child(3)').text()
const match = duration.match(/(\d{2}):(\d{2})/)
const hours = parseInt(match[1])
const minutes = parseInt(match[2])
@@ -126,18 +108,15 @@ function parseDuration(item) {
return hours * 60 + minutes
}
-function parseStart(item, date) {
- const $ = cheerio.load(item)
- let time = $('td:nth-child(1)').text()
+function parseStart($item, date) {
+ let time = $item('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) {
- const $ = cheerio.load(item)
-
- return $('td:nth-child(2) > a').text()
+function parseTitle($item) {
+ return $item('td:nth-child(2) > a').text()
}
function parseItems(content) {
@@ -148,13 +127,57 @@ function parseItems(content) {
function parsePages(content) {
const $ = cheerio.load(content)
- const links = $('#schedule > div.schedule_search_result_container > div.box.well > a').toArray()
+ const links = $('#schedule > div.schedule_search_result_container > div.box.well > a')
+ .map((i, el) => {
+ return $(el).attr('href')
+ })
+ .get()
- const pages = {}
- for (let link of links) {
- const url = $(link).attr('href')
- pages[url] = true
- }
-
- return Object.keys(pages)
+ 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
+ })
+}
+
+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 })
+ .then(r => parseCookies(r.headers))
+ .catch(err => null)
+}
+
+async function loadDescription($item, cookies) {
+ const url = $item('a').attr('href')
+ if (!url) return null
+ const content = await axios
+ .get(url, {
+ headers: { 'X-Requested-With': 'XMLHttpRequest', Cookie: cookies },
+ timeout: 30000
+ })
+ .then(r => r.data)
+ .catch(err => null)
+ if (!content) return null
+
+ const $page = cheerio.load(content)
+ const description = $page('.synopsis').text().trim()
+
+ return description !== '-' ? description : null
+}
+
+function parseCookies(headers) {
+ return Array.isArray(headers['set-cookie']) ? headers['set-cookie'].join(';') : null
}
diff --git a/sites/mncvision.id/mncvision.id.test.js b/sites/mncvision.id/mncvision.id.test.js
index faa3ee3e..91c2ddd3 100644
--- a/sites/mncvision.id/mncvision.id.test.js
+++ b/sites/mncvision.id/mncvision.id.test.js
@@ -1,8 +1,10 @@
+// npx epg-grabber --config=sites/mncvision.id/mncvision.id.config.js --channels=sites/mncvision.id/mncvision.id_id-id.channels.xml --output=guide.xml --timeout=30000 --days=2
+// npx epg-grabber --config=sites/mncvision.id/mncvision.id.config.js --channels=sites/mncvision.id/mncvision.id_id-en.channels.xml --output=guide.xml --timeout=30000 --days=2
// node ./scripts/channels.js --config=./sites/mncvision.id/mncvision.id.config.js --output=./sites/mncvision.id/mncvision.id_id.channels.xml
-// npx epg-grabber --config=sites/mncvision.id/mncvision.id.config.js --channels=sites/mncvision.id/mncvision.id_id-id.channels.xml --output=guide.xml --days=2
-// npx epg-grabber --config=sites/mncvision.id/mncvision.id.config.js --channels=sites/mncvision.id/mncvision.id_id-en.channels.xml --output=guide.xml --days=2
const { parser, url, request } = require('./mncvision.id.config.js')
+const fs = require('fs')
+const path = require('path')
const axios = require('axios')
const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc')
@@ -12,181 +14,138 @@ dayjs.extend(utc)
jest.mock('axios')
-const date = dayjs.utc('2021-11-12', 'YYYY-MM-DD').startOf('d')
-const channelID = {
- site_id: '203',
- xmltv_id: 'AnimalPlanetSoutheastAsia.us',
+const date = dayjs.utc('2022-10-05', 'YYYY-MM-DD').startOf('d')
+const channel = {
+ site_id: '38',
+ xmltv_id: 'MiaoMi.hk',
lang: 'id'
}
-const channelEN = {
- site_id: '203',
- xmltv_id: 'AnimalPlanetSoutheastAsia.us',
- lang: 'en'
+const headers = {
+ 'set-cookie': [
+ 's1nd0vL=05e9pr6gi112tdmutsn7big93o75r0b0; expires=Wed, 05-Oct-2022 14:18:22 GMT; Max-Age=7200; path=/; HttpOnly'
+ ]
}
-const setCookie = [
- 's1nd0vL=0qpsmm7dpjmi7nt8d2h5epf16rmgg8a8; expires=Sat, 05-Mar-2022 15:44:22 GMT; Max-Age=7200; path=/; HttpOnly'
-]
-
-const content0 = `