Skip to content

feat: add gallery support to identify task - #6927

Open
slick-daddy wants to merge 20 commits into
stashapp:developfrom
slick-daddy:gallery-identify
Open

feat: add gallery support to identify task#6927
slick-daddy wants to merge 20 commits into
stashapp:developfrom
slick-daddy:gallery-identify

Conversation

@slick-daddy

@slick-daddy slick-daddy commented May 14, 2026

Copy link
Copy Markdown
Contributor

Description

Adds gallery support to the Identify feature, mirroring the existing scene identify pipeline. Galleries can now be identified individually (by selecting them in the gallery list) or in bulk (identify-all mode for unorganized galleries).

Architecture

The gallery identify implementation is a faithful parallel of the scene identify system:

Scene Identify Gallery Identify
SceneIdentifier GalleryIdentifier (internal/identify/gallery.go)
sceneRelationships{studio, performers, tags} galleryRelationships{studio, performers, tags}
SceneUpdatePostHookExecutor GalleryUpdatePostHookExecutor (internal/identify/identify.go)
scraperSource.ScrapeScenes() galleryScraperSource.ScrapeGalleries() (internal/manager/task_identify.go)
SceneIdentifier.Identify() → scrape → getUpdater → modify GalleryIdentifier.Identify() → same 3-step pipeline
identifyAllScenes() (batch query via Scene.Query()) identifyAllGalleries() (batch query via Gallery.Query())
getScenePartial() getGalleryPartial()
SceneUpdateSet/ScenePartial gallery.UpdateSet/GalleryPartial (pkg/gallery/update.go)

Key differences:

  • Gallery identify skips stash-box sources — stash-box does not support gallery scraping, so sources using stash_box_endpoint are logged as warnings and skipped
  • getGalleryPartial() maps ScrapedGallery fields to GalleryPartial: title, code, details, photographer, date, urls, organized

Frontend

  • IdentifyDialog accepts a type prop ("scene" | "gallery")
  • For galleries: filters to gallery-capable scrapers only, omits stash-box sources, passes galleryIDs instead of sceneIDs in the identify input
  • Gallery list overflow menu now includes "Identify…" button (modal opens with type="gallery")

Control Flow (IdentifyJob.Execute())

  1. If GalleryIDs are explicitly provided → identify those galleries
  2. Else if no SceneIDs → identify all unorganized galleries (only if gallery sources exist)
  3. Then identify scenes (if SceneIDs provided, or if no GalleryIDs — preserving the legacy scene-only path)

This ensures scenes are never silently dropped when gallery sources are present.

Test Coverage

13 table-driven tests in internal/manager/task_identify_test.go covering IdentifyJob.Execute() orchestration:

Test Case Scene IDs Gallery IDs Sources Expected
No sources empty No-op
Scene IDs only [1, 2] Both scenes identified
Gallery IDs only [1, 2] Both galleries identified
Both IDs [1] [2] Scene and gallery identified
Scene ID not found [999] Error: "scene with id 999 not found"
Gallery ID not found [999] Error: "gallery with id 999 not found"
Invalid scene ID ["bad"] Error: "invalid scene IDs"
Invalid gallery ID ["bad"] Error: "invalid gallery IDs"
Identify-all, scenes only ✓ (no gallery sources) Scene identified, no gallery query
Identify-all, both types Both scene and gallery identified
Cancellation during gallery IDs [1, 2, 3] ≤ 1 gallery processed
Cancellation during scene IDs [1, 2, 3] ≤ 1 scene processed

The test job uses overridable sourcesFn/gallerySourcesFn/identifySceneFn/identifyGalleryFn fields to avoid global instance dependencies (same pattern used by ScanJob).

Notes

  • No stash-box support — stash-box has no gallery fingerprint search API
  • No cover image handlingScrapedGallery has no Image field

Personal Testing

I am not familiar with galleries and don't use them personally. It would be great to hear some feedback from users who use it. Test coverage has been added logically but user testing is still needed.

@slick-daddy slick-daddy changed the title Gallery identify (feat): add Gallery Identify May 14, 2026
@slick-daddy slick-daddy changed the title (feat): add Gallery Identify feat: add gallery support to identify task Jun 19, 2026
slick-daddy and others added 16 commits June 19, 2026 06:34
…rror, nil ret check, i18n gallery placeholder
1. Fix dead identifyAllGalleries in Execute: when GalleryIDs and SceneIDs
   are both empty, fall through to identifyAllGalleries (mirroring the
   scene pattern with identifyAllScenes).

2. Add post-update hooks to modifyGallery:
   - Define GalleryUpdatePostHookExecutor interface in identify package
   - Add PostHookExecutor field to GalleryIdentifier struct
   - Invoke ExecuteGalleryUpdatePostHooks after successful gallery update
   - Add ExecuteGalleryUpdatePostHooks method to plugin Cache
   - Wire the executor in task_identify.go

3. Disable 'Set as default' button in gallery mode to prevent gallery
   sources from overwriting the shared scene identify defaults slot.
…rType and StashIds resolver

The generated exec file references stash_id fields on ImageFilterType that
did not exist, and requires a StashIds method on imageResolver. Add the
missing fields to the model type and a stub resolver returning nil.
- In getGalleryPartial, replace sliceutil.Exclude check in FieldStrategyOverwrite
  with sliceutil.SliceSame to also detect when gallery URLs should be removed
  (not just added).
- Add explanatory comment to imageResolver.StashIds documenting it is a
  pre-existing stub since the Image model and repository layer do not support
  stash IDs.
The earlier exclusive branching silently dropped scenes when:
1. Both galleryIDs and sceneIDs were provided
2. Identify-all mode with both scene + gallery scrapers configured

Now galleries and scenes run sequentially within a single job,
and redundant getGallerySources() call is avoided when GalleryIDs > 0.
- Add repository field and overridable source/identify function fields
- Replace instance.Repository with j.repository
- Add nil-guard to Progress.updated() to prevent panic in tests
- 13 table-driven tests covering all Execute() orchestration paths:
  no sources, scene IDs, gallery IDs, both IDs, not found,
  invalid IDs, identify-all (scenes/galleries/both), cancellation
@DogmaDragon DogmaDragon added the missing documentation Feature or functionality lacks proper documentation label Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

missing documentation Feature or functionality lacks proper documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants