Ошибки:
- исключение в фоновых циклах (сбой сети при обновлении календаря, заблокировавший бота
пользователь, битый календарь) останавливало весь бот — теперь ошибка у одного
пользователя логируется и не мешает остальным;
- повторяющиеся события с UNTIL местным временем или датой роняли разбор календаря
(ValueError из dateutil) — UNTIL приводится к UTC;
- названия и описания событий подставлялись в HTML без экранирования: «<» или «&» ломали
отправку уведомления;
- сообщение до /start и кривой ввод времени напоминаний роняли обработчик;
- при отсутствии файла календаря разбор падал.
Безопасность: ссылка скачивалась без проверки (wget), бота можно было заставить ходить по
любым адресам, включая внутренние. Теперь принимается только https://calendar.yandex.*,
скачивание — через aiohttp с таймаутом и без редиректов, содержимое проверяется как iCal
до замены старого файла.
Уведомления (по issue #3): без даты и года — только время, пустые описание и организатор
не показываются, организатор без «mailto:», для событий на весь день — «Весь день» и без
напоминаний в 00:01; новые команды /link и /unsubscribe.
Прочее: токен из BOT_TOKEN, таблицы SQLite создаются при первом запуске (пустые базы
убраны из репозитория), ссылка «АВТОР» — на EDeev вместо чужого теперь профиля IGlek.