feat(tagging): title-based WIP auto-tagging (#1458)
Auto-apply the `wip` system tag to posts whose TITLE explicitly declares
work-in-progress ("WIP" / "work in progress") — a deterministic, high-precision
complement to the image-based ML `wip` head. WIP images are excluded from the
Explore/gallery browse, so honouring the artist's own label keeps unfinished
pieces out of the main browse.
- services/wip_title.py: precision-first token-anchored matcher (swipe/wiped
never trip it) + sync apply helpers (source='wip_title', ON CONFLICT DO
NOTHING, chunked under the psycopg param ceiling).
- importer: live hook on FRESH import only (never on deep-scan/supersede), so a
manually-removed WIP tag is never re-applied by a routine re-scan.
- maintenance.backfill_wip_title_tags: operator-triggered back-catalogue sweep
(coarse SQL prefilter + regex confirm, keyset-paginated). Deliberately NOT a
beat — a periodic re-run would silently undo manual removals.
- ImportSettings.wip_title_tagging_enabled (default ON, migration 0085) gating
the live hook; GET/PATCH + POST /settings/wip-title/scan.
- Settings UI: toggle + "Scan existing posts" button.
- Tests: pure matcher unit tests + integration (apply idempotency, backfill
precision).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,35 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-divider class="my-5" />
|
||||
|
||||
<!-- Title-based WIP auto-tagging (task #1458). The switch gates the LIVE
|
||||
import hook; the button runs the one-off back-catalogue scan (an
|
||||
explicit action — it is deliberately not a scheduled sweep so it can't
|
||||
silently re-apply a WIP tag you removed by hand). -->
|
||||
<div class="fc-wip">
|
||||
<div class="fc-wip__title">WIP auto-tagging</div>
|
||||
<v-switch
|
||||
v-model="local.wip_title_tagging_enabled"
|
||||
label="Tag work-in-progress from post titles"
|
||||
density="compact" hide-details color="primary" @change="save"
|
||||
/>
|
||||
<div class="fc-help mb-3">
|
||||
When a post's title says <strong>“WIP”</strong> or
|
||||
<strong>“work in progress”</strong>, new imports get the
|
||||
<code>wip</code> tag automatically — keeping unfinished pieces out of
|
||||
the Explore browse. Applies to new imports; run the scan below to catch
|
||||
posts already in your library.
|
||||
</div>
|
||||
<v-btn
|
||||
variant="tonal" color="primary" size="small"
|
||||
:loading="store.wipScanBusy" prepend-icon="mdi-magnify"
|
||||
@click="store.scanWipTitles()"
|
||||
>
|
||||
Scan existing posts for WIP titles
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-alert v-if="store.settingsError" type="error" variant="tonal" class="mt-2" closable>
|
||||
{{ store.settingsError }}
|
||||
</v-alert>
|
||||
@@ -109,6 +138,7 @@ const local = reactive({
|
||||
skip_transparent: false, transparency_threshold: 0.9,
|
||||
skip_single_color: false, single_color_threshold: 0.95,
|
||||
phash_threshold: 10,
|
||||
wip_title_tagging_enabled: true,
|
||||
})
|
||||
|
||||
watch(() => store.settings, (s) => { if (s) Object.assign(local, s) }, { immediate: true })
|
||||
@@ -124,11 +154,18 @@ async function save() {
|
||||
color: rgb(var(--v-theme-on-surface-variant));
|
||||
margin-top: 2px;
|
||||
}
|
||||
.fc-phash__title {
|
||||
.fc-phash__title,
|
||||
.fc-wip__title {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
color: rgb(var(--v-theme-on-surface));
|
||||
}
|
||||
.fc-wip code {
|
||||
font-size: 0.85em;
|
||||
padding: 1px 4px;
|
||||
border-radius: 3px;
|
||||
background: rgb(var(--v-theme-surface-variant));
|
||||
}
|
||||
/* Headroom so the tick labels (Exact/Strict/Default/Loose) aren't clipped. */
|
||||
.fc-phash__slider { margin-bottom: 18px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user