Skip to content

Developers

drew.po28@gmail.com edited this page Jun 20, 2026 · 3 revisions

Для разработчиков

Внутреннее устройство pico-spec (не часть экранного меню). Первая тема — pico-spec-catalog, который питает браузер Web Archives.

pico-spec-catalog

Отдельный репозиторий — drewpo28/pico-spec-catalog — питающий браузер Web Archives на устройстве (Network → F5 → Web Archives). Он прячет все различия между сайтами (HTML-скрейпинг, JSON-API, HTTPS, распаковка) за одним простым табулированным строчным протоколом, поэтому прошивка остаётся тонкой, а новые источники добавляются в репо каталога — без перепрошивки.

Как связан с pico-spec

  • Сторона устройства: src/HttpCatalogFs.cpp (реализация RemoteFs) + Config::catalog_host. Браузер Web Archives листает и качает через него, переиспользуя тот же UI файлового браузера, что и FTP/SFTP.
  • HTTPS считает само устройство — TLS 1.2 через mbedTLS (TlsSock) на RP2350; ESP-01S — просто TCP-мост (та же схема «крипта на хосте / тупой ESP», что и у SSH).
  • catalog_host (хранится в wifi.cfg) выбирает источник — HttpCatalogFs::useStaticTree():
    • пусто → встроенный URL по умолчанию https://drewpo28.github.io/pico-spec-catalog (CATALOG_DEFAULT_URL) — статическое дерево.
    • полный http(s)://… базовый URL → статическое дерево по этому адресу.
    • голый host / host:port → динамический сервер /v1 (см. ниже).

Два режима отдачи

  1. Бессерверный статический (по умолчанию, живой). GitHub Action (cron, 04:17 UTC) запускает gen_static.py, который заранее рендерит весь каталог в статическое дерево .tsv с зеркалированными файлами и публикует на GitHub Pages. Никакого постоянного сервера. Обход идёт на раннерах GitHub (их IP, реальный браузерный UA), поэтому устройство никогда не обращается к живым сайтам-архивам — оно лишь GET-ит статические URL.
  2. Динамический сервер (опционально). Сервис FastAPI (docker compose up, порт 8080) как всегда-свежий кэширующий HTTP-прокси с протоколом /v1/sites, /v1/list, /v1/get. Прошивка по-прежнему говорит на /v1, когда catalog_host — голый host:port. (Собственный код постоянного catalog-сервера из прошивки pico-spec удалён; репо каталога держит сервер для локальной разработки.)

Раскладка статического дерева (корень Pages)

sites.tsv                 "<id>\t<display>\n"  — по строке на источник
<site>/_root.tsv          корневой листинг сайта
<site>/<slug>.tsv         листинг каталога <path>   (slug: "" → _root, '/' → '~')
<site>/files/<slug>/<fn>  зеркалированные байты файла (цели скачивания)

Формат строки листинга (TAB-разделённый)

D <TAB> <name> <TAB> 0      <TAB> <child-slug>   подкаталог → GET <site>/<child-slug>.tsv
F <TAB> <name> <TAB> <size> <TAB> <url>          файл      → GET <url>  (относительно
                                                 корня Pages, либо абсолютный, если http)

4-я колонка locator — это то, что позволяет статическому клиенту разрешить скачивание без сервера. HttpCatalogFs в точности повторяет slug() из gen_static.py для построения URL .tsv, читает locator из строки F для get(), тянет каждый .tsv кусками Range по 16 КБ (чтобы каждое TLS-чтение было мелким) и кэширует в /tmp/.catv_*.tsv на SD, чтобы последующее скачивание не качало повторно по HTTPS.

Источники (адаптеры — app/adapters/)

id источник как
vtrd vtrd.in HTML-скрейпинг — нет API, и он 403-ит небраузерные UA, поэтому обход обязан идти на сервере
sc Spectrum Computing листинг из дампа ZXDB (MySQL); файлы отдаются с spectrumcomputing.co.uk (TLS устройства держит её сертификат через mbedTLS SHA384_C)
zxart zxart.ee JSON API (Games + Demoscene)

Workflow по умолчанию: SITES="vtrd sc zxart", MAX_FILES=400, MAX_DEPTH=4 (workflow_dispatch даёт переопределить). Добавить архив: реализовать Adapter.list() / Adapter.fetch() и зарегистрировать в app/adapters/__init__.py — прошивку менять не нужно. gen_static.py использует те же адаптеры, что и динамический сервер, так что второго скрейпера нет.

Зачем вообще каталог (а не на устройстве)

  • У vtrd.in нет API (чистый HTML) и он 403-ит ботов — скрейпинг + браузерный UA место на сервере, а не в прошивке.
  • Скачивания вверх по цепочке — HTTPS и часто в zip; рендеринг дерева на сервере и зеркалирование уже распакованных .trd/.tap означают, что устройство просто GET-ит статический URL, а не борется с 403 + распаковкой.
  • Листинги пререндерятся — устройство быстрое, а архивы не долбят запросами.

💡 На железе Network → HTTP test (curl) может GET-нуть любой из этих статических URL, чтобы проверить TLS-через-ESP и посмотреть сырой .tsv.

Ссылки

Clone this wiki locally