Implement media rule editor and enhance gallery functionality
- Introduced a rule editor in the gallery for users to define actions when a media item is found again, allowing for better management of media rules. - Updated `GalleryViewModel` to handle rule actions, including saving, editing, and removing rules, with appropriate UI bindings. - Enhanced UI components in `GalleryView.axaml` to support rule editing, including action selection and source management. - Added localization strings for new rule-related features in both English and Russian. - Improved unit tests to cover new rule management functionalities, ensuring robust behavior during rule creation and editing. These changes significantly enhance the user experience by providing a more interactive and flexible way to manage media items in the gallery.
This commit is contained in:
@@ -76,6 +76,30 @@
|
||||
повторный рендер, который тихо разъедется с шаблоном. Ctrl+C без выделения копирует весь журнал.
|
||||
В Avalonia 12 `SetTextAsync` — расширение из `Avalonia.Input.Platform`, а не член `IClipboard`.
|
||||
|
||||
## Правила на картинку
|
||||
|
||||
Пользователь открывает картинку в галерее и говорит, что делать, когда она попадётся снова:
|
||||
`MediaRule` (SHA-256 → действие + список источников), таблица `media_rule`, редактор — оверлей
|
||||
`x:Name="RuleEditor"` в `GalleryView`.
|
||||
|
||||
- **Опознание по байтам, и только.** Ни адрес, ни размер не отличают «удалено» и «недоступно в вашей
|
||||
стране» от настоящей картинки — сервис отдаёт и то и другое честным 200. Перцептивных хешей здесь
|
||||
нет намеренно, поэтому пережатая версия того же баннера — другое правило; притворяться иначе значит
|
||||
тихо терять настоящие находки.
|
||||
- **Область — источники.** Одни и те же байты у одного хоста заглушка, у другого обычная картинка.
|
||||
Пусто = все источники. Новое правило открывается отмеченным на источнике этой картинки.
|
||||
- **`Skip` удаляет и уже собранную копию.** Правило ставят, глядя на мусор в галерее; оставить его на
|
||||
диске значит выполнить половину просьбы. Удаление идёт через существующий tombstone — он один умеет
|
||||
снимать копии вместе со ссылками showcase.
|
||||
- **`RetryElsewhere` перезапрашивает тот же адрес через другую страну**, до `MaxCountryAttempts`, и
|
||||
**требует прокси даже у источника, которому разрешено прямое подключение**: смысл в том, чтобы
|
||||
прийти откуда-то ещё, а свой адрес — ровно то место, где баннер уже видели.
|
||||
- **Некуда идти — ничего не сохраняем, адрес остаётся повторяемым** (`GeoBlocked`, нетерминальный).
|
||||
Баннер это не картинка, а записать его как решённый исход значит сжечь id навсегда из-за
|
||||
сегодняшнего состава пула. Прокси без страны в фиде исключить не из чего — это тоже конец попыток.
|
||||
- **Старые tombstone приезжают в ту же карту как безобластной `Skip`**: у фетчера один поиск на
|
||||
скачивание, а правило по тому же хешу перебивает, как более позднее и более конкретное.
|
||||
|
||||
## Хранилище медиа
|
||||
|
||||
- **В `blobs/` попадает только дочитанное.** Загрузка идёт во временный файл в соседнем каталоге на
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
всего набора — то есть из пары тысяч непроверенных адресов, и почти каждый запрос платил полный
|
||||
connect-таймаут, чтобы это выяснить. Теперь «живых N» на странице и то, куда реально ходит сбор, —
|
||||
одно и то же число.
|
||||
- **`AcquireAsync(excludedCountries)` — для правила «попробовать из другой страны».** Записи, у
|
||||
которых фид не назвал страну, остаются в игре: неизвестная страна — не совпадение, и отбрасывать их
|
||||
значит сужать пул из-за пустого поля.
|
||||
- **Фолбэк на всё доступное, когда живых нет.** Непроверенная ≠ мёртвая: на холодном пуле строгий
|
||||
фильтр не выдал бы ничего и сбор просто встал бы, не попробовав. Ответившая на этом пути прокси
|
||||
сама себя переводит в живые.
|
||||
|
||||
Reference in New Issue
Block a user