Перейти к содержанию

Структура директории данных

Все постоянные данные приложения находятся рядом с исполняемым файлом. Это портативная структура — перемещение бандла .app перемещает все данные вместе с ним. Пути централизованы в src-tauri/src/app_paths.rs.

Источник: src-tauri/src/app_paths.rs


Структура

{exe_dir}/
  rutracker/
    session.json        cookie jar reqwest (Base64 JSON)
    meta.json           имя пользователя, data URL аватара, активное зеркало
    proxy.txt           URL HTTP-прокси (одна строка, необязательно)
    covers/             дисковый cache обложек из постов торрентов
    webview/            директория данных WebView2 (окно входа)

  soulseek/
    creds.json          учётные данные { username, password }
    covers/             дисковый cache обложек от peer-ов SoulSeek

  bt/                   (debug-сборки: dev/bt/)
    torrent/            состояние сессии librqbit (экспорт загрузок)
    covers/             сессия обложек librqbit
    vozduxan/           состояние сессии libtorrent C++ vozduxan

  cache_settings.json   ограничения размера cache и переопределения TTL
  app_debug.json        ring buffer лога отладки (сохраняется при выходе)
  general-list.json     debug-реестр треков (все виденные треки)
  likes.json            массив ID понравившихся треков

  dev/                  только debug-сборки
    bt/torrent|covers|vozduxan/   изолированные dev-сессии стриминга
    dumps/              snapshot-ы поисковых дампов

Debug-сборки используют dev/bt/ вместо bt/, чтобы dev-сессии libtorrent (с накопленным piece cache и списками peer-ов) не загрязняли production-данные на той же машине.


Вспомогательные функции путей

Каждый путь в приложении получается через вспомогательную функцию в app_paths.rs. Добавление нового файла требует добавления функции там — никогда не следует хардкодить строку пути в каком-либо другом модуле.

fn base(_app: &AppHandle) -> Result<PathBuf, String> {
    let exe = std::env::current_exe()?;
    exe.parent()
        .ok_or_else(|| "executable has no parent directory".to_string())
        .map(|p| p.to_path_buf())
}

base() — это директория исполняемого файла. Все остальные вспомогательные функции строятся на её основе:

// RuTracker
pub fn rt_session_path(app: &AppHandle) -> Result<PathBuf, String> {
    Ok(rt_dir(app)?.join("session.json"))
}

// BitTorrent (debug vs release)
pub fn bt_vozduxan_dir(app: &AppHandle) -> Result<PathBuf, String> {
    Ok(bt_base_dir(app)?.join("vozduxan"))
}

pub fn bt_base_dir(app: &AppHandle) -> Result<PathBuf, String> {
    let b = base(app)?;
    Ok(if cfg!(debug_assertions) {
        b.join("dev").join("bt")
    } else {
        b.join("bt")
    })
}

Примечательные файлы

session.json

Cookie jar reqwest в формате JSON. Используется HTTP-клиентом RuTracker для сохранения cookie сессии phpBB между перезапусками приложения. При запуске rutracker_restore_session проверяет актуальность cookie, выполняя живой запрос; если проверка не прошла — очищает файл и возвращает состояние «не авторизован».

meta.json

{
  "username": "user123",
  "avatar_data_url": "data:image/jpeg;base64,...",
  "mirror": "rutracker.org"
}

Аватар хранится как data URL, потому что WebView не разделяет cookie с HTTP-клиентом на Rust — прямая загрузка URL аватара вернула бы 403. Rust загружает его при входе и сериализует в base64.

vozduxan/

Состояние сессии libtorrent: данные возобновления для всех известных торрентов, таблица маршрутизации DHT и piece cache. Эта директория может вырасти до значительных размеров у пользователей, стримящих много разных альбомов. Размер cache и TTL настраиваются через cache_settings.json и применяются функцией vozduxan_session_evict.

general-list.json

Debug-реестр, записывающий каждый entity трека, который когда-либо видело приложение. Записывается функцией general_list_write (Rust) через Tauri-команду general_list_append. Используется для восстановления истории сессии при отладке — не является частью обычного пользовательского функционала.


Примечание о бандле macOS

На macOS std::env::current_exe() возвращает путь внутри бандла .app:

neegde.app/Contents/MacOS/neegde

Поэтому bt/vozduxan/ находится по пути:

neegde.app/Contents/MacOS/bt/vozduxan/

Это сделано намеренно — данные перемещаются вместе с бандлом. Директория Contents/MacOS/ бандла доступна для записи владельцем на macOS (в отличие от Contents/Resources/).