Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 41 additions & 16 deletions backend/Api/MoonfinController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -534,31 +534,56 @@ private static string GetTag(ItemImageInfo info)
/// </summary>
private List<BaseItem> GetLibraryItems(List<string>? libraryIds, int limit)
{
var query = new InternalItemsQuery
if (libraryIds is not { Count: > 0 })
{
IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series],
Limit = limit,
Recursive = true
};
// No specific libraries selected — query across all libraries
var query = new InternalItemsQuery
{
IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series],
Limit = limit,
Recursive = true
};
SetRandomOrder(query);
return _libraryManager.GetItemsResult(query).Items.ToList();
}

// Set OrderBy = Random via reflection to avoid compile-time reference to
// SortOrder which moved assemblies between Jellyfin 10.10 and 10.11
SetRandomOrder(query);
// Query each selected library via ParentId (matches user view IDs from getUserViews).
// TopParentIds won't work here — it filters on an internal DB column
// whose values differ from the user-facing view GUIDs.
var allItems = new List<BaseItem>();
var seenIds = new HashSet<Guid>();
var perLibraryLimit = Math.Max(1, limit / libraryIds.Count + 1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

kinda late, sorry, but is per library fairness really what you want?

example:
Library1 - 1000
Library2 - 250
Library3 - 20
Library4 - 10
Library5 - 5

Ideally Library1 should be represented the most. Right now you would have a lot of repeats from small libraries.


if (libraryIds is { Count: > 0 })
foreach (var libId in libraryIds)
{
var parsedIds = libraryIds
.Select(id => Guid.TryParse(id, out var g) ? g : Guid.Empty)
.Where(g => g != Guid.Empty)
.ToArray();
if (!Guid.TryParse(libId, out var parentGuid)) continue;

if (parsedIds.Length > 0)
var query = new InternalItemsQuery
{
IncludeItemTypes = [BaseItemKind.Movie, BaseItemKind.Series],
ParentId = parentGuid,
Limit = perLibraryLimit,
Recursive = true
};
SetRandomOrder(query);

foreach (var item in _libraryManager.GetItemsResult(query).Items)
{
query.TopParentIds = parsedIds;
if (seenIds.Add(item.Id))
{
allItems.Add(item);
}
}
}

return _libraryManager.GetItemsResult(query).Items.ToList();
// Shuffle merged results for fair representation across libraries
for (var i = allItems.Count - 1; i > 0; i--)
{
var j = Random.Shared.Next(i + 1);
(allItems[i], allItems[j]) = (allItems[j], allItems[i]);
}

return allItems.Take(limit).ToList();
}

/// <summary>
Expand Down
Loading