Есть у меня на Android TV несколько спортивных каналов . Я — хоккейный фанат и слежу за играми на доступных КХЛ ТВ и Viju sports.
Встал вопрос — как бы получать программы по времени в виде таблицы телепередач с этих двух каналов.
Поиск сетки передач для сбора
Тут всё просто. Спасибо мэйл.ру и их программе телепередач.
Вероятно, есть и другие сервисы, но этот первым попался под руку.
Как обычно проваливаюсь в ссылку и смотрю возможности получить данные со страницы:
Из стандартных формул подходит importxml
— про нее было много написано на этом сайте, потому рассказ не про нее.
Как обычно, лист, ссылка и xpath
Получаю данные в строку. Дальше транспонирую =TRANSPOSE(A4:Z4)
Далее все это раскладываю в столбцы:
- Канал —
=ARRAYFORMULA(IF(A7:A<>"";"KHL";""))
- Время —
=ARRAYFORMULA(LEFT(A7:A;5))
- Содержание программы —
=IFERROR(ARRAYFORMULA(RIGHT(A7:A;(LEN(A7:A)-5)));"")
получая следующую таблицу:
которая будет динамически меняться исходя из обновления данных с программы передач.
Ровно такую же историю делаю по каналу Viju sports на которой показывают шведскую хоккейную лигу 🙂
Как результат у меня есть 2 отдельных листа на которых есть все необходимое для сведение в одно целое.
Консолидация разных ТВ-программ
Создаю лист «AllSports» на который вывожу программу передач с листов «КХЛ» и «Viju» через формулу
={FILTER(Viju!F7:H1000;Viju!G7:G<>"");FILTER(KHL!F7:H1000;KHL!G7:G<>"")}
затем сортирую их по времени
=SORT(H1:J;TO_DATE(I1:I);true)
в результате получая данные, подходящие для вывода в интернет:
Скриптовая часть
Так как в том или ином виде этот скрипт расписывался в блоге уже много раз (массив в API), поэтому просто код:
function getAllSports() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getSheetByName("AllSports");
const allSportsArray = ws.getRange(1, 1, ws.getLastRow(), 3).getValues();
return allSportsArray
}
function doGet() {
const webArr = getAllSports()
const contService = ContentService.createTextOutput((JSON.stringify(webArr)))
contService.setMimeType(ContentService.MimeType.JSON)
return contService
}
Frontend через Vue
HTML
<div id="app">
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col">Канал</th>
<th scope="col">Время</th>
<th scope="col">Программа</th>
</tr>
</thead>
<tbody>
<tr v-for="(event, index) in events " :key="index">
<td>{{event[0]}}</td>
<td>{{event[1]}}</td>
<td>{{event[2]}}</td>
</tr>
</tbody>
</table>
</div>
</div>
JS
const vueApp = {
data() {
return {
events: [],
};
},
methods: {
async getData() {
const link ="https://script.google.com/macros/s/AKfycbwWtYVgL2gHmT86bKBPVpok4QW40_fyDPEpx54TM1vc2GC2ODAPgI2EQ7-Vi2TDUdwh/exec";
const res = await fetch(link);
this.events = await res.json();
},
},
mounted() {
this.getData();
},
};
const app = Vue.createApp(vueApp);
app.mount("#app");
В конечном виде получая следующий результат — https://codepen.io/DmitriiBeattle/full/GRPyXgp
При этом данный подход масштабируемый. Можно создавать еще листы таблиц, делать аналогичное и потом добавлять их в массив с формулами фильтра:
={FILTER(Viju!F7:H1000;Viju!G7:G<>"");FILTER(KHL!F7:H1000;KHL!G7:G<>""
;FILTER("Еще канал и так далее"!F7:H1000;KHL!G7:G<>"")
}
Обновление спустя месяц
- Добавлен KHL Prime — в своей основе он дублирует сетку KHL, но когда в одно и то же время идут разные матчи, Прайм показывает другую игру.
- До этого макрос выводил данные абсолютно все программы начина с 00-00 по Московскому времени, что было несколько неудобно в части навигации — если сейчас 16-00, то надо скроллить половину страницы, что на телефоне делать лениво 🙂 В связи с этим была добавлена следующая функциональность:
- Получение текущего времени «минус два часа» — для того, чтобы выводить программу с учетом уже идущих передач, начавшихся ранее.
function getCurrentTime() {
const currentDate = new Date();
return currentDate.getHours() - 2;
}
2. Вывод не всего массива с телепередачами, а той части, которая идет «сейчас и далее»:
const currentTime = getCurrentTime();
const filteredArray = allSportsArray.filter(row => Number(row[1].slice(0, 2)) > currentTime)
return filteredArray
Ваше мнение важно и может улучшить блог
Я хочу услышать ваше мнение и ваши идеи о том, как сделать этот сайт еще лучше. Примите участие в опросе, чтобы поделиться вашими пожеланиями, предложениями и замечаниями. Пройдите опрос сейчас и помогите сделать этот сайт более полезным для вас!