Skip to content

Instantly share code, notes, and snippets.

@iliakonnov
Last active September 27, 2022 20:52
Show Gist options
  • Save iliakonnov/c106bb6b8c3b64378fbb15516574b1af to your computer and use it in GitHub Desktop.
Save iliakonnov/c106bb6b8c3b64378fbb15516574b1af to your computer and use it in GitHub Desktop.

Что это?

Гуглоскрипт, который берёт моё расписания из РУЗа в гуглокалендарь, что позволяет:

  • заранее понимать какие пары я пропущу
  • получать своевременные напоминания
  • видеть нужную аудиторию прямо на стандартном виджете часов

image

Настройка

Шаг 1. Выяснить свой ID

Для этого нужно перейти на ruz.hse.ru и в консольке браузера ввести следующее:

await fetch('https://ruz.hse.ru/api/search?type=student&term=' + prompt("Имя:")).then(x => x.json()).then(x => alert(x.map(x => `[${x.id}] ${x.label} (${x.description})`).join('\n')));

Появится окошко, в котором можно будет обменять свои ФИО на айдишник. В моём случае это 325099.

image

Шаг 2. Настроить календарь

  1. Перейти по ссылочке: https://calendar.google.com/calendar/u/0/r/settings/createcalendar
  2. Создать календарь с названием ruz (именно так!)

image

Будьте осторожны, скрипт уничтожает все события из календаря, с которым работает. Лучше, если у вас не будет других нужных календарей с названием ruz.

Шаг 3. Настроить гуглоскрипт

  1. Перейти сюда: https://script.google.com/home/projects/create
  2. Скопипастить весь код
  3. Поправить в первой строчке айдишник на полученный в шаге 1.
  4. Жахнуть тестовый прогон кнопкой «выполнить», выдать права, запустить ещё раз. Убедиться, что события медленно начали появляться в календаре.
  5. Перейти в раздел «Триггеры» слева и настроить запуск syncAll каждые сутки (см. картинку)

image

Доработки

Если скрипт TLится

Есть вероятность, что скрипт упрется в лимит по времени исполнения, тогда имеет смысл разбить запуск на несколько поменьше.

В скрипте:

function sync1() { sync(addWeeks(-1), addWeeks(0)); }
function sync2() { sync(addWeeks(0), addWeeks(1)); }
function sync3() { sync(addWeeks(1), addWeeks(2)); }
function sync4() { sync(addWeeks(2), addWeeks(3)); }

В триггерах:

image

У меня они ещё и по времени разнесены с 00:00 до 4:59.

Отображение положения на карте

Календарь умеет показывать положение мероприятия на карте и даже предупреждать заранее, что пора бы выехать, чтобы успеть вовремя. Для этого нужно заменить

const location = `${room}, ${building}`

на

const location = `${building}, ${room}`

Однако тогда на виджете часов влезает только название «Покровский б-р, 11, …», что в целом и так ясно. А вот аудитория мне важнее.

const student_id = 325099;
function addWeeks(numOfWeeks) {
let date = new Date();
date.setDate(date.getDate() + numOfWeeks * 7);
return date;
}
function formatDate(date) {
return date.toISOString().slice(0, 10).replace(/-/g,".");
}
function sync(startDate, endDate) {
const calendar = CalendarApp.getCalendarsByName("ruz")[0];
const start = formatDate(startDate);
const end = formatDate(endDate);
const data = UrlFetchApp.fetch(`https://ruz.hse.ru/api/schedule/student/${student_id}?start=${start}&finish=${end}&lng=1`);
const text = data.getContentText();
const lessons = JSON.parse(text);
const cleared = {};
for (let lesson of lessons) {
const date = lesson.date.replace(/\./g, "-"); // 2022-09-05
const room = lesson.auditorium; // R401
const building = lesson.building;
const beginLesson = lesson.beginLesson; // 09:30
const endLesson = lesson.endLesson; // 10:50
const kind = lesson.kindOfWork; // лекция
const name = lesson.discipline; // Математические методы анализа данных (анг)
const lecturer = lesson.lecturer_title; // Полунина Полина Алексеевна
const notes = [];
for (let key of ['note', 'url1', 'url2']) {
const url = lesson[key];
const description = lesson[`${key}_description`];
const note = [];
if (url) note.push(url);
if (description) note.push(description);
if (note.length) notes.push(note.join('\n'));
}
if (notes.length) notes.push('');
let comment = notes.join('\n\n');
if (!cleared[date]) {
console.log(`clearing ${date}`);
cleared[date] = true;
for (let event of calendar.getEventsForDay(new Date(date))) {
event.deleteEvent();
}
}
const startTime = new Date(`${date}T${beginLesson}`);
const endTime = new Date(`${date}T${endLesson}`);
const description = comment + `Ведёт ${lecturer}`;
const location = `${room}, ${building}`
const title = name.startsWith(kind) ? name : `${kind} ${name}`;
console.log(`adding ${title} at ${startTime}`);
calendar.createEvent(title, startTime, endTime, {description, location});
}
}
function syncAll() {
sync(addWeeks(-1), addWeeks(3));
}
@aiexz
Copy link

aiexz commented Sep 27, 2022

Возможно, кому-то проще указать почту, чем ФИ(О) для получения id. Вот такой вариант:

await fetch('https://ruz.hse.ru/api/studentinfo?email=' + prompt("Почта без @edu.hse.ru:") + "@edu.hse.ru").then(x => x.json()).then(x => alert(`[${x.id}] ${x.fio} (${x.info})`));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment