Своя инсталляция
Lectern — свободное программное обеспечение под лицензией GPL. Исходный код, инструкции по установке и трекер задач — github.com/duckhawk/lectern.
Дальше — конспект для того, кто администрирует инсталляцию, а не замена README в репозитории.
Из чего это состоит
Приложение на Django, PostgreSQL для каталога, Redis для кэша страниц и каталог с файлами книг, в который приложение никогда не пишет. Книги могут лежать россыпью, внутри zip-архивов или быть перечислены в индексе INPX — сканер умеет все три варианта.
Всё, что настраивается во время работы, лежит в админке Django в разделе Constance: менять эти параметры можно без перезапуска и передеплоя.
Сканирование
python3 manage.py sopds_scanner start запускает сканер по расписанию, заданному
в админке (SOPDS_SCAN_SHED_*, синтаксис cron), а scan/rescan — однократно.
Сканер вычитывает метаданные из каждой книги и строит индекс дайджестов, по
которому прогресс из KOReader находит нужную книгу.
SOPDS_ROOT_LIB — каталог, который он обходит, SOPDS_BOOK_EXTENSIONS — какие
файлы считать книгами.
Конвертеры
Необязательные, все настраиваются в админке:
SOPDS_FB2TOEPUB,SOPDS_FB2TOMOBI— внешние программы; если заданы, книги в FB2 дополнительно предлагаются в этих форматах.SOPDS_DJVUTOPDF—ddjvuиз djvulibre, именно он делает DjVu читаемым в браузере. Ключ-qualityиз команды по умолчанию убирать не следует: без него скан с фотографиями конвертируется в растр без потерь, и сотня страниц может дать гигабайт.
Учётные записи и почта
SOPDS_AUTH решает, нужен ли для каталога вход вообще,
SOPDS_ALLOW_REGISTRATION — могут ли посетители заводить себе учётные записи
сами. Заполненные SOPDS_SMTP_* включают восстановление пароля и отправку книг
на устройство. SOPDS_OIDC_* добавляет на страницу входа кнопку Keycloak, а
SOPDS_LOGIN_NOTICE_EN и SOPDS_LOGIN_NOTICE_RU — вашу собственную строку над
формой входа: у кого просить учётную запись или под чем входить в публичное
демо. По строке на язык; если заполнена только одна, показывается она.
Первая учётная запись должна откуда-то взяться:
python3 manage.py sopds_util ensureuser <имя> <пароль> --superuser
В отличие от createsuperuser из Django, эта команда идемпотентна — она создаёт
учётную запись или сбрасывает ей пароль, — поэтому её может выполнять деплой при
каждом выкате. Пароль передаётся в командной строке, где его видно в списке
процессов, так что для всего, кроме демо, лучше завести учётную запись один раз
и сменить пароль через веб-интерфейс.
Язык интерфейса
SOPDS_LANGUAGE задаёт язык для всех. Там, где сайтом пользуются несколько
человек, SOPDS_LANGUAGE_SWITCHER добавляет переключатель в шапку, и каждый
посетитель выбирает язык себе; выбор живёт в его сессии, а настройка выше
становится значением по умолчанию для тех, кто ничего не выбирал.
Переезд на другой домен
OPDS-каталог, сохранённый на читалке, закладка, настройки синхронизации в
KOReader — ничего из этого отсюда не поправить, и всё это ломается при смене
имени хоста. Поэтому оставьте старое имя в ALLOWED_HOSTS, а переменной
окружения CANONICAL_HOST задайте новое. Тогда любой запрос, пришедший на другое
имя, получает постоянный редирект с сохранением пути и параметров, и сохранённые
каталоги продолжают работать.
Резервные копии
Файлы книг лежат на диске, и повторное сканирование восстановит каталог из них,
но оно не восстановит того, что накопили читатели: полки, статусы, оценки,
позиции чтения, теги, списки, счётчики и метаданные, которые дособрал
sopds_enrich.
python3 manage.py sopds_userdata_export backup.json
python3 manage.py sopds_userdata_import backup.json
Выгрузка опирается на признаки, которые переживают пересборку каталога, — путь и имя файла, по которым книгу узнаёт сам сканер, с дайджестом содержимого в качестве запасного варианта. Идентификаторы книг при пересборке меняются, и восстановление по ним назвало бы не те книги.
Мониторинг
/healthz и /readyz для проб, /metrics в формате Prometheus при включённом
SOPDS_METRICS_ENABLE (при желании — за bearer-токеном). Метрики считаются из
базы, поэтому все воркеры отдают одинаковые числа.