Merge pull request #229 from iptv-org/update-elcinema-com

Update elcinema.com
This commit is contained in:
Aleksandr Statciuk
2021-11-11 14:55:55 +03:00
committed by GitHub
2 changed files with 118 additions and 64 deletions

View File

@@ -1,9 +1,9 @@
const jsdom = require('jsdom') const cheerio = require('cheerio')
const { JSDOM } = jsdom
const dayjs = require('dayjs') const dayjs = require('dayjs')
const utc = require('dayjs/plugin/utc') const utc = require('dayjs/plugin/utc')
const timezone = require('dayjs/plugin/timezone') const timezone = require('dayjs/plugin/timezone')
const customParseFormat = require('dayjs/plugin/customParseFormat') const customParseFormat = require('dayjs/plugin/customParseFormat')
require('dayjs/locale/ar')
dayjs.extend(customParseFormat) dayjs.extend(customParseFormat)
dayjs.extend(timezone) dayjs.extend(timezone)
@@ -17,31 +17,25 @@ module.exports = {
return `https://elcinema.com/${lang}tvguide/${channel.site_id}/` return `https://elcinema.com/${lang}tvguide/${channel.site_id}/`
}, },
logo({ content }) { logo({ content }) {
const dom = new JSDOM(content) const $ = cheerio.load(content)
const img = dom.window.document.querySelector('.intro-box > .row > div.columns.large-2 > img') 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 programs = []
const items = parseItems(content, channel, date)
const items = parseItems(content, date)
items.forEach(item => { 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 start = parseStart(item, date)
const duration = parseDuration(item) const duration = parseDuration(item)
const stop = start.add(duration, 'm') const stop = start.add(duration, 'm')
programs.push({ programs.push({
title, title: parseTitle(item),
description, description: parseDescription(item),
category, category: parseCategory(item),
icon, icon: parseIcon(item),
start, start: start.toJSON(),
stop stop: stop.toJSON()
}) })
}) })
@@ -50,41 +44,36 @@ module.exports = {
} }
function parseIcon(item) { function parseIcon(item) {
const img = const $ = cheerio.load(item)
item.querySelector('.row > div.columns.small-3.large-1 > a > img') || const imgSrc =
item.querySelector('.row > div.columns.small-5.large-1 > img') $('.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) { function parseCategory(item) {
const category = ( const $ = cheerio.load(item)
item.querySelector('.row > div.columns.small-6.large-3 > ul > li:nth-child(2)') || { const category = $('.row > div.columns.small-6.large-3 > ul > li:nth-child(2)').text()
textContent: ''
}
).textContent
return category.replace(/\(\d+\)/, '').trim() return category.replace(/\(\d+\)/, '').trim() || null
} }
function parseDuration(item) { function parseDuration(item) {
const duration = ( const $ = cheerio.load(item)
item.querySelector('.row > div.columns.small-3.large-2 > ul > li:nth-child(2) > span') || const duration =
item.querySelector('.row > div.columns.small-7.large-11 > ul > li:nth-child(2) > span') || { $('.row > div.columns.small-3.large-2 > ul > li:nth-child(2) > span').text() ||
textContent: '' $('.row > div.columns.small-7.large-11 > ul > li:nth-child(2) > span').text()
}
).textContent
return duration.replace(/\D/g, '') return duration.replace(/\D/g, '') || ''
} }
function parseStart(item, initDate) { function parseStart(item, initDate) {
let time = ( const $ = cheerio.load(item)
item.querySelector('.row > div.columns.small-3.large-2 > ul > li:nth-child(1)') || let time =
item.querySelector('.row > div.columns.small-7.large-11 > ul > li:nth-child(2)') || { $('.row > div.columns.small-3.large-2 > ul > li:nth-child(1)').text() ||
textContent: '' $('.row > div.columns.small-7.large-11 > ul > li:nth-child(2)').text() ||
} ''
).textContent
time = time time = time
.replace(/\[.*\]/, '') .replace(/\[.*\]/, '')
@@ -94,37 +83,36 @@ function parseStart(item, initDate) {
time = `${initDate.format('DD/MM/YYYY')} ${time}` 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) { function parseTitle(item) {
const $ = cheerio.load(item)
return ( return (
item.querySelector('.row > div.columns.small-6.large-3 > ul > li:nth-child(1) > a') || $('.row > div.columns.small-6.large-3 > ul > li:nth-child(1) > a').text() ||
item.querySelector('.row > div.columns.small-7.large-11 > ul > li:nth-child(1)') || { $('.row > div.columns.small-7.large-11 > ul > li:nth-child(1)').text() ||
textContent: '' null
} )
).textContent
} }
function parseDescription(item) { function parseDescription(item) {
const excerpt = ( const $ = cheerio.load(item)
item.querySelector('.row > div.columns.small-12.large-6 > ul > li:nth-child(3)') || { const excerpt = $('.row > div.columns.small-12.large-6 > ul > li:nth-child(3)').text() || ''
textContent: ''
}
).textContent
const desc = (
item.querySelector('.row > div.columns.small-12.large-6 > ul > li:nth-child(3) > .hide') || {
textContent: ''
}
).textContent
return excerpt.replace('...اقرأ المزيد', '').replace('...Read more', '') + desc return excerpt.replace('...اقرأ المزيد', '').replace('...Read more', '')
} }
function parseItems(content, date) { function parseItems(content, channel, date) {
const dom = new JSDOM(content) const $ = cheerio.load(content)
const diff = date.diff(dayjs().startOf('d'), 'd') const dateString = date.locale(channel.lang).format('dddd D MMMM')
const listNum = (diff + 1) * 2 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()
} }

View File

@@ -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 = `<!DOCTYPE html><html lang="ar" dir="rtl"> <head></head> <body> <div class="row"> <div class="columns small-12 min-body"> <div class="intro-box"> <div class="row"> <div class="columns large-2"> <img src="https://media.elcinema.com/tvguide/1127_1.png" alt=""/> </div></div></div><div class="row tvgrid"> <div class="columns small-12"> <div class="dates">الخميس 11 نوفمبر</div></div><div class="columns small-12"> <div class="boxed-category-3 padded-half"> <div class="row"> <div class="columns small-3 large-2"> <ul class="unstyled text-center"> <li>12:30 مساءً</li><li><span class="subheader">[30 دقيقة]</span></li></ul> </div><div class="columns small-3 large-1"> <a href="/work/2009394/" ><img class="lazy-loaded" data-src="https://media.elcinema.com/uploads/_150x200_2f74473c92a69d7bfd25bd7fca8576168e8a58da4dd5cb8222eb1297caa13915.jpg" src=""/></a> </div><div class="columns small-6 large-3"> <ul class="unstyled no-margin"> <li><a href="/work/2009394/">أحلى ما طاش</a></li><li>مسلسل (2020)</li><li> <a href="#" data-key="favourite.work.2009394" class="button minimize small action-button-off" title="أضف إلى مفضلاتك" ><i class="fa fa-heart fa-1x"></i><span>مفضل</span></a > <a href="#" data-key="reminder.tvguide.6555590" class="button minimize small action-button-off" title="ذكرني" ><i class="fa fa-bell fa-1x"></i><span>ذكرني</span></a > </li></ul> </div><div class="columns small-12 large-6"> <ul class="unstyled no-margin"> <li></li><li> <ul class="list-separator"> <li><a href="/person/1104390/">عبدالله السدحان</a></li><li><a href="/person/1104389/">ناصر القصبي</a></li><li><a href="/person/1103184/">عبير عيسى</a></li><li><a href="/person/1103278/">زينب العسكري</a></li></ul> </li><li> يعيد برنامج (أحلى ما طاش) عرضا لمجموعة من أفضل الحلقات التي<a href="#" id="read-more" >...اقرأ المزيد</a ><span class="hide"> تم تقديمها من خلال المسلسل الكوميدي السعودي (طاش ما طاش)، والذي استمر عرضه على التليفزيون السعودي لمدة 18 موسمًا متواصلًا، والتي ناقش من خلالها (ناصر القصبي) و(عبدالله السدحان) مجموعة من القضايا الاجتماعية التي تشغل بال المجتمع السعودي بطريقة ساخرة.</span > </li></ul> </div></div></div></div><div class="columns small-12"> <div class="dates">الجمعة 12 نوفمبر</div></div><div class="columns small-12"> <div class="boxed-category-0 padded-half"> <div class="row"> <div class="columns small-5 large-1"> <img class="lazy-loaded" data-src="https://media.elcinema.com/blank_photos/150x200.jpg" src=""/> </div><div class="columns small-7 large-11"> <ul class="unstyled no-margin"> <li>يوميات موسم الرياض 2021</li><li> 12:00 صباحًا <span class="subheader">[15 دقيقة]</span> </li></ul> </div></div></div></div></div></div></div></body></html>`
const contentEN = `<!DOCTYPE html><html lang="en" dir="ltr"> <head></head> <body> <div class="intro-box"> <div class="row"> <div class="columns large-2"> <img src="https://media.elcinema.com/tvguide/1127_1.png" alt=""/> </div></div></div><div class="row tvgrid"> <div class="columns small-12"> <div class="dates">Thursday 11 November</div></div><div class="columns small-12"> <div class="boxed-category-16 padded-half"> <div class="row"> <div class="columns small-3 large-2"> <ul class="unstyled text-center"> <li>10:00 AM</li><li><span class="subheader">[120 minutes]</span></li></ul> </div><div class="columns small-3 large-1"> <a href="/en/work/2009399/" ><img class="lazy-loaded" data-src="https://media.elcinema.com/uploads/_150x200_5659fb4f174c49b54cc14cb53e70a5467abef429b5bb9d1a1cf2a40aa37562b2.jpg" src=""/></a> </div><div class="columns small-6 large-3"> <ul class="unstyled no-margin"> <li><a href="/en/work/2009399/">Good Morning Arab</a></li><li>Program (2006)</li><li> <a href="#" data-key="favourite.work.2009399" class="button minimize small action-button-off" title="Add to your favourites!" ><i class="fa fa-heart fa-1x"></i><span>Favourite</span></a > <a href="#" data-key="reminder.tvguide.6555650" class="button minimize small action-button-off" title="Remind me!" ><i class="fa fa-bell fa-1x"></i><span>Reminder</span></a > </li></ul> </div><div class="columns small-12 large-6"> <ul class="unstyled no-margin"> <li></li><li> <ul class="list-separator"> <li><a href="/en/person/1102191/">Hend Mohamed</a></li><li><a href="/en/person/1104553/">Abdel Aziz El Skirien</a></li><li><a href="/en/person/1102656/">Muhammad Al Hajji</a></li><li><a href="/en/person/2075739/">Turki Kreidis</a></li></ul> </li><li>As Abdel Mohsen passes away and his will is read to the<a href="#" id="read-more">...Read more</a><span class="hide"> family members, the true essence of each of them emerges, resulting in unthinkable discord. </span></li></ul> </div></div></div></div></div></body></html>`
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: `<!DOCTYPE html><html lang="ar" dir="rtl"><head></head><body></body></html>`
})
expect(result).toMatchObject([])
})