SILVER-RenamerBlack
Развитие SILVER-Renamer: добавлены чёрные кадры-разделители между сериями и поддержка комплектов через vision-классификатор.
Сервис: https://renamerblack.6sl.ru (Selectel, РФ-хост — обход блокировки upload через ТСПУ для зарубежных IP).
Чем отличается от SILVER-Renamer
| SILVER-Renamer | SILVER-RenamerBlack | |
|---|---|---|
| Базовое переименование (бирка → артикул → серия) | да | да |
| Чёрные кадры как границы групп | — | да |
| Vision-классификация типа украшения | — | OpenAI gpt-4o-mini / Anthropic claude-sonnet-4-6 |
| Комплекты: копия общего фото для всех артикулов группы | — | да |
CLI / .exe-сборка |
да | — (только web — vision требует сети) |
| Хостинг | Hetzner (EU) + зеркало Selectel (RU) | Selectel (RU) |
Как пользоваться
- Фотограф снимает партию. Между сериями каждого артикула (или комплекта) делает кадр глухого чёрного — закрытая крышка объектива. Этот кадр — разделитель.
- Внутри партии одного комплекта может быть несколько артикулов (бирки на каждый из них) и общие фото комплекта целиком (все украшения вместе на одной поверхности).
- Менеджер открывает https://renamerblack.6sl.ru и загружает папку с фото + Excel
(колонка A=УИН, B=Артикул). - Имена файлов могут бытьYYYYMMDD_HHMMSS.jpg(Samsung) илиfile_1.jpg, file_2.jpg, ...— главное, чтобы порядок «по возрастанию» соответствовал хронологии съёмки. - Сервис обрабатывает партию (этапы — см. ниже) и возвращает HTML-отчёт + ZIP с переименованными файлами и CSV-логом.
Что делает сервис (пошагово)
- Сортировка. Все
.jpgсортируютсяnatsort'ом (естественный порядок:file_1 < file_2 < file_10). - Разбиение на группы. Каждый файл проверяется на «глухой чёрный» (
mean < 10Иstd < 10по grayscale). Чёрные кадры режут поток на группы. Сами разделители в результат не попадают. - Внутри группы — базовое переименование (как в SILVER-Renamer):
- Бирка декодируется
zxing-cpp(Data Matrix / QR). UIN → артикул из Excel → новая под-серия. - Кадр с биркой →output/{артикул}_001.jpg(технический, для проверки). - Следующие фото без бирки → ракурсы артикулаoutput/{артикул}_01.jpg,_02.jpg, … - До первой бирки или UIN не из Excel →_unknown/. - Vision-классификация каждого переименованного фото (
KIND_RENAMED). Метки:ring | earrings | pendant | bracelet | chain | necklace | set | tag | unknown. Параллельно через ThreadPoolExecutor (10 воркеров) — 600 фото ≈ 90 секунд. - Размножение set-фото. Для каждой группы, где есть ≥ 2 разных артикула:
- Находим фото с меткой
set. - Каждое такое фото копируется под каждый артикул группы кроме того, к которому оно уже отнесено. Имя копии —{артикул}_{max_NN_для_артикула + 1}.jpg. - CSV-лог.
rename_log.csvфиксирует все операции (tag | renamed | tag-uin-not-in-excel | no-tag-yet | black-divider | set-copy) с указаниемgroup_idx.
Архитектура
src/
├── silver_renamer.py # ядро: чёрные кадры, группы, бирки → артикулы → серии
├── sets.py # vision-классификация + копии set-фото в группе
├── vision.py # OpenAI / Anthropic классификаторы + SOCKS5
└── web.py # FastAPI: /process, /report/<job>, /docs, /thumb, /file
templates/{base,index,report,docs}.html
static/style.css
deploy/
├── silver-renamerblack.service # systemd unit (port 8770, requires tg-tunnel)
├── Caddyfile.snippet # reverse_proxy renamerblack.6sl.ru → :8770
└── install.sh # идемпотентный sudo-установщик на Selectel
requirements.txt
initial-delmepls/with_razdeliteli_test/ # smoke-test: 18 фото + 3 чёрных разделителя
Поток данных
upload (folder + .xlsx)
↓
web.py:/process — сохраняет в /tmp/silver-renamer-jobs/<id>/input/
↓
silver_renamer.process() — основное переименование, output/ + _unknown/ + rename_log.csv
↓
sets.expand_sets() — vision-классификация (через SOCKS5) + set-копии
↓
pickle(result, expansion) → /report/<id> — HTML-отчёт
zip(output/ + _unknown/ + rename_log.csv) → /download/<id>/result.zip
Vision и сеть
- Бэкенды: OpenAI
gpt-4o-mini(default) или Anthropicclaude-sonnet-4-6. Переключение через envVISION_PROVIDER=openai|anthropic. - Промпт один на всех бэкендов (см.
src/vision.py). Изображение ресайзится до 1024×1024 JPEG q85 — снижает upload и стоимость токенов. - Сеть. Селектел блокирует РФ-IP исходящий к OpenAI/Anthropic. Поэтому vision идёт через
SOCKS_PROXY=socks5://127.0.0.1:1080→ SSH-туннельtg-tunnel.service→ Hetzner. Если переменная не задана (на dev-Hetzner) — прямой выход. - Мягкая деградация: если vision-классификатор не сконфигурирован (нет ключа) или упал в рантайме — основное переименование всё равно отрабатывает, фаза комплектов пропускается с warning в отчёте.
Стек
Python 3.12, FastAPI + uvicorn + Jinja2, Caddy reverse proxy.
zxing-cpp (Data Matrix/QR), openpyxl, opencv-python-headless, natsort, Pillow, markdown.
Vision: openai, anthropic, httpx[socks], python-dotenv.
Запуск (dev, Hetzner)
python3.12 -m venv .venv
.venv/bin/pip install -r requirements.txt
# Один раз — секреты в ~/.config/silver-renamerblack/.env (mode 600):
# OPENAI_API_KEY=sk-proj-...
# ANTHROPIC_API_KEY=sk-ant-... # опционально
# VISION_PROVIDER=openai
# # SOCKS_PROXY=socks5://127.0.0.1:1080 # только на Selectel
PYTHONPATH=src .venv/bin/uvicorn web:app --host 127.0.0.1 --port 8770
Деплой (Selectel)
# на Hetzner
rsync -av --delete \
--exclude='.venv' --exclude='.git' --exclude='__pycache__' \
--exclude='initial-delmepls' --exclude='*.pyc' \
./ 135.106.137.112:/home/vadim/PROJECTS/SILVER-RenamerBlack/
# на Selectel: создать venv (если ещё нет) и поставить deps
ssh 135.106.137.112 'cd PROJECTS/SILVER-RenamerBlack && \
python3.12 -m venv .venv && \
.venv/bin/pip install -r requirements.txt'
# секреты — на Selectel ~/.config/silver-renamerblack/.env mode 600
# (с SOCKS_PROXY=socks5://127.0.0.1:1080 — vision идёт через tg-tunnel)
# первый раз — sudo-установщик копирует env в /etc, systemd unit, Caddy block:
ssh 135.106.137.112 'cd PROJECTS/SILVER-RenamerBlack && sudo bash deploy/install.sh'
# обновления кода — rsync + рестарт:
ssh 135.106.137.112 'sudo systemctl restart silver-renamerblack'
Тестовая партия
initial-delmepls/with_razdeliteli_test/ — 18 фото + 3 чёрных разделителя + Vega2005.xlsx. Ожидаемый результат: 3 группы (по 2 артикула каждая, с парой кольцо + серьги), 15 переименованных + 3 set-копии (по одной на группу). Эталон от менеджера: yandex-disk.
Статус
Развёрнут на https://renamerblack.6sl.ru. Smoke-тест на 18 фото — пройден end-to-end (3 группы, 3 set-копии, корректное переименование, ZIP без оригиналов). Следующий шаг — реальная партия (≈600 фото) от менеджера.