From 55ace2bfe4c23f1545ddd038581bfbecb2e4419e Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Fri, 18 Aug 2023 14:51:35 -0700 Subject: [PATCH 01/17] Initial commit --- sites/moji.id/moji.id.channels.xml | 7 ++ sites/moji.id/moji.id.config.js | 100 +++++++++++++++++++++++++++++ sites/moji.id/moji.id.test.js | 14 ++++ 3 files changed, 121 insertions(+) create mode 100644 sites/moji.id/moji.id.channels.xml create mode 100644 sites/moji.id/moji.id.config.js create mode 100644 sites/moji.id/moji.id.test.js diff --git a/sites/moji.id/moji.id.channels.xml b/sites/moji.id/moji.id.channels.xml new file mode 100644 index 00000000..2b0db07e --- /dev/null +++ b/sites/moji.id/moji.id.channels.xml @@ -0,0 +1,7 @@ + + + + Moji + + \ No newline at end of file diff --git a/sites/moji.id/moji.id.config.js b/sites/moji.id/moji.id.config.js new file mode 100644 index 00000000..882b3e23 --- /dev/null +++ b/sites/moji.id/moji.id.config.js @@ -0,0 +1,100 @@ +const cheerio = require('cheerio') +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) + +const currentYear = new Date().getFullYear() + +module.exports = { + site: 'moji.id', + days: 4, + output: 'moji.id.guide.xml', + channels: 'moji.id.channels.xml', + lang: 'en', + delay: 5000, + + url: function () { + return 'https://moji.id/schedule' + }, + + request: { + method: 'GET', + timeout: 5000, + cache: { ttl: 60 * 60 * 1000 }, + headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' } + }, + + logo: function (context) { + return context.channel.logo + }, + + parser: function (context) { + const programs = [] + + const items = parseItems(context.content) + + items.forEach(function(item, i) { + programs.push({ + title: item.progTitle, + description: item.progDesc, + start: item.progStart, + stop: item.progStop + }) + }) + + return programs + } +} + +function parseItems(content) { + const $ = cheerio.load(content) + let schDayMonths = $('.date-slider .slide').toArray() + let schPrograms = $('.desc-slider .list-slider .accordion').toArray() + let items = []; + schDayMonths.forEach(function(schDayMonth, i) { + schPrograms.forEach(function(program, i) { + let itemDay = { + progStart: parseStart(schDayMonth, program), + progStop: parseStop(schDayMonth, program, schPrograms[i+1]), + progTitle: parseTitle(program), + progDesc: parseDescription(program) + }; + items.push(itemDay) + }) + }) + + return items +} + +function parseTitle(item) { + return cheerio.load(item)('.name-prog').text() +} + +function parseDescription(item) { + return cheerio.load(item)('.content-acc span').text() +} + +function parseStart(schDayMonth, item) { + let monthDate = cheerio.load(schDayMonth)('.slide .month').text().split(' ') + let startTime = cheerio.load(item)('.pkl').text() + let progStart = dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + monthDate[1] + ' ' + startTime, 'YYYY MMM DD HH:mm', 'Asia/Jakarta') + return progStart +} + +function parseStop(schDayMonth, itemCurrent, itemNext) { + let monthDate = cheerio.load(schDayMonth)('.slide .month').text().split(' ') + + if (itemNext) { + let stopTime = cheerio.load(itemNext)('.pkl').text() + return dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + monthDate[1] + ' ' + stopTime, 'YYYY MMM DD HH:mm', 'Asia/Jakarta') + } + else + { + return dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + monthDate[1] + ' 24:00', 'YYYY MMM DD HH:mm', 'Asia/Jakarta') + } +} \ No newline at end of file diff --git a/sites/moji.id/moji.id.test.js b/sites/moji.id/moji.id.test.js new file mode 100644 index 00000000..9842ff65 --- /dev/null +++ b/sites/moji.id/moji.id.test.js @@ -0,0 +1,14 @@ +// npx epg-grabber --config=sites/moji.id/moji.id.config.js --channels=sites/moji.id/moji.id.channels.xml --output=guide.xml --days=2 +// npx jest moji.id.test.js + +const { url, parser } = require('./moji.id.config.js') +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +dayjs.extend(utc) + +const date = dayjs.utc('2023-04-29', 'YYYY-MM-DD').startOf('d') +const channel = { site_id: '0', xmltv_id: 'moji.id', lang: 'en', logo: 'https://moji.id/site/uploads/logo/62f9387ce00a2-224-x-71.png' } + +it('can generate valid url', () => { + expect(url({ channel, date })).toBe('https://moji.id/schedule') +}) \ No newline at end of file From 51359b0e21f8397e31bb4e460aa30b174a600274 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Fri, 18 Aug 2023 14:54:19 -0700 Subject: [PATCH 02/17] Added test cases --- sites/moji.id/moji.id.test.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sites/moji.id/moji.id.test.js b/sites/moji.id/moji.id.test.js index 9842ff65..8e0db7a6 100644 --- a/sites/moji.id/moji.id.test.js +++ b/sites/moji.id/moji.id.test.js @@ -11,4 +11,9 @@ const channel = { site_id: '0', xmltv_id: 'moji.id', lang: 'en', logo: 'https:// it('can generate valid url', () => { expect(url({ channel, date })).toBe('https://moji.id/schedule') +}) + +it('can handle empty guide', () => { + const results = parser({ content: '' }) + expect(results).toMatchObject([]) }) \ No newline at end of file From 1f50f0c0ce5ceab93120692759385497fde17566 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Fri, 18 Aug 2023 17:06:41 -0700 Subject: [PATCH 03/17] Bug fix on parsing the end-of-day stop time --- sites/moji.id/moji.id.config.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sites/moji.id/moji.id.config.js b/sites/moji.id/moji.id.config.js index 882b3e23..bf8b3f6c 100644 --- a/sites/moji.id/moji.id.config.js +++ b/sites/moji.id/moji.id.config.js @@ -53,14 +53,16 @@ module.exports = { function parseItems(content) { const $ = cheerio.load(content) - let schDayMonths = $('.date-slider .slide').toArray() - let schPrograms = $('.desc-slider .list-slider .accordion').toArray() + const schDayMonths = $('.date-slider .slide').toArray() + const schPrograms = $('.desc-slider .list-slider').toArray() let items = []; schDayMonths.forEach(function(schDayMonth, i) { - schPrograms.forEach(function(program, i) { + let schDayPrograms = $(schPrograms[i]).find('.accordion').toArray() + //let schDayPrograms = $('.accordion').toArray() + schDayPrograms.forEach(function(program, i) { let itemDay = { progStart: parseStart(schDayMonth, program), - progStop: parseStop(schDayMonth, program, schPrograms[i+1]), + progStop: parseStop(schDayMonth, program, schDayPrograms[i+1]), progTitle: parseTitle(program), progDesc: parseDescription(program) }; @@ -95,6 +97,6 @@ function parseStop(schDayMonth, itemCurrent, itemNext) { } else { - return dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + monthDate[1] + ' 24:00', 'YYYY MMM DD HH:mm', 'Asia/Jakarta') + return dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + (parseInt(monthDate[1]) + 1) + ' 00:00', 'YYYY MMM DD HH:mm', 'Asia/Jakarta') } } \ No newline at end of file From 61c16903e79d1e15a8a8b2693302243b23f5a27e Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Fri, 18 Aug 2023 17:29:45 -0700 Subject: [PATCH 04/17] Additional test case --- sites/moji.id/moji.id.test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sites/moji.id/moji.id.test.js b/sites/moji.id/moji.id.test.js index 8e0db7a6..d3db597b 100644 --- a/sites/moji.id/moji.id.test.js +++ b/sites/moji.id/moji.id.test.js @@ -9,6 +9,8 @@ dayjs.extend(utc) const date = dayjs.utc('2023-04-29', 'YYYY-MM-DD').startOf('d') const channel = { site_id: '0', xmltv_id: 'moji.id', lang: 'en', logo: 'https://moji.id/site/uploads/logo/62f9387ce00a2-224-x-71.png' } +const content = `

schedule

FriAug 18
SatAug 19
SunAug 20
Jam TayangProgram
00:00TRUST
Informasi seputar menjaga vitalitas pria
00:302023 AVC CHALLENGE CUP FOR WOMEN (RECORDED)
India Vs. Vietnam
02:30ONE CHAMPIONSHIP 2021
Siaran laga-laga pertandingan tinju gaya bebas internasional. Meyuguhkan pertarungan sengit dari para petarung profeisional kelas dunia.
03:30VOLLEYBALL NATION'S LEAGUE 2023 (RECORDED)
TURKI vs BRAZIL
05:00MOJI SPORT
MOJI SPORT
06:15LIPUTAN 6 PAGI MOJI
Kompilasi ragam berita hard news dan soft news baik dari dalam negeri maupun internasional juga info prediksi cuaca di wilayah Indonesia
07:00UNGKAP
Liputan investigasi seputar berbagai topik dan peristiwa hangat serta kontroversial yang terjadi di Indonesia
08:00PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
10:30SERIES PAGI
GANTENG GANTENG SERIGALA
12:30DIAM-DIAM SUKA
DIAM-DIAM SUKA
13:30PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
16:00PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
18:00PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
20:00MOJI DRAMA (CHHOTI SARDARNI)
CHHOTI SARDARNI
21:30SINEMA MALAM (BIDADARI CANTIK DI RUMAH KOST)
(BIDADARI CANTIK DI RUMAH KOST
23:00TRUST
Informasi seputar menjaga vitalitas pria
23:30TRUST
Informasi seputar menjaga vitalitas pria
` + it('can generate valid url', () => { expect(url({ channel, date })).toBe('https://moji.id/schedule') }) @@ -16,4 +18,17 @@ it('can generate valid url', () => { it('can handle empty guide', () => { const results = parser({ content: '' }) expect(results).toMatchObject([]) +}) + +it('can parse response', () => { + const results = parser({ content }) + + expect(results[0]).toMatchObject( + { + title: 'TRUST', + start: dayjs.tz('2023 Aug 18 00:00', 'YYYY MMM DD HH:mm', 'Asia/Jakarta'), + stop: dayjs.tz('2023 Aug 18 00:30', 'YYYY MMM DD HH:mm', 'Asia/Jakarta'), + description: 'Informasi seputar menjaga vitalitas pria' + } + ) }) \ No newline at end of file From 5a037ff089b8d857a78230541d6ea9b18a7e08da Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Sun, 20 Aug 2023 22:19:50 -0700 Subject: [PATCH 05/17] Initial commit --- .../taiwanplus.com.channels.xml | 7 ++ sites/taiwanplus.com/taiwanplus.com.config.js | 71 +++++++++++++++++++ sites/taiwanplus.com/taiwanplus.com.test.js | 38 ++++++++++ 3 files changed, 116 insertions(+) create mode 100644 sites/taiwanplus.com/taiwanplus.com.channels.xml create mode 100644 sites/taiwanplus.com/taiwanplus.com.config.js create mode 100644 sites/taiwanplus.com/taiwanplus.com.test.js diff --git a/sites/taiwanplus.com/taiwanplus.com.channels.xml b/sites/taiwanplus.com/taiwanplus.com.channels.xml new file mode 100644 index 00000000..320a0ec0 --- /dev/null +++ b/sites/taiwanplus.com/taiwanplus.com.channels.xml @@ -0,0 +1,7 @@ + + + + Taiwan Plus TV + + \ No newline at end of file diff --git a/sites/taiwanplus.com/taiwanplus.com.config.js b/sites/taiwanplus.com/taiwanplus.com.config.js new file mode 100644 index 00000000..803f1844 --- /dev/null +++ b/sites/taiwanplus.com/taiwanplus.com.config.js @@ -0,0 +1,71 @@ +const dayjs = require('dayjs') + +var isSameOrAfter = require('dayjs/plugin/isSameOrAfter') +dayjs.extend(isSameOrAfter) + +var isSameOrBefore = require('dayjs/plugin/isSameOrBefore') +dayjs.extend(isSameOrBefore) + +module.exports = { + site: 'taiwanplus.com', + days: 7, + output: 'taiwanplus.com.guide.xml', + channels: 'taiwanplus.com.channels.xml', + lang: 'en', + delay: 5000, + + url: function () { + return 'https://www.taiwanplus.com/api/video/live/schedule/0' + }, + + request: { + method: 'GET', + timeout: 5000, + cache: { ttl: 60 * 60 * 1000 }, // 60 * 60 seconds = 1 hour + headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' } + }, + + logo: function (context) { + return context.channel.logo + }, + + parser: function (context) { + let programs = [] + const scheduleDates = parseItems(context.content) + const today = dayjs.utc(context.date).startOf('day') + const lastDay = today.add(1, 'day') + + for(let scheduleDate of scheduleDates) { + const currentScheduleDate = new dayjs.utc(scheduleDate.date, 'YYYY/MM/DD') + + if (currentScheduleDate.isBefore(today)) { + continue + } else if (currentScheduleDate.isBefore(lastDay)) { + scheduleDate.schedule.forEach(function(program, i) { + programs.push({ + title: program.title, + start: dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm'), + stop: (i != (scheduleDate.schedule.length - 1)) ? dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm') : dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm').add(1, 'day').startOf('day'), + description: program.description, + icon: program.image, + category: program.categoryName, + rating: program.ageRating + }) + }) + } else { + continue + } + } + + return programs + } +} + +function parseItems(content) { + if (content != '') { + const data = JSON.parse(content) + return (!data || !data.data || !Array.isArray(data.data)) ? [] : data.data + } else { + return [] + } +} \ No newline at end of file diff --git a/sites/taiwanplus.com/taiwanplus.com.test.js b/sites/taiwanplus.com/taiwanplus.com.test.js new file mode 100644 index 00000000..dace4883 --- /dev/null +++ b/sites/taiwanplus.com/taiwanplus.com.test.js @@ -0,0 +1,38 @@ +// npx epg-grabber --config=sites/taiwanplus.com/taiwanplus.com.config.js --channels=sites/taiwanplus.com/taiwanplus.com.channels.xml --output=guide.xml --days=3 +// npx jest taiwanplus.com.test.js + +const { url, parser } = require('./taiwanplus.com.config.js') +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +dayjs.extend(utc) + +const date = dayjs.utc('2023-08-20', 'YYYY-MM-DD').startOf('d') +const channel = { site_id: '#', xmltv_id: 'TaiwanPlusTV.tw', lang: 'en', logo: 'https://i.imgur.com/SfcZyqm.png' } + +it('can generate valid url', () => { + expect(url({ channel, date })).toBe('https://www.taiwanplus.com/api/video/live/schedule/0') +}) + +it('can parse response', () => { + const content = `{"data":[{"date":"2023/08/20","weekday":"SUN","schedule":[{"programId":30668,"dateTime":"2023/08/20 00:00","time":"00:00","image":"https://prod-img.taiwanplus.com/live-schedule/Single/S30668_20230810104937.webp","title":"Master Class","shortDescription":"From blockchain to Buddha statues, Taiwan’s culture is a kaleidoscope of old and new just waiting to be discovered.","description":"From blockchain to Buddha statues, Taiwan’s culture is a kaleidoscope of old and new just waiting to be discovered.","ageRating":"0+","programWebSiteType":"4","url":"","vodId":null,"categoryId":90000474,"categoryType":2,"categoryName":"TaiwanPlus ✕ Discovery","categoryFullPath":"Originals/TaiwanPlus ✕ Discovery","encodedCategoryFullPath":"originals/taiwanplus-discovery"}]}],"success":true,"code":"0000","message":""}` + + const results = parser({ content, date }) + + expect(results).toMatchObject([ + { + title: 'Master Class', + start: dayjs.utc('2023/08/20 00:00', 'YYYY/MM/DD HH:mm'), + stop: dayjs.utc('2023/08/21 00:00', 'YYYY/MM/DD HH:mm'), + description: `From blockchain to Buddha statues, Taiwan’s culture is a kaleidoscope of old and new just waiting to be discovered.`, + icon: 'https://prod-img.taiwanplus.com/live-schedule/Single/S30668_20230810104937.webp', + category: 'TaiwanPlus ✕ Discovery', + rating: '0+' + } + ]) +}) + +it('can handle empty guide', () => { + const results = parser({ content: '' }) + + expect(results).toMatchObject([]) +}) From 1f74bff26c77edda4b817c64a670f60a909578c1 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Sun, 20 Aug 2023 22:37:16 -0700 Subject: [PATCH 06/17] Simplified date comparison --- sites/taiwanplus.com/taiwanplus.com.config.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sites/taiwanplus.com/taiwanplus.com.config.js b/sites/taiwanplus.com/taiwanplus.com.config.js index 803f1844..d05b31de 100644 --- a/sites/taiwanplus.com/taiwanplus.com.config.js +++ b/sites/taiwanplus.com/taiwanplus.com.config.js @@ -38,9 +38,7 @@ module.exports = { for(let scheduleDate of scheduleDates) { const currentScheduleDate = new dayjs.utc(scheduleDate.date, 'YYYY/MM/DD') - if (currentScheduleDate.isBefore(today)) { - continue - } else if (currentScheduleDate.isBefore(lastDay)) { + if (currentScheduleDate.isSame(today)) { scheduleDate.schedule.forEach(function(program, i) { programs.push({ title: program.title, @@ -51,9 +49,7 @@ module.exports = { category: program.categoryName, rating: program.ageRating }) - }) - } else { - continue + }); } } From 2212362e49f75e9a1aa25cf5b6728adadaf20d9f Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Sun, 20 Aug 2023 22:44:04 -0700 Subject: [PATCH 07/17] Modified variable declaration --- sites/taiwanplus.com/taiwanplus.com.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/taiwanplus.com/taiwanplus.com.config.js b/sites/taiwanplus.com/taiwanplus.com.config.js index d05b31de..78cf674c 100644 --- a/sites/taiwanplus.com/taiwanplus.com.config.js +++ b/sites/taiwanplus.com/taiwanplus.com.config.js @@ -30,7 +30,7 @@ module.exports = { }, parser: function (context) { - let programs = [] + const programs = [] const scheduleDates = parseItems(context.content) const today = dayjs.utc(context.date).startOf('day') const lastDay = today.add(1, 'day') From a8d2e6c7aea3fa2426def9b16897f0a796591334 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Sun, 20 Aug 2023 22:58:03 -0700 Subject: [PATCH 08/17] Bug fix on determining program stop time --- sites/taiwanplus.com/taiwanplus.com.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/taiwanplus.com/taiwanplus.com.config.js b/sites/taiwanplus.com/taiwanplus.com.config.js index 78cf674c..e5267c26 100644 --- a/sites/taiwanplus.com/taiwanplus.com.config.js +++ b/sites/taiwanplus.com/taiwanplus.com.config.js @@ -43,7 +43,7 @@ module.exports = { programs.push({ title: program.title, start: dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm'), - stop: (i != (scheduleDate.schedule.length - 1)) ? dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm') : dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm').add(1, 'day').startOf('day'), + stop: (i != (scheduleDate.schedule.length - 1)) ? dayjs.utc(scheduleDate.schedule[i+1].dateTime, 'YYYY/MM/DD HH:mm') : dayjs.utc(program.dateTime, 'YYYY/MM/DD HH:mm').add(1, 'day').startOf('day'), description: program.description, icon: program.image, category: program.categoryName, From 5e32930c752b9bec41f3724b79d4bd011e497412 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Mon, 21 Aug 2023 09:08:55 -0700 Subject: [PATCH 09/17] Adjusted the xmltv_id of Moji TV to follow its legacy tvg-id, which is OChannel.id --- sites/moji.id/moji.id.channels.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/moji.id/moji.id.channels.xml b/sites/moji.id/moji.id.channels.xml index 2b0db07e..5157482b 100644 --- a/sites/moji.id/moji.id.channels.xml +++ b/sites/moji.id/moji.id.channels.xml @@ -1,7 +1,7 @@ - Moji \ No newline at end of file From 307da2bb7cd792bc4eef3775e98f6274f63c5bf8 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Mon, 21 Aug 2023 10:48:27 -0700 Subject: [PATCH 10/17] Optimized parseItems to only process requested date, improved config to accept context as per spec, fixed test parameter. --- sites/moji.id/moji.id.config.js | 40 +++++++++++++++++---------------- sites/moji.id/moji.id.test.js | 9 ++++++-- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/sites/moji.id/moji.id.config.js b/sites/moji.id/moji.id.config.js index bf8b3f6c..926b0f97 100644 --- a/sites/moji.id/moji.id.config.js +++ b/sites/moji.id/moji.id.config.js @@ -35,8 +35,7 @@ module.exports = { parser: function (context) { const programs = [] - - const items = parseItems(context.content) + const items = parseItems(context) items.forEach(function(item, i) { programs.push({ @@ -51,23 +50,26 @@ module.exports = { } } -function parseItems(content) { - const $ = cheerio.load(content) - const schDayMonths = $('.date-slider .slide').toArray() +function parseItems(context) { + const $ = cheerio.load(context.content) + const schDayMonths = $('.date-slider .month').toArray() const schPrograms = $('.desc-slider .list-slider').toArray() - let items = []; + const monthDate = dayjs(context.date).format('MMM D') + const items = []; + schDayMonths.forEach(function(schDayMonth, i) { - let schDayPrograms = $(schPrograms[i]).find('.accordion').toArray() - //let schDayPrograms = $('.accordion').toArray() - schDayPrograms.forEach(function(program, i) { - let itemDay = { - progStart: parseStart(schDayMonth, program), - progStop: parseStop(schDayMonth, program, schDayPrograms[i+1]), - progTitle: parseTitle(program), - progDesc: parseDescription(program) - }; - items.push(itemDay) - }) + if (monthDate == $(schDayMonth).text()) { + let schDayPrograms = $(schPrograms[i]).find('.accordion').toArray() + schDayPrograms.forEach(function(program, i) { + let itemDay = { + progStart: parseStart(schDayMonth, program), + progStop: parseStop(schDayMonth, program, schDayPrograms[i+1]), + progTitle: parseTitle(program), + progDesc: parseDescription(program) + }; + items.push(itemDay) + }) + } }) return items @@ -82,14 +84,14 @@ function parseDescription(item) { } function parseStart(schDayMonth, item) { - let monthDate = cheerio.load(schDayMonth)('.slide .month').text().split(' ') + let monthDate = cheerio.load(schDayMonth).text().split(' ') let startTime = cheerio.load(item)('.pkl').text() let progStart = dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + monthDate[1] + ' ' + startTime, 'YYYY MMM DD HH:mm', 'Asia/Jakarta') return progStart } function parseStop(schDayMonth, itemCurrent, itemNext) { - let monthDate = cheerio.load(schDayMonth)('.slide .month').text().split(' ') + let monthDate = cheerio.load(schDayMonth).text().split(' ') if (itemNext) { let stopTime = cheerio.load(itemNext)('.pkl').text() diff --git a/sites/moji.id/moji.id.test.js b/sites/moji.id/moji.id.test.js index d3db597b..b579aa37 100644 --- a/sites/moji.id/moji.id.test.js +++ b/sites/moji.id/moji.id.test.js @@ -6,11 +6,16 @@ const dayjs = require('dayjs') const utc = require('dayjs/plugin/utc') dayjs.extend(utc) -const date = dayjs.utc('2023-04-29', 'YYYY-MM-DD').startOf('d') +const date = dayjs.utc('2023-08-18', 'YYYY-MM-DD').startOf('d') const channel = { site_id: '0', xmltv_id: 'moji.id', lang: 'en', logo: 'https://moji.id/site/uploads/logo/62f9387ce00a2-224-x-71.png' } const content = `

schedule

FriAug 18
SatAug 19
SunAug 20
Jam TayangProgram
00:00TRUST
Informasi seputar menjaga vitalitas pria
00:302023 AVC CHALLENGE CUP FOR WOMEN (RECORDED)
India Vs. Vietnam
02:30ONE CHAMPIONSHIP 2021
Siaran laga-laga pertandingan tinju gaya bebas internasional. Meyuguhkan pertarungan sengit dari para petarung profeisional kelas dunia.
03:30VOLLEYBALL NATION'S LEAGUE 2023 (RECORDED)
TURKI vs BRAZIL
05:00MOJI SPORT
MOJI SPORT
06:15LIPUTAN 6 PAGI MOJI
Kompilasi ragam berita hard news dan soft news baik dari dalam negeri maupun internasional juga info prediksi cuaca di wilayah Indonesia
07:00UNGKAP
Liputan investigasi seputar berbagai topik dan peristiwa hangat serta kontroversial yang terjadi di Indonesia
08:00PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
10:30SERIES PAGI
GANTENG GANTENG SERIGALA
12:30DIAM-DIAM SUKA
DIAM-DIAM SUKA
13:30PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
16:00PIALA KAPOLRI 2023 PUTRI (LIVE)
PIALA KAPOLRI 2023 PUTRI (LIVE)
18:00PIALA KAPOLRI 2023 PUTRA (LIVE)
PIALA KAPOLRI 2023 PUTRA (LIVE)
20:00MOJI DRAMA (CHHOTI SARDARNI)
CHHOTI SARDARNI
21:30SINEMA MALAM (BIDADARI CANTIK DI RUMAH KOST)
(BIDADARI CANTIK DI RUMAH KOST
23:00TRUST
Informasi seputar menjaga vitalitas pria
23:30TRUST
Informasi seputar menjaga vitalitas pria
` +const context = { + 'content': content, + 'date': date +} + it('can generate valid url', () => { expect(url({ channel, date })).toBe('https://moji.id/schedule') }) @@ -21,7 +26,7 @@ it('can handle empty guide', () => { }) it('can parse response', () => { - const results = parser({ content }) + const results = parser({ content: content, date: date }) expect(results[0]).toMatchObject( { From 7e35926143f695d6537aaccb3d00da2362179543 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Mon, 21 Aug 2023 13:46:08 -0700 Subject: [PATCH 11/17] Fixed dayjs.utc import --- sites/taiwanplus.com/taiwanplus.com.config.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sites/taiwanplus.com/taiwanplus.com.config.js b/sites/taiwanplus.com/taiwanplus.com.config.js index e5267c26..d8cb4896 100644 --- a/sites/taiwanplus.com/taiwanplus.com.config.js +++ b/sites/taiwanplus.com/taiwanplus.com.config.js @@ -1,9 +1,10 @@ const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +const isSameOrAfter = require('dayjs/plugin/isSameOrAfter') +const isSameOrBefore = require('dayjs/plugin/isSameOrBefore') -var isSameOrAfter = require('dayjs/plugin/isSameOrAfter') +dayjs.extend(utc) dayjs.extend(isSameOrAfter) - -var isSameOrBefore = require('dayjs/plugin/isSameOrBefore') dayjs.extend(isSameOrBefore) module.exports = { From d3748413b2fb18d13e11d346798277e6b4c348e6 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Fri, 25 Aug 2023 14:10:54 -0700 Subject: [PATCH 12/17] Initial commit --- sites/arirang.com/__data__/detail.json | 187 +++++++++++++++++++++ sites/arirang.com/__data__/schedule.json | 93 ++++++++++ sites/arirang.com/arirang.com.channels.xml | 10 ++ sites/arirang.com/arirang.com.config.js | 114 +++++++++++++ sites/arirang.com/arirang.com.test.js | 59 +++++++ 5 files changed, 463 insertions(+) create mode 100644 sites/arirang.com/__data__/detail.json create mode 100644 sites/arirang.com/__data__/schedule.json create mode 100644 sites/arirang.com/arirang.com.channels.xml create mode 100644 sites/arirang.com/arirang.com.config.js create mode 100644 sites/arirang.com/arirang.com.test.js diff --git a/sites/arirang.com/__data__/detail.json b/sites/arirang.com/__data__/detail.json new file mode 100644 index 00000000..bf7ce091 --- /dev/null +++ b/sites/arirang.com/__data__/detail.json @@ -0,0 +1,187 @@ +{ + "resultCode": { + "code": 200000, + "http_status": 200, + "timestamp": 0, + "message": null, + "trace": null, + "access_token": null, + "expire_time": 0 + }, + "program_id": 173, + "order": 21, + "is_news_allow": true, + "bis_program": [ + { + "bis_program_code": "2023003T", + "bis_program_title": "WITHIN THE FRAME [L]" + }, + { + "bis_program_code": "2023004T", + "bis_program_title": "WITHIN THE FRAME [R]" + } + ], + "bis_bundle_program_code": "2023003T", + "bis_category_code": "시사보도", + "program_type": "tv", + "category_Info": [ + { + "category_id": 29, + "local": "en", + "title": "Current Affairs" + }, + { + "category_id": 29, + "local": "ko", + "title": "Current Affairs" + } + ], + "title": [ + { + "lan_code": "en", + "text": "WITHIN THE FRAME [L]" + }, + { + "lan_code": "ko", + "text": "WITHIN THE FRAME [L]" + } + ], + "content": [ + { + "lan_code": "en", + "text": "NEWS
" + }, + { + "lan_code": "ko", + "text": "NEWS 대담
" + } + ], + "property": { + "open_status": { + "is_allow": true, + "is_origin_allow": null, + "start_date": null, + "end_date": null + }, + "is_onair": true, + "is_teaser_allow": false, + "running_time": 30, + "schedule": [ + { + "week": [ + "Mon", + "Tue", + "Wed", + "Thu", + "Fri" + ], + "start_time": 1110 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + }, + { + "week": [ + "" + ], + "start_time": -1 + } + ] + }, + "platform": { + "is_aos_allow": true, + "is_ios_allow": true, + "is_smat_tv_allow": true + }, + "image": [ + { + "order": 0, + "type": "horizontal", + "name": "2080840096998752900.png", + "action": null, + "url": "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202308/2080840096998752900.png" + }, + { + "order": 0, + "type": "vertical", + "name": "1773516657138860509.png", + "action": null, + "url": "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202301/1773516657138860509.png" + }, + { + "order": 0, + "type": "mobile", + "name": "1773516657893835229.png", + "action": null, + "url": "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202301/1773516657893835229.png" + }, + { + "order": 0, + "type": "pc", + "name": "1773742773929771485.png", + "action": null, + "url": "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202301/1773742773929771485.png" + }, + { + "order": 0, + "type": "smarttv", + "name": "1773742775607493085.png", + "action": null, + "url": "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202301/1773742775607493085.png" + }, + { + "order": 0, + "type": "square", + "name": "1773742767839642077.png", + "action": null, + "url": "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202301/1773742767839642077.png" + } + ], + "reg_date": "2023-01-03 10:21:56.0", + "update_date": "2023-08-03 10:55:34.0" +} \ No newline at end of file diff --git a/sites/arirang.com/__data__/schedule.json b/sites/arirang.com/__data__/schedule.json new file mode 100644 index 00000000..b6f620fa --- /dev/null +++ b/sites/arirang.com/__data__/schedule.json @@ -0,0 +1,93 @@ +{ + "resultCode": { + "code": 200000, + "http_status": 200, + "timestamp": 0, + "message": null, + "trace": null, + "access_token": null, + "expire_time": 0 + }, + "responseBody": { + "dsSchWeek": [ + { + "chanId": "CH_W", + "broadYmd": "20230825", + "planNo": 1, + "scheduleSeq": 1, + "broadHm": "0000", + "viewHm": "0000", + "broadRun": 30, + "timeGrade": "1", + "pgmCd": "2023004T", + "broadType": "R", + "displayNm": "WITHIN THE FRAME [R]", + "episodeNo": 4, + "episodeNm": "#4", + "displayEpisodeNm": null, + "partNo": 0, + "firstClf": "02", + "broadClf": "02", + "scheduleClf": "0", + "scheduleGrp": "01", + "videoClf": "H", + "audioClf": "0", + "liveClf": null, + "captionYn": "N", + "signLangYn": "N", + "dvsYn": "N", + "captionExceptClf": "N", + "signLangExceptClf": "N", + "dvsExceptClf": "N", + "delibGrade": "00", + "delibTopicYn": "N", + "delibLanguageYn": "N", + "delibCopyYn": "N", + "delibViolenceYn": "N", + "delibSexualYn": "N", + "infoGrade": "0+", + "episodeRun": null, + "bandCd": null, + "bandNm": null, + "keepYn": "N", + "firstYn": "N", + "addInfo": null, + "viewRating": null, + "scheduleColor": null, + "bgColor": null, + "bgColorR": null, + "bgColorG": null, + "bgColorB": null, + "textColorCd": null, + "textColorR": null, + "textColorG": null, + "textColorB": null, + "textColorHex": null, + "scheduleLineYn": "N", + "mediaInfo": null, + "regClf": "0", + "uuid": null, + "regUserId": "kylek", + "regDt": "20230816112556023", + "updUserId": "kylek", + "updDt": "20230817094411 ", + "weekDay": null, + "mtrlYn": null, + "timeGradeColor": null, + "timeGradeNm": "SA", + "broadClfNm": "재방", + "broadTypeNm": null, + "delibGradeNm": null, + "newsYn": "Y", + "bundlePgmCd": "2023003T", + "bundlePgmNm": "WITHIN THE FRAME", + "pgmOnm": "WITHIN THE FRAME [R]" + } + ], + "dmResult": { + "resultCode": "0", + "resultMsg": "success" + } + }, + "responseXML": null +} \ No newline at end of file diff --git a/sites/arirang.com/arirang.com.channels.xml b/sites/arirang.com/arirang.com.channels.xml new file mode 100644 index 00000000..893c33da --- /dev/null +++ b/sites/arirang.com/arirang.com.channels.xml @@ -0,0 +1,10 @@ + + + + Arirang TV + + + \ No newline at end of file diff --git a/sites/arirang.com/arirang.com.config.js b/sites/arirang.com/arirang.com.config.js new file mode 100644 index 00000000..4d117bb1 --- /dev/null +++ b/sites/arirang.com/arirang.com.config.js @@ -0,0 +1,114 @@ +const axios = require('axios') +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 = { + site: 'arirang.com', + output: 'arirang.com.guide.xml', + channels: 'arirang.com.channels.xml', + lang: 'en', + days: 7, + delay: 5000, + url: 'https://www.arirang.com/v1.0/open/external/proxy', + + request: { + method: 'POST', + timeout: 5000, + cache: { ttl: 60 * 60 * 1000 }, + headers: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': 'application/json', + 'Origin': 'https://www.arirang.com', + 'Referer': 'https://www.arirang.com/schedule', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' + }, + data: function (context) { + const { channel, date } = context + return { + 'address': 'https://script.arirang.com/api/v1/bis/listScheduleV3.do', + 'method': 'POST', + 'headers': {}, + 'body': { + 'data': { + 'dmParam': { + 'chanId': channel.site_id, + 'broadYmd': dayjs.tz(date, 'Asia/Seoul').format('YYYYMMDD'), + 'planNo': '1' + } + } + } + } + } + }, + + logo: function (context) { + return context.channel.logo + }, + + async parser(context) { + const programs = [] + const items = parseItems(context.content) + + for (let item of items) { + const programDetail = await parseProgramDetail(item) + + programs.push({ + title: item.displayNm, + start: parseStart(item), + stop: parseStop(item), + icon: programDetail.image[0].url, + category: programDetail.category_Info[0].title, + description: programDetail.content[0].text + + }) + } + + return programs + } +} + +function parseItems(content) { + if (content != '') { + const data = JSON.parse(content) + return (!data || !data.responseBody || !Array.isArray(data.responseBody.dsSchWeek)) ? [] : data.responseBody.dsSchWeek + } else { + return [] + } +} + +function parseStart(item) { + return dayjs.tz(item.broadYmd + ' ' + item.broadHm, 'YYYYMMDD HHmm', 'Asia/Seoul') +} + +function parseStop(item) { + return dayjs.tz(item.broadYmd + ' ' + item.broadHm, 'YYYYMMDD HHmm', 'Asia/Seoul').add(item.broadRun, 'minute') +} + +async function parseProgramDetail(item) { + const data = await axios.post( + 'https://www.arirang.com/v1.0/open/program/detail', + { + 'bis_program_code': item.pgmCd + }, + { + headers: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': 'application/json', + 'Origin': 'https://www.arirang.com', + 'Referer': 'https://www.arirang.com/schedule', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' + } + }) + .then(r => r.data) + .catch() + + if (!data) + return {} + + return data +} \ No newline at end of file diff --git a/sites/arirang.com/arirang.com.test.js b/sites/arirang.com/arirang.com.test.js new file mode 100644 index 00000000..8f22db86 --- /dev/null +++ b/sites/arirang.com/arirang.com.test.js @@ -0,0 +1,59 @@ +// npx epg-grabber --config=sites/arirang.com/arirang.com.config.js --channels=sites/arirang.com/arirang.com.channels.xml --output=guide.xml --days=2 +// npx jest arirang.com.test.js + +const { url, parser } = require('./arirang.com.config.js') +const fs = require('fs') +const path = require('path') +const axios = require('axios') +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +const { program } = require('commander') +dayjs.extend(utc) + +jest.mock('axios') + +const date = dayjs.tz('2023-08-25', 'Asia/Seoul').startOf('d') +const channel = { xmltv_id: 'ArirangWorld.kr', site_id: 'CH_W', name: 'Arirang World', lang: 'en', logo: 'https://i.imgur.com/5Aoithj.png' } +const content = fs.readFileSync(path.resolve(__dirname, '__data__/schedule.json'), 'utf8') +const programDetail = fs.readFileSync(path.resolve(__dirname, '__data__/detail.json'), 'utf8') +const context = { 'channel': channel, 'content': content, 'date': date } + +it('can generate valid url', () => { + expect(url).toBe('https://www.arirang.com/v1.0/open/external/proxy') +}) + +it('can handle empty guide', async () => { + const results = await parser({ 'channel': channel, 'content': '', 'date': date }) + expect(results).toMatchObject([]) +}) + +it('can parse response', async () => { + axios.post.mockImplementation((url, data) => { + if (url === 'https://www.arirang.com/v1.0/open/external/proxy' && JSON.stringify(data) === JSON.stringify({ "address": "https://script.arirang.com/api/v1/bis/listScheduleV3.do", "method": "POST", "headers": {}, "body": { "data": { "dmParam": { "chanId": "CH_W", "broadYmd": "20230825", "planNo": "1" } } } })) { + return Promise.resolve({ + data: JSON.parse(content) + }) + } else if (url === 'https://www.arirang.com/v1.0/open/program/detail' && JSON.stringify(data) === JSON.stringify({ "bis_program_code": "2023004T" })) { + return Promise.resolve({ + data: JSON.parse(programDetail) + }) + } else { + return Promise.resolve({ + data: '' + }) + } + }) + + const results = await parser(context) + + expect(results[0]).toMatchObject( + { + title: "WITHIN THE FRAME [R]", + start: dayjs.tz(date, 'Asia/Seoul'), + stop: dayjs.tz(date, 'Asia/Seoul').add(30, 'minute'), + icon: "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202308/2080840096998752900.png", + description: "NEWS
", + category: "Current Affairs" + } + ) +}) \ No newline at end of file From 420807769d7ac20d297c81a1369e56ae45b14fb0 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Fri, 25 Aug 2023 14:12:12 -0700 Subject: [PATCH 13/17] Uncomment other channels --- sites/arirang.com/arirang.com.channels.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/sites/arirang.com/arirang.com.channels.xml b/sites/arirang.com/arirang.com.channels.xml index 893c33da..140ab525 100644 --- a/sites/arirang.com/arirang.com.channels.xml +++ b/sites/arirang.com/arirang.com.channels.xml @@ -2,9 +2,7 @@ Arirang TV - \ No newline at end of file From 6988c53c12b2367fb987a62c424e7f5d8e922202 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Sat, 26 Aug 2023 11:47:24 -0700 Subject: [PATCH 14/17] Bug fix: need to return the promise --- sites/arirang.com/arirang.com.config.js | 27 ++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/sites/arirang.com/arirang.com.config.js b/sites/arirang.com/arirang.com.config.js index 4d117bb1..172f24ca 100644 --- a/sites/arirang.com/arirang.com.config.js +++ b/sites/arirang.com/arirang.com.config.js @@ -61,10 +61,9 @@ module.exports = { title: item.displayNm, start: parseStart(item), stop: parseStop(item), - icon: programDetail.image[0].url, - category: programDetail.category_Info[0].title, - description: programDetail.content[0].text - + icon: programDetail ? programDetail.image[0].url : '', + category: programDetail ? programDetail.category_Info[0].title : '', + description: programDetail ? programDetail.content[0].text : '' }) } @@ -90,7 +89,7 @@ function parseStop(item) { } async function parseProgramDetail(item) { - const data = await axios.post( + return axios.post( 'https://www.arirang.com/v1.0/open/program/detail', { 'bis_program_code': item.pgmCd @@ -102,13 +101,13 @@ async function parseProgramDetail(item) { 'Origin': 'https://www.arirang.com', 'Referer': 'https://www.arirang.com/schedule', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' - } - }) - .then(r => r.data) - .catch() - - if (!data) - return {} - - return data + }, + timeout: 5000, + cache: { ttl: 60 * 1000 }, + } + ).then(function (response) { + return response.data + }).catch(function (error) { + // console.log(error) + }) } \ No newline at end of file From 472f03e9819d68ad889a57da5a1445015e012813 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Mon, 28 Aug 2023 19:41:38 -0700 Subject: [PATCH 15/17] Strip HTML tags in description --- sites/arirang.com/arirang.com.config.js | 34 ++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/sites/arirang.com/arirang.com.config.js b/sites/arirang.com/arirang.com.config.js index 172f24ca..d0c133d5 100644 --- a/sites/arirang.com/arirang.com.config.js +++ b/sites/arirang.com/arirang.com.config.js @@ -61,9 +61,9 @@ module.exports = { title: item.displayNm, start: parseStart(item), stop: parseStop(item), - icon: programDetail ? programDetail.image[0].url : '', - category: programDetail ? programDetail.category_Info[0].title : '', - description: programDetail ? programDetail.content[0].text : '' + icon: parseIcon(programDetail), + category: parseCategory(programDetail), + description: parseDescription(programDetail) }) } @@ -110,4 +110,30 @@ async function parseProgramDetail(item) { }).catch(function (error) { // console.log(error) }) -} \ No newline at end of file +} + +function parseIcon(programDetail) { + if (programDetail && programDetail.image && programDetail.image[0].url) { + return programDetail.image[0].url + } else { + return '' + } +} + +function parseCategory(programDetail) { + if (programDetail && programDetail.category_Info && programDetail.category_Info[0].title) { + return programDetail.category_Info[0].title + } else { + return '' + } +} + +function parseDescription(programDetail) { + if (programDetail && programDetail.content && programDetail.content[0] && programDetail.content[0].text) { + let description = programDetail.content[0].text + let regex = /(<([^>]+)>)/ig + return description.replace(regex, '') + } else { + return '' + } +} From 8b1be0607f3ce9433ca42b42e6202f93d228e330 Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Sun, 3 Sep 2023 17:47:51 -0700 Subject: [PATCH 16/17] Bug fix for single digit days --- sites/moji.id/moji.id.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sites/moji.id/moji.id.config.js b/sites/moji.id/moji.id.config.js index 926b0f97..b9c4ffe3 100644 --- a/sites/moji.id/moji.id.config.js +++ b/sites/moji.id/moji.id.config.js @@ -54,7 +54,7 @@ function parseItems(context) { const $ = cheerio.load(context.content) const schDayMonths = $('.date-slider .month').toArray() const schPrograms = $('.desc-slider .list-slider').toArray() - const monthDate = dayjs(context.date).format('MMM D') + const monthDate = dayjs(context.date).format('MMM DD') const items = []; schDayMonths.forEach(function(schDayMonth, i) { @@ -99,6 +99,6 @@ function parseStop(schDayMonth, itemCurrent, itemNext) { } else { - return dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + (parseInt(monthDate[1]) + 1) + ' 00:00', 'YYYY MMM DD HH:mm', 'Asia/Jakarta') + return dayjs.tz(currentYear + ' ' + monthDate[0] + ' ' + (parseInt(monthDate[1]) + 1).toString().padStart(2, '0') + ' 00:00', 'YYYY MMM DD HH:mm', 'Asia/Jakarta') } } \ No newline at end of file From a1f6afa9f8fb636e63c7d5590c5295fb33bf4bda Mon Sep 17 00:00:00 2001 From: Arif Budiman Date: Mon, 18 Sep 2023 17:10:46 -0700 Subject: [PATCH 17/17] Fix for test case, since we now remove HTML tags from program description --- sites/arirang.com/arirang.com.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/arirang.com/arirang.com.test.js b/sites/arirang.com/arirang.com.test.js index 8f22db86..f0d4d165 100644 --- a/sites/arirang.com/arirang.com.test.js +++ b/sites/arirang.com/arirang.com.test.js @@ -52,7 +52,7 @@ it('can parse response', async () => { start: dayjs.tz(date, 'Asia/Seoul'), stop: dayjs.tz(date, 'Asia/Seoul').add(30, 'minute'), icon: "https://img.arirang.com/v1/AUTH_d52449c16d3b4bbca17d4fffd9fc44af/public/images/202308/2080840096998752900.png", - description: "NEWS
", + description: "NEWS", category: "Current Affairs" } )