VkArchiveViewer
README.md
VK Archive Reader
Удобная читалка вашего архива ВКонтакте. Когда вы скачиваете свои данные из ВК, они приходят набором «сырых» веб-страниц, которые неудобно листать и в которых нельзя нормально искать. Это приложение превращает их в привычный мессенджер: список чатов, чтение переписок, поиск по всем сообщениям и галерея всех фотографий.
🔒 Всё работает только на вашем устройстве. Приложение ничего никуда не отправляет и не выкладывает в интернет. Ваши переписки остаются у вас.
📸 Как это выглядит
| Главная страница | Поиск |
|---|---|
![]() |
![]() |
| Галерея | Группировка по лицам |
![]() |
![]() |
Скриншоты появятся здесь после добавления файлов в
docs/screenshots/(см. инструкцию).
⬇️ Скачать и установить
Готовые установщики лежат на странице Releases (последняя версия — сверху).
| Система | Файл | Как установить |
|---|---|---|
| 🪟 Windows | VkArchiveReader-*.msi |
Запустите файл и следуйте мастеру установки. Если Windows покажет «SmartScreen», нажмите «Подробнее» → «Выполнить в любом случае». |
| 🍎 macOS | VkArchiveReader-*.dmg |
Откройте образ и перетащите приложение в «Программы». При первом запуске нажмите на иконке правой кнопкой → «Открыть» (приложение без подписи Apple). |
| 🤖 Android | VkArchiveReader-android.apk |
Скопируйте файл на телефон и откройте его. Разрешите «установку из неизвестных источников», если телефон попросит. |
Предупреждения системы про «неизвестного разработчика» — это нормально для бесплатных приложений без платной цифровой подписи. Установщики собираются автоматически из исходного кода этого репозитория (см. раздел для разработчиков ниже).
🗂 Как получить свой архив ВКонтакте
- Откройте инструкцию ВК: Как получить архив со своими данными?
- Закажите выгрузку и дождитесь письма/уведомления, что архив готов (это может занять несколько часов или дней).
- Скачайте архив. Это будет
.zipфайл или папка с файломindex.htmlвнутри и каталогомmessages/. - Откройте приложение и перетащите папку или
.zipв окно — либо нажмите кнопку «Выбрать архив».
Готово — приложение прочитает переписки и покажет их в удобном виде.
🎬 Нет своего архива? Попробуйте демо
Не хотите ждать выгрузку — просто нажмите на стартовом экране «Нет своего архива? Открыть демо-данные». Приложение откроет встроенный демонстрационный архив с несколькими выдуманными чатами, фотографиями и людьми, чтобы вы могли попробовать все возможности: чтение, поиск, галерею и группировку по лицам.
Демо-данные вымышлены; фотографии загружаются из открытых сервисов-заглушек, поэтому для демо нужен интернет.
✨ Что умеет приложение
- 💬 Список чатов с превью последнего сообщения и счётчиками сообщений и медиа.
- 🔀 Сортировка чатов: по дате, по количеству сообщений, по количеству медиа, по названию.
- 🔎 Поиск по сообщениям — сразу по всем перепискам или внутри одного чата, с фильтрами по человеку/группе и по автору.
- 🧵 Чтение переписки удобными «пузырьками» с эмодзи и подгрузкой по мере прокрутки.
- 🖼 Галерея всех фотографий — по всем чатам или по конкретному, с настройкой числа колонок и полноэкранным просмотром.
- ⬇️ Скачивание фотографий на устройство.
- 🧑🤝🧑 Группировка по лицам (на компьютере) — приложение само находит на фотографиях лица и группирует их по людям, полностью локально.
- 💾 Кеш изображений для быстрой повторной загрузки, с настройкой размера.
❓ Частые вопросы
Некоторые фотографии не открываются — почему? Фото в архиве хранятся не как файлы, а как ссылки на серверы ВК с ограниченным сроком жизни. Для старых архивов часть ссылок уже недоступна — это ограничение самих данных, а не приложения.
Приложение отправляет мои переписки в интернет? Нет. Разбор архива и группировка по лицам происходят на вашем устройстве. В сеть уходят только запросы на загрузку самих картинок по их ссылкам (как в браузере).
На каком устройстве лучше запускать? Для чтения и поиска подойдёт всё. Для группировки по лицам нужен компьютер (Windows/macOS/Linux).
🛠 Документация для разработчиков и LLM
Ниже — техническая часть: архитектура, стек, сборка, формат архива и как устроены демо-данные и распознавание лиц.
Стек и платформы
| Слой | Технология |
|---|---|
| Язык | Kotlin Multiplatform |
| UI | Compose Multiplatform (Material 3) |
| Загрузка картинок | Coil 3 поверх Ktor 3 (CIO/OkHttp/JS/Darwin по платформам) |
| DI | Koin 4 |
| Хранилище лиц (Desktop) | SQLite (sqlite-jdbc) |
| ML лиц (Desktop) | OpenCV через Bytedeco (YuNet + SFace) |
| Пагинация | Собственный инкрементальный постраничный загрузчик (по 50 сообщений) |
| Платформа | Статус |
|---|---|
| Desktop (macOS/Windows/Linux, JVM) | ✅ выбор папки/zip + drag-and-drop; распознавание лиц |
| Android | ✅ открытие .zip через системный выбор файла |
| Web (JS / Wasm) | ✅ выбор распакованной папки (webkitdirectory); zip и лица пока нет |
| iOS | ⚙️ UI собирается; выбор файла не реализован |
Пагинация написана вручную, потому что AndroidX/Cash App Paging 3 не поддерживают wasmJs, а Web — целевая платформа. Свой загрузчик в
ConversationViewModelработает на всех таргетах.
Архитектура
shared/commonMain/.../ru/normno/vkarchivereader
├── core/ Cp1251 (декодер/энкодер windows-1251), Html (сущности/теги)
├── domain/model/ ChatSummary, Message, Attachment, MediaItem, ChatSortOrder
├── data/
│ ├── parser/ VkArchiveParser — чистый парсинг HTML архива
│ ├── source/ ArchiveSource (expect-доступ к файлам), ArchivePicker (expect),
│ │ DemoArchiveSource (встроенные демо-данные, common)
│ └── repository/ ArchiveRepository — сканирование архива, поиск, чтение страниц
├── face/ Детекция/эмбеддинги/кластеризация лиц (expect/actual)
├── di/ AppModule (Koin)
└── presentation/ welcome / archive / conversation / media / face / components
Поток данных
- Пользователь выбирает папку/zip → платформенный
ArchiveSource(или встроенныйDemoArchiveSource). - Двухфазная загрузка ради отзывчивости на больших архивах:
ArchiveRepository.open()— лёгкий проход (≈2 чтения на чат): список чатов с точным числом сообщений и превью почти мгновенно.ArchiveRepository.indexMedia()— фоновый проход по всем страницам, наполняет счётчики медиа и галерею, кооперативно уступая (yield).
- Сообщения чата подгружаются постранично при прокрутке.
- Поиск (
search) перечитывает нужные страницы и фильтрует.
Формат самого архива задокументирован в VK_ARCHIVE_STRUCTURE.md.
⚠️ Медиа в архиве — это подписанные ссылки VK с ограниченным сроком жизни; для старого архива часть уже недоступна (показывается заглушка).
Как устроены демо-данные
DemoArchiveSource (в data/source, commonMain) — это ArchiveSource,
который генерирует HTML точно той же формы, что и реальная выгрузка VK, и
кодирует его в windows-1251 через Cp1251.encode. Благодаря этому демо проходит
через тот же VkArchiveParser/ArchiveRepository, что и настоящий архив — без
единого спец-случая в остальном коде. Кнопка на WelcomeScreen просто отдаёт
ArchivePickOutcome.Success(DemoArchiveSource()).
- Кириллица кодируется в cp1251; эмодзи пишутся как числовые HTML-сущности
(
😀), т.к. cp1251 их не содержит — парсер разворачивает их обратно. - Фото ссылаются на публичные заглушки (
randomuser.me— стабильные портреты для группировки по лицам,picsum.photos— пейзажи), поэтому демо требует сети. - Чат «Мемы и котики» намеренно содержит 56 постов (> 50), чтобы демонстрировать пагинацию; беседа «Друзья» — несколько авторов (для фильтра по автору и лиц).
- Покрыто тестом
DemoArchiveTest(парсинг, пагинация, авторы, медиа, поиск).
Группировка по лицам (Desktop)
Полностью локальный конвейер (ничего не уходит с устройства), запускается из экрана «Все медиа» кнопкой «Лица»:
- Детекция: YuNet (OpenCV Zoo, ~340 КБ ONNX).
- Эмбеддинги: SFace (128-мерный вектор; «один человек» при косинусной близости > 0.363).
- Кластеризация: жадная онлайн-кластеризация (
OnlineFaceClusterer) — потоковая, без знания числа людей заранее. - Рантайм: OpenCV через Bytedeco. Только нативы под текущий десктоп —
javacpp.platformвgradle.properties(по умолчаниюmacosx-arm64); для других ОС переопределяйте (windows-x86_64,linux-x86_64,macosx-x86_64). Версия закреплена на4.9.0-1.5.10(в4.10.0нативныйvideoioпод macOS arm64 ссылается на несуществующийlibOrbbecSDK.1.9.dylibи роняетFaceDetectorYN). Модели скачиваются один раз в~/.vkarchivereader/modelsс LFS-эндпоинтаmedia.githubusercontent.com. - Хранение: локальная SQLite (
~/.vkarchivereader/faces.db); сами фото не сохраняются — только ссылка, группа и чат-источник.
На Android/iOS/Web распознавание пока недоступно; за expect/actual
(createFaceEngine) его можно добавить позже.
Интеграционный тест
FaceDetectIntegrationTestкачает настоящие модели и находит лицо на реальном портрете. Он бьёт в сеть, поэтому по умолчанию пропускается — запуск:./gradlew :shared:jvmTest -DrunFaceIntegration=true.
Запуск из исходников
# Desktop (JVM)
./gradlew :desktopApp:run
# Android (debug APK)
./gradlew :androidApp:assembleDebug
# Web
./gradlew :webApp:wasmJsBrowserDevelopmentRun # Wasm
./gradlew :webApp:jsBrowserDevelopmentRun # JS
# iOS — открыть ./iosApp в Xcode
# Тесты
./gradlew :shared:jvmTest
Сборка установщиков
Установщики собираются jpackage через плагин Compose Desktop, поэтому каждый
формат собирается только на своей ОС (нельзя собрать .msi на macOS).
# macOS → .dmg (на macOS)
./gradlew :desktopApp:packageDmg
# Windows → .msi (на Windows)
./gradlew :desktopApp:packageMsi -Pjavacpp.platform=windows-x86_64
# Linux → .deb (на Linux)
./gradlew :desktopApp:packageDeb -Pjavacpp.platform=linux-x86_64
# Android → .apk
./gradlew :androidApp:assembleDebug
Готовый вывод:
desktopApp/build/compose/binaries/main/{dmg,msi,deb}/androidApp/build/outputs/apk/debug/androidApp-debug.apk
CI
Workflow .github/workflows/release.yml
собирает все три установщика на соответствующих раннерах (Windows/macOS/Ubuntu).
Он запускается вручную (Actions → Run workflow) или по тегу версии, и при пуше
тега публикует артефакты в GitHub Release:
git tag v1.0.0 && git push origin v1.0.0
Лицензия
MIT.
Релизы
Открытые issues
Открытых issues нет 🎉



