rpi: books-sync — диалоги с ИИ не выгружать, только заметки и рекапы

Нужное из диалога владелец сохраняет кнопкой «В заметки». Файл книги, где заметок
не осталось, переписывается шапкой («Мои мысли» сохраняются).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gilfanovr
2026-10-18 00:43:08 +03:00
co-authored by Claude Opus 5.5
parent 71486960c5
commit 4eacb09f8e
3 changed files with 11 additions and 9 deletions
+1 -1
View File
@@ -300,5 +300,5 @@ Docker CE 29.9 + Compose v5.6 из репо download.docker.com (в Debian ст
## Читалка books → Obsidian (с 2026-10-18)
- Заметки, рекапы и диалоги с ИИ из books.ruzzy.dev → vault `Книги/` (файл на книгу) раз в 10 мин: `books-sync.timer` (astra) тянет `GET /api/export` с токеном `export:obsidian-rpi` (`/etc/books-sync/token`, root:astra 640; на fr1 только хэш). Export-токены читалка пускает только на `/api/export`. Подробно — [`stacks/rpi-books-sync/`](../stacks/rpi-books-sync/README.md).
- Заметки и рекапы из books.ruzzy.dev (диалоги с ИИ — только через кнопку «В заметки», целиком не выгружаются) → vault `Книги/` (файл на книгу) раз в 10 мин: `books-sync.timer` (astra) тянет `GET /api/export` с токеном `export:obsidian-rpi` (`/etc/books-sync/token`, root:astra 640; на fr1 только хэш). Export-токены читалка пускает только на `/api/export`. Подробно — [`stacks/rpi-books-sync/`](../stacks/rpi-books-sync/README.md).
- Односторонняя: выше `## Мои мысли` перезаписывается, раздел владельца сохраняется. Первая синхронизация 2026-10-18 00:38 — «Efficient Go», «Observability Engineering».
+3 -2
View File
@@ -1,6 +1,6 @@
# Читалка books → Obsidian (rpi)
С 2026-10-18: заметки, рекапы и диалоги с ИИ из читалки books.ruzzy.dev (fr1) раз в 10 минут попадают в vault
С 2026-10-18: заметки и рекапы из читалки books.ruzzy.dev (fr1) раз в 10 минут попадают в vault
владельца, папка **`Книги/`** — файл на книгу, главы разделами. Дальше их разносит Obsidian Sync (Mac, iPhone, Boox).
- **Доставка — pull с малины по HTTPS** (fr1 до малины за NAT не достучится): `GET https://books.ruzzy.dev/api/export?v=<версия>`
@@ -12,7 +12,8 @@
состояние `/var/lib/books-sync/state.json` (версия, book_id → файл).
- **Односторонняя:** всё выше `## Мои мысли` перезаписывается из читалки; сам раздел и всё ниже — не трогается
(свои мысли писать туда). Правки заметок — в читалке. Книгу переименовали — файл переименовывается вместе с «Моими мыслями».
- Файлы — только для книг, где есть заметки/рекапы/диалоги. Длинные цитаты обрезаются до 1500 знаков.
- Диалоги с ИИ целиком не выгружаются (владелец 2026-10-18): нужное — кнопкой «В заметки» в окне объяснения, приходит обычной заметкой.
- Файлы — только для книг, где есть заметки/рекапы. Длинные цитаты обрезаются до 1500 знаков.
Удалённая из читалки книга — файл остаётся.
```sh
+7 -6
View File
@@ -1,9 +1,10 @@
#!/usr/bin/env python3
"""books-sync — заметки, рекапы и диалоги читалки books.ruzzy.dev → Obsidian-vault владельца (папка «Книги/»).
"""books-sync — заметки и рекапы читалки books.ruzzy.dev → Obsidian-vault владельца (папка «Книги/»).
Раз в 10 мин (books-sync.timer, юзер astra): GET /api/export с токеном «export:obsidian-rpi» (/etc/books-sync/token);
если версия не изменилась — ничего не делаем. Файл на книгу: «Книги/<название>.md», главы — разделами (рекап, заметки,
диалоги). Всё выше заголовка «## Мои мысли» перезаписывается из читалки, сам раздел и всё ниже — не трогаем.
если версия не изменилась — ничего не делаем. Файл на книгу: «Книги/<название>.md», главы — разделами (рекап, заметки).
Диалоги с ИИ целиком не выгружаются (владелец 2026-10-18): нужное сохраняется кнопкой «В заметки» в окне объяснения —
ИИ сжимает разговор в обычную заметку, она и приходит сюда. Всё выше заголовка «## Мои мысли» перезаписывается из читалки, сам раздел и всё ниже — не трогаем.
Синхронизация односторонняя: правки заметок — в читалке. Только stdlib.
books-sync синхронизировать (таймер)
@@ -133,9 +134,9 @@ def main():
changed = []
for b in data["books"]:
sel = lambda xs: [x for x in xs if x["book_id"] == b["id"]]
notes, recaps, dialogs = sel(data["notes"]), sel(data["recaps"]), sel(data["dialogs"])
if not (notes or recaps or dialogs):
continue
notes, recaps, dialogs = sel(data["notes"]), sel(data["recaps"]), [] # диалоги — только через «В заметки»
if not (notes or recaps or dialogs) and str(b["id"]) not in files:
continue # уже был файл, а заметок не осталось — перепишем шапкой, «Мои мысли» сохранятся
rel = f"{FOLDER}/{safe(b['title'])}.md"
old = files.get(str(b["id"]))
if old and old != rel and (VAULT / old).exists() and not (VAULT / rel).exists():