Образ Flibusta-at-home не содержит ни одной книги — только движок. Книги
приходят в виде zip-архивов Флибусты, которые вы кладёте в директорию,
смонтированную как /flibusta. Эта статья о том, где эти архивы взять, что
значат их имена и как библиотека по имени архива понимает, какая книга в нём
лежит.
Откуда берутся архивы
Флибуста раздаёт свою коллекцию через торренты: на сайте есть раздел с торрент-файлами и magnet-ссылками на архивы. Коллекция разбита на файлы по диапазонам идентификаторов книг, а не по датам или авторам; новые поступления выкладываются отдельными архивами и рано или поздно попадают в общий торрент.
Способа получить архивы два:
- Любым торрент-клиентом на любом компьютере, потом положить файлы в
/flibusta. Так удобно для первоначальной закачки полной коллекции, которая занимает сотни гигабайт и может идти сутками. - Прямо из библиотеки: раздел «Сервис», блок «Добавить книги из
торрента». Вставьте magnet-ссылку или загрузите
.torrent, и встроенныйaria2cскачает только те файлы, которых у вас ещё нет, в/cache/local. Удобно для регулярных «дельт». Подробнее — в статье об административных разделах.
Есть и третий источник — ежедневные обновления (/daily/ на сайте
Флибусты), которые кнопка «Скачать последние обновления» складывает в
/cache/local. Это небольшие архивы за последние дни; когда те же книги
появляются в торрент-архиве, ежедневные файлы становятся ненужными, и
библиотека сама удаляет их (см. ниже).
Что означают имена файлов
f.fb2-000024-030559.zip
f.usr-000004-030559.zip
f.n-812345-813210.zip
f.fb2.815000-815999.zip
d.fb2-120000-125000.zip
Схема: <префикс>.<класс>[-.]<первый id>-<последний id>.zip.
- Класс
fb2— книги в формате fb2, основная масса художественной литературы. Внутри архива файлы называются<id>.fb2. - Класс
usr— все остальные форматы: pdf, djvu, epub, docx, mobi, rtf, txt, html. Внутри —<id>.<расширение>. - Класс
n— «новые» архивы; библиотека относит их к fb2. - Два числа — диапазон идентификаторов книг, которые могут быть внутри.
Это идентификаторы из базы Флибусты, те же, что в адресе книги на сайте
(
/b/123456). Не все id диапазона обязательно присутствуют в архиве — часть книг удалена, часть относится к другому классу. - Разделитель между классом и первым числом бывает и
-, и.— библиотека понимает оба варианта. - Префикс
d.тоже принимается (архивd.fb2-009…исключён явно, это историческая особенность).
Библиотеке важно только имя: в нём должен быть дефис, окончание .zip и
подстрока fb2 для fb2-класса. Не переименовывайте и не распаковывайте
архивы. Файл с именем не по схеме будет проигнорирован при сканировании.
Как строится индекс архивов
Кнопка «Сканирование ZIP» (скрипт update_zip_list.php) делает следующее:
- Читает имена файлов в
/flibustaи в/cache/local, разбирает из имени класс и диапазон. - Для каждого класса отдельно выбирает минимальный набор архивов,
покрывающий все идентификаторы. Если один архив целиком перекрыт
другими (типичный случай: ежедневная «дельта» в
/cache/local, книги которой уже вошли в большой торрент-архив в/flibusta), он в индекс не попадает. - Архивы из
/cache/local, которые в индекс не попали, удаляются с диска — их содержимое уже есть в основной коллекции. Список удалённых пишется в/cache/clearlists/. Файлы из/flibustaне трогаются никогда: директория смонтирована только для чтения. - Если между диапазонами есть разрыв, скрипт пишет
Got a gapв/cache/log/update_zip_list.logи продолжает; книги из разрыва будут считаться отсутствующими (и, при включённом режиме, скачиваться на лету). - Таблица
book_zipочищается и заполняется заново: для каждого выбранного архива — путь, первый id, последний id и признак класса. - Тот же список выгружается в файл
/cache/zip_index.php— это и есть тот индекс, которым библиотека пользуется в работе (см. следующий раздел).
Отсюда практические следствия:
- Перекрывающиеся архивы держать можно, вреда нет — индексатор выберет нужные.
- После любого изменения набора файлов нужно сканирование: добавили
торрент, удалили файл, перенесли архивы из
/cache/localв/flibusta. Без сканирования библиотека будет искать книги по старой карте. - Порядок id в базе Флибусты и в именах архивов один и тот же, поэтому «свежие» книги — это архивы с большими номерами. Хотите держать только новинки — оставьте последние несколько архивов.
Как библиотека находит книгу
При открытии книги с идентификатором N и форматом из базы:
- Поиск в индексе архивов: архив нужного класса, у которого
start_id ≤ N ≤ end_id. - Внутри архива ищется запись
N.fb2(илиN.<расширение>дляusr). В некоторых архивах книга лежит вложенным zip-файлом (N.fb2.zip, а иногда с человекочитаемым именем, которое записано в таблицеlibfilename); тогда вложенный zip один раз распаковывается в/cache/local/N.fb2, и дальше используется этот файл. - Если подходящего архива нет — срабатывает
скачивание на лету,
если оно включено; результат тоже оказывается в
/cache/local/N.<формат>.
Файл /cache/local/N.<формат> всегда проверяется первым, до открытия
архива. Поэтому /cache/local со временем растёт: там и распакованные
вложенные zip, и скачанные на лету книги, и ежедневные архивы, и
одно-книжные zip из раздела «Добавить». Всё, кроме последнего, можно
безболезненно удалять — библиотека восстановит нужное при следующем
обращении.
Где живёт сам индекс
Поиск архива происходит не в базе. Данных в индексе немного — одна строка на
архив, обычно несколько тысяч, — и меняются они только при сканировании,
поэтому индекс дополнительно выгружается в генерируемый PHP-файл
/cache/zip_index.php. PHP держит его разобранным в разделяемой памяти
(OPcache), так что поиск нужного архива — это двоичный поиск в массиве без
единого обращения к Postgres. Открытие книги, её скачивание и показ обложки
перестали из-за этого ходить в базу.
Таблица book_zip никуда не делась: она остаётся источником, из которого
файл собирается, и запасным вариантом, если файла ещё нет. Практических
следствий два:
- При обновлении библиотеки с более старой версии индекс строится автоматически при первом запуске контейнера — отдельно запускать сканирование не нужно.
- Если удалить
/cache/zip_index.phpруками, библиотека продолжит работать, обращаясь к таблице, и напишет об этом в лог; файл вернётся после следующего «Сканирования ZIP» или перезапуска контейнера.
Есть одна тонкость, которую стоит знать: если диапазоны двух архивов пересекаются и книга попадает в оба, выбирается архив с более поздним началом диапазона, то есть более узкий. Благодаря этому одно-книжный zip, созданный разделом «Добавить», выигрывает у большого торрент-архива, который формально накрывает тот же идентификатор.
Как разложить по дискам
/flibusta— только чтение (:roв docker-compose). Это может быть отдельный большой диск, RAID, том NAS, даже сетевой ресурс по NFS или SMB: библиотека только читает из архивов, скорость сети редко становится узким местом. Нужны права на чтение для uid 82./cache— на запись, желательно на быстром диске: сюда пишутся распакованные книги, обложки, логи. Если планируете много скачивать на лету или торрентами через «Сервис», заложите место./sql— несколько гигабайт под распакованные дампы; растёт при каждом обновлении дампа только до размера текущего.
Полная коллекция fb2 на сегодня занимает несколько сотен гигабайт, usr —
ещё столько же. Если диска на всё не хватает, начните с fb2 или вообще с
пустой директории — библиотека умеет работать с частичным архивом, об этом
отдельная статья.
Проверка, что архивы «увидены»
После сканирования на странице «Сервис» обновится «Последний скан ZIP» и «Размер архива». Точный список того, что попало в индекс, можно получить из базы (как подключиться — в статье о скриптах):
SELECT filename, start_id, end_id, usr FROM book_zip ORDER BY usr, start_id;
Или, без базы, прямо в файле индекса:
docker exec flibusta-fpm head -20 /cache/zip_index.php
Число архивов в файле и в таблице должно совпадать; если нет — запустите «Сканирование ZIP», оно перестраивает оба.
Если какого-то архива в списке нет — проверьте имя файла по схеме выше и
права на чтение, и загляните в /cache/log/update_zip_list.log.