mirror of
https://github.com/iptv-org/epg
synced 2026-03-22 03:41:02 -04:00
Delete tv.tandex.ru
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
|||||||
<!DOCTYPE html><html><head></head><body></body></html>
|
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
{
|
|
||||||
"id": 217749657,
|
|
||||||
"channelId": 142,
|
|
||||||
"channelFamilyId": 16,
|
|
||||||
"live": false,
|
|
||||||
"episode": {
|
|
||||||
"id": 6773710,
|
|
||||||
"description": "Валерий Сюткин делится историями из жизни, которые повлияли на его судьбу.",
|
|
||||||
"title": "Мелодии моей жизни"
|
|
||||||
},
|
|
||||||
"program": {
|
|
||||||
"trailers": [],
|
|
||||||
"hasTrailers": false,
|
|
||||||
"onlines": [],
|
|
||||||
"id": 6719800,
|
|
||||||
"type": {
|
|
||||||
"id": 6,
|
|
||||||
"name": "досуг",
|
|
||||||
"alias": "entertain",
|
|
||||||
"isFilm": false,
|
|
||||||
"isSerial": false,
|
|
||||||
"isForChildren": false
|
|
||||||
},
|
|
||||||
"title": "ПОДКАСТ.ЛАБ",
|
|
||||||
"transliteratedTitle": "podkastlab-6719800",
|
|
||||||
"description": "Впереди вся ночь и есть о чем поговорить. Фильмы, музыка, любовь, звезды, еда, мода, анекдоты, спорт, деньги, настоящее, будущее - все это в творческом эксперименте.\nЛариса Гузеева читает любовные письма. Леонид Якубович рассказывает, кого не берут в пилоты. Арина Холина - какой секс способен довести до мужа или до развода. Валерий Сюткин на ходу сочиняет песню для Карины Кросс и Вали Карнавал. Дмитрий Дибров дарит новую жизнь любимой \"Антропологии\". Денис Казанский - все о футболе, хоккее и не только.\n\"ПОДКАСТЫ. ЛАБ\" - серия подкастов разной тематики, которые невозможно проспать. Интеллектуальные дискуссии после полуночи с самыми компетентными экспертами и актуальными спикерами.",
|
|
||||||
"year": 2023,
|
|
||||||
"countries": [
|
|
||||||
"Россия"
|
|
||||||
],
|
|
||||||
"images": [
|
|
||||||
{
|
|
||||||
"original": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/55890/2a000001855e1ed32c3da7ce9494f185a8ac/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"sizes": {
|
|
||||||
"29": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/40x22"
|
|
||||||
},
|
|
||||||
"80": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/alice_80_80"
|
|
||||||
},
|
|
||||||
"297": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/335x223"
|
|
||||||
},
|
|
||||||
"300": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/300x225"
|
|
||||||
},
|
|
||||||
"312": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/375x234"
|
|
||||||
},
|
|
||||||
"426": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/alice_426_240"
|
|
||||||
},
|
|
||||||
"447": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/502x335"
|
|
||||||
},
|
|
||||||
"640": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/640x480"
|
|
||||||
},
|
|
||||||
"960": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/1280x720"
|
|
||||||
},
|
|
||||||
"1440": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"originalSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/55890/2a000001855e1ed32c3da7ce9494f185a8ac/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"maxSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"original": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e3724b48661908410321ff/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"sizes": {
|
|
||||||
"29": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/40x22"
|
|
||||||
},
|
|
||||||
"80": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/alice_80_80"
|
|
||||||
},
|
|
||||||
"297": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/335x223"
|
|
||||||
},
|
|
||||||
"300": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/300x225"
|
|
||||||
},
|
|
||||||
"312": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/375x234"
|
|
||||||
},
|
|
||||||
"426": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/alice_426_240"
|
|
||||||
},
|
|
||||||
"447": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/502x335"
|
|
||||||
},
|
|
||||||
"640": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/640x480"
|
|
||||||
},
|
|
||||||
"960": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/1280x720"
|
|
||||||
},
|
|
||||||
"1440": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"originalSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e3724b48661908410321ff/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"maxSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/50973/2a00000185c4d7e30a08109cbc342ad18fde/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"original": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a0000018664020a81fce5ca527c59ea04ea/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"sizes": {
|
|
||||||
"29": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/40x22"
|
|
||||||
},
|
|
||||||
"80": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/alice_80_80"
|
|
||||||
},
|
|
||||||
"297": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/335x223"
|
|
||||||
},
|
|
||||||
"300": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/300x225"
|
|
||||||
},
|
|
||||||
"312": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/375x234"
|
|
||||||
},
|
|
||||||
"426": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/alice_426_240"
|
|
||||||
},
|
|
||||||
"447": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/502x335"
|
|
||||||
},
|
|
||||||
"640": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/640x480"
|
|
||||||
},
|
|
||||||
"960": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/1280x720"
|
|
||||||
},
|
|
||||||
"1440": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"originalSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a0000018664020a81fce5ca527c59ea04ea/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"maxSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/28886/2a00000186640209f0d50440ea234752e490/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"original": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147715147a9a8cf1dcc9f926a0/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"sizes": {
|
|
||||||
"29": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/40x22"
|
|
||||||
},
|
|
||||||
"80": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/alice_80_80"
|
|
||||||
},
|
|
||||||
"297": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/335x223"
|
|
||||||
},
|
|
||||||
"300": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/300x225"
|
|
||||||
},
|
|
||||||
"312": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/375x234"
|
|
||||||
},
|
|
||||||
"426": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/alice_426_240"
|
|
||||||
},
|
|
||||||
"447": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/502x335"
|
|
||||||
},
|
|
||||||
"640": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/640x480"
|
|
||||||
},
|
|
||||||
"960": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/1280x720"
|
|
||||||
},
|
|
||||||
"1440": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/1920x1080"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"originalSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147715147a9a8cf1dcc9f926a0/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"maxSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-shows/70674/2a00000187147714ac0572a0371774e388ef/1920x1080"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mainImageBaseUrl": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75",
|
|
||||||
"persons": [
|
|
||||||
{
|
|
||||||
"name": "Дмитрий Бак",
|
|
||||||
"role": "presenter"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Илья Кривицкий",
|
|
||||||
"role": "producer"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ageRestriction": 16,
|
|
||||||
"favourite": false,
|
|
||||||
"tags": [],
|
|
||||||
"displayIfNoEvents": false,
|
|
||||||
"duplicateIds": [
|
|
||||||
6719800
|
|
||||||
],
|
|
||||||
"url": "/program/podkastlab-6719800"
|
|
||||||
},
|
|
||||||
"start": "2023-11-26T08:35:00+07:00",
|
|
||||||
"finish": "2023-11-26T09:10:00+07:00",
|
|
||||||
"hasSubtitles": false,
|
|
||||||
"yacFamilyId": 0,
|
|
||||||
"title": "ПОДКАСТ.ЛАБ. Мелодии моей жизни",
|
|
||||||
"programTitle": "ПОДКАСТ.ЛАБ. ",
|
|
||||||
"episodeTitle": "Мелодии моей жизни",
|
|
||||||
"seasonTitle": "",
|
|
||||||
"url": "/program/podkastlab-6719800?eventId=217749657",
|
|
||||||
"hasDescription": true,
|
|
||||||
"hasReminder": false,
|
|
||||||
"hasReminderButton": true,
|
|
||||||
"startTime": "08:35",
|
|
||||||
"hasStarted": false,
|
|
||||||
"isNow": false,
|
|
||||||
"hasFinished": false,
|
|
||||||
"progress": 0,
|
|
||||||
"humanDate": "26 ноября, воскресенье, 08:35 — 09:10"
|
|
||||||
}
|
|
||||||
@@ -1,274 +0,0 @@
|
|||||||
{
|
|
||||||
"schedule": {
|
|
||||||
"isMain": false,
|
|
||||||
"isMy": false,
|
|
||||||
"isAll": true,
|
|
||||||
"selectedDate": "2023-11-26",
|
|
||||||
"selectedPeriod": "all-day",
|
|
||||||
"selectedChannelGenre": "all",
|
|
||||||
"programTypes": [
|
|
||||||
{
|
|
||||||
"isFilm": false,
|
|
||||||
"isSerial": false,
|
|
||||||
"isForChildren": false,
|
|
||||||
"name": "Все жанры"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"name": "Фильмы",
|
|
||||||
"alias": "films",
|
|
||||||
"isFilm": true,
|
|
||||||
"isSerial": false,
|
|
||||||
"isForChildren": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 4,
|
|
||||||
"name": "Сериалы",
|
|
||||||
"alias": "series",
|
|
||||||
"isFilm": false,
|
|
||||||
"isSerial": true,
|
|
||||||
"isForChildren": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 7,
|
|
||||||
"name": "Спорт",
|
|
||||||
"alias": "sport",
|
|
||||||
"isFilm": false,
|
|
||||||
"isSerial": false,
|
|
||||||
"isForChildren": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 3,
|
|
||||||
"name": "Детям",
|
|
||||||
"alias": "for-children",
|
|
||||||
"isFilm": false,
|
|
||||||
"isSerial": false,
|
|
||||||
"isForChildren": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"channelGenres": [
|
|
||||||
{
|
|
||||||
"name": "Основные",
|
|
||||||
"alias": "main"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Избранные",
|
|
||||||
"alias": "my"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 27,
|
|
||||||
"name": "Фильмы и сериалы",
|
|
||||||
"alias": "movies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 21,
|
|
||||||
"name": "Познавательные",
|
|
||||||
"alias": "discovery"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 24,
|
|
||||||
"name": "Спорт",
|
|
||||||
"alias": "sport"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 28,
|
|
||||||
"name": "Детям",
|
|
||||||
"alias": "kids"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 22,
|
|
||||||
"name": "Информация",
|
|
||||||
"alias": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 23,
|
|
||||||
"name": "Музыка",
|
|
||||||
"alias": "music"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 29,
|
|
||||||
"name": "Увлечения",
|
|
||||||
"alias": "hobbies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 32,
|
|
||||||
"name": "Развлечения",
|
|
||||||
"alias": "entertain"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 30,
|
|
||||||
"name": "HD",
|
|
||||||
"alias": "hd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 26,
|
|
||||||
"name": "Другое",
|
|
||||||
"alias": "other"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Все каналы",
|
|
||||||
"alias": "all"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"selectedProgramTypes": [],
|
|
||||||
"availableProgramTypes": [
|
|
||||||
null,
|
|
||||||
"for-children",
|
|
||||||
"info",
|
|
||||||
null,
|
|
||||||
"series",
|
|
||||||
"sport",
|
|
||||||
"entertain",
|
|
||||||
"films",
|
|
||||||
"discover"
|
|
||||||
],
|
|
||||||
"schedules": [
|
|
||||||
{
|
|
||||||
"finish": "2023-12-04T08:00:00+07:00",
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"id": 217749657,
|
|
||||||
"channelId": 142,
|
|
||||||
"channelFamilyId": 16,
|
|
||||||
"live": false,
|
|
||||||
"episode": {
|
|
||||||
"id": 6773710,
|
|
||||||
"title": "Мелодии моей жизни"
|
|
||||||
},
|
|
||||||
"program": {
|
|
||||||
"trailers": [],
|
|
||||||
"onlines": [],
|
|
||||||
"id": 6719800,
|
|
||||||
"type": {
|
|
||||||
"id": 6,
|
|
||||||
"name": "досуг",
|
|
||||||
"alias": "entertain",
|
|
||||||
"isFilm": false,
|
|
||||||
"isSerial": false,
|
|
||||||
"isForChildren": false
|
|
||||||
},
|
|
||||||
"title": "ПОДКАСТ.ЛАБ",
|
|
||||||
"transliteratedTitle": "podkastlab-6719800",
|
|
||||||
"mainImageBaseUrl": "//avatars.mds.yandex.net/get-tv-shows/33373/2a000001855e1ed2ca7953c3f757c279fc75",
|
|
||||||
"favourite": false,
|
|
||||||
"tags": [],
|
|
||||||
"displayIfNoEvents": false,
|
|
||||||
"duplicateIds": [
|
|
||||||
6719800
|
|
||||||
],
|
|
||||||
"url": "/program/podkastlab-6719800",
|
|
||||||
"images": []
|
|
||||||
},
|
|
||||||
"start": "2023-11-26T08:35:00+07:00",
|
|
||||||
"finish": "2023-11-26T09:10:00+07:00",
|
|
||||||
"hasSubtitles": false,
|
|
||||||
"yacFamilyId": 0,
|
|
||||||
"title": "ПОДКАСТ.ЛАБ. Мелодии моей жизни",
|
|
||||||
"programTitle": "ПОДКАСТ.ЛАБ. ",
|
|
||||||
"episodeTitle": "Мелодии моей жизни",
|
|
||||||
"seasonTitle": "",
|
|
||||||
"url": "/program/podkastlab-6719800?eventId=217749657",
|
|
||||||
"hasDescription": false,
|
|
||||||
"hasReminder": false,
|
|
||||||
"hasReminderButton": true,
|
|
||||||
"startTime": "08:35",
|
|
||||||
"hasStarted": false,
|
|
||||||
"isNow": false,
|
|
||||||
"hasFinished": false,
|
|
||||||
"progress": 0,
|
|
||||||
"humanDate": "26 ноября, воскресенье, 08:35 — 09:10"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"channel": {
|
|
||||||
"siteUrl": "http://www.1tv.ru/",
|
|
||||||
"title": "Первый",
|
|
||||||
"familyTitle": "Первый",
|
|
||||||
"transliteratedFamilyTitle": "pervyy-16",
|
|
||||||
"logo": {
|
|
||||||
"original": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/28884/2a000001600801bd354ae2476e3c586f5d58/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"sizes": {
|
|
||||||
"38": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/28884/2a000001600801bd354ae2476e3c586f5d58/small"
|
|
||||||
},
|
|
||||||
"64": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/28884/2a000001600801bd354ae2476e3c586f5d58/alice_64_48"
|
|
||||||
},
|
|
||||||
"80": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/55846/2a000001600801be3ac16928934aba46427e/orig"
|
|
||||||
},
|
|
||||||
"114": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/28884/2a000001600801bd354ae2476e3c586f5d58/114x80"
|
|
||||||
},
|
|
||||||
"160": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/69315/2a000001600801c33618e8beca2d1d6654db/orig"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"originalSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/28884/2a000001600801bd354ae2476e3c586f5d58/orig",
|
|
||||||
"original": true
|
|
||||||
},
|
|
||||||
"maxSize": {
|
|
||||||
"src": "//avatars.mds.yandex.net/get-tv-channel-logos/69315/2a000001600801c33618e8beca2d1d6654db/orig"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"synonyms": [
|
|
||||||
"1 tv",
|
|
||||||
"1tv",
|
|
||||||
"орт",
|
|
||||||
"первый",
|
|
||||||
"Первый канал",
|
|
||||||
"1 канал"
|
|
||||||
],
|
|
||||||
"familyId": 16,
|
|
||||||
"id": 142,
|
|
||||||
"genres": [
|
|
||||||
{
|
|
||||||
"id": 26,
|
|
||||||
"name": "другое",
|
|
||||||
"alias": "other"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"type": "regional",
|
|
||||||
"url": "/channel/pervyy-16?date=2023-11-26",
|
|
||||||
"isFavorite": false,
|
|
||||||
"hasBroadcasting": false,
|
|
||||||
"broadcastingUrl": "",
|
|
||||||
"hasBroadcastingPlayer": false,
|
|
||||||
"broadcastingPlayerUrl": ""
|
|
||||||
},
|
|
||||||
"hasFinished": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"scheduleMap": [
|
|
||||||
{
|
|
||||||
"id": 0,
|
|
||||||
"limit": 11,
|
|
||||||
"offset": 0,
|
|
||||||
"channelIds": [
|
|
||||||
142,
|
|
||||||
143,
|
|
||||||
422,
|
|
||||||
435,
|
|
||||||
465,
|
|
||||||
166,
|
|
||||||
1775,
|
|
||||||
1375,
|
|
||||||
1046,
|
|
||||||
161,
|
|
||||||
761
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"currentPage": 0,
|
|
||||||
"providers": [],
|
|
||||||
"dndEnabled": false,
|
|
||||||
"totalPages": 34,
|
|
||||||
"favoriteChannelIds": [],
|
|
||||||
"hasRecommendedEditorial": false,
|
|
||||||
"ottSelectionTitle": "Смотрите Кинопоиск и любимые онлайн-шоу на любом телевизоре",
|
|
||||||
"ottSelectionSubtitle": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"currentPage": 1,
|
|
||||||
"schedules": []
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
# tv.yandex.ru
|
|
||||||
|
|
||||||
https://tv.yandex.ru/
|
|
||||||
|
|
||||||
This site is protected by captcha, so if you hit by an error `Got captcha, please goto https://tv.yandex.ru and update cookies!`,
|
|
||||||
update site configuration in `tv.yandex.ru.config.js` by heading to this site and use browser
|
|
||||||
Developer Tools and replace matching cookies. The Cookie will likely lasting for one year.
|
|
||||||
|
|
||||||
To enable debugging while updating channel list or grabbing the guide, set `DEBUG` environment
|
|
||||||
to `site:tv.yandex.ru` or `site:*`.
|
|
||||||
|
|
||||||
On Windows with Command Prompt:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
set DEBUG="site:tv.yandex.ru"
|
|
||||||
```
|
|
||||||
|
|
||||||
On Windows with PowerShell:
|
|
||||||
|
|
||||||
```ps
|
|
||||||
$env:DEBUG="site:tv.yandex.ru"
|
|
||||||
```
|
|
||||||
|
|
||||||
On Unix-like OSes:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
export DEBUG="site:tv.yandex.ru"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Download the guide
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run grab --- --site=tv.yandex.ru
|
|
||||||
```
|
|
||||||
|
|
||||||
### Update channel list
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run channels:parse --- --config=sites/tv.yandex.ru/tv.yandex.ru.config.js --output=sites/tv.yandex.ru/tv.yandex.ru.channels.xml
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm test --- tv.yandex.ru
|
|
||||||
```
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<channels>
|
|
||||||
<channel site="tv.yandex.ru" site_id="12" lang="ru" xmltv_id="Channel5.ru@SD">Пятый International</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="16" lang="ru" xmltv_id="ChannelOne.ru@SD">Первый</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="23" lang="ru" xmltv_id="OTV.ru@SD">ОТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="55" lang="ru" xmltv_id="MuzTV.ru@SD">МУЗ-ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="63" lang="ru" xmltv_id="Uspeh.ru@SD">Успех</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="66" lang="ru" xmltv_id="EchoTV.ru@SD">Эхо TV</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="70" lang="ru" xmltv_id="RT.ru@SD">RT</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="95" lang="ru" xmltv_id="360.ru@SD">360.ru</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="112" lang="ru" xmltv_id="TVMChannel.ru@SD">TVMChannel</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="116" lang="ru" xmltv_id="BigAsia.ru@SD">Большая Азия</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="120" lang="ru" xmltv_id="ZagorodnyyInt.ru@SD">Загородный Int</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="148" lang="ru" xmltv_id="">Foodman.club</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="174" lang="ru" xmltv_id="ZharPtitsa.ru@SD">Жар Птица</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="188" lang="ru" xmltv_id="TNVPlanet.ru@SD">ТНВ-планета</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="206" lang="ru" xmltv_id="DivingTV.ru@SD">Дайвинг.TV</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="216" lang="ru" xmltv_id="JibekJoly.kz@SD">Jibek Joly</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="218" lang="ru" xmltv_id="3ABNRussia.ru@SD">Три Ангела</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="225" lang="ru" xmltv_id="">Вкусное TV</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="229" lang="ru" xmltv_id="SovetskoeKino.ru@SD">Советское кино</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="230" lang="ru" xmltv_id="">Советские мультфильмы</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="231" lang="ru" xmltv_id="">Сказки Зайки</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="234" lang="ru" xmltv_id="earthTV.de@SD">EarthTV The World Live</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="237" lang="ru" xmltv_id="A1.ru@SD">A1</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="239" lang="ru" xmltv_id="AmediaHit.ru@SD">Amedia Hit</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="241" lang="ru" xmltv_id="JoyCook.ru@SD">Joy Cook</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="242" lang="ru" xmltv_id="">Терра Инкогнита</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="244" lang="ru" xmltv_id="">Мир вокруг</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="382" lang="ru" xmltv_id="Retro.ru@SD">Ретро ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="395" lang="ru" xmltv_id="Nano.ru@SD">Нано</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="396" lang="ru" xmltv_id="Cinema.ru@SD">Cinema</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="435" lang="ru" xmltv_id="">Россия-Планета</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="438" lang="ru" xmltv_id="">MTV 80s</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="441" lang="ru" xmltv_id="STSInternational.ru@SD">СТС International</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="477" lang="ru" xmltv_id="ZooTV.ru@SD">Зоо ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="531" lang="ru" xmltv_id="NTVMir.ru@SD">НТВ-Мир</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="537" lang="ru" xmltv_id="ShotTV.ru@SD">Shot TV</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="539" lang="ru" xmltv_id="TVCentrInternational.ru@SD">ТВ Центр-International</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="554" lang="ru" xmltv_id="Carousel.ru@SD">Карусель INT</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="567" lang="ru" xmltv_id="VH1ClassicEurope.uk@SD">MTV 00s</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="593" lang="ru" xmltv_id="MatchFutbol2.ru@SD">Матч! Футбол 2</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="649" lang="ru" xmltv_id="Vremya.ru@SD">Время</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="658" lang="ru" xmltv_id="Prosveshchenie.ru@SD">Просвещение</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="691" lang="ru" xmltv_id="Nostalgia.ru@SD">Ностальгия</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="700" lang="ru" xmltv_id="IndiyskoyeKino.ru@SD">Индийское кино</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="737" lang="ru" xmltv_id="Teatr.ru@SD">Театр</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="766" lang="ru" xmltv_id="Kinosemja.ru@SD">Киносемья</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1090" lang="ru" xmltv_id="Zhivayapriroda.ru@SD">Живая природа</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1102" lang="ru" xmltv_id="">CNL-Сибирь</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1134" lang="ru" xmltv_id="ZhivayaPlaneta.ru@SD">Живая планета</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1240" lang="ru" xmltv_id="TNTInternational.ru@SD">ТНТ International</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1251" lang="ru" xmltv_id="StranaFM.ru@SD">Страна FM</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1256" lang="ru" xmltv_id="Detskimir.ru@SD">Детский мир</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1257" lang="ru" xmltv_id="">4K Fashion TV</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1258" lang="ru" xmltv_id="RTDocumentary.ru@English">RT Doc</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1259" lang="ru" xmltv_id="UltraHDCinema.ru@SD">Ultra HD Cinema</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1269" lang="ru" xmltv_id="">Смайлик ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1324" lang="ru" xmltv_id="">Бьюти.TV</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1419" lang="ru" xmltv_id="HuzurTV.ru@SD">Хузур ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1445" lang="ru" xmltv_id="Sportivnyy.ru@SD">ТВ Спорт</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1446" lang="ru" xmltv_id="Futbolnyy.ru@SD">Мяч</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1447" lang="ru" xmltv_id="Khokkeynyy.ru@SD">Хоккей ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1448" lang="ru" xmltv_id="ProLyubov.ru@SD">Про Любовь</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1449" lang="ru" xmltv_id="Kamedi.ru@SD">Камеди</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1451" lang="ru" xmltv_id="NashKinopokaz.ru@HD">Наш Кинопоказ HD</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1454" lang="ru" xmltv_id="Blokbaster.ru@SD">Блокбастер HD</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1455" lang="ru" xmltv_id="Nashemuzhskoe.ru@HD">Наше Мужское HD</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1458" lang="ru" xmltv_id="BRIDGEFresh.ru@SD">Bridge TV Фрэш</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1459" lang="ru" xmltv_id="Hit.ru@SD">Хит HD</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1461" lang="ru" xmltv_id="">Удар</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1465" lang="ru" xmltv_id="STARTAir.ru@SD">START Air</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1466" lang="ru" xmltv_id="STARTWorld.ru@SD">START World</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1468" lang="ru" xmltv_id="NTVHit.ru@SD">НТВ Хит</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1469" lang="ru" xmltv_id="SuperGeroi.ru@SD">СуперГерои</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1471" lang="ru" xmltv_id="">Дума ТВ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1473" lang="ru" xmltv_id="GlazamiTurista.ru@SD">Глазами туриста</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1474" lang="ru" xmltv_id="">Глазами туриста 4К</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1475" lang="ru" xmltv_id="">Живи активно HD</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1476" lang="ru" xmltv_id="StartTriumf.ru@SD">Старт Триумф</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1477" lang="ru" xmltv_id="TERRA.ru@SD">TERRA</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1478" lang="ru" xmltv_id="Kineko.ru@SD">Кинеко</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1479" lang="ru" xmltv_id="Saphire.ru@SD">Сапфир</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1480" lang="ru" xmltv_id="Leva.ru@SD">Лёва</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1549" lang="ru" xmltv_id="">Sumiko</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1552" lang="ru" xmltv_id="">ROMANCE</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1553" lang="ru" xmltv_id="">Cartoon Classics</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1554" lang="ru" xmltv_id="">Suspense</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1556" lang="ru" xmltv_id="">VHS</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1557" lang="ru" xmltv_id="">Чижик</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1558" lang="ru" xmltv_id="">KIONХИТ</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1559" lang="ru" xmltv_id="">Народ Все Видит</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1560" lang="ru" xmltv_id="">Новый Игровой Канал</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1561" lang="ru" xmltv_id="">Epic</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1562" lang="ru" xmltv_id="">MIXM</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1567" lang="ru" xmltv_id="">Мы</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1570" lang="ru" xmltv_id="">Q Arena</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1571" lang="ru" xmltv_id="">Q Footboll</channel>
|
|
||||||
<channel site="tv.yandex.ru" site_id="1572" lang="ru" xmltv_id="">Q League</channel>
|
|
||||||
</channels>
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
const dayjs = require('dayjs')
|
|
||||||
const doFetch = require('@ntlab/sfetch')
|
|
||||||
const debug = require('debug')('site:tv.yandex.ru')
|
|
||||||
|
|
||||||
doFetch.setDebugger(debug).setMaxWorker(10)
|
|
||||||
|
|
||||||
// enable to fetch guide description but its take a longer time
|
|
||||||
const detailedGuide = true
|
|
||||||
|
|
||||||
// update this data by heading to https://tv.yandex.ru and change the values accordingly
|
|
||||||
const cookies = {
|
|
||||||
i: 'eIUfSP+/mzQWXcH+Cuz8o1vY+D2K8fhBd6Sj0xvbPZeO4l3cY+BvMp8fFIuM17l6UE1Z5+R2a18lP00ex9iYVJ+VT+c=',
|
|
||||||
spravka:
|
|
||||||
'dD0xNzM0MjA0NjM4O2k9MTI1LjE2NC4xNDkuMjAwO0Q9QTVCQ0IyOTI5RDQxNkU5NkEyOTcwMTNDMzZGMDAzNjRDNTFFNDM4QkE2Q0IyOTJDRjhCOTZDRDIzODdBQzk2MzRFRDc5QTk2Qjc2OEI1MUY5MTM5M0QzNkY3OEQ2OUY3OTUwNkQ3RjBCOEJGOEJDMjAwMTQ0RDUwRkFCMDNEQzJFMDI2OEI5OTk5OUJBNEFERUYwOEQ1MjUwQTE0QTI3RDU1MEQwM0U0O3U9MTczNDIwNDYzODUyNDYyNzg1NDtoPTIxNTc0ZTc2MDQ1ZjcwMDBkYmY0NTVkM2Q2ZWMyM2Y1',
|
|
||||||
yandexuid: '1197179041732383499',
|
|
||||||
yashr: '4682342911732383504',
|
|
||||||
yuidss: '1197179041732383499',
|
|
||||||
user_display: 824
|
|
||||||
}
|
|
||||||
const headers = {
|
|
||||||
'User-Agent':
|
|
||||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 OPR/114.0.0.0'
|
|
||||||
}
|
|
||||||
const caches = {}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
site: 'tv.yandex.ru',
|
|
||||||
days: 2,
|
|
||||||
url({ date }) {
|
|
||||||
return getUrl(date)
|
|
||||||
},
|
|
||||||
request: {
|
|
||||||
cache: {
|
|
||||||
ttl: 3600000 // 1 hour
|
|
||||||
},
|
|
||||||
headers: getHeaders()
|
|
||||||
},
|
|
||||||
async parser({ content, date, channel }) {
|
|
||||||
const programs = []
|
|
||||||
const events = []
|
|
||||||
|
|
||||||
if (content && parseContent(content, date, true)) {
|
|
||||||
const cacheid = date.format('YYYY-MM-DD')
|
|
||||||
if (!caches[cacheid]) {
|
|
||||||
debug(`Please wait while fetching schedules for ${cacheid}`)
|
|
||||||
caches[cacheid] = await fetchSchedules({ date, content })
|
|
||||||
}
|
|
||||||
if (detailedGuide) {
|
|
||||||
await fetchPrograms({ schedules: caches[cacheid], date, channel })
|
|
||||||
}
|
|
||||||
caches[cacheid].forEach(schedule => {
|
|
||||||
schedule.events
|
|
||||||
.filter(
|
|
||||||
event => event.channelFamilyId == channel.site_id && date.isSame(event.start, 'day')
|
|
||||||
)
|
|
||||||
.forEach(event => {
|
|
||||||
if (events.indexOf(event.id) < 0) {
|
|
||||||
events.push(event.id)
|
|
||||||
programs.push({
|
|
||||||
title: event.title,
|
|
||||||
description: event.program.description,
|
|
||||||
category: event.program.type.name,
|
|
||||||
start: dayjs(event.start),
|
|
||||||
stop: dayjs(event.finish)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return programs
|
|
||||||
},
|
|
||||||
async channels() {
|
|
||||||
const channels = []
|
|
||||||
const included = []
|
|
||||||
const schedules = await fetchSchedules({ date: dayjs() })
|
|
||||||
schedules.forEach(schedule => {
|
|
||||||
if (schedule.channel && included.indexOf(schedule.channel.familyId) < 0) {
|
|
||||||
included.push(schedule.channel.familyId)
|
|
||||||
channels.push({
|
|
||||||
lang: 'ru',
|
|
||||||
site_id: schedule.channel.familyId.toString(),
|
|
||||||
name: schedule.channel.title
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return channels
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchSchedules({ date, content = null }) {
|
|
||||||
const schedules = []
|
|
||||||
const queues = []
|
|
||||||
const fetches = []
|
|
||||||
const url = getUrl(date)
|
|
||||||
|
|
||||||
let mainApi
|
|
||||||
// parse content as schedules and add to queue if more requests is needed
|
|
||||||
const f = (src, res, headers) => {
|
|
||||||
if (src) {
|
|
||||||
fetches.push(src)
|
|
||||||
}
|
|
||||||
if (headers) {
|
|
||||||
parseCookies(headers)
|
|
||||||
}
|
|
||||||
const [q, s] = parseContent(res, date)
|
|
||||||
if (!mainApi) {
|
|
||||||
mainApi = true
|
|
||||||
if (caches.region) {
|
|
||||||
queues.push(getQueue(getUrl(date, caches.region), src))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const url of q) {
|
|
||||||
if (fetches.indexOf(url) < 0) {
|
|
||||||
queues.push(getQueue(url, src))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
schedules.push(...s)
|
|
||||||
}
|
|
||||||
// is main html already fetched?
|
|
||||||
if (content) {
|
|
||||||
f(url, content)
|
|
||||||
} else {
|
|
||||||
queues.push(getQueue(url, 'https://tv.yandex.ru/'))
|
|
||||||
}
|
|
||||||
// fetch all queues
|
|
||||||
await doFetch(queues, f)
|
|
||||||
|
|
||||||
return schedules
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchPrograms({ schedules, date, channel }) {
|
|
||||||
const queues = []
|
|
||||||
schedules
|
|
||||||
.filter(schedule => schedule.channel.familyId == channel.site_id)
|
|
||||||
.forEach(schedule => {
|
|
||||||
queues.push(
|
|
||||||
...schedule.events
|
|
||||||
.filter(event => date.isSame(event.start, 'day'))
|
|
||||||
.map(event => getQueue(getUrl(null, caches.region, null, event), 'https://tv.yandex.ru/'))
|
|
||||||
)
|
|
||||||
})
|
|
||||||
await doFetch(queues, (queue, res, headers) => {
|
|
||||||
if (headers) {
|
|
||||||
parseCookies(headers)
|
|
||||||
}
|
|
||||||
// is it a program?
|
|
||||||
if (res?.program) {
|
|
||||||
let updated = false
|
|
||||||
schedules.forEach(schedule => {
|
|
||||||
schedule.events.forEach(event => {
|
|
||||||
if (event.channelFamilyId === res.channelFamilyId && event.id === res.id) {
|
|
||||||
Object.assign(event, res)
|
|
||||||
updated = true
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (updated) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseContent(content, date, checkOnly = false) {
|
|
||||||
const queues = []
|
|
||||||
const schedules = []
|
|
||||||
let valid = false
|
|
||||||
if (content) {
|
|
||||||
if (Buffer.isBuffer(content)) {
|
|
||||||
content = content.toString()
|
|
||||||
}
|
|
||||||
// got captcha, its look like our cookies has expired
|
|
||||||
if (
|
|
||||||
content?.type === 'captcha' ||
|
|
||||||
(typeof content === 'string' && content.match(/SmartCaptcha/))
|
|
||||||
) {
|
|
||||||
throw new Error('Got captcha, please goto https://tv.yandex.ru and update cookies!')
|
|
||||||
}
|
|
||||||
if (typeof content === 'object') {
|
|
||||||
let items
|
|
||||||
if (content.schedule) {
|
|
||||||
// fetch next request based on schedule map
|
|
||||||
if (Array.isArray(content.schedule.scheduleMap)) {
|
|
||||||
queues.push(...content.schedule.scheduleMap.map(m => getUrl(date, caches.region, m)))
|
|
||||||
}
|
|
||||||
// find some schedules?
|
|
||||||
if (Array.isArray(content.schedule.schedules)) {
|
|
||||||
items = content.schedule.schedules
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find another schedules?
|
|
||||||
if (Array.isArray(content.schedules)) {
|
|
||||||
items = content.schedules
|
|
||||||
}
|
|
||||||
// add programs
|
|
||||||
if (items && items.length) {
|
|
||||||
schedules.push(...getSchedules(items))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// prepare headers for next http request
|
|
||||||
const [, region] = content.match(/region: '(\d+)'/i) || [null, null]
|
|
||||||
const [, initialSk] = content.match(/window.__INITIAL_SK__ = (.*);/i) || [null, null]
|
|
||||||
const [, sessionId] = content.match(/window.__USER_SESSION_ID__ = "(.*)";/i) || [null, null]
|
|
||||||
const tvSk = initialSk ? JSON.parse(initialSk) : {}
|
|
||||||
if (region) {
|
|
||||||
caches.region = region
|
|
||||||
}
|
|
||||||
if (tvSk.key) {
|
|
||||||
headers['X-Tv-Sk'] = tvSk.key
|
|
||||||
}
|
|
||||||
if (sessionId) {
|
|
||||||
headers['X-User-Session-Id'] = sessionId
|
|
||||||
}
|
|
||||||
if (checkOnly && region && tvSk.key && sessionId) {
|
|
||||||
valid = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkOnly ? valid : [queues, schedules]
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseCookies(headers) {
|
|
||||||
if (Array.isArray(headers['set-cookie'])) {
|
|
||||||
headers['set-cookie'].forEach(cookie => {
|
|
||||||
const [key, value] = cookie.split('; ')[0].split('=')
|
|
||||||
if (cookies[key] !== value) {
|
|
||||||
cookies[key] = value
|
|
||||||
debug(`Update cookie ${key}=${value}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSchedules(schedules) {
|
|
||||||
return schedules.filter(schedule => schedule.events.length)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getHeaders(data = {}) {
|
|
||||||
return Object.assign(
|
|
||||||
{},
|
|
||||||
headers,
|
|
||||||
{
|
|
||||||
Cookie: Object.keys(cookies)
|
|
||||||
.map(cookie => `${cookie}=${cookies[cookie]}`)
|
|
||||||
.join('; ')
|
|
||||||
},
|
|
||||||
data
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUrl(date, region = null, page = null, event = null) {
|
|
||||||
let url = 'https://tv.yandex.ru/'
|
|
||||||
if (region) {
|
|
||||||
url += `api/${region}`
|
|
||||||
}
|
|
||||||
if (page && page.id !== undefined) {
|
|
||||||
url += `${url.endsWith('/') ? '' : '/'}main/chunk?page=${page.id}`
|
|
||||||
}
|
|
||||||
if (event && event.id !== undefined) {
|
|
||||||
url += `${url.endsWith('/') ? '' : '/'}event?eventId=${event.id}&programCoId=`
|
|
||||||
}
|
|
||||||
if (date) {
|
|
||||||
url += `${url.indexOf('?') < 0 ? '?' : '&'}date=${date.format('YYYY-MM-DD')}${
|
|
||||||
!page ? '&grid=all' : ''
|
|
||||||
}&period=all-day`
|
|
||||||
}
|
|
||||||
if (page && page.id !== undefined && page.offset !== undefined) {
|
|
||||||
url += `${url.indexOf('?') < 0 ? '?' : '&'}offset=${page.offset}`
|
|
||||||
}
|
|
||||||
if (page && page.id !== undefined && page.limit !== undefined) {
|
|
||||||
url += `${url.indexOf('?') < 0 ? '?' : '&'}limit=${page.limit}`
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
function getQueue(url, referer) {
|
|
||||||
const data = {
|
|
||||||
Origin: 'https://tv.yandex.ru'
|
|
||||||
}
|
|
||||||
if (referer) {
|
|
||||||
data['Referer'] = referer
|
|
||||||
}
|
|
||||||
if (url.indexOf('api') > 0) {
|
|
||||||
data['X-Requested-With'] = 'XMLHttpRequest'
|
|
||||||
}
|
|
||||||
const headers = getHeaders(data)
|
|
||||||
return {
|
|
||||||
url,
|
|
||||||
params: { headers }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
const { parser, url, request } = require('./tv.yandex.ru.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 customParseFormat = require('dayjs/plugin/customParseFormat')
|
|
||||||
|
|
||||||
dayjs.extend(customParseFormat)
|
|
||||||
dayjs.extend(utc)
|
|
||||||
|
|
||||||
jest.mock('axios')
|
|
||||||
|
|
||||||
const date = dayjs.utc('2023-11-26').startOf('d')
|
|
||||||
const channel = {
|
|
||||||
site_id: '16',
|
|
||||||
xmltv_id: 'ChannelOne.ru'
|
|
||||||
}
|
|
||||||
axios.get.mockImplementation(url => {
|
|
||||||
if (url === 'https://tv.yandex.ru/?date=2023-11-26&grid=all&period=all-day') {
|
|
||||||
return Promise.resolve({
|
|
||||||
headers: {},
|
|
||||||
data: fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (url === 'https://tv.yandex.ru/api/120809?date=2023-11-26&grid=all&period=all-day') {
|
|
||||||
return Promise.resolve({
|
|
||||||
headers: {},
|
|
||||||
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/schedule.json')))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
url ===
|
|
||||||
'https://tv.yandex.ru/api/120809/main/chunk?page=0&date=2023-11-26&period=all-day&offset=0&limit=11'
|
|
||||||
) {
|
|
||||||
return Promise.resolve({
|
|
||||||
headers: {},
|
|
||||||
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/schedule0.json')))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (url === 'https://tv.yandex.ru/api/120809/event?eventId=217749657&programCoId=') {
|
|
||||||
return Promise.resolve({
|
|
||||||
headers: {},
|
|
||||||
data: JSON.parse(fs.readFileSync(path.resolve(__dirname, '__data__/program.json')))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can generate valid url', () => {
|
|
||||||
expect(url({ date })).toBe('https://tv.yandex.ru/?date=2023-11-26&grid=all&period=all-day')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can generate valid request headers', () => {
|
|
||||||
expect(request.headers).toMatchObject({
|
|
||||||
Cookie:
|
|
||||||
'i=eIUfSP+/mzQWXcH+Cuz8o1vY+D2K8fhBd6Sj0xvbPZeO4l3cY+BvMp8fFIuM17l6UE1Z5+R2a18lP00ex9iYVJ+VT+c=; ' +
|
|
||||||
'spravka=dD0xNzM0MjA0NjM4O2k9MTI1LjE2NC4xNDkuMjAwO0Q9QTVCQ0IyOTI5RDQxNkU5NkEyOTcwMTNDMzZGMDAzNjRDNTFFNDM4QkE2Q0IyOTJDRjhCOTZDRDIzODdBQzk2MzRFRDc5QTk2Qjc2OEI1MUY5MTM5M0QzNkY3OEQ2OUY3OTUwNkQ3RjBCOEJGOEJDMjAwMTQ0RDUwRkFCMDNEQzJFMDI2OEI5OTk5OUJBNEFERUYwOEQ1MjUwQTE0QTI3RDU1MEQwM0U0O3U9MTczNDIwNDYzODUyNDYyNzg1NDtoPTIxNTc0ZTc2MDQ1ZjcwMDBkYmY0NTVkM2Q2ZWMyM2Y1; ' +
|
|
||||||
'yandexuid=1197179041732383499; ' +
|
|
||||||
'yashr=4682342911732383504; ' +
|
|
||||||
'yuidss=1197179041732383499; ' +
|
|
||||||
'user_display=824'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can parse response', async () => {
|
|
||||||
const content = fs.readFileSync(path.resolve(__dirname, '__data__/content.html'))
|
|
||||||
const result = (await parser({ content, date, channel })).map(p => {
|
|
||||||
p.start = p.start.toJSON()
|
|
||||||
p.stop = p.stop.toJSON()
|
|
||||||
return p
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(result).toMatchObject([
|
|
||||||
{
|
|
||||||
start: '2023-11-26T01:35:00.000Z',
|
|
||||||
stop: '2023-11-26T02:10:00.000Z',
|
|
||||||
title: 'ПОДКАСТ.ЛАБ. Мелодии моей жизни',
|
|
||||||
category: 'досуг',
|
|
||||||
description:
|
|
||||||
'Впереди вся ночь и есть о чем поговорить. Фильмы, музыка, любовь, звезды, еда, мода, анекдоты, спорт, деньги, настоящее, будущее - все это в творческом эксперименте.\nЛариса Гузеева читает любовные письма. Леонид Якубович рассказывает, кого не берут в пилоты. Арина Холина - какой секс способен довести до мужа или до развода. Валерий Сюткин на ходу сочиняет песню для Карины Кросс и Вали Карнавал. Дмитрий Дибров дарит новую жизнь любимой "Антропологии". Денис Казанский - все о футболе, хоккее и не только.\n"ПОДКАСТЫ. ЛАБ" - серия подкастов разной тематики, которые невозможно проспать. Интеллектуальные дискуссии после полуночи с самыми компетентными экспертами и актуальными спикерами.'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('can handle empty guide', async () => {
|
|
||||||
const result = await parser({
|
|
||||||
date,
|
|
||||||
channel,
|
|
||||||
content: fs.readFileSync(path.resolve(__dirname, '__data__', 'no_content.html'), 'utf8')
|
|
||||||
})
|
|
||||||
expect(result).toMatchObject([])
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user