Nested-archive extraction (#718) + post-first ingest (#67) + post-body canary (#862) #109

Merged
bvandeusen merged 6 commits from dev into main 2026-06-15 21:37:39 -04:00
Showing only changes of commit b48ba60830 - Show all commits
+18 -22
View File
@@ -682,6 +682,15 @@ class Importer:
error=f"{pct:.2%} transparent",
)
# Artist anchored to the attribution path (folder→artist), resolved
# UP-FRONT so the enrich-on-duplicate branches link provenance with the
# right artist even when the sidecar carries none — which is now the norm
# for archive members under post-first (the per-media sidecar is minimal).
# Without this a cross-posted / re-packed archive image deduped and was
# left UNLINKED from the new post = a post showing "no images" (#718).
_artist_name = derive_top_level_artist(attribution_path, self.import_root)
path_artist = self._upsert_artist(_artist_name) if _artist_name else None
# Hash dedup (exact).
sha = _sha256_of(source)
existing_stmt = select(ImageRecord).where(ImageRecord.sha256 == sha)
@@ -691,9 +700,9 @@ class Importer:
# Enrich-on-duplicate (parity with attach_in_place): a re-scanned
# file that is a byte-dup of an existing image still links its
# post via _apply_sidecar, so a cross-posted image shows on every
# post. Artist is derived from the sidecar here (not yet resolved).
# post.
self._apply_sidecar(
existing, attribution_path, None,
existing, attribution_path, path_artist,
explicit_source=explicit_source,
)
self.session.commit()
@@ -727,7 +736,7 @@ class Importer:
larger = self.session.get(ImageRecord, match_id)
if larger is not None:
self._apply_sidecar(
larger, attribution_path, None,
larger, attribution_path, path_artist,
explicit_source=explicit_source,
)
self.session.commit()
@@ -761,13 +770,11 @@ class Importer:
self.session.flush()
self._phash_cache_append(phash, width, height, record.id)
# Folder→artist (anchored to attribution_path).
artist = None
artist_name = derive_top_level_artist(
attribution_path, self.import_root
)
if artist_name:
artist = self._attach_artist(record, artist_name)
# Folder→artist (path_artist resolved up-front above); bind it to the
# new record so it carries the canonical Artist.
if path_artist is not None and record.artist_id is None:
record.artist_id = path_artist.id
self.session.flush()
# Sidecar provenance (best-effort; never fails the import).
# explicit_source lets the FC-3c download path bind the new
@@ -777,7 +784,7 @@ class Importer:
# subscription-downloaded zip previously lost subscription
# linkage if the on-disk layout didn't match assumptions.
self._apply_sidecar(
record, attribution_path, artist, explicit_source=explicit_source,
record, attribution_path, path_artist, explicit_source=explicit_source,
)
# Thumbnail is queued separately by the calling task; the importer
@@ -1076,17 +1083,6 @@ class Importer:
self.session.flush()
return artist
def _attach_artist(self, record: ImageRecord, artist_name: str) -> Artist:
"""Upsert the Artist and set it as the image's canonical artist.
Artist-kind tags were retired in FC-2d-vii-c — the Artist row is
the single source of truth. Returns the Artist (sidecar
provenance attaches its Source to it)."""
artist = self._upsert_artist(artist_name)
if record.artist_id is None:
record.artist_id = artist.id
self.session.flush()
return artist
@staticmethod
def _sidecar_artist_name(data: dict) -> str | None:
for k in ("artist", "author_name"):