The three folder image providers #110 did not name #152
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
#110 named seven of upstream's dynamic image providers and closed them. There
are ten. The three it did not name all subclass
BaseFolderImageProvider(
Emby.Server.Implementations/Images/) and all do the same thing: take thefirst child's
Primarypicture and copy it whole, which is theCreateSingleImagepath the box set already goes through here.MusicAlbumImageProvider— the one that matters. An album with no coverof its own is given the first track's, which together with the
AudioImageProvider#110 landed is the whole chain that gives a music libraryartwork: the track's cover art comes out of the file, and the album copies it.
Without this an album stays blank while its tracks do not.
FolderImageProvider— a plain folder, with two exclusions of its own: aPhotoAlbumor aMusicAlbumis somebody else's, and a folder that is a topparent gets none.
PhotoAlbumImageProvider— the same for a photo album.The child chosen is not the first row: the query is
Parent = item, Recursive = true, ImageTypes = [Primary], OrderBy = (IsFolder asc, SortName asc), Limit = 1, so a folder sorts before a file and the namedecides between equals.
One behaviour to port deliberately rather than discover:
HasChangedByDatereturns
falsefor aMusicAlbum, so an album's copied cover is neverconsidered stale by the file's date the way every other one is.
Where to start
jellyfin_app::scan::by_name::copiedandLINKEDare the shape — the box setalready copies a picture whole and files it as
poster<ext>under the item'sown metadata directory. What differs is the source query (children rather than
linked children) and the filename:
ImageSaver.GetStandardSavePathwritesfolder<ext>and notposter<ext>for aMusicAlbum, aMusicArtist, aPhotoAlbumand aPerson.How to know it is done
diff-dbonBaseItemImageInfosover a music library both servers scanned, andthe files compared on bytes — a copy is a copy, so this is one of the few
picture paths where byte equality is available rather than approximate.
It cannot be measured against the fixture as it stands. Registration
disables every image fetcher per type, so upstream draws none of these either;
and nothing in the fixture media carries cover art for an album to copy. Both
are the same precondition #110 left behind — see
reference/README.md.House rules
Tests run under
cargo nextest; upstream's source is the checkout inupstream/at the pin (v12.0-rc5,6d501ba4), not the clone beside therepository. Generated artifacts are regenerated, never edited. A comment says
what the code does, not how it got there.
ARCHITECTURE.mddecides which cratea thing goes in;
DECISIONS.mdsays why a rule exists.Landed in
9a2f8fd.Both providers are the
CreateSingleImagecopy the box set already takes, sowhat went in is the source query and the filename, not new mechanism:
rows_to_illustrate_from_insideandby_name::copied_as.What the port settles
Only two of the three.
PhotoAlbumImageProviderstays absent becausenothing here files a photo album —
Kindhas no such variant.Neither reaches a series, a season or a box set. This was the thing worth
checking before writing anything.
BaseFolderImageProvider<T>is anICustomMetadataProvider<T>,IMetadataProvider<TItemType>is invariant, andProviderManager.RefreshSingleItempicks the metadata service by exact typefirst (
CanRefreshPrimary) — soFolderImageProvider, typedFolder, isoffered only to
FolderMetadataService, which claims a plainFolder. ASeriesgetsSeriesMetadataServiceand never sees it. The issue's framing —"a plain folder, with two exclusions of its own" — is right, and the exclusions
for
PhotoAlbum/MusicAlbuminsideFolderImageProvider.Supportsareunreachable for the same reason.
The directory a library points at is passed over.
IsTopParentis true fora folder whose parent is the
AggregateFolder, which is exactly the physicaldirectory a library covers, so upstream draws nothing for it.
Only the first candidate. The base query is
Parent = item, Recursive = true, ImageTypes = [Primary], OrderBy = (IsFolder asc, SortName asc), Limit = 1, andCreateSingleImagethen filters that one for a local file with anextension. So a row whose first candidate has no extension gets nothing — it
does not fall through to the next, which is the opposite of the box set,
where the whole child list is handed over and filtered afterwards. Both are
reproduced as they are.
The album's exclusion is the reason it is there.
Limit = 1runs before.Where(i => i is not Folder), so the filter only bites when the singlecandidate is a folder — which happens when no file below the album carries a
Primary. Upstream's comment says why: a folder can have been given a collage,and copying that onto the record would be the album wearing another row's
picture.
Where it runs
Directly after the extraction the previous commit landed and before the by-name
pictures. That order is load-bearing in both directions: the cover an album
copies is the one
AudioImageProviderjust took out of its first track, and amusic genre's collage is drawn from what both leave behind.
What is not measured
The same wall #110 left: the fixture disables every image fetcher per library
and per type, so upstream copies nothing there either, and no track in the
fixture media carries cover art for an album to copy. This is measurable
against a pair on a library provisioned with the fetchers on — see
reference/README.mdand the fixture half of #153.HasChangedByDatereturningfalsefor aMusicAlbumis not ported and doesnot need to be: it governs re-drawing, and this server leaves a row that
already carries a picture alone. The note beside that check says so.