Структура директории данных¶
Все постоянные данные приложения находятся рядом с исполняемым файлом. Это портативная структура — перемещение бандла .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:
Поэтому bt/vozduxan/ находится по пути:
Это сделано намеренно — данные перемещаются вместе с бандлом. Директория Contents/MacOS/ бандла доступна для записи владельцем на macOS (в отличие от Contents/Resources/).