Petr Polezhaev b8f82607f9 Fix archive plugins for НЭБ and Alib; add network integration tests
- html_scraper: add img_alt strategy (НЭБ titles from <img alt>), bold_text
  strategy (Alib entries from <p><b>), Windows-1251 encoding support,
  _cls_inner_texts() helper that strips inner HTML tags
- rsl: rewrite to POST SearchFilterForm[search] with CSRF token and CQL
  title:(words) AND author:(word) query format
- config: update rusneb (img_alt + correct author_class) and alib_web
  (encoding + bold_text) to match fixed plugin strategies
- tests: add tests/test_archives.py with network-marked tests for all six
  archive plugins; НЛР and ШПИЛ marked xfail (endpoints return HTTP 404)
- presubmit: exclude network tests from default run (-m "not network")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 22:59:19 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00
2026-03-09 14:17:13 +03:00

Bookshelf

Photo-based book cataloger. Organizes books in a Room -> Cabinet -> Shelf -> Book hierarchy. Photographs shelf spines; AI plugins identify books and look up metadata in library archives.

Requirements

  • Python 3.11+, Poetry
  • An OpenAI-compatible API endpoint (OpenRouter recommended)

Setup

poetry install

Create config/credentials.user.yaml with your API key:

credentials:
  openrouter:
    api_key: "sk-or-your-key-here"

Start the server:

poetry run serve

Open http://localhost:8000 in a browser.

Configuration

Config is loaded from config/*.default.yaml merged with config/*.user.yaml overrides. User files take precedence; dicts merge recursively, lists replace entirely. User files are gitignored.

File Purpose
credentials.default.yaml API endpoints and keys
models.default.yaml Model selection and prompts per AI function
functions.default.yaml Plugin definitions (boundary detection, text recognition, identification, archive search)
ui.default.yaml UI display settings

To use a different model for a function, create config/models.user.yaml:

models:
  vl_recognize:
    credentials: openrouter
    model: "google/gemini-2.0-flash"

To add an alternative provider, add it to config/credentials.user.yaml and reference it in models.user.yaml.

Usage

  1. Add a room, then cabinets and shelves using the tree in the sidebar.
  2. Upload a photo of each cabinet or shelf.
  3. Drag boundary lines on the photo to segment shelves (or books within a shelf). The AI boundary detector can suggest splits automatically.
  4. Run the text recognizer on a book to extract spine text, then the book identifier to match it against library archives.
  5. Review and approve AI suggestions in the detail panel. Use the batch button to process all unidentified books at once.
  6. On mobile, use the photo queue button on a cabinet or shelf to photograph books one by one with automatic AI processing.

Development

poetry run presubmit   # black check + flake8 + pyright + pytest + JS tests
poetry run fmt         # auto-format Python with black
npm install            # install JS dev tools (ESLint, Prettier) — requires network
npm run lint           # ESLint
npm run fmt            # Prettier

Tests are in tests/ (Python) and tests/js/ (JavaScript).

Description
bookshelf scan and management program (ai-written)
Readme 301 KiB
Languages
Python 65.4%
JavaScript 29.4%
CSS 4%
HTML 1.2%