From 8e5d23ef3d9c2d53d3e59ee085b3e1fdaf573dfc Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Wed, 8 Apr 2026 18:18:17 +0300
Subject: [PATCH 1/6] Create content.html
---
sites/ayn.om/__data__/content.html | 4897 ++++++++++++++++++++++++++++
1 file changed, 4897 insertions(+)
create mode 100644 sites/ayn.om/__data__/content.html
diff --git a/sites/ayn.om/__data__/content.html b/sites/ayn.om/__data__/content.html
new file mode 100644
index 000000000..ca4c11f2f
--- /dev/null
+++ b/sites/ayn.om/__data__/content.html
@@ -0,0 +1,4897 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AYN TV - قناة عمان الرياضية - جدول البرامج
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+
+
+
هل أنت متأكد أنك تريد الخروج من واجهة الطفل؟
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
لا يفوتك
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 6a0e83ca12ff33cca774f3e5c9f1d24e1fb55bb6 Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Wed, 8 Apr 2026 18:18:20 +0300
Subject: [PATCH 2/6] Create no_content.html
---
sites/ayn.om/__data__/no_content.html | 2091 +++++++++++++++++++++++++
1 file changed, 2091 insertions(+)
create mode 100644 sites/ayn.om/__data__/no_content.html
diff --git a/sites/ayn.om/__data__/no_content.html b/sites/ayn.om/__data__/no_content.html
new file mode 100644
index 000000000..e56469bc1
--- /dev/null
+++ b/sites/ayn.om/__data__/no_content.html
@@ -0,0 +1,2091 @@
+
+
+
+
+
+
+
+ Server Error
+
+
+
+
+
+
+
+
+
+
From 674ea0efc8b772395047fcf6f56a1124545e3324 Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Wed, 8 Apr 2026 18:19:08 +0300
Subject: [PATCH 3/6] Create ayn.om.test.js
---
sites/ayn.om/ayn.om.test.js | 70 +++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 sites/ayn.om/ayn.om.test.js
diff --git a/sites/ayn.om/ayn.om.test.js b/sites/ayn.om/ayn.om.test.js
new file mode 100644
index 000000000..ef198b67d
--- /dev/null
+++ b/sites/ayn.om/ayn.om.test.js
@@ -0,0 +1,70 @@
+const { parser, url } = require('./ayn.om.config.js')
+const fs = require('fs')
+const path = require('path')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+dayjs.extend(customParseFormat)
+dayjs.extend(utc)
+
+const channel = {
+ site_id: '159/قناة-عمان-الرياضية'
+}
+
+it('can generate valid url', () => {
+ expect(url({ channel })).toBe('https://ayn.om/schedule/159/قناة-عمان-الرياضية')
+})
+
+it('can parse response for today', () => {
+ jest.useFakeTimers().setSystemTime(new Date('2026-04-08'))
+ const date = dayjs.utc('2026-04-08', 'YYYY-MM-DD').startOf('d')
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
+
+ const results = parser({ content, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+
+ return p
+ })
+
+ expect(results.length).toBe(22)
+ expect(results[0]).toMatchObject({
+ title: 'لا يوجد جدول',
+ start: '2026-04-07T20:00:00.000Z',
+ stop: '2026-04-07T21:00:00.000Z'
+ })
+
+ jest.useRealTimers()
+})
+
+it('can parse response for friday', () => {
+ const date = dayjs.utc('2026-04-10', 'YYYY-MM-DD').startOf('d')
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
+
+ const results = parser({ content, date }).map(p => {
+ p.start = p.start.toJSON()
+ p.stop = p.stop.toJSON()
+
+ return p
+ })
+
+ expect(results.length).toBe(24)
+ expect(results[0]).toMatchObject({
+ title: 'دوري جندال لكرة القدم 2025-2026 - الحلقة 73',
+ start: '2026-04-09T20:00:00.000Z',
+ stop: '2026-04-09T21:00:00.000Z'
+ })
+ expect(results[23]).toMatchObject({
+ title: 'الدكـة - S1- 2026 - الحلقة 23',
+ start: '2026-04-10T19:00:00.000Z',
+ stop: '2026-04-10T20:00:00.000Z'
+ })
+})
+
+it('can handle empty guide', () => {
+ const date = dayjs.utc('2026-04-10', 'YYYY-MM-DD').startOf('d')
+ const content = fs.readFileSync(path.resolve(__dirname, '__data__/no_content.html'))
+ const results = parser({ content, date })
+
+ expect(results).toMatchObject([])
+})
From bbf38eb27ec48fbce42712c654a191284510ece3 Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Wed, 8 Apr 2026 18:19:18 +0300
Subject: [PATCH 4/6] Create ayn.om.config.js
---
sites/ayn.om/ayn.om.config.js | 104 ++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+)
create mode 100644 sites/ayn.om/ayn.om.config.js
diff --git a/sites/ayn.om/ayn.om.config.js b/sites/ayn.om/ayn.om.config.js
new file mode 100644
index 000000000..e97f77658
--- /dev/null
+++ b/sites/ayn.om/ayn.om.config.js
@@ -0,0 +1,104 @@
+const cheerio = require('cheerio')
+const dayjs = require('dayjs')
+const utc = require('dayjs/plugin/utc')
+const isToday = require('dayjs/plugin/isToday')
+const timezone = require('dayjs/plugin/timezone')
+const customParseFormat = require('dayjs/plugin/customParseFormat')
+
+require('dayjs/locale/ar')
+
+dayjs.extend(utc)
+dayjs.extend(isToday)
+dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
+
+module.exports = {
+ site: 'ayn.om',
+ days: 2,
+ url({ channel }) {
+ return `https://ayn.om/schedule/${channel.site_id}`
+ },
+ parser({ content, date }) {
+ const items = parseItems(content, date)
+
+ let programs = []
+ items.forEach(item => {
+ const prev = programs[programs.length - 1]
+ const $item = cheerio.load(item)
+ const start = parseStart($item, date)
+ if (prev) prev.stop = start
+ const stop = start.add(1, 'h')
+
+ programs.push({
+ title: parseTitle($item),
+ start,
+ stop
+ })
+ })
+
+ return programs
+ },
+ channels() {
+ return [
+ {
+ lang: 'ar',
+ name: 'قناة عمان العامة',
+ site_id: '158/قناة-عمان-العامة'
+ },
+ {
+ lang: 'ar',
+ name: 'قناة عمان الرياضية',
+ site_id: '159/قناة-عمان-الرياضية'
+ },
+ {
+ lang: 'ar',
+ name: 'قناة عمان الثقافية',
+ site_id: '160/قناة-عمان-الثقافية'
+ },
+ {
+ lang: 'ar',
+ name: 'قناة عمان مباشر',
+ site_id: '161/قناة-عمان-مباشر'
+ }
+ ]
+ }
+}
+
+function parseTitle($item) {
+ return $item('*').attr('title')
+}
+
+function parseStart($item, date) {
+ const time = $item('p').text().trim()
+
+ return dayjs.tz(`${date.format('YYYY-MM-DD')} ${time}`, 'YYYY-MM-DD HH:mm', 'Asia/Muscat')
+}
+
+function parseItems(content, date) {
+ const $ = cheerio.load(content)
+
+ let day
+ if (date.isToday()) {
+ day = 'اليوم'
+ } else {
+ day = date.locale('ar').format('dddd')
+ }
+
+ const $heading = $(
+ `#day-1 > div.epg_bottom_sec > div > div > div.epg_channel_wrap > div > div.epg_timeline_aside > div > div > div > div > h3:contains("${day}")`
+ )
+
+ if (!$heading.length) return []
+
+ const $wrapper = $heading.closest('.epg_channel_wrap')
+
+ if (!$wrapper.length) return []
+
+ const items = $wrapper
+ .find('.epg_swipe_wrapper > .epg_swipe_inner_wrap > .epg_timeline_show_row > .epg_tl_item')
+ .toArray()
+
+ if (!Array.isArray(items)) return []
+
+ return items
+}
From d5fc8e6fcbb33e3ed1e338865b237ba3932e60cd Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Wed, 8 Apr 2026 18:22:48 +0300
Subject: [PATCH 5/6] Create ayn.om.channels.xml
---
sites/ayn.om/ayn.om.channels.xml | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 sites/ayn.om/ayn.om.channels.xml
diff --git a/sites/ayn.om/ayn.om.channels.xml b/sites/ayn.om/ayn.om.channels.xml
new file mode 100644
index 000000000..d7bee79cf
--- /dev/null
+++ b/sites/ayn.om/ayn.om.channels.xml
@@ -0,0 +1,7 @@
+
+
+ قناة عمان العامة
+ قناة عمان الرياضية
+ قناة عمان الثقافية
+ قناة عمان مباشر
+
From a1d355e6430c08e973b0cbbd0fd4e7e641afb958 Mon Sep 17 00:00:00 2001
From: freearhey <7253922+freearhey@users.noreply.github.com>
Date: Wed, 8 Apr 2026 18:23:02 +0300
Subject: [PATCH 6/6] Create readme.md
---
sites/ayn.om/readme.md | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 sites/ayn.om/readme.md
diff --git a/sites/ayn.om/readme.md b/sites/ayn.om/readme.md
new file mode 100644
index 000000000..25119b6c2
--- /dev/null
+++ b/sites/ayn.om/readme.md
@@ -0,0 +1,21 @@
+# ayn.om
+
+https://ayn.om [Geo-blocked]
+
+### Download the guide
+
+```sh
+npm run grab --- --site=ayn.om
+```
+
+### Update channel list
+
+```sh
+npm run channels:parse --- --config=./sites/ayn.om/ayn.om.config.js --output=./sites/ayn.om/ayn.om.channels.xml
+```
+
+### Test
+
+```sh
+npm test --- ayn.om
+```