v1.0.3
Поверх v1.0.2 — четыре функциональные доработки и пара фиксов производительности UI. Ничего из v1.0.2 не ломается, апдейт безопасный.
Главное в этом релизе — менеджер пресетов (отдельная панель со всеми пресетами разом, их расписаниями автовыгрузки, кнопками быстрого запуска), пересборка манифеста по диску (если папка разъехалась с .manifest.json) и формат имени файла JoySave-совместимый.
Менеджер пресетов
Сверху в шапке между ⚙ и 📋 появилась кнопка «📑 Пресеты». Открывает отдельную панель со всеми сохранёнными пресетами в виде компактных карточек — две строки на пресет:
| Имя · #теги · @автор · ★рейтинг · лимит [▶ 📂 📋 🗑] |
| ☐ Авто-обновление ⏱ N назад → через X ч Y мин |
Что показано в строке:
- Сводка фильтров в одну строку: первые теги через
·,@автор,★200+,NSFW only, лимит — то, что помогает опознать пресет на лету. - Папка — в tooltip на строке (мышью наводишь — видишь полный путь; чтобы открыть, жми 📂).
- Чекбокс «Авто-обновление» — мгновенно переключает
Preset.AutoPull, без необходимости загружать пресет в форму. - ⏱ «N назад» — сколько прошло с последней автовыгрузки (в tooltip — точная дата). «ни разу» если ещё не выгружался.
- → «через N ч M мин» — live-обратный отсчёт до следующего автозапуска (тикает раз в секунду, пересчитывается из глобального интервала
⚙ → Авто-обновление). «готова к запуску», когда таймер достиг нуля. «автовыгрузка выключена», если чекбокс не отмечен.
Кнопки действий в строке:
- ▶ — запустить пресет вручную сейчас. Создаёт задачу в очереди тем же путём, что и scheduler. Помечает
LastAutoPullAt = now, поэтому следующий автозапуск произойдёт через полный интервал, а не сразу — «ручной запуск съедает запланированный». - 📂 — открыть папку пресета в проводнике.
- 📋 — загрузить пресет в форму фильтров (для редактирования всех полей, включая теги/рейтинг/размеры).
- 🗑 — удалить пресет с подтверждением.
Сортировка: пресеты с включённой автовыгрузкой первыми, затем по алфавиту.
В шапке панели показан текущий глобальный интервал автовыгрузки (24 ч по умолчанию). Меняется по-прежнему в ⚙ → Авто-обновление.
Пересборка манифеста по диску
.manifest.json — это файл, в котором приложение хранит, какие attribute.id уже скачаны. По этому файлу при следующих сканированиях фильтра решается, какие картинки уже есть локально (бейдж «✓» на плитке, пропуск в очереди загрузки). Раньше его можно было только удалить целиком («забыть всё»). Но если часть файлов в папке загрузок перетасовали мимо приложения (переименовали, перенесли между подпапками, дозалили картинки извне, импортировали папку из другого даунлоадера), то манифест и реальное содержимое уходили в рассинхрон, и приложение либо качало дубликаты, либо считало удалённые файлы скачанными.
В ⚙ → Манифест добавилась кнопка «🔄 Полностью пересобрать по файлам из директории…»:
- Указываешь папку для сканирования.
- Приложение рекурсивно её обходит, парсит имена в одном из четырёх поддерживаемых форматов:
<номер_поста>_<id_аттрибута>.<ext>— наш дефолтный «По ID».[тег1][тег2]..._<номер_поста>_<id_аттрибута>.<ext>— наш «По тегам (в скобках)».<номер_поста>_<0|1>_<id, padded к 9>__<тег1>-<тег2>...<ext>— наш новый «JoySave-совместимый» формат (см. ниже), а также имена, написанные JoySave.<slug-через-дефисы>-<id_аттрибута>.<ext>— формат JR CDN, то есть имена картинок, сохранённых из браузера правой кнопкой.
- Манифест приводится в точное соответствие с тем, что найдено на диске:
- неизвестные файлы — добавляются (с текущим timestamp);
- записи, у которых файла на диске больше нет — удаляются;
- совпавшие записи сохраняют свой исходный timestamp скачивания и URL.
Расширения принимаются только из списка медиа JR (jpeg/png/gif/bmp/tiff/mp4/webm/webp) — это сделано чтобы случайные посторонние файлы с числами в конце (IMG_20250115_NNN.jpg, RDT_*.jpg, отчёты 2025-01-15.jpg) не попали в манифест.
.manifest.json на всё приложение), пересборка по одной из папок сотрёт записи о файлах, лежащих в других папках. UI выводит соответствующий confirm-диалог с явным предупреждением.
Имя файла «JoySave-совместимый»
В ⚙ → Формат имени файла появился третий вариант «JoySave-совместимый». Имена строятся 1:1 как у JoySave (corax4/JoySave), что полезно если папка делится между двумя инструментами или импортируется готовый архив:
<номер_поста>_0_<id_аттрибута, padded к 9 нулями>__<до 4 тегов через `-`>.<ext>
Пример: пост 12345, картинка 67890, теги «art», «cat ears», «anime»:
12345_0_000067890__art-cat-ears-anime.jpeg
Детали:
_0_— у JoySave это слот «откуда картинка»:0для тела поста,1для приложения в комментарии. У нас массовая загрузка ходит только заPost.AttributesчерезQuery.search(картинок из комментариев в этой загрузке нет), так что_0_захардкожен.- ID аттрибута выравнивается нулями слева до 9 символов (
67890→000067890). - Тег-блок: первые 4 тега в исходном порядке (без алфавитной сортировки — как у JoySave), разделитель
-, пробелы внутри имени тега →-. - Запрещённые в Windows символы (
\/:*?|<>") на всём имени →@(post-process sweep как у JoySave).
Отличия от существующих форматов:
- «По ID» (
12345_67890.jpg) и «По тегам (в скобках)» ([art][cat][dog]_12345_67890.jpg) — наши собственные форматы, дают детерминированное имя (теги сортируются алфавитно). - «JoySave-совместимый» — побайтовая совместимость с JoySave: один и тот же пост может дать разные имена при двух запусках, если API вернул теги в разном порядке. Это осознанный tradeoff — обмен на то, что файлы 1:1 узнаются JoySave-ом.
Дедупликация при скачивании во всех случаях остаётся по attribute.id в манифесте — формат имени на это не влияет.
Выбранный в ⚙ → Формат имени файла формат применяется ко всем способам запуска задачи — ручному «+ Добавить в очередь», запуску ▶ из менеджера пресетов и автоматической выгрузке через scheduler.
UI: меньше перерисовок при массовой загрузке
В v1.0.2 при активной массовой загрузке UI ощутимо «дёргался» — мерцали hover-состояния кнопок, теги-чипы, выпадайка автокомплита, изредка прыгал каретка ввода. Причина: каждое сохранение картинки (job:update) триггерило полную перерисовку #app.innerHTML — топбар, форма фильтров, грид превью, всё, до 60 раз в секунду, хотя реально менялось максимум одна зелёная галка на превью раз в секунду.
В v1.0.3:
- Обновление зелёных галок «уже скачано» на плитках теперь делается хирургически: новая функция проходит по уже отрендеренным плиткам и точечно добавляет/удаляет/обновляет только сам бейдж. Полная перерисовка не вызывается.
- Обновления счётчиков задач (saved/skipped/failed) не вызывают рендер, если очередь задач закрыта (там нечему меняться). Открыли очередь —
openQueue()сам подтянет накопленное состояние. - При открытой очереди счётчики обновляются с дебаунсом 250 мс (≤4 раза/сек вместо 60). Глазу разницы нет, но шелл больше не пересобирается.
Переходы между состояниями задач (running → done/canceled/error, удаление, добавление) по-прежнему отрабатываются мгновенно — топбар-бейдж и таблица очереди обновляются без задержки.
Скачивание
Тот же набор файлов, что и в v1.0.2 — Windows portable / NSIS-setup, macOS universal .app, Linux .tar.gz.
Лицензия
MIT.
Full Changelog: v1.0.2...v1.0.3