OrderMapper.cs 4.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #pragma warning disable RS0030 // Do not use banned APIs
  2. using System;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using Jellyfin.Data.Enums;
  6. using Jellyfin.Database.Implementations;
  7. using Jellyfin.Database.Implementations.Entities;
  8. using MediaBrowser.Controller.Entities;
  9. using Microsoft.EntityFrameworkCore;
  10. namespace Jellyfin.Server.Implementations.Item;
  11. /// <summary>
  12. /// Static class for methods which maps types of ordering to their respecting ordering functions.
  13. /// </summary>
  14. public static class OrderMapper
  15. {
  16. /// <summary>
  17. /// Creates Func to be executed later with a given BaseItemEntity input for sorting items on query.
  18. /// </summary>
  19. /// <param name="sortBy">Item property to sort by.</param>
  20. /// <param name="query">Context Query.</param>
  21. /// <param name="jellyfinDbContext">Context.</param>
  22. /// <returns>Func to be executed later for sorting query.</returns>
  23. public static Expression<Func<BaseItemEntity, object?>> MapOrderByField(ItemSortBy sortBy, InternalItemsQuery query, JellyfinDbContext jellyfinDbContext)
  24. {
  25. return (sortBy, query.User) switch
  26. {
  27. (ItemSortBy.AirTime, _) => e => e.SortName, // TODO
  28. (ItemSortBy.Runtime, _) => e => e.RunTimeTicks,
  29. (ItemSortBy.Random, _) => e => EF.Functions.Random(),
  30. (ItemSortBy.DatePlayed, _) => e => e.UserData!.FirstOrDefault(f => f.UserId.Equals(query.User!.Id))!.LastPlayedDate,
  31. (ItemSortBy.PlayCount, _) => e => e.UserData!.FirstOrDefault(f => f.UserId.Equals(query.User!.Id))!.PlayCount,
  32. (ItemSortBy.IsFavoriteOrLiked, _) => e => e.UserData!.FirstOrDefault(f => f.UserId.Equals(query.User!.Id))!.IsFavorite,
  33. (ItemSortBy.IsFolder, _) => e => e.IsFolder,
  34. (ItemSortBy.IsPlayed, _) => e => e.UserData!.FirstOrDefault(f => f.UserId.Equals(query.User!.Id))!.Played,
  35. (ItemSortBy.IsUnplayed, _) => e => !e.UserData!.FirstOrDefault(f => f.UserId.Equals(query.User!.Id))!.Played,
  36. (ItemSortBy.DateLastContentAdded, _) => e => e.DateLastMediaAdded,
  37. (ItemSortBy.Artist, _) => e => e.ItemValues!.Where(f => f.ItemValue.Type == ItemValueType.Artist).Select(f => f.ItemValue.CleanValue).FirstOrDefault(),
  38. (ItemSortBy.AlbumArtist, _) => e => e.ItemValues!.Where(f => f.ItemValue.Type == ItemValueType.AlbumArtist).Select(f => f.ItemValue.CleanValue).FirstOrDefault(),
  39. (ItemSortBy.Studio, _) => e => e.ItemValues!.Where(f => f.ItemValue.Type == ItemValueType.Studios).Select(f => f.ItemValue.CleanValue).FirstOrDefault(),
  40. (ItemSortBy.OfficialRating, _) => e => e.InheritedParentalRatingValue,
  41. (ItemSortBy.SeriesSortName, _) => e => e.SeriesName,
  42. (ItemSortBy.Album, _) => e => e.Album,
  43. (ItemSortBy.DateCreated, _) => e => e.DateCreated,
  44. (ItemSortBy.PremiereDate, _) => e => (e.PremiereDate ?? (e.ProductionYear.HasValue ? DateTime.MinValue.AddYears(e.ProductionYear.Value - 1) : null)),
  45. (ItemSortBy.StartDate, _) => e => e.StartDate,
  46. (ItemSortBy.Name, _) => e => e.CleanName,
  47. (ItemSortBy.CommunityRating, _) => e => e.CommunityRating,
  48. (ItemSortBy.ProductionYear, _) => e => e.ProductionYear,
  49. (ItemSortBy.CriticRating, _) => e => e.CriticRating,
  50. (ItemSortBy.VideoBitRate, _) => e => e.TotalBitrate,
  51. (ItemSortBy.ParentIndexNumber, _) => e => e.ParentIndexNumber,
  52. (ItemSortBy.IndexNumber, _) => e => e.IndexNumber,
  53. (ItemSortBy.SeriesDatePlayed, not null) => e =>
  54. jellyfinDbContext.BaseItems
  55. .Where(w => w.SeriesPresentationUniqueKey == e.PresentationUniqueKey)
  56. .Join(jellyfinDbContext.UserData.Where(w => w.UserId == query.User.Id && w.Played), f => f.Id, f => f.ItemId, (item, userData) => userData.LastPlayedDate)
  57. .Max(f => f),
  58. (ItemSortBy.SeriesDatePlayed, null) => e => jellyfinDbContext.BaseItems.Where(w => w.SeriesPresentationUniqueKey == e.PresentationUniqueKey)
  59. .Join(jellyfinDbContext.UserData.Where(w => w.Played), f => f.Id, f => f.ItemId, (item, userData) => userData.LastPlayedDate)
  60. .Max(f => f),
  61. // ItemSortBy.SeriesDatePlayed => e => jellyfinDbContext.UserData
  62. // .Where(u => u.Item!.SeriesPresentationUniqueKey == e.PresentationUniqueKey && u.Played)
  63. // .Max(f => f.LastPlayedDate),
  64. // ItemSortBy.AiredEpisodeOrder => "AiredEpisodeOrder",
  65. _ => e => e.SortName
  66. };
  67. }
  68. }