# SHiNE Test Publisher Автономный publisher заранее подготовленных постов в существующий канал SHiNE. ## Что делает - публикует следующий элемент `queue/jokes.json` через случайный интервал; - создаёт настоящий SHiNE Frame v1 + подписанный Ed25519 ANS-104 DataItem; - отправляет его обычной операцией `AddBlock` на SHiNE-server; - хранит прогресс в `state.json` и продолжает после рестарта; - перед отправкой сохраняет `pending`, поэтому падение между отправкой и записью state не должно съедать или дублировать элемент очереди; - при расхождении head цепочки с state останавливается вместо создания форка; - очередь по умолчанию НЕ зациклена. В комплекте 60 заранее подготовленных нейтральных коротких анекдотов/шуток. ## Требования Python 3.11+. ```bash python3 -m venv .venv . .venv/bin/activate pip install -r requirements.txt ``` ## Настройка ```bash cp config.example.json config.json ``` Заполнить: - `server_ws` — WebSocket SHiNE-server; - `blockchain_name` — активная цепочка тестового пользователя; - `channel_name` — имя существующего канала (его canonical slug = lowercase); - `channel_root_block_number` — номер CREATE_CHANNEL этого канала; - `key_file` — Solana JSON blockchain key пользователя; - интервалы публикации. Ключ должен соответствовать owner активной blockchain. Реальный ключ не класть в git, права рекомендуется `chmod 600`. При первом запуске `state.json` отсутствует: publisher читает head цепочки и последний POST канала с сервера и создаёт state автоматически. ## Проверка ```bash .venv/bin/python publisher/publisher.py status --config config.json ``` `status` при первом запуске также инициализирует state. Принудительно опубликовать следующий пост: ```bash .venv/bin/python publisher/publisher.py publish-now --config config.json ``` Обычный режим: ```bash .venv/bin/python publisher/publisher.py run --config config.json ``` ## systemd Скопировать каталог в `/opt/shine-test-publisher`, создать venv и настроить `config.json`, затем: ```bash sudo cp systemd/shine-test-publisher.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now shine-test-publisher journalctl -u shine-test-publisher -f ``` Service предполагает пользователя `shine`; поменяйте `User=` при необходимости. ## state.json Не редактировать при запущенном publisher. В нём сохраняются: - следующий индекс очереди; - последний global block/hash; - последний line number/hash канала; - время следующей публикации; - `pending` для crash recovery; - общее число опубликованных элементов. Если очередь закончилась и `loop_queue=false`, новые посты не создаются. Можно дописать новые элементы в JSON; `next_index` продолжит движение дальше.