From 751bea95967293872b93f03fcba312f1642c5472 Mon Sep 17 00:00:00 2001 From: Aleksandr Statciuk Date: Thu, 11 Nov 2021 14:52:45 +0300 Subject: [PATCH 1/2] Create elcinema.com.test.js --- sites/elcinema.com/elcinema.com.test.js | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 sites/elcinema.com/elcinema.com.test.js diff --git a/sites/elcinema.com/elcinema.com.test.js b/sites/elcinema.com/elcinema.com.test.js new file mode 100644 index 00000000..7fe1109c --- /dev/null +++ b/sites/elcinema.com/elcinema.com.test.js @@ -0,0 +1,66 @@ +// npx epg-grabber --config=sites/elcinema.com/elcinema.com.config.js --channels=sites/elcinema.com/elcinema.com_eg-en.channels.xml --output=.gh-pages/guides/eg-en/elcinema.com.epg.xml --days=2 +// npx epg-grabber --config=sites/elcinema.com/elcinema.com.config.js --channels=sites/elcinema.com/elcinema.com_eg-ar.channels.xml --output=.gh-pages/guides/eg-ar/elcinema.com.epg.xml --days=2 + +const { parser, url, request, logo } = require('./elcinema.com.config.js') +const dayjs = require('dayjs') +const utc = require('dayjs/plugin/utc') +const customParseFormat = require('dayjs/plugin/customParseFormat') +dayjs.extend(customParseFormat) +dayjs.extend(utc) + +const date = dayjs.utc('2021-11-11', 'YYYY-MM-DD').startOf('d') +const channelAR = { + lang: 'ar', + site_id: '1127', + xmltv_id: 'MBC.ae' +} +const channelEN = { + lang: 'en', + site_id: '1127', + xmltv_id: 'MBC.ae' +} +const contentAR = `
الخميس 11 نوفمبر
  • 12:30 مساءً
  • [30 دقيقة]
  • يعيد برنامج (أحلى ما طاش) عرضا لمجموعة من أفضل الحلقات التي...اقرأ المزيد تم تقديمها من خلال المسلسل الكوميدي السعودي (طاش ما طاش)، والذي استمر عرضه على التليفزيون السعودي لمدة 18 موسمًا متواصلًا، والتي ناقش من خلالها (ناصر القصبي) و(عبدالله السدحان) مجموعة من القضايا الاجتماعية التي تشغل بال المجتمع السعودي بطريقة ساخرة.
الجمعة 12 نوفمبر
  • يوميات موسم الرياض 2021
  • 12:00 صباحًا [15 دقيقة]
` +const contentEN = `
Thursday 11 November
  • 10:00 AM
  • [120 minutes]
` + +it('can generate valid url', () => { + expect(url({ channel: channelEN })).toBe('https://elcinema.com/en/tvguide/1127/') +}) + +it('can get logo url', () => { + expect(logo({ content: contentEN })).toBe('https://media.elcinema.com/tvguide/1127_1.png') +}) + +it('can parse response (en)', () => { + expect(parser({ date, channel: channelEN, content: contentEN })).toMatchObject([ + { + start: '2021-11-11T08:00:00.000Z', + stop: '2021-11-11T10:00:00.000Z', + title: 'Good Morning Arab', + icon: 'https://media.elcinema.com/uploads/_150x200_5659fb4f174c49b54cc14cb53e70a5467abef429b5bb9d1a1cf2a40aa37562b2.jpg', + description: `As Abdel Mohsen passes away and his will is read to the family members, the true essence of each of them emerges, resulting in unthinkable discord. `, + category: 'Program' + } + ]) +}) + +it('can parse response (ar)', () => { + expect(parser({ date, channel: channelAR, content: contentAR })).toMatchObject([ + { + start: '2021-11-11T10:30:00.000Z', + stop: '2021-11-11T11:00:00.000Z', + title: 'أحلى ما طاش', + icon: 'https://media.elcinema.com/uploads/_150x200_2f74473c92a69d7bfd25bd7fca8576168e8a58da4dd5cb8222eb1297caa13915.jpg', + description: ` يعيد برنامج (أحلى ما طاش) عرضا لمجموعة من أفضل الحلقات التي تم تقديمها من خلال المسلسل الكوميدي السعودي (طاش ما طاش)، والذي استمر عرضه على التليفزيون السعودي لمدة 18 موسمًا متواصلًا، والتي ناقش من خلالها (ناصر القصبي) و(عبدالله السدحان) مجموعة من القضايا الاجتماعية التي تشغل بال المجتمع السعودي بطريقة ساخرة. `, + category: 'مسلسل' + } + ]) +}) + +it('can handle empty guide', () => { + const result = parser({ + date, + channel: channelEN, + content: `` + }) + expect(result).toMatchObject([]) +}) From fe5e5a23a7c062bbca3395ac1843d96f801acbe0 Mon Sep 17 00:00:00 2001 From: Aleksandr Statciuk Date: Thu, 11 Nov 2021 14:53:34 +0300 Subject: [PATCH 2/2] Update elcinema.com.config.js --- sites/elcinema.com/elcinema.com.config.js | 116 ++++++++++------------ 1 file changed, 52 insertions(+), 64 deletions(-) diff --git a/sites/elcinema.com/elcinema.com.config.js b/sites/elcinema.com/elcinema.com.config.js index 0c84e76e..efcfdc7c 100644 --- a/sites/elcinema.com/elcinema.com.config.js +++ b/sites/elcinema.com/elcinema.com.config.js @@ -1,9 +1,9 @@ -const jsdom = require('jsdom') -const { JSDOM } = jsdom +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') +require('dayjs/locale/ar') dayjs.extend(customParseFormat) dayjs.extend(timezone) @@ -17,31 +17,25 @@ module.exports = { return `https://elcinema.com/${lang}tvguide/${channel.site_id}/` }, logo({ content }) { - const dom = new JSDOM(content) - const img = dom.window.document.querySelector('.intro-box > .row > div.columns.large-2 > img') + const $ = cheerio.load(content) + const imgSrc = $('.intro-box > .row > div.columns.large-2 > img').attr('src') - return img.src || null + return imgSrc || null }, - parser({ content, date }) { + parser({ content, channel, date }) { const programs = [] - - const items = parseItems(content, date) + const items = parseItems(content, channel, date) items.forEach(item => { - const title = parseTitle(item) - const description = parseDescription(item) - const category = parseCategory(item) - const icon = parseIcon(item) const start = parseStart(item, date) const duration = parseDuration(item) const stop = start.add(duration, 'm') - programs.push({ - title, - description, - category, - icon, - start, - stop + title: parseTitle(item), + description: parseDescription(item), + category: parseCategory(item), + icon: parseIcon(item), + start: start.toJSON(), + stop: stop.toJSON() }) }) @@ -50,41 +44,36 @@ module.exports = { } function parseIcon(item) { - const img = - item.querySelector('.row > div.columns.small-3.large-1 > a > img') || - item.querySelector('.row > div.columns.small-5.large-1 > img') + const $ = cheerio.load(item) + const imgSrc = + $('.row > div.columns.small-3.large-1 > a > img').data('src') || + $('.row > div.columns.small-5.large-1 > img').data('src') - return img.dataset.src || null + return imgSrc || null } function parseCategory(item) { - const category = ( - item.querySelector('.row > div.columns.small-6.large-3 > ul > li:nth-child(2)') || { - textContent: '' - } - ).textContent + const $ = cheerio.load(item) + const category = $('.row > div.columns.small-6.large-3 > ul > li:nth-child(2)').text() - return category.replace(/\(\d+\)/, '').trim() + return category.replace(/\(\d+\)/, '').trim() || null } function parseDuration(item) { - const duration = ( - item.querySelector('.row > div.columns.small-3.large-2 > ul > li:nth-child(2) > span') || - item.querySelector('.row > div.columns.small-7.large-11 > ul > li:nth-child(2) > span') || { - textContent: '' - } - ).textContent + const $ = cheerio.load(item) + const duration = + $('.row > div.columns.small-3.large-2 > ul > li:nth-child(2) > span').text() || + $('.row > div.columns.small-7.large-11 > ul > li:nth-child(2) > span').text() - return duration.replace(/\D/g, '') + return duration.replace(/\D/g, '') || '' } function parseStart(item, initDate) { - let time = ( - item.querySelector('.row > div.columns.small-3.large-2 > ul > li:nth-child(1)') || - item.querySelector('.row > div.columns.small-7.large-11 > ul > li:nth-child(2)') || { - textContent: '' - } - ).textContent + const $ = cheerio.load(item) + let time = + $('.row > div.columns.small-3.large-2 > ul > li:nth-child(1)').text() || + $('.row > div.columns.small-7.large-11 > ul > li:nth-child(2)').text() || + '' time = time .replace(/\[.*\]/, '') @@ -94,37 +83,36 @@ function parseStart(item, initDate) { time = `${initDate.format('DD/MM/YYYY')} ${time}` - return dayjs.tz(time, 'DD/MM/YYYY H:mm A', 'Africa/Algiers') + return dayjs.tz(time, 'DD/MM/YYYY H:mm A', 'Africa/Cairo') } function parseTitle(item) { + const $ = cheerio.load(item) + return ( - item.querySelector('.row > div.columns.small-6.large-3 > ul > li:nth-child(1) > a') || - item.querySelector('.row > div.columns.small-7.large-11 > ul > li:nth-child(1)') || { - textContent: '' - } - ).textContent + $('.row > div.columns.small-6.large-3 > ul > li:nth-child(1) > a').text() || + $('.row > div.columns.small-7.large-11 > ul > li:nth-child(1)').text() || + null + ) } function parseDescription(item) { - const excerpt = ( - item.querySelector('.row > div.columns.small-12.large-6 > ul > li:nth-child(3)') || { - textContent: '' - } - ).textContent - const desc = ( - item.querySelector('.row > div.columns.small-12.large-6 > ul > li:nth-child(3) > .hide') || { - textContent: '' - } - ).textContent + const $ = cheerio.load(item) + const excerpt = $('.row > div.columns.small-12.large-6 > ul > li:nth-child(3)').text() || '' - return excerpt.replace('...اقرأ المزيد', '').replace('...Read more', '') + desc + return excerpt.replace('...اقرأ المزيد', '').replace('...Read more', '') } -function parseItems(content, date) { - const dom = new JSDOM(content) - const diff = date.diff(dayjs().startOf('d'), 'd') - const listNum = (diff + 1) * 2 +function parseItems(content, channel, date) { + const $ = cheerio.load(content) + const dateString = date.locale(channel.lang).format('dddd D MMMM') + const list = $('.dates') + .filter((i, el) => { + return $(el).text().trim() === dateString + }) + .first() + .parent() + .next() - return dom.window.document.querySelectorAll(`.tvgrid > div:nth-child(${listNum}) > .padded-half`) + return $('.padded-half', list).toArray() }