Skip to content

feat(search): honest has-preview prop and thumbnails relationship - #3210

Draft
dschmidt wants to merge 9 commits into
feat/thumbnails-raw-embedded-previewfrom
feat/search-preview-presence
Draft

dschmidt wants to merge 9 commits into
feat/thumbnails-raw-embedded-previewfrom
feat/search-preview-presence

Conversation

@dschmidt

@dschmidt dschmidt commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

Makes preview availability honest instead of a blanket mimetype match, and bases the driveItem thumbnails on it.

  • Split the preview types into unconditional ones and those that carry their preview inside the file + HasPreview as the single source of truth (unconditional types follow from the mimetype, an audio cover depends on what the index saw). Both live in services/webdav/pkg/thumbnail now, where webdav owns the type list since Push based thumbnailer architecture #3397.
  • Index the embedded cover: its dimensions and the type it is in, as oc.preview (preferring the front cover).
  • The thumbnail of a cover is written in the cover's own type: webdav reads oc.preview.contentType when it stats the file, so the output type is settled before the cache key is built and a png cover stays a png. Nothing is derived from the image bytes, and the cache keeps its interface.
  • No indexed cover, no preview. Without dimensions and type nothing can say what the thumbnail would be, so webdav answers 404 instead of extracting and guessing a format. The type mapping no longer pins audio to jpeg.
  • Honest oc:has-preview for audio in search results (new preview field on the search message entity).
  • Graph driveItem thumbnails ($expand=thumbnails) are gated on HasPreview and gain a source thumbnail requested at the original size. No thumbnail carries dimensions: the served size snaps to the configured resolution set, not knowable at listing time.

Stacked on #3332, which is what closes the gap this PR used to carry: the preview metadata and the rendered preview now come from the same extraction, so they cannot describe different pictures. What is indexed is what gets rendered.

Removing a cover does not clear an already indexed oc.preview yet. The stale facet cleanup in #3682 only covers the libre.graph. prefix, so whichever of the two merges last has to add oc.preview. to its stale check.

Follow-ups (kept out to stay focused): consolidate the shared-view thumbnail blocks via a generic odata expand-set, and switch reva propfind has-preview to thumbnail.HasPreview.

Note

Even once this PR and #3211 (graph search query endpoint) are both merged, hits from POST /graph/v1beta1/search/query still won't carry thumbnails: the $expand=thumbnails wiring for search hits builds on both PRs and currently only exists on the consolidation branch (dschmidt/opencloud@feat/graph-search-full-2, commit 0d94199a: searchEntityThumbnailSet in searchquery.go, preview presence via thumbnail.HasPreviewForMimeType + indexed oc.preview/image-facet dimensions). It needs a follow-up PR once both are in.

@codacy-production

codacy-production Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 50 complexity

Metric Results
Complexity 50

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from 5748d3c to 8d0b8ed Compare July 30, 2026 18:31
@dschmidt dschmidt changed the title feat(search): honest previews and driveItem thumbnails relationship feat(search): honest has-preview and driveItem thumbnails relationship Jul 30, 2026
@dschmidt dschmidt changed the title feat(search): honest has-preview and driveItem thumbnails relationship feat(search): honest has-preview and thumbnails relationship Jul 30, 2026
@dschmidt dschmidt changed the title feat(search): honest has-preview and thumbnails relationship feat(search): honest has-preview prop and thumbnails relationship Jul 31, 2026
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from 72d4dcb to 3027a39 Compare August 18, 2026 16:36
Comment on lines +11 to +14
const (
PreviewWidthKey = "oc.preview.width"
PreviewHeightKey = "oc.preview.height"
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a single oc.preview property with 200x300 as the dimension. While we do cache the properties in nats, I think splitting by x is more efficient.

@dschmidt dschmidt Aug 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not the biggest fan tbh.

Would need concatenation on the indexing site and parsing on the consuming side, while making querying for it more awkward and require special handling.
I could imagine for my music server it could be nice for some views to query only files with specific (minimal) preview sizes e.g.

If you insist, we can do it.. but I'd prefer not to

@butonic

butonic commented Aug 27, 2026

Copy link
Copy Markdown
Member

Hm ...

I need the availability and dimensions of embedded previews at index time (#3210).

🤔

You mean you need them to be created when indexing (after postprocessing), so they are available during dirlistings?

@dschmidt

Copy link
Copy Markdown
Contributor Author

I need the availability and dimensions of embedded previews at index time (#3210).

You mean you need them to be created when indexing (after postprocessing), so they are available during dirlistings?

Basically, yes - I need the dimensions in ArbitraryMetadata during listings and in the index during search, so I can fill the thumbnails relationship.
It's basically the same as all the other extracted metadata like audio artists, geo data in images, etc.
This was the original motivation to implement the extraction in Tika, so it's completely anologous to the other metadata extraction, because that seemed like a completely natural fit.
The only downside of doing it like this is, that previews for files out of the EmbeddedPreviewMimeTypes group become available only when they have been indexed.

@dschmidt
dschmidt changed the base branch from feat/search-tika-facets to main September 1, 2026 08:44
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch 7 times, most recently from 9de577a to 3bf02cf Compare September 3, 2026 08:25
@dschmidt
dschmidt changed the base branch from main to feat/graph-expand-thumbnails September 6, 2026 21:48
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from 6a65302 to a943a1c Compare October 15, 2026 10:38
@dschmidt
dschmidt removed this pull request from stack #3473 October 15, 2026 14:10
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from a943a1c to 6161356 Compare October 15, 2026 14:21

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be solved more elegantly with the approach in #3332 but this is good enough for an interim step

@dschmidt
dschmidt marked this pull request as ready for review October 15, 2026 15:02
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from 1efe7a7 to e885a92 Compare October 19, 2026 11:34
@dschmidt
dschmidt changed the base branch from main to feat/thumbnails-raw-embedded-preview October 19, 2026 11:34
@dschmidt
dschmidt added this pull request to stack #3759 October 19, 2026 11:44
@dschmidt
dschmidt marked this pull request as draft October 19, 2026 11:45
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from f9e9f67 to fc5835f Compare October 19, 2026 12:57
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from fc5835f to 423df6c Compare October 19, 2026 12:59
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from 423df6c to d5255a8 Compare October 19, 2026 13:05
@dschmidt
dschmidt force-pushed the feat/search-preview-presence branch from d5255a8 to cf223d0 Compare October 19, 2026 13:07
Unconditional types follow from the mimetype, embedded ones (audio cover art) need indexed oc.preview dimensions.
Prefers the front cover. Adds the preview field to the search entity.
oc.preview now carries the cover's own content type next to its dimensions, so
webdav knows before it builds the cache key what a thumbnail of it is written
in: a png cover stays a png instead of being re-encoded to the jpeg the
container's type maps to.
A file that carries its preview inside is only previewable once the extraction
has seen it: dimensions and the type it is in. Without that nothing here could
say what a thumbnail would be, so the mapping no longer pins audio to jpeg and
the workflow refuses instead of guessing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants