Заметки о поведении по результатам тестирования ics_to_discourse.py
Я провёл серию тестов этого скрипта (с флагом --time-only-dedupe и без него) и решил подробно задокументировать процесс обновления и присвоения (adoption).
1. Как определяется уникальность
- Режим по умолчанию: для присвоения требуется точное совпадение начала + конца + места.
- С флагом
--time-only-dedupe: для присвоения требуется совпадение только начала + конца; место считается «достаточно близким».
Если существующая тема не соответствует этим правилам, создаётся новая тема.
2. Роль маркера UID
- Каждой теме события добавляется скрытый HTML-маркер в первом посте:
<!-- ICSUID:xxxxxxxxxxxxxxxx -->
- При последующих запусках скрипт в первую очередь ищет этот маркер.
- Если он найден, тема считается совпадением по UID и обновляется напрямую, независимо от того, насколько зашумлённым или устаревшим может быть текст описания (DESCRIPTION).
- Таким образом, UID становится истинным ключом идентификации. Видимые поля описания не влияют на сопоставление.
3. Процесс обновления при совпадении по UID
- Скрипт получает первый пост и удаляет маркер:
old_clean = strip_marker(old_raw)
fresh_clean = strip_marker(fresh_raw)
- Если
old_clean == fresh_clean: обновление не выполняется (избегаем лишних изменений). - Если они различаются: проверяется, является ли изменение «существенным»:
meaningful = (
_norm_time(old_attrs.get("start")) != _norm_time(new_attrs.get("start"))
or _norm_time(old_attrs.get("end")) != _norm_time(new_attrs.get("end"))
or _norm_loc(old_attrs.get("location")) != _norm_loc(new_attrs.get("location"))
)
- Если
meaningful = True→ обновление с поднятием в ленте (тема поднимается в разделе «Последние»). - Если
meaningful = False→ тихое обновление (bypass_bump=True→ только создание ревизии, без поднятия).
- Теги объединяются (гарантирует наличие статических/типовых тегов, никогда не удаляет теги модераторов или ручные).
- Заголовок и категория при обновлении никогда не меняются.
4. Процесс обновления при отсутствии совпадения по UID
- Скрипт пытается присвоить тему:
- Строит кортежи кандидатов из начала/конца/места (или только начала/конца с флагом
--time-only-dedupe). - Ищет в
/search.jsonи/latest.jsonсуществующее событие с совпадающими атрибутами. - Если найдено → присваивает эту тему, добавляет маркер UID и теги (тело на этом этапе не изменяется).
- Если не найдено → создаёт совершенно новую тему с маркером и тегами.
- После присвоения или создания все последующие синхронизации будут разрешаться напрямую по UID.
5. Практические последствия
- Изменение времени
- По умолчанию: присвоение не удаётся (время отличается) → создаётся новая тема.
- С флагом
--time-only-dedupe: присвоение также не удаётся; создаётся новая тема. - Изменение места
- По умолчанию: присвоение не удаётся (место отличается) → создаётся новая тема.
- С флагом
--time-only-dedupe: присвоение удаётся (время совпадает), но различие в месте помечается как «существенное» → обновление с поднятием в ленте. - Изменение описания
- Если текст DESCRIPTION изменился, но начало/конец/место остались прежними:
- Тело обновляется тихо (
bypass_bump=True). - Создаётся ревизия темы, но без поднятия в разделе «Последние».
- Если DESCRIPTION не изменился (или изменился только шум, например «Последнее обновление:», который нормализуется), обновление вообще не происходит.
- Маркер UID
- Обеспечивает надёжное сопоставление при будущих синхронизациях.
- Гарантирует, что зашумлённые поля DESCRIPTION не влияют на поиск правильной темы.
6. Почему описание иногда «остаётся прежним»
Скрипт сравнивает всё тело (за исключением маркера UID).
Если изменилась только изменчивая строка, например «Последнее обновление:», но она нормализуется (например, пробелы, переносы строк, Unicode), то old_clean и fresh_clean выглядят идентичными → обновление не выполняется.
Это сделано намеренно, чтобы предотвратить лишние изменения из-за шума в ленте.
Резюме
- Время определяет уникальность (всегда создаёт новую тему при изменении времени).
- Изменение места → видимое поднятие в ленте (чтобы пользователи заметили изменение места проведения).
- Изменение описания → тихое обновление (ревизия, но без поднятия).
- Маркер UID = надёжный ключ идентификации, гарантирует, что правильная тема всегда будет найдена, даже если DESCRIPTION устарел или зашумлён.
Это обеспечивает хороший баланс: важные изменения появляются в разделе «Последние», а незначительные изменения остаются незаметными.