diff --git a/.github/workflows/auto-update.yml b/.github/workflows/auto-update.yml index 201a8ebd..ebb660ab 100644 --- a/.github/workflows/auto-update.yml +++ b/.github/workflows/auto-update.yml @@ -34,7 +34,7 @@ jobs: tvtv.ca, tvtv.us, tv.lv, - vidio.com, + mncvision.id, tvguide.com, tvprofil.com ] diff --git a/README.md b/README.md index 464faf45..df339dbd 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ To load a program guide, all you need to do is copy the link to one of the guide 🇬🇷 Greecehttps://iptv-org.github.io/epg/guides/cosmote.gr.guide.xml 🇬🇹 Guatemalahttps://iptv-org.github.io/epg/guides/mi.tv.guide.xml 🇭🇳 Hondurashttps://iptv-org.github.io/epg/guides/mi.tv.guide.xml + 🇮🇩 Indonesiahttps://iptv-org.github.io/epg/guides/mncvision.id.guide.xml 🇭🇺 Hungaryhttps://iptv-org.github.io/epg/guides/tvprofil.com.guide.xml - 🇮🇩 Indonesiahttps://iptv-org.github.io/epg/guides/vidio.com.guide.xml 🇮🇹 Italyhttps://iptv-org.github.io/epg/guides/guidatv.sky.it.guide.xml 🇮🇪 Irelandhttps://iptv-org.github.io/epg/guides/ontvtonight.com.guide.xml 🇰🇿 Kazakhstanhttps://iptv-org.github.io/epg/guides/tv.yandex.ru.guide.xml diff --git a/package-lock.json b/package-lock.json index 554f1be0..1de7a29c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "license": "MIT", "dependencies": { + "form-data": "^4.0.0", "cheerio": "^1.0.0-rc.10", "dayjs": "^1.10.4", "epg-grabber": "^0.6.6", @@ -374,6 +375,7 @@ } }, "node_modules/domhandler": { + "version": "4.2.0", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.2.0.tgz", "integrity": "sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==", @@ -537,16 +539,16 @@ } }, "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" }, "engines": { - "node": ">= 0.12" + "node": ">= 6" } }, "node_modules/fs.realpath": { @@ -1028,6 +1030,18 @@ "node": ">=0.8" } }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } "node_modules/request/node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -1698,12 +1712,12 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, @@ -2067,6 +2081,16 @@ "uuid": "^3.3.2" }, "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", diff --git a/package.json b/package.json index b9ca30c0..495c5f40 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dayjs": "^1.10.4", "epg-grabber": "^0.6.6", "epg-parser": "^0.1.3", + "form-data": "^4.0.0", "glob": "^7.1.6", "html-to-text": "^7.0.0", "iconv-lite": "^0.4.24", diff --git a/sites/mncvision.id.channels.xml b/sites/mncvision.id.channels.xml new file mode 100755 index 00000000..4cf588c6 --- /dev/null +++ b/sites/mncvision.id.channels.xml @@ -0,0 +1,109 @@ + + + + ABC Australia Asia + Al Jazeera English + Al Quran Al Kareem TV + Animal Planet Southeast Asia + Animax Asia + ANTV + Arirang World + Asian Food Network + AXN East Asia + BabyTV Asia + BBC Earth Asia + BBC World News Asia Pacific + beIN Sports 1 Indonesia + beIN Sports 2 Indonesia + Berita Satu News Channel + Besmart + Bloomberg TV Asia + Boomerang South East Asia + Cartoon Network Asia + CBeebies Asia + Celestial Classic Movies + Celestial Movies Indonesia + CGTN + CGTN Documentary + Channel V International + Cinemax Asia + CNA + CNBC Asia-Pacific + CNN International Asia Pacific + Crime + Investigation Asia + Discovery Channel Southeast Asia + Disney Channel Indonesia + Disney Junior Asia + DW English + Ent + Fight Sports + FMN + Fox Action Movies + Fox Crime Asia + Fox Family Movies + Fox Indonesia + Fox Life Indonesia + Fox Movies Indonesia + Fox News Channel + Fox Sports 2 Asia + Fox Sports 3 Asia + Fox Sports Asia + France 24 English + GTV + HBO Asia + HBO Family Asia + HBO Hits + HBO Signature Asia + HGTV Asia + History Asia + Hits + Hits Movies + IDX Channel + Indosiar + iNews + Jak TV + Kids TV + Kix + Kompas TV + Life + Lifestyle & Fashion + Lifetime Asia + Metro TV + Miao Mi + MNC News + MNC Sports + MNCTV + MShop Signature + MShop Super Sale! + Music TV + Muslim TV + Nat Geo People Asia + National Geographic Asia + National Geographic Wild Asia + NET. + NHK World Japan + NHK World Premium + Nick Jr Asia + Nickelodeon South East Asia + OK TV + One + RCTI + SCTV + SEA Today + Soccer Channel + Star Chinese Movies Legend + Star Chinese Movies South East Asia + Tawaf TV + Thrill + TLC Southeast Asia + Trans 7 + Trans TV + tvN Movies Indonesia + tvN Premium Indonesia + tvOne + TVRI Nasional + Vision Prime + Warner TV Southeast Asia + Zee Bioskop + + \ No newline at end of file diff --git a/sites/mncvision.id.config.js b/sites/mncvision.id.config.js new file mode 100644 index 00000000..1b8c729c --- /dev/null +++ b/sites/mncvision.id.config.js @@ -0,0 +1,81 @@ +const FormData = require('form-data') +const jsdom = require('jsdom') +const { JSDOM } = jsdom +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +const timezone = require('dayjs/plugin/timezone') +const customParseFormat = require('dayjs/plugin/customParseFormat') + +dayjs.extend(utc) +dayjs.extend(timezone) +dayjs.extend(customParseFormat) + +module.exports = { + lang: 'en', + site: 'mncvision.id', + channels: 'mncvision.id.channels.xml', + output: '.gh-pages/guides/mncvision.id.guide.xml', + request: { + method: 'POST', + data: function ({ channel, date }) { + const formData = new FormData() + formData.setBoundary('X-EPG-BOUNDARY') + formData.append('search_model', 'channel') + formData.append('af0rmelement', 'aformelement') + formData.append('fdate', date.format('YYYY-MM-DD')) + formData.append('fchannel', channel.site_id) + formData.append('submit', 'Search') + + return formData + }, + headers: { + 'Content-Type': 'multipart/form-data; boundary=X-EPG-BOUNDARY' + } + }, + logo({ channel }) { + return `https://www.mncvision.id/userfiles/image/channel/channel_${channel.site_id}.png` + }, + url({ channel }) { + return `https://www.mncvision.id/schedule/table` + }, + parser({ content, date }) { + const programs = [] + const items = parseItems(content) + items.forEach(item => { + const title = parseTitle(item) + const start = parseStart(item, date) + const duration = parseDuration(item) + const stop = start.add(duration, 'm') + + programs.push({ title, start, stop }) + }) + + return programs + } +} + +function parseDuration(item) { + let duration = (item.querySelector('td:nth-child(3)') || { textContent: '' }).textContent + const match = duration.match(/(\d{2}):(\d{2})/) + const hours = parseInt(match[1]) + const minutes = parseInt(match[2]) + + return hours * 60 + minutes +} + +function parseStart(item, date) { + let time = (item.querySelector('td:nth-child(1)') || { textContent: '' }).textContent + time = `${date.format('DD/MM/YYYY')} ${time}` + + return dayjs.tz(time, 'DD/MM/YYYY HH:mm', 'Asia/Jakarta') +} + +function parseTitle(item) { + return (item.querySelector('td:nth-child(2) > a') || { textContent: '' }).textContent +} + +function parseItems(content) { + const dom = new JSDOM(content) + + return dom.window.document.querySelectorAll('tr[valign="top"]') +}