📆 Как я приручил цифровой календарь (в целом) и CalDAV (в частности)

 Публичный пост
20 ноября 2021  4187

Предыстория

Где-то в 2013 году у меня заканчивалась студенческая жизнь и начиналась активная подготовка к семейной жизни: я и моя будущая жена стали чаще проводить время вместе в отпусках (мы жили до этого в разных странах), ездить знакомиться к родителям, что-то планировать и думать как нам съехаться вместе, наконец.

Супруга моя искренне охуевала от моей несобранности и неорганизованности, я же до сих пор искренне охуеваю от того, сколько всяких дел генерирует эта сраная взрослая жизнь. Век бы глаза мои этого всего не видели, но раз уж взялся — придётся играть по правилам.

Сначала был опробован самый простой и самый понятный способ внести порядок в мой хаос повседневности: купить ежедневник. Недостатки этого подхода не заставили себя ждать: я забывал в него записывать дела, я забывал в него заглядывать, я вообще забывал его где попало, а в одном из отпусков я его вовсе потерял. Не сработало.

Ладно, этот вариант отбросили. Мой взор пал на вещицу, которую я ни разу не терял и всегда носил с собой, а именно мобильник. Пришло время узнать что там внутри этой скучной папки под названием "Офис". Уже тогда был Android 4.x, в котором всё плюс-минус знакомое и поныне.

Попробовал сначала возможности календаря Google. Вроде бы даже устраивать, можно записывать события и задачки. Класс, наконец-то. И на следующей же неделе я его дропнул, поскольку дефолты в календаре стояли такие, что можно было создать инвайт любому человеку в Интернете, тем самым рассылая спам. В голове снова зазвенело слово "приватность".

Узнал, что хостить свой сервер календаря можно относительно безболезненно, и это даже не отнимет уйму времени на настройку. Личный виртуальный сервер тогда у меня был уже давно, добавить туда Nextcloud не составило огромного труда. И тут меня подстерегало первое маленькое разочарование: Android нативно не поддерживает CalDAV, нужно использовать сторонний адаптер. Ладно, и тут справились, благо есть DavDroid, ныне DAVx5. Второе маленькое разочарование: Nextcloud слишком жирный и перегруженный фичами для моего маленького серверочка, пришлось поискать что полегче. Нашёлся Radicale, есть из коробки в Debian, неприхотлив, но и интерфейс не такой мощный, shared-lists можно сделать только создав отдельный аккаунт для этого. Ну и ладно, переживём и так.

С этого момента я собрал кости, то есть серверную часть, и начал наращивать на них мясо, то есть клиенты и обвязки.

Мотивация

Прежде чем объяснить как я что-то делал стоит объяснить зачем вообще такие сложности, ведь можно было бы в принципе обойтись всего одним календарём и радоваться жизни при этом.

Большой и разнообразный набор клиентов CalDAV помогает мне по-разному организовывать представление задач, чтобы лучше понимать в какую сторону ворочать дела. Увы, универсальных решений не существует(кто сказал НОУШЕН?!), поэтому приходится использовать несколько клиентов сразу.

Всё это огромное и сложное мне нужно не для того, чтобы делать больше. Эти инструменты мне как раз нужны чтобы не делать больше, чем я могу. Три основных представления, список, таймлайн и канбан, помогают мне быстрее определить что можно добавить, когда добавить и куда. Мощные средства фильтрации помогают отсечь лишнее: если у меня перед глазами в текущий момент висит больше трёх задач, то я начинаю беситься и мне хочется сломать всё вокруг.

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

Инструменты

Tasks.org (клиент)

Пожалуй, лучшее, что случалось с миром productivity apps на Android: очень богатый клиент с мощными средствами фильтрации и сортировки. Отвечает за представление задач в виде списка с возможностью эти самые задачи создавать, редактировать, удалять и отмечать как выполненные. Основная повседневная работа с задачами осуществляется тут.

Люблю его за киллер-фичу: используя поле DTSTART(время начала задачи) в CalDAV можно скрыть таски до того момента, когда они понадобятся. Это очень прочищает мозги и позволяет не париться о запланированном.

DAVx5 (CalDAV-адаптер для Android)

Как было сказано выше, Android из коробки не поддерживает CalDAV, поэтому приходится использовать сторонний костыль и разрешать ему кушать батарейку. Бонусом идёт то, что настроенные аккаунты автоматически синхронизируются с Tasks.org

Radicale (сервер)

Поскольку я не хочу доверять свою ценную (на самом деле не очень) информацию третьим лицам, сервер тоже использую опенсорсный. Не очень сложный CRUD на питоне, который складывает все сущности в файлы на диске. Также есть примитивный веб-интерфейс, который позволяет заводить директории для событий, задач и контактов.

Работает, жрать не просит.

pimutils в докере

А вот тут уже начинается самое интересное. По какой-то неведомой логике VTODO (таски) и VEVENT (события в календаре) в протоколе CalDAV — это разные сущности, хотя во многом они пересекаются. Мне же важно видеть какой тайм-слот занимают запланированные задачки. Чтобы устранить это недоразумение я написал обёртку для pimutils, которая конвертирует таски в события в зависимости от паттерна:

  • Таски с низким приоритетом не попадают в календарь вообще, это несрочные и не очень важные задачи, выполнение которых может откладываться хоть до самой тепловой смерти Вселенной. Повторяющаяся домашняя рутина также попадает сюда: я пробовал получать все напоминалки о бытовых мелочах ежедневно и вскоре понял, что это плохая идея.
  • Таски со средним приоритетом занимают слот в 15 минут и получают оповещение в календарь за 10 минут до due date. Сюда могут попасть несрочные, но важные задачи, переносить которые можно, но нежелательно. Сюда я кидаю долгосрочную проектную работу, раздробленную на мелкие кусочки.
  • Таски с высоким приоритетом занимают слот в 30 минут и получают оповещение за 30 минут до начала события. Это задачи, которые откладывать вообще никак нельзя: приём лекарств, лечебные процедуры, запись у врача, поездки и прочее, для чего есть строго отведённое время.

Чтобы автоматизировать такой сложный конфиг, нужен хорошо отлаженный набор инструментов. В лучших традициях юниксвея три утилиты в контейнере делают каждая что-то одно, но хорошо:

  • vdirsyncer: синхронизирует все сущности CalDAV из локальной директории на сервер и обратно. Позволяет получить изменения, пришедшие от клиентов и зафиксировать собственные изменения. Собственно, здесь я принимаю VTODO, превращаю их в календарные события и отправляю обратно.
  • todoman: консольный менеджер тудушек. Работает с локальной директорией, получает из неё файлы, структурирует данные и присваивает каждой таске свой ID. С его помощью я превращаю VCALENDAR в обычный бытовой JSON, который потом можно скормить другим утилитам. Этот же JSON потом складывается в отдельный файлик, который доступен легковесным самописным клиентам.
  • khal: то же самое, но уже для календарных событий. Получает поля из отформатированного JSON, который заботливо подготавливает todoman, и складывает результат в другие файлики. Также output redirect создаёт в специальной директории lock-файл, имя которого состоит из md5-хэша summary задачки и unix timestamp её срока, чтобы не создавались дубликаты в календаре. Если задача переносится на другой день, создаётся новое событие в календаре и тем самым создаётся новый lock-файл.

Всё это работает в цикле и работает прекрасно. Единственная возможная жалоба — временной лаг, который включает в себя период синхронизации на клиентах, плюс время ожидания на сервере, время обработки очереди, обратная синхронизация на клиент. Суммарно до получаса, но меня это не пугает, всё планирование у меня и так происходит заранее.

Google Calendar, Apple Calendar, Etar, eM Client и другие

Вот тут как раз вся фишечка, то, ради чего этот проект затевался: результирующий фид можно считать на любом устройстве, которое поддерживает синхронизацию через CalDAV, и это будет доступно мне бесплатно всегда, и даже чашка кофе в месяц не потребуется. Здесь я уже просматриваю свои задачки в срезе календарного потока и получаю оповещения о том, когда и что начать делать. Именно с этого и началось моё стремление овладеть электронным календарём: я хочу создать события и чтобы в нужный момент они у меня бздынькали в телефоне.

Trello

Trello я любил всегда, люблю и сейчас, хоть его и стремительно пожирает Atlassian. Но каким боком он к этой схеме? А вот каким: помимо всего прочего todoman смотрит в поле Description, и если видит там ссылку на карточку, то обновляет её через API соответствующим образом, то есть либо ставит/меняет Due Date связанной задачи, либо помечает задачку как Done. Это даёт мне удобный срез в представлении kanban, я могу окинуть одним взглядом доску с карточками и с высоты птичьего полёта понять на каком этапе находится проект и насколько всё запущено.

К слову, Trello на Android отлично работает в тандеме с Tasks.org: если создать карточку, потом нажать Share и выбрать Tasks, то создастся новая задачка с именем карточки в Summary и со ссылкой на неё в поле Description. Как раз то что надо.

Бонус! todoman также посылает мне сообщения в специальный чат в телеграме если видит ссылку на карточку Trello в задачке и если она помечена как сделанная. Чтобы в конце дня посмотреть и сказать себе какой я молодец.

Дополнительно:

FSMQ (менеджер очереди) и интерфейс к нему

Очень часто мне надо бывает гонять какой-то свой бытовой payload с сервера на домашние устройства и обратно. Желательно ещё и так, чтобы команды на загрузку payload можно было оставлять в небезопасных местах, используя одноразовые токены.

Я раньше любил запускать бэкапы серверов на работе внутри screen и получать оповещения о завершении в телеграм. Для этого у меня была специальная защищённая апишечка со своим отдельным токеном, чтобы не палить credentials своего персонального бота. Со временем похожие паттерны начали накапливаться, я писал в своей API эндпоинты на каждый кейс и мне это порядком надоело, захотелось чего-то универсального. Так появился FSMQ, менеджер очередей с HTTP-фронтендом, одноразовыми токенами и файловой системой в качестве хранилища сообщений.

Но каким боком это вообще всё к вышеописанному? А таким, что скрипт с pimutils является также клиентом FSMQ. Я могу пулять в специальную очередь сообщения с описанием задачек в формате JSON, а потом скрипт запросит batch, пройдётся циклом по ID сообщений и запишет все задачки в локальную директорию, которая потом синхронизируется с сервером. Сложно, но очень кайфово!

Таким образом я могу использовать любой калькулятор для отправки себе сообщений на будущее. В моих дотфайлах есть скрипт, который как раз обрабатывает преобразованный легковесный фид и по сути является полноценным таск-менеджером. Даже по приоритетам сортирует и в нужные цвета всё красит.

Обычный бумажный блокнот

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

В блокноте я обычно составляю might-do list, все спонтанные идеи находят своё место здесь и остаются там и только там когда блокнот закрыт. Позже я могу вернуться к своим записям, пробежаться по ним взглядом и зацепиться глазом за что-нибудь, что имело бы сейчас смысл и на что есть желание. В цифровом виде такой отстойник для задач не работает, я пробовал это много раз.

С выбором блокнота у меня тоже много капризов, не всякая модель мне подойдёт. Остановился на маленькой вертикальной перекидной записной книжечке с картонной обложкой, застёжкой из резинки и резиновым же пеналом для ручки. Очень удобно когда устройство ввода не теряется.

Вместо заключения

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

Две мои настольные книги, которые я перечитываю время от времени и даже дарю друзьям:

  • Make Time (Jake Knapp, John Zeratsky) — отличная книга, написанная двумя бывшими гуглерами из эпохи "Don't be Evil", которая предлагает простые и понятные способы справиться с хаосом повседневности и найти время для самого важного и самого главного
  • Time Management for System Administrators (Thomas Limoncelli) — специфика профессии, но очень многие лайфхаки оттуда прижились, все идеи использования внешнего мозга пришли оттуда

Инструмент, который я описал, довольно сложный и подходит только мне, но он мне нужен как кораблю нужен лоцман, для навигации в сложной и непонятной взрослой жизни. Однако, инструмент — далеко не главное. Главное — выжить.

P.S.: выкинуть свою поделку в опенсорс я сейчас не могу, там много хардкода и приватных ключей :D Если интересны какие-то отдельные моменты в деталях, буду рад рассказать!

14 комментариев 👇

А что сподвигло делать своё решение?
В статье очень много технических подробностей и совсем нет про описание реальных задач
Просто если брать то же gtd- это чёткое разделение на календарные задачи и список задач
Насколько я понял, автор в календарь пихает вообще все

Было бы интересно почитать реальные примеры. То есть встреча в 15-00, контекстное напоминание купить молока, указание себе ложиться спать не позже 12 и задача из плана на день, вроде запилить фичу Х - это разные сущности. Интересно как они располагаются в календаре.
Я вот так и не смог приспособить календарь для задач, которые можно делать в любое время. Да и нужно ли это все держать в календаре большой вопрос

  Развернуть 1 комментарий

@gwyllium,

что сподвигло делать своё решение

Приватность и меняющиеся политики сервисов по подписке. Я очень не хочу проснуться одним прекрасным утром и обнаружить что жизненно важная мне фича теперь стоит чашечку кофе в месяц.

автор в календарь пихает вообще все

Как раз нет. Низкоприоритетные задачи не попадают в календарь вообще, им там не место. Распределение же остальных задач по календарному таймлайну позволяет мне ясно видеть, какие из задач какие тайм-слоты занимают. Ну и кроссплатформенные алерты, да. Они мне очень нужны.

Интересно как они располагаются в календаре.

Сейчас расскажу:

встреча в 15-00

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

контекстное напоминание купить молока

Низкий приоритет, не попадает в календарь, висит в TO-DO листе до самой тепловой смерти вселенной

указание себе ложиться спать не позже 12

Средний приоритет, алерт должен быть, но можно за 10 минут. Как раз можно отложить все девайсы, почистить зубы, выдохнуть и лечь.

задача из плана на день, вроде запилить фичу Х

А это уже хайлайт. Для него нужен блок в календаре на полтора часа минимум, без прерываний. Причём я обычно знаю какие это полтора часа в день, поэтому я делаю своеобразную защиту от пересечения с другими задачками, т.е. если что-то наезжает на зарезервированный блок времени в представлении календаря, я смело могу это выкинуть на следующий день.

  Развернуть 1 комментарий

@rcmd, спасибо большое за ответ. А какие задачи тогда с трелло конектятся? Вряд ли купить молока

Как в этой схеме существуют всякие хотелки типа списка книг для прочтения или проекты?

  Развернуть 1 комментарий

@gwyllium, с трелло коннектятся задачи среднего и высшего приоритета, а также долгосрочные проекты. В карточках есть чеклисты, в которые можно залинковать другие карточки и тем самым измерять прогресс. Как раз сейчас отмеряю прогресс по задаче "съездить в отпуск к родителям", без чёткой разбивки там с катушек съехать можно.

Книги, музыка, кино — отдельный борд, в который я просто посматриваю, когда встаёт вопрос "что почитать" или "что посмотреть вечером за ужином".

Хакспейс — также отдельный борд, в котором создаются "эпики", из которых могут вырасти планируемые атомарные задачи.

  Развернуть 1 комментарий
Valery Frontend developer | Angular 22 ноября 2021

С пушки по воробьям)

  Развернуть 1 комментарий

DAVx5 пользуюсь давно, а вот рекоммендуемый в нём opentasks настолько не прижился, что даже альтернативу искать не стал. Спасибо за tasks.org, сделаю второй заход!

  Развернуть 1 комментарий

Tasks.org выглядит офигенно, спасибо.

  Развернуть 1 комментарий

О, а я когда прочитал книжку про Time Management для системных администраторов так захотел понять как это перенести на свои области что аж пошёл работать сисадмином на полгода :)

У тебя в итоге в этом всё замешан один календарь или несколько? Шаришь ли ты этот календарь с кем-то? Создают ли тебе встречи в этом календаре другие люди?

  Развернуть 1 комментарий

@shrimpsizemoose, Ух ты, даже так бывает! Я искренне впечатлён :) Книга действительно мировая. Может выглядеть немного старомодно, но принципы не поменялись.

У меня в этом замешано несколько календарей и даже несколько аккаунтов.

Есть календарь Goals, для хайлайтов. Это те проектные задачки, которые я ставлю себе сам, которые помогают мне исполнить какую-нибудь заветную мечту или же заметно прокачаться. Некоторые дни из этого списка зарезервированы. Например, по четвергам у меня в Goals записано "раскидать всю текучку", чтобы расчистить место в другие дни, а в субботу это всегда сходить на турецкий базар за свежими продуктами и устроить сеанс телекоммуникации с родителями.

Железобетонное правило: в календаре Goals ни при каких условиях не должно появляться больше одного события в день, и только этому событию позволено находиться перед моими глазами, иначе хайлайт перестаёт быть хайлайтом. Можно менять, нельзя добавлять.

Есть календарь Chores, куда ссыпается всё остальное и линкуется с Trello для прозрачности. Я попытался приучить жену добавлять идеи и таски туда, но не вышло, ей проще менеджить задачки в бумажном ежедневнике, поэтому мы синхронизируемся чаще голосом.

Есть, правда, shared-аккаунты: Guests и Family, в которых заносится информация о предстоящем приезде гостей и о семейных событиях.

Пока система работает, но возможно будут дополнения.

  Развернуть 1 комментарий

Time Management for System Administrators (Thomas Limoncelli)

Ого, оказывается не только я читал эту книгу. Спасибо за пост!

  Развернуть 1 комментарий

@Mykola, рад, что понравилось!

Книгу я не только читаю, но и регулярно перечитываю. Каждый раз извлекаю что-то новое, какой-то интересный подход или какую-то маленькую деталь, которая в итоге изменяет процесс к лучшему.

  Развернуть 1 комментарий

Зайду ещё раз, Tasks.org - мировая вещь, легко взлетела и делает всё, что должна делать (есть даже версия для жадных на F-Droid с полным функционалом). Пробовал держать несколько календарей, пока потерпел фиаско (комментарии дали подсказки почему - просто нужно больше интерфейсов синхронизации данных, Карл!) и по итогу веду всё в одно лицо, но теперь понял, куда надо копать.
Ещё внезапно для себя упёрся в то, что прекрасный обновленный Synology Calendar v7 на который я возлагал большие надежды - УГ и не умеет нормально шарить календари ( в том числе не умеет нормально шарить группам пользователей - ни в какие ворота), но с этим будет разбираться техподдержка.
Очень хорошо помню, что с пару лет назад собирал прототип WOL-from-calendar (фактически task - from calendar event), но заказчик был мутноватый и дело так и не дошло до внедрения(продолжило работать на двух скриптах с хардкодом), а больше применять было негде и я перестал копать и со временем забил на допиливание. Так вот - описанный тулкит как-раз может решать такие задачи! Как раз будет фундамент, когда вернусь к вопросу ещё раз.

  Развернуть 1 комментарий

а кто-то может посоветовать такие же прекрасные клиенты как Tasks.org, DAVx5 итп для экосистемы эпла?

  Развернуть 1 комментарий

@Andrewsha, вот это выглядит многообещающе, а CalDAV там и так встроенный.

https://www.2doapp.com/ios/

  Развернуть 1 комментарий

😎

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

Что вообще здесь происходит?


Войти  или  Вступить в Клуб