Skip to content

HelpFreedom/note-desktop

Repository files navigation

Notes Desktop

English version | Подробно в видео

License: GPL v3

screenshot

Настольное приложение для заметок в стиле Telegram Desktop на PySide6 / Qt 6 (Python 3.11). Папки работают как чаты, заметки — как сообщения: узкая колонка папок слева, широкая лента сообщений справа с полем ввода снизу.

Приложение полностью офлайн — без серверов и телеметрии. Опциональный движок peer-to-peer синхронизации позволяет устройствам обмениваться заметками напрямую по локальной сети, а опциональный слой локального шифрования защищает хранилище за ПИНом.

Мобильный компаньон (Flutter/Android): notes-mobile — использует тот же протокол синхронизации и формат шифрования, поэтому телефон и десктоп сходятся к одному состоянию.


Возможности

  • Папки как чаты — цветные иконки, создание / переименование / удаление, контекстное меню.
  • Заметки как сообщения в ленте: текст, форматированный текст (Ж / К / Ч / зачёркнутый), картинки, любые файлы, альбомы файлов. Пузыри на всю ширину.
  • Богатый ввод: набор, вставка с сохранением форматирования, drag-n-drop файлов в окно, вставка картинок из буфера. Поле авто-растёт, авто-фокус.
  • Кликабельные ссылки (URL) и ссылки между заметками («копировать ID-ссылку» → переход).
  • Календарь с цветными событиями; маркеры на датах.
  • Нечёткий поиск — SQLite FTS5 для быстрых кандидатов + rapidfuzz с устойчивостью к опечаткам; область — папка или глобально; поиск по дате.
  • Экспорт / импорт — хранилище это просто папка файлов; экспорт = zip, импорт сливает по id и пересобирает поисковый индекс.
  • Тёмная тема в духе Telegram Desktop.

Опционально: peer-to-peer синхронизация

  • Напрямую устройство-устройство по mutual-TLS с пиннингом сертификата.
  • Обнаружение по mDNS в локальной сети + сопряжение по QR (одноразовое, с TTL).
  • Разрешение конфликтов через append-only журнал операций с version vectors и last-writer-wins по времени правки; удаления фиксируются tombstone'ами.
  • Кросс-языковой набор conformance-тестов фиксирует семантику wire/крипто/слияния, чтобы десктоп и Flutter-приложение не разошлись молча.

Опционально: локальное шифрование и duress

  • Шифрование всего хранилища AES-256-GCM (субключи на файл через HKDF) за ПИНом.
  • Аппаратный гейт на поддерживаемых машинах (TPM 2.0 с анти-откатным NV-счётчиком) против офлайн-перебора ПИНа.
  • Режим duress: обратный ПИН крипто-стирает keyring, удаляет файлы по явному allowlist'у и показывает подложные заметки.

Ментальная модель

Папка    ==  чат
Заметка  ==  сообщение

Правая область — QStackedWidget: лента сообщений (QScrollArea из виджетов-пузырей с полем ввода снизу) и страница календаря. Заметки хранятся обычными файлами на диске плюс перестраиваемый индекс SQLite/FTS5 — поэтому перенос хранилища это просто перенос папки.

Раскладка хранилища

<vault>/
  folders/<folder-id>/
    folder.json
    notes/<note-id>.json
    notes/attachments/<note-id>/
  calendar/events.json
  index.sqlite          # перестраиваемый индекс поиска (в экспорт не входит)

Требования

  • Linux с Qt-совместимой сессией (разрабатывалось на Debian 11).
  • Python 3.11.
  • Зависимости (см. requirements.txt): PySide6, rapidfuzz, python-dateutil. Всё остальное — стандартная библиотека.

Опциональный аппаратный гейт: tpm2-tools и устройство TPM 2.0 (без них приложение деградирует к программному ПИН-гейту).

Установка и запуск

python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
./run.sh           # или: python -m qtnotes

Путь к хранилищу по умолчанию ~/.local/share/QtNotes, переопределяется переменной окружения QTNOTES_VAULT. Настройки приложения — в $XDG_CONFIG_HOME/QtNotes/settings.json.

Тесты

Слой логики (хранилище, индексация, синхронизация, крипто) покрыт headless-тестами, работающими без дисплея:

QT_QPA_PLATFORM=offscreen python tests/test_storage.py
# ...или весь набор:
for t in tests/test_*.py; do QT_QPA_PLATFORM=offscreen python "$t"; done

Кросс-языковые conformance-тесты (test_convergence_conformance.py, test_golden_vectors.py) дополнительно гоняют Flutter-приложение, если dart есть в PATH и проект qtnotes-mobile лежит рядом; иначе проверяется Python-сторона, а Dart-сторона пропускается.

Структура проекта

qtnotes/
  app.py, __main__.py, config.py, fsutil.py
  storage/    models, vault, index, exporter, crypto_fs, owned_paths
  sync/       engine, oplog, apply, wire, transport, discovery, pairing
  crypto/     unlock, keyvault, valuecrypt, duress, primitives
  ui/         main_window, chat_view, sidebar, message_bubble, calendar_view, ...
tests/        headless логика + conformance-тесты

О безопасности

Это личный проект, а не профессионально проаудированный security-продукт. Шифрование и duress — это защита в глубину, рассчитанная прежде всего на кражу устройства и принуждение, когда устройство заблокировано. Никакая программная схема не защищает данные, если у атакующего есть root на устройстве, где приложение сейчас разблокировано (ключ тогда в памяти). Не полагайтесь на это приложение как на единственную защиту критически важных секретов без собственной проверки.

Нашли проблему безопасности — заведите issue (или сообщите приватно, если предпочитаете).

Лицензия

GNU GPL v3.0 — можно использовать, изучать, изменять и распространять, но производные работы тоже должны выходить под GPL.

About

Note — Telegram-style desktop notes app (PySide6/Qt6) with P2P sync and local encryption

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors