mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-05-24 02:02:29 -04:00
Naming refactoring and WIP porting of new interface repositories
This commit is contained in:
parent
15bf43e3ad
commit
be48cdd9e9
@ -40,6 +40,7 @@ using Jellyfin.MediaEncoding.Hls.Playlist;
|
|||||||
using Jellyfin.Networking.Manager;
|
using Jellyfin.Networking.Manager;
|
||||||
using Jellyfin.Networking.Udp;
|
using Jellyfin.Networking.Udp;
|
||||||
using Jellyfin.Server.Implementations;
|
using Jellyfin.Server.Implementations;
|
||||||
|
using Jellyfin.Server.Implementations.Item;
|
||||||
using Jellyfin.Server.Implementations.MediaSegments;
|
using Jellyfin.Server.Implementations.MediaSegments;
|
||||||
using MediaBrowser.Common;
|
using MediaBrowser.Common;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
@ -83,7 +84,6 @@ using MediaBrowser.Model.Net;
|
|||||||
using MediaBrowser.Model.Serialization;
|
using MediaBrowser.Model.Serialization;
|
||||||
using MediaBrowser.Model.System;
|
using MediaBrowser.Model.System;
|
||||||
using MediaBrowser.Model.Tasks;
|
using MediaBrowser.Model.Tasks;
|
||||||
using MediaBrowser.Providers.Chapters;
|
|
||||||
using MediaBrowser.Providers.Lyric;
|
using MediaBrowser.Providers.Lyric;
|
||||||
using MediaBrowser.Providers.Manager;
|
using MediaBrowser.Providers.Manager;
|
||||||
using MediaBrowser.Providers.Plugins.Tmdb;
|
using MediaBrowser.Providers.Plugins.Tmdb;
|
||||||
@ -494,7 +494,12 @@ namespace Emby.Server.Implementations
|
|||||||
|
|
||||||
serviceCollection.AddSingleton<IUserDataManager, UserDataManager>();
|
serviceCollection.AddSingleton<IUserDataManager, UserDataManager>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IItemRepository, SqliteItemRepository>();
|
serviceCollection.AddSingleton<IItemRepository, BaseItemRepository>();
|
||||||
|
serviceCollection.AddSingleton<IPeopleRepository, PeopleRepository>();
|
||||||
|
serviceCollection.AddSingleton<IChapterRepository, ChapterRepository>();
|
||||||
|
serviceCollection.AddSingleton<IMediaAttachmentRepository, MediaAttachmentRepository>();
|
||||||
|
serviceCollection.AddSingleton<IMediaStreamRepository, MediaStreamRepository>();
|
||||||
|
serviceCollection.AddSingleton<IItemTypeLookup, ItemTypeLookup>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IMediaEncoder, MediaBrowser.MediaEncoding.Encoder.MediaEncoder>();
|
serviceCollection.AddSingleton<IMediaEncoder, MediaBrowser.MediaEncoding.Encoder.MediaEncoder>();
|
||||||
serviceCollection.AddSingleton<EncodingHelper>();
|
serviceCollection.AddSingleton<EncodingHelper>();
|
||||||
@ -539,8 +544,6 @@ namespace Emby.Server.Implementations
|
|||||||
|
|
||||||
serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
|
serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IChapterManager, ChapterManager>();
|
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
|
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IAuthService, AuthService>();
|
serviceCollection.AddSingleton<IAuthService, AuthService>();
|
||||||
@ -578,8 +581,6 @@ namespace Emby.Server.Implementations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
((SqliteItemRepository)Resolve<IItemRepository>()).Initialize();
|
|
||||||
|
|
||||||
var localizationManager = (LocalizationManager)Resolve<ILocalizationManager>();
|
var localizationManager = (LocalizationManager)Resolve<ILocalizationManager>();
|
||||||
await localizationManager.LoadAll().ConfigureAwait(false);
|
await localizationManager.LoadAll().ConfigureAwait(false);
|
||||||
|
|
||||||
|
139
Emby.Server.Implementations/Data/ItemTypeLookup.cs
Normal file
139
Emby.Server.Implementations/Data/ItemTypeLookup.cs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Channels;
|
||||||
|
using Emby.Server.Implementations.Playlists;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
using MediaBrowser.Controller.Persistence;
|
||||||
|
using MediaBrowser.Controller.Playlists;
|
||||||
|
using MediaBrowser.Model.Querying;
|
||||||
|
|
||||||
|
namespace Jellyfin.Server.Implementations.Item;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides static topic based lookups for the BaseItemKind.
|
||||||
|
/// </summary>
|
||||||
|
public class ItemTypeLookup : IItemTypeLookup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all values of the ItemFields type.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<ItemFields> AllItemFields { get; } = Enum.GetValues<ItemFields>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered Programs.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ProgramTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.Program,
|
||||||
|
BaseItemKind.TvChannel,
|
||||||
|
BaseItemKind.LiveTvProgram,
|
||||||
|
BaseItemKind.LiveTvChannel
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that should be excluded from parent lookup.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ProgramExcludeParentTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.Series,
|
||||||
|
BaseItemKind.Season,
|
||||||
|
BaseItemKind.MusicAlbum,
|
||||||
|
BaseItemKind.MusicArtist,
|
||||||
|
BaseItemKind.PhotoAlbum
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered to be provided by services.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ServiceTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.TvChannel,
|
||||||
|
BaseItemKind.LiveTvChannel
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that have a StartDate.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> StartDateTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.Program,
|
||||||
|
BaseItemKind.LiveTvProgram
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered Series.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> SeriesTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.Book,
|
||||||
|
BaseItemKind.AudioBook,
|
||||||
|
BaseItemKind.Episode,
|
||||||
|
BaseItemKind.Season
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are not to be evaluated for Artists.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ArtistExcludeParentTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.Series,
|
||||||
|
BaseItemKind.Season,
|
||||||
|
BaseItemKind.PhotoAlbum
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered Artists.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ArtistsTypes { get; } =
|
||||||
|
[
|
||||||
|
BaseItemKind.Audio,
|
||||||
|
BaseItemKind.MusicAlbum,
|
||||||
|
BaseItemKind.MusicVideo,
|
||||||
|
BaseItemKind.AudioBook
|
||||||
|
];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets mapping for all BaseItemKinds and their expected serialisaition target.
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<BaseItemKind, string?> BaseItemKindNames { get; } = new Dictionary<BaseItemKind, string?>()
|
||||||
|
{
|
||||||
|
{ BaseItemKind.AggregateFolder, typeof(AggregateFolder).FullName },
|
||||||
|
{ BaseItemKind.Audio, typeof(Audio).FullName },
|
||||||
|
{ BaseItemKind.AudioBook, typeof(AudioBook).FullName },
|
||||||
|
{ BaseItemKind.BasePluginFolder, typeof(BasePluginFolder).FullName },
|
||||||
|
{ BaseItemKind.Book, typeof(Book).FullName },
|
||||||
|
{ BaseItemKind.BoxSet, typeof(BoxSet).FullName },
|
||||||
|
{ BaseItemKind.Channel, typeof(Channel).FullName },
|
||||||
|
{ BaseItemKind.CollectionFolder, typeof(CollectionFolder).FullName },
|
||||||
|
{ BaseItemKind.Episode, typeof(Episode).FullName },
|
||||||
|
{ BaseItemKind.Folder, typeof(Folder).FullName },
|
||||||
|
{ BaseItemKind.Genre, typeof(Genre).FullName },
|
||||||
|
{ BaseItemKind.Movie, typeof(Movie).FullName },
|
||||||
|
{ BaseItemKind.LiveTvChannel, typeof(LiveTvChannel).FullName },
|
||||||
|
{ BaseItemKind.LiveTvProgram, typeof(LiveTvProgram).FullName },
|
||||||
|
{ BaseItemKind.MusicAlbum, typeof(MusicAlbum).FullName },
|
||||||
|
{ BaseItemKind.MusicArtist, typeof(MusicArtist).FullName },
|
||||||
|
{ BaseItemKind.MusicGenre, typeof(MusicGenre).FullName },
|
||||||
|
{ BaseItemKind.MusicVideo, typeof(MusicVideo).FullName },
|
||||||
|
{ BaseItemKind.Person, typeof(Person).FullName },
|
||||||
|
{ BaseItemKind.Photo, typeof(Photo).FullName },
|
||||||
|
{ BaseItemKind.PhotoAlbum, typeof(PhotoAlbum).FullName },
|
||||||
|
{ BaseItemKind.Playlist, typeof(Playlist).FullName },
|
||||||
|
{ BaseItemKind.PlaylistsFolder, typeof(PlaylistsFolder).FullName },
|
||||||
|
{ BaseItemKind.Season, typeof(Season).FullName },
|
||||||
|
{ BaseItemKind.Series, typeof(Series).FullName },
|
||||||
|
{ BaseItemKind.Studio, typeof(Studio).FullName },
|
||||||
|
{ BaseItemKind.Trailer, typeof(Trailer).FullName },
|
||||||
|
{ BaseItemKind.TvChannel, typeof(LiveTvChannel).FullName },
|
||||||
|
{ BaseItemKind.TvProgram, typeof(LiveTvProgram).FullName },
|
||||||
|
{ BaseItemKind.UserRootFolder, typeof(UserRootFolder).FullName },
|
||||||
|
{ BaseItemKind.UserView, typeof(UserView).FullName },
|
||||||
|
{ BaseItemKind.Video, typeof(Video).FullName },
|
||||||
|
{ BaseItemKind.Year, typeof(Year).FullName }
|
||||||
|
}.AsReadOnly();
|
||||||
|
}
|
@ -28,7 +28,7 @@ namespace Emby.Server.Implementations.MediaEncoder
|
|||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILogger<EncodingManager> _logger;
|
private readonly ILogger<EncodingManager> _logger;
|
||||||
private readonly IMediaEncoder _encoder;
|
private readonly IMediaEncoder _encoder;
|
||||||
private readonly IChapterManager _chapterManager;
|
private readonly IChapterRepository _chapterManager;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.MediaEncoder
|
|||||||
ILogger<EncodingManager> logger,
|
ILogger<EncodingManager> logger,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
IMediaEncoder encoder,
|
IMediaEncoder encoder,
|
||||||
IChapterManager chapterManager,
|
IChapterRepository chapterManager,
|
||||||
ILibraryManager libraryManager)
|
ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
@ -13,7 +13,7 @@ public class AncestorId
|
|||||||
|
|
||||||
public Guid ItemId { get; set; }
|
public Guid ItemId { get; set; }
|
||||||
|
|
||||||
public required BaseItem Item { get; set; }
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
public string? AncestorIdText { get; set; }
|
public string? AncestorIdText { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ public class AttachmentStreamInfo
|
|||||||
{
|
{
|
||||||
public required Guid ItemId { get; set; }
|
public required Guid ItemId { get; set; }
|
||||||
|
|
||||||
public required BaseItem Item { get; set; }
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
public required int Index { get; set; }
|
public required int Index { get; set; }
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
namespace Jellyfin.Data.Entities;
|
namespace Jellyfin.Data.Entities;
|
||||||
|
|
||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
public class BaseItem
|
public class BaseItemEntity
|
||||||
{
|
{
|
||||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||||
|
|
||||||
@ -160,6 +160,7 @@ public class BaseItem
|
|||||||
|
|
||||||
public long? Size { get; set; }
|
public long? Size { get; set; }
|
||||||
|
|
||||||
|
#pragma warning disable CA2227 // Collection properties should be read only
|
||||||
public ICollection<People>? Peoples { get; set; }
|
public ICollection<People>? Peoples { get; set; }
|
||||||
|
|
||||||
public ICollection<UserData>? UserData { get; set; }
|
public ICollection<UserData>? UserData { get; set; }
|
@ -5,11 +5,28 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
namespace Jellyfin.Data.Entities;
|
namespace Jellyfin.Data.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an Key-Value relaten of an BaseItem's provider.
|
||||||
|
/// </summary>
|
||||||
public class BaseItemProvider
|
public class BaseItemProvider
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the reference ItemId.
|
||||||
|
/// </summary>
|
||||||
public Guid ItemId { get; set; }
|
public Guid ItemId { get; set; }
|
||||||
public required BaseItem Item { get; set; }
|
|
||||||
|
|
||||||
public string ProviderId { get; set; }
|
/// <summary>
|
||||||
public string ProviderValue { get; set; }
|
/// Gets or Sets the reference BaseItem.
|
||||||
|
/// </summary>
|
||||||
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the ProvidersId.
|
||||||
|
/// </summary>
|
||||||
|
public required string ProviderId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the Providers Value.
|
||||||
|
/// </summary>
|
||||||
|
public required string ProviderValue { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ public class Chapter
|
|||||||
{
|
{
|
||||||
public Guid ItemId { get; set; }
|
public Guid ItemId { get; set; }
|
||||||
|
|
||||||
public required BaseItem Item { get; set; }
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
public required int ChapterIndex { get; set; }
|
public required int ChapterIndex { get; set; }
|
||||||
|
|
||||||
|
@ -5,12 +5,33 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
namespace Jellyfin.Data.Entities;
|
namespace Jellyfin.Data.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an ItemValue for a BaseItem.
|
||||||
|
/// </summary>
|
||||||
public class ItemValue
|
public class ItemValue
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the reference ItemId.
|
||||||
|
/// </summary>
|
||||||
public Guid ItemId { get; set; }
|
public Guid ItemId { get; set; }
|
||||||
public required BaseItem Item { get; set; }
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the referenced BaseItem.
|
||||||
|
/// </summary>
|
||||||
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the Type.
|
||||||
|
/// </summary>
|
||||||
public required int Type { get; set; }
|
public required int Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the Value.
|
||||||
|
/// </summary>
|
||||||
public required string Value { get; set; }
|
public required string Value { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the sanatised Value.
|
||||||
|
/// </summary>
|
||||||
public required string CleanValue { get; set; }
|
public required string CleanValue { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ public class MediaStreamInfo
|
|||||||
{
|
{
|
||||||
public Guid ItemId { get; set; }
|
public Guid ItemId { get; set; }
|
||||||
|
|
||||||
public required BaseItem Item { get; set; }
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
public int StreamIndex { get; set; }
|
public int StreamIndex { get; set; }
|
||||||
|
|
||||||
|
@ -4,14 +4,44 @@ using System.ComponentModel.DataAnnotations;
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Jellyfin.Data.Entities;
|
namespace Jellyfin.Data.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// People entity.
|
||||||
|
/// </summary>
|
||||||
public class People
|
public class People
|
||||||
{
|
{
|
||||||
public Guid ItemId { get; set; }
|
/// <summary>
|
||||||
public BaseItem Item { get; set; }
|
/// Gets or Sets The ItemId.
|
||||||
|
/// </summary>
|
||||||
|
public required Guid ItemId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets Reference Item.
|
||||||
|
/// </summary>
|
||||||
|
public required BaseItemEntity Item { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the Persons Name.
|
||||||
|
/// </summary>
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the Role.
|
||||||
|
/// </summary>
|
||||||
public string? Role { get; set; }
|
public string? Role { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the Type.
|
||||||
|
/// </summary>
|
||||||
public string? PersonType { get; set; }
|
public string? PersonType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the SortOrder.
|
||||||
|
/// </summary>
|
||||||
public int? SortOrder { get; set; }
|
public int? SortOrder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or Sets the ListOrder.
|
||||||
|
/// </summary>
|
||||||
public int? ListOrder { get; set; }
|
public int? ListOrder { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -24,112 +24,23 @@ using MediaBrowser.Model.Entities;
|
|||||||
using MediaBrowser.Model.LiveTv;
|
using MediaBrowser.Model.LiveTv;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Internal;
|
|
||||||
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
|
|
||||||
using BaseItemDto = MediaBrowser.Controller.Entities.BaseItem;
|
using BaseItemDto = MediaBrowser.Controller.Entities.BaseItem;
|
||||||
using BaseItemEntity = Jellyfin.Data.Entities.BaseItem;
|
using BaseItemEntity = Jellyfin.Data.Entities.BaseItemEntity;
|
||||||
|
|
||||||
namespace Jellyfin.Server.Implementations.Item;
|
namespace Jellyfin.Server.Implementations.Item;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles all storage logic for BaseItems.
|
/// Handles all storage logic for BaseItems.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class BaseItemManager : IItemRepository, IDisposable
|
/// <remarks>
|
||||||
|
/// Initializes a new instance of the <see cref="BaseItemRepository"/> class.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="dbProvider">The db factory.</param>
|
||||||
|
/// <param name="appHost">The Application host.</param>
|
||||||
|
/// <param name="itemTypeLookup">The static type lookup.</param>
|
||||||
|
public sealed class BaseItemRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IServerApplicationHost appHost, IItemTypeLookup itemTypeLookup)
|
||||||
|
: IItemRepository, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
|
|
||||||
private readonly IServerApplicationHost _appHost;
|
|
||||||
|
|
||||||
private readonly ItemFields[] _allItemFields = Enum.GetValues<ItemFields>();
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _programTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.Program,
|
|
||||||
BaseItemKind.TvChannel,
|
|
||||||
BaseItemKind.LiveTvProgram,
|
|
||||||
BaseItemKind.LiveTvChannel
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _programExcludeParentTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.Series,
|
|
||||||
BaseItemKind.Season,
|
|
||||||
BaseItemKind.MusicAlbum,
|
|
||||||
BaseItemKind.MusicArtist,
|
|
||||||
BaseItemKind.PhotoAlbum
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _serviceTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.TvChannel,
|
|
||||||
BaseItemKind.LiveTvChannel
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _startDateTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.Program,
|
|
||||||
BaseItemKind.LiveTvProgram
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _seriesTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.Book,
|
|
||||||
BaseItemKind.AudioBook,
|
|
||||||
BaseItemKind.Episode,
|
|
||||||
BaseItemKind.Season
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _artistExcludeParentTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.Series,
|
|
||||||
BaseItemKind.Season,
|
|
||||||
BaseItemKind.PhotoAlbum
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly BaseItemKind[] _artistsTypes = new[]
|
|
||||||
{
|
|
||||||
BaseItemKind.Audio,
|
|
||||||
BaseItemKind.MusicAlbum,
|
|
||||||
BaseItemKind.MusicVideo,
|
|
||||||
BaseItemKind.AudioBook
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly Dictionary<BaseItemKind, string?> _baseItemKindNames = new()
|
|
||||||
{
|
|
||||||
{ BaseItemKind.AggregateFolder, typeof(AggregateFolder).FullName },
|
|
||||||
{ BaseItemKind.Audio, typeof(Audio).FullName },
|
|
||||||
{ BaseItemKind.AudioBook, typeof(AudioBook).FullName },
|
|
||||||
{ BaseItemKind.BasePluginFolder, typeof(BasePluginFolder).FullName },
|
|
||||||
{ BaseItemKind.Book, typeof(Book).FullName },
|
|
||||||
{ BaseItemKind.BoxSet, typeof(BoxSet).FullName },
|
|
||||||
{ BaseItemKind.Channel, typeof(Channel).FullName },
|
|
||||||
{ BaseItemKind.CollectionFolder, typeof(CollectionFolder).FullName },
|
|
||||||
{ BaseItemKind.Episode, typeof(Episode).FullName },
|
|
||||||
{ BaseItemKind.Folder, typeof(Folder).FullName },
|
|
||||||
{ BaseItemKind.Genre, typeof(Genre).FullName },
|
|
||||||
{ BaseItemKind.Movie, typeof(Movie).FullName },
|
|
||||||
{ BaseItemKind.LiveTvChannel, typeof(LiveTvChannel).FullName },
|
|
||||||
{ BaseItemKind.LiveTvProgram, typeof(LiveTvProgram).FullName },
|
|
||||||
{ BaseItemKind.MusicAlbum, typeof(MusicAlbum).FullName },
|
|
||||||
{ BaseItemKind.MusicArtist, typeof(MusicArtist).FullName },
|
|
||||||
{ BaseItemKind.MusicGenre, typeof(MusicGenre).FullName },
|
|
||||||
{ BaseItemKind.MusicVideo, typeof(MusicVideo).FullName },
|
|
||||||
{ BaseItemKind.Person, typeof(Person).FullName },
|
|
||||||
{ BaseItemKind.Photo, typeof(Photo).FullName },
|
|
||||||
{ BaseItemKind.PhotoAlbum, typeof(PhotoAlbum).FullName },
|
|
||||||
{ BaseItemKind.Playlist, typeof(Playlist).FullName },
|
|
||||||
{ BaseItemKind.PlaylistsFolder, typeof(PlaylistsFolder).FullName },
|
|
||||||
{ BaseItemKind.Season, typeof(Season).FullName },
|
|
||||||
{ BaseItemKind.Series, typeof(Series).FullName },
|
|
||||||
{ BaseItemKind.Studio, typeof(Studio).FullName },
|
|
||||||
{ BaseItemKind.Trailer, typeof(Trailer).FullName },
|
|
||||||
{ BaseItemKind.TvChannel, typeof(LiveTvChannel).FullName },
|
|
||||||
{ BaseItemKind.TvProgram, typeof(LiveTvProgram).FullName },
|
|
||||||
{ BaseItemKind.UserRootFolder, typeof(UserRootFolder).FullName },
|
|
||||||
{ BaseItemKind.UserView, typeof(UserView).FullName },
|
|
||||||
{ BaseItemKind.Video, typeof(Video).FullName },
|
|
||||||
{ BaseItemKind.Year, typeof(Year).FullName }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This holds all the types in the running assemblies
|
/// This holds all the types in the running assemblies
|
||||||
/// so that we can de-serialize properly when we don't have strong types.
|
/// so that we can de-serialize properly when we don't have strong types.
|
||||||
@ -137,17 +48,6 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
private static readonly ConcurrentDictionary<string, Type?> _typeMap = new ConcurrentDictionary<string, Type?>();
|
private static readonly ConcurrentDictionary<string, Type?> _typeMap = new ConcurrentDictionary<string, Type?>();
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="BaseItemManager"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbProvider">The db factory.</param>
|
|
||||||
/// <param name="appHost">The Application host.</param>
|
|
||||||
public BaseItemManager(IDbContextFactory<JellyfinDbContext> dbProvider, IServerApplicationHost appHost)
|
|
||||||
{
|
|
||||||
_dbProvider = dbProvider;
|
|
||||||
_appHost = appHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
@ -159,124 +59,12 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery filter, int[] itemValueTypes, string returnType)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(filter);
|
|
||||||
|
|
||||||
if (!filter.Limit.HasValue)
|
|
||||||
{
|
|
||||||
filter.EnableTotalRecordCount = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
|
||||||
|
|
||||||
var innerQuery = new InternalItemsQuery(filter.User)
|
|
||||||
{
|
|
||||||
ExcludeItemTypes = filter.ExcludeItemTypes,
|
|
||||||
IncludeItemTypes = filter.IncludeItemTypes,
|
|
||||||
MediaTypes = filter.MediaTypes,
|
|
||||||
AncestorIds = filter.AncestorIds,
|
|
||||||
ItemIds = filter.ItemIds,
|
|
||||||
TopParentIds = filter.TopParentIds,
|
|
||||||
ParentId = filter.ParentId,
|
|
||||||
IsAiring = filter.IsAiring,
|
|
||||||
IsMovie = filter.IsMovie,
|
|
||||||
IsSports = filter.IsSports,
|
|
||||||
IsKids = filter.IsKids,
|
|
||||||
IsNews = filter.IsNews,
|
|
||||||
IsSeries = filter.IsSeries
|
|
||||||
};
|
|
||||||
var query = TranslateQuery(context.BaseItems, context, innerQuery);
|
|
||||||
|
|
||||||
query = query.Where(e => e.Type == returnType && e.ItemValues!.Any(f => e.CleanName == f.CleanValue && itemValueTypes.Contains(f.Type)));
|
|
||||||
|
|
||||||
var outerQuery = new InternalItemsQuery(filter.User)
|
|
||||||
{
|
|
||||||
IsPlayed = filter.IsPlayed,
|
|
||||||
IsFavorite = filter.IsFavorite,
|
|
||||||
IsFavoriteOrLiked = filter.IsFavoriteOrLiked,
|
|
||||||
IsLiked = filter.IsLiked,
|
|
||||||
IsLocked = filter.IsLocked,
|
|
||||||
NameLessThan = filter.NameLessThan,
|
|
||||||
NameStartsWith = filter.NameStartsWith,
|
|
||||||
NameStartsWithOrGreater = filter.NameStartsWithOrGreater,
|
|
||||||
Tags = filter.Tags,
|
|
||||||
OfficialRatings = filter.OfficialRatings,
|
|
||||||
StudioIds = filter.StudioIds,
|
|
||||||
GenreIds = filter.GenreIds,
|
|
||||||
Genres = filter.Genres,
|
|
||||||
Years = filter.Years,
|
|
||||||
NameContains = filter.NameContains,
|
|
||||||
SearchTerm = filter.SearchTerm,
|
|
||||||
SimilarTo = filter.SimilarTo,
|
|
||||||
ExcludeItemIds = filter.ExcludeItemIds
|
|
||||||
};
|
|
||||||
query = TranslateQuery(query, context, outerQuery)
|
|
||||||
.OrderBy(e => e.PresentationUniqueKey);
|
|
||||||
|
|
||||||
if (filter.OrderBy.Count != 0
|
|
||||||
|| filter.SimilarTo is not null
|
|
||||||
|| !string.IsNullOrEmpty(filter.SearchTerm))
|
|
||||||
{
|
|
||||||
query = ApplyOrder(query, filter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
query = query.OrderBy(e => e.SortName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
|
|
||||||
{
|
|
||||||
var offset = filter.StartIndex ?? 0;
|
|
||||||
|
|
||||||
if (offset > 0)
|
|
||||||
{
|
|
||||||
query = query.Skip(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.Limit.HasValue)
|
|
||||||
{
|
|
||||||
query.Take(filter.Limit.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new QueryResult<(BaseItem, ItemCounts)>();
|
|
||||||
string countText = string.Empty;
|
|
||||||
if (filter.EnableTotalRecordCount)
|
|
||||||
{
|
|
||||||
result.TotalRecordCount = query.DistinctBy(e => e.PresentationUniqueKey).Count();
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultQuery = query.Select(e => new
|
|
||||||
{
|
|
||||||
item = e,
|
|
||||||
itemCount = new ItemCounts()
|
|
||||||
{
|
|
||||||
SeriesCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Series),
|
|
||||||
EpisodeCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Episode),
|
|
||||||
MovieCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Movie),
|
|
||||||
AlbumCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.MusicAlbum),
|
|
||||||
ArtistCount = e.ItemValues!.Count(e => e.Type == 0 || e.Type == 1),
|
|
||||||
SongCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.MusicAlbum),
|
|
||||||
TrailerCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Trailer),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
result.StartIndex = filter.StartIndex ?? 0;
|
|
||||||
result.Items = resultQuery.ToImmutableArray().Select(e =>
|
|
||||||
{
|
|
||||||
return (DeserialiseBaseItem(e.item), e.itemCount);
|
|
||||||
}).ToImmutableArray();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void DeleteItem(Guid id)
|
public void DeleteItem(Guid id)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(id.IsEmpty() ? null : id);
|
ArgumentNullException.ThrowIfNull(id.IsEmpty() ? null : id);
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
using var transaction = context.Database.BeginTransaction();
|
using var transaction = context.Database.BeginTransaction();
|
||||||
context.Peoples.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
|
context.Peoples.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
|
||||||
context.Chapters.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
|
context.Chapters.Where(e => e.ItemId.Equals(id)).ExecuteDelete();
|
||||||
@ -291,7 +79,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void UpdateInheritedValues()
|
public void UpdateInheritedValues()
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
using var transaction = context.Database.BeginTransaction();
|
using var transaction = context.Database.BeginTransaction();
|
||||||
|
|
||||||
context.ItemValues.Where(e => e.Type == 6).ExecuteDelete();
|
context.ItemValues.Where(e => e.Type == 6).ExecuteDelete();
|
||||||
@ -324,7 +112,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
ArgumentNullException.ThrowIfNull(filter);
|
ArgumentNullException.ThrowIfNull(filter);
|
||||||
PrepareFilterQuery(filter);
|
PrepareFilterQuery(filter);
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
var dbQuery = TranslateQuery(context.BaseItems.AsNoTracking(), context, filter)
|
var dbQuery = TranslateQuery(context.BaseItems.AsNoTracking(), context, filter)
|
||||||
.DistinctBy(e => e.Id);
|
.DistinctBy(e => e.Id);
|
||||||
|
|
||||||
@ -352,56 +140,56 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery filter)
|
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery filter)
|
||||||
{
|
{
|
||||||
return GetItemValues(filter, new[] { 0, 1 }, typeof(MusicArtist).FullName!);
|
return GetItemValues(filter, [0, 1], typeof(MusicArtist).FullName!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery filter)
|
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery filter)
|
||||||
{
|
{
|
||||||
return GetItemValues(filter, new[] { 0 }, typeof(MusicArtist).FullName!);
|
return GetItemValues(filter, [0], typeof(MusicArtist).FullName!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery filter)
|
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery filter)
|
||||||
{
|
{
|
||||||
return GetItemValues(filter, new[] { 1 }, typeof(MusicArtist).FullName!);
|
return GetItemValues(filter, [1], typeof(MusicArtist).FullName!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery filter)
|
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery filter)
|
||||||
{
|
{
|
||||||
return GetItemValues(filter, new[] { 3 }, typeof(Studio).FullName!);
|
return GetItemValues(filter, [3], typeof(Studio).FullName!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery filter)
|
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery filter)
|
||||||
{
|
{
|
||||||
return GetItemValues(filter, new[] { 2 }, typeof(Genre).FullName!);
|
return GetItemValues(filter, [2], typeof(Genre).FullName!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery filter)
|
public QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery filter)
|
||||||
{
|
{
|
||||||
return GetItemValues(filter, new[] { 2 }, typeof(MusicGenre).FullName!);
|
return GetItemValues(filter, [2], typeof(MusicGenre).FullName!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IReadOnlyList<string> GetStudioNames()
|
public IReadOnlyList<string> GetStudioNames()
|
||||||
{
|
{
|
||||||
return GetItemValueNames(new[] { 3 }, Array.Empty<string>(), Array.Empty<string>());
|
return GetItemValueNames([3], Array.Empty<string>(), Array.Empty<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IReadOnlyList<string> GetAllArtistNames()
|
public IReadOnlyList<string> GetAllArtistNames()
|
||||||
{
|
{
|
||||||
return GetItemValueNames(new[] { 0, 1 }, Array.Empty<string>(), Array.Empty<string>());
|
return GetItemValueNames([0, 1], Array.Empty<string>(), Array.Empty<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IReadOnlyList<string> GetMusicGenreNames()
|
public IReadOnlyList<string> GetMusicGenreNames()
|
||||||
{
|
{
|
||||||
return GetItemValueNames(
|
return GetItemValueNames(
|
||||||
new[] { 2 },
|
[2],
|
||||||
new string[]
|
new string[]
|
||||||
{
|
{
|
||||||
typeof(Audio).FullName!,
|
typeof(Audio).FullName!,
|
||||||
@ -416,7 +204,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
public IReadOnlyList<string> GetGenreNames()
|
public IReadOnlyList<string> GetGenreNames()
|
||||||
{
|
{
|
||||||
return GetItemValueNames(
|
return GetItemValueNames(
|
||||||
new[] { 2 },
|
[2],
|
||||||
Array.Empty<string>(),
|
Array.Empty<string>(),
|
||||||
new string[]
|
new string[]
|
||||||
{
|
{
|
||||||
@ -443,7 +231,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
PrepareFilterQuery(filter);
|
PrepareFilterQuery(filter);
|
||||||
var result = new QueryResult<BaseItemDto>();
|
var result = new QueryResult<BaseItemDto>();
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
var dbQuery = TranslateQuery(context.BaseItems, context, filter)
|
var dbQuery = TranslateQuery(context.BaseItems, context, filter)
|
||||||
.DistinctBy(e => e.Id);
|
.DistinctBy(e => e.Id);
|
||||||
if (filter.EnableTotalRecordCount)
|
if (filter.EnableTotalRecordCount)
|
||||||
@ -477,7 +265,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
ArgumentNullException.ThrowIfNull(filter);
|
ArgumentNullException.ThrowIfNull(filter);
|
||||||
PrepareFilterQuery(filter);
|
PrepareFilterQuery(filter);
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
var dbQuery = TranslateQuery(context.BaseItems, context, filter)
|
var dbQuery = TranslateQuery(context.BaseItems, context, filter)
|
||||||
.DistinctBy(e => e.Id);
|
.DistinctBy(e => e.Id);
|
||||||
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
|
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
|
||||||
@ -505,7 +293,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
// Hack for right now since we currently don't support filtering out these duplicates within a query
|
// Hack for right now since we currently don't support filtering out these duplicates within a query
|
||||||
PrepareFilterQuery(filter);
|
PrepareFilterQuery(filter);
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
var dbQuery = TranslateQuery(context.BaseItems, context, filter);
|
var dbQuery = TranslateQuery(context.BaseItems, context, filter);
|
||||||
|
|
||||||
return dbQuery.Count();
|
return dbQuery.Count();
|
||||||
@ -646,7 +434,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
var excludeTypes = filter.ExcludeItemTypes;
|
var excludeTypes = filter.ExcludeItemTypes;
|
||||||
if (excludeTypes.Length == 1)
|
if (excludeTypes.Length == 1)
|
||||||
{
|
{
|
||||||
if (_baseItemKindNames.TryGetValue(excludeTypes[0], out var excludeTypeName))
|
if (itemTypeLookup.BaseItemKindNames.TryGetValue(excludeTypes[0], out var excludeTypeName))
|
||||||
{
|
{
|
||||||
baseQuery = baseQuery.Where(e => e.Type != excludeTypeName);
|
baseQuery = baseQuery.Where(e => e.Type != excludeTypeName);
|
||||||
}
|
}
|
||||||
@ -656,7 +444,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
var excludeTypeName = new List<string>();
|
var excludeTypeName = new List<string>();
|
||||||
foreach (var excludeType in excludeTypes)
|
foreach (var excludeType in excludeTypes)
|
||||||
{
|
{
|
||||||
if (_baseItemKindNames.TryGetValue(excludeType, out var baseItemKindName))
|
if (itemTypeLookup.BaseItemKindNames.TryGetValue(excludeType, out var baseItemKindName))
|
||||||
{
|
{
|
||||||
excludeTypeName.Add(baseItemKindName!);
|
excludeTypeName.Add(baseItemKindName!);
|
||||||
}
|
}
|
||||||
@ -667,7 +455,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
}
|
}
|
||||||
else if (includeTypes.Length == 1)
|
else if (includeTypes.Length == 1)
|
||||||
{
|
{
|
||||||
if (_baseItemKindNames.TryGetValue(includeTypes[0], out var includeTypeName))
|
if (itemTypeLookup.BaseItemKindNames.TryGetValue(includeTypes[0], out var includeTypeName))
|
||||||
{
|
{
|
||||||
baseQuery = baseQuery.Where(e => e.Type == includeTypeName);
|
baseQuery = baseQuery.Where(e => e.Type == includeTypeName);
|
||||||
}
|
}
|
||||||
@ -677,7 +465,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
var includeTypeName = new List<string>();
|
var includeTypeName = new List<string>();
|
||||||
foreach (var includeType in includeTypes)
|
foreach (var includeType in includeTypes)
|
||||||
{
|
{
|
||||||
if (_baseItemKindNames.TryGetValue(includeType, out var baseItemKindName))
|
if (itemTypeLookup.BaseItemKindNames.TryGetValue(includeType, out var baseItemKindName))
|
||||||
{
|
{
|
||||||
includeTypeName.Add(baseItemKindName!);
|
includeTypeName.Add(baseItemKindName!);
|
||||||
}
|
}
|
||||||
@ -1421,7 +1209,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
ArgumentNullException.ThrowIfNull(item);
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
|
|
||||||
var images = SerializeImages(item.ImageInfos);
|
var images = SerializeImages(item.ImageInfos);
|
||||||
using var db = _dbProvider.CreateDbContext();
|
using var db = dbProvider.CreateDbContext();
|
||||||
|
|
||||||
db.BaseItems
|
db.BaseItems
|
||||||
.Where(e => e.Id.Equals(item.Id))
|
.Where(e => e.Id.Equals(item.Id))
|
||||||
@ -1457,7 +1245,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
tuples[i] = (item, ancestorIds, topParent, userdataKey, inheritedTags);
|
tuples[i] = (item, ancestorIds, topParent, userdataKey, inheritedTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
foreach (var item in tuples)
|
foreach (var item in tuples)
|
||||||
{
|
{
|
||||||
var entity = Map(item.Item);
|
var entity = Map(item.Item);
|
||||||
@ -1501,7 +1289,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
throw new ArgumentException("Guid can't be empty", nameof(id));
|
throw new ArgumentException("Guid can't be empty", nameof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
var item = context.BaseItems.FirstOrDefault(e => e.Id.Equals(id));
|
var item = context.BaseItems.FirstOrDefault(e => e.Id.Equals(id));
|
||||||
if (item is null)
|
if (item is null)
|
||||||
{
|
{
|
||||||
@ -1832,7 +1620,7 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
|
|
||||||
private IReadOnlyList<string> GetItemValueNames(int[] itemValueTypes, IReadOnlyList<string> withItemTypes, IReadOnlyList<string> excludeItemTypes)
|
private IReadOnlyList<string> GetItemValueNames(int[] itemValueTypes, IReadOnlyList<string> withItemTypes, IReadOnlyList<string> excludeItemTypes)
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = dbProvider.CreateDbContext();
|
||||||
|
|
||||||
var query = context.ItemValues
|
var query = context.ItemValues
|
||||||
.Where(e => itemValueTypes.Contains(e.Type));
|
.Where(e => itemValueTypes.Contains(e.Type));
|
||||||
@ -1857,6 +1645,118 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
return Map(baseItemEntity, dto);
|
return Map(baseItemEntity, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private QueryResult<(BaseItemDto Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery filter, int[] itemValueTypes, string returnType)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(filter);
|
||||||
|
|
||||||
|
if (!filter.Limit.HasValue)
|
||||||
|
{
|
||||||
|
filter.EnableTotalRecordCount = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var context = dbProvider.CreateDbContext();
|
||||||
|
|
||||||
|
var innerQuery = new InternalItemsQuery(filter.User)
|
||||||
|
{
|
||||||
|
ExcludeItemTypes = filter.ExcludeItemTypes,
|
||||||
|
IncludeItemTypes = filter.IncludeItemTypes,
|
||||||
|
MediaTypes = filter.MediaTypes,
|
||||||
|
AncestorIds = filter.AncestorIds,
|
||||||
|
ItemIds = filter.ItemIds,
|
||||||
|
TopParentIds = filter.TopParentIds,
|
||||||
|
ParentId = filter.ParentId,
|
||||||
|
IsAiring = filter.IsAiring,
|
||||||
|
IsMovie = filter.IsMovie,
|
||||||
|
IsSports = filter.IsSports,
|
||||||
|
IsKids = filter.IsKids,
|
||||||
|
IsNews = filter.IsNews,
|
||||||
|
IsSeries = filter.IsSeries
|
||||||
|
};
|
||||||
|
var query = TranslateQuery(context.BaseItems, context, innerQuery);
|
||||||
|
|
||||||
|
query = query.Where(e => e.Type == returnType && e.ItemValues!.Any(f => e.CleanName == f.CleanValue && itemValueTypes.Contains(f.Type)));
|
||||||
|
|
||||||
|
var outerQuery = new InternalItemsQuery(filter.User)
|
||||||
|
{
|
||||||
|
IsPlayed = filter.IsPlayed,
|
||||||
|
IsFavorite = filter.IsFavorite,
|
||||||
|
IsFavoriteOrLiked = filter.IsFavoriteOrLiked,
|
||||||
|
IsLiked = filter.IsLiked,
|
||||||
|
IsLocked = filter.IsLocked,
|
||||||
|
NameLessThan = filter.NameLessThan,
|
||||||
|
NameStartsWith = filter.NameStartsWith,
|
||||||
|
NameStartsWithOrGreater = filter.NameStartsWithOrGreater,
|
||||||
|
Tags = filter.Tags,
|
||||||
|
OfficialRatings = filter.OfficialRatings,
|
||||||
|
StudioIds = filter.StudioIds,
|
||||||
|
GenreIds = filter.GenreIds,
|
||||||
|
Genres = filter.Genres,
|
||||||
|
Years = filter.Years,
|
||||||
|
NameContains = filter.NameContains,
|
||||||
|
SearchTerm = filter.SearchTerm,
|
||||||
|
SimilarTo = filter.SimilarTo,
|
||||||
|
ExcludeItemIds = filter.ExcludeItemIds
|
||||||
|
};
|
||||||
|
query = TranslateQuery(query, context, outerQuery)
|
||||||
|
.OrderBy(e => e.PresentationUniqueKey);
|
||||||
|
|
||||||
|
if (filter.OrderBy.Count != 0
|
||||||
|
|| filter.SimilarTo is not null
|
||||||
|
|| !string.IsNullOrEmpty(filter.SearchTerm))
|
||||||
|
{
|
||||||
|
query = ApplyOrder(query, filter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query = query.OrderBy(e => e.SortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
|
||||||
|
{
|
||||||
|
var offset = filter.StartIndex ?? 0;
|
||||||
|
|
||||||
|
if (offset > 0)
|
||||||
|
{
|
||||||
|
query = query.Skip(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.Limit.HasValue)
|
||||||
|
{
|
||||||
|
query.Take(filter.Limit.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new QueryResult<(BaseItem, ItemCounts)>();
|
||||||
|
string countText = string.Empty;
|
||||||
|
if (filter.EnableTotalRecordCount)
|
||||||
|
{
|
||||||
|
result.TotalRecordCount = query.DistinctBy(e => e.PresentationUniqueKey).Count();
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultQuery = query.Select(e => new
|
||||||
|
{
|
||||||
|
item = e,
|
||||||
|
itemCount = new ItemCounts()
|
||||||
|
{
|
||||||
|
SeriesCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Series),
|
||||||
|
EpisodeCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Episode),
|
||||||
|
MovieCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Movie),
|
||||||
|
AlbumCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.MusicAlbum),
|
||||||
|
ArtistCount = e.ItemValues!.Count(e => e.Type == 0 || e.Type == 1),
|
||||||
|
SongCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.MusicAlbum),
|
||||||
|
TrailerCount = e.ItemValues!.Count(e => e.Type == (int)BaseItemKind.Trailer),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
result.StartIndex = filter.StartIndex ?? 0;
|
||||||
|
result.Items = resultQuery.ToImmutableArray().Select(e =>
|
||||||
|
{
|
||||||
|
return (DeserialiseBaseItem(e.item), e.itemCount);
|
||||||
|
}).ToImmutableArray();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private static void PrepareFilterQuery(InternalItemsQuery query)
|
private static void PrepareFilterQuery(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
|
if (query.Limit.HasValue && query.EnableGroupByMetadataKey)
|
||||||
@ -2046,12 +1946,12 @@ public sealed class BaseItemManager : IItemRepository, IDisposable
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _appHost.ReverseVirtualPath(path);
|
return appHost.ReverseVirtualPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string RestorePath(string path)
|
private string RestorePath(string path)
|
||||||
{
|
{
|
||||||
return _appHost.ExpandVirtualPath(path);
|
return appHost.ExpandVirtualPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ItemImageInfo? ItemImageInfoFromValueString(ReadOnlySpan<char> value)
|
internal ItemImageInfo? ItemImageInfoFromValueString(ReadOnlySpan<char> value)
|
@ -14,46 +14,69 @@ namespace Jellyfin.Server.Implementations.Item;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Chapter manager.
|
/// The Chapter manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ChapterManager : IChapterManager
|
public class ChapterRepository : IChapterRepository
|
||||||
{
|
{
|
||||||
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
|
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider;
|
||||||
private readonly IImageProcessor _imageProcessor;
|
private readonly IImageProcessor _imageProcessor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ChapterManager"/> class.
|
/// Initializes a new instance of the <see cref="ChapterRepository"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dbProvider">The EFCore provider.</param>
|
/// <param name="dbProvider">The EFCore provider.</param>
|
||||||
/// <param name="imageProcessor">The Image Processor.</param>
|
/// <param name="imageProcessor">The Image Processor.</param>
|
||||||
public ChapterManager(IDbContextFactory<JellyfinDbContext> dbProvider, IImageProcessor imageProcessor)
|
public ChapterRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IImageProcessor imageProcessor)
|
||||||
{
|
{
|
||||||
_dbProvider = dbProvider;
|
_dbProvider = dbProvider;
|
||||||
_imageProcessor = imageProcessor;
|
_imageProcessor = imageProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IChapterManager"/>
|
/// <inheritdoc cref="IChapterRepository"/>
|
||||||
public ChapterInfo? GetChapter(BaseItemDto baseItem, int index)
|
public ChapterInfo? GetChapter(BaseItemDto baseItem, int index)
|
||||||
|
{
|
||||||
|
return GetChapter(baseItem.Id, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IChapterRepository"/>
|
||||||
|
public IReadOnlyList<ChapterInfo> GetChapters(BaseItemDto baseItem)
|
||||||
|
{
|
||||||
|
return GetChapters(baseItem.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IChapterRepository"/>
|
||||||
|
public ChapterInfo? GetChapter(Guid baseItemId, int index)
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = _dbProvider.CreateDbContext();
|
||||||
var chapter = context.Chapters.FirstOrDefault(e => e.ItemId.Equals(baseItem.Id) && e.ChapterIndex == index);
|
var chapter = context.Chapters
|
||||||
|
.Select(e => new
|
||||||
|
{
|
||||||
|
chapter = e,
|
||||||
|
baseItemPath = e.Item.Path
|
||||||
|
})
|
||||||
|
.FirstOrDefault(e => e.chapter.ItemId.Equals(baseItemId) && e.chapter.ChapterIndex == index);
|
||||||
if (chapter is not null)
|
if (chapter is not null)
|
||||||
{
|
{
|
||||||
return Map(chapter, baseItem);
|
return Map(chapter.chapter, chapter.baseItemPath!);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IChapterManager"/>
|
/// <inheritdoc cref="IChapterRepository"/>
|
||||||
public IReadOnlyList<ChapterInfo> GetChapters(BaseItemDto baseItem)
|
public IReadOnlyList<ChapterInfo> GetChapters(Guid baseItemId)
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = _dbProvider.CreateDbContext();
|
||||||
return context.Chapters.Where(e => e.ItemId.Equals(baseItem.Id))
|
return context.Chapters.Where(e => e.ItemId.Equals(baseItemId))
|
||||||
|
.Select(e => new
|
||||||
|
{
|
||||||
|
chapter = e,
|
||||||
|
baseItemPath = e.Item.Path
|
||||||
|
})
|
||||||
.ToList()
|
.ToList()
|
||||||
.Select(e => Map(e, baseItem))
|
.Select(e => Map(e.chapter, e.baseItemPath!))
|
||||||
.ToImmutableArray();
|
.ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IChapterManager"/>
|
/// <inheritdoc cref="IChapterRepository"/>
|
||||||
public void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters)
|
public void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters)
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = _dbProvider.CreateDbContext();
|
||||||
@ -80,20 +103,21 @@ public class ChapterManager : IChapterManager
|
|||||||
ImageDateModified = chapterInfo.ImageDateModified,
|
ImageDateModified = chapterInfo.ImageDateModified,
|
||||||
ImagePath = chapterInfo.ImagePath,
|
ImagePath = chapterInfo.ImagePath,
|
||||||
ItemId = itemId,
|
ItemId = itemId,
|
||||||
Name = chapterInfo.Name
|
Name = chapterInfo.Name,
|
||||||
|
Item = null!
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChapterInfo Map(Chapter chapterInfo, BaseItemDto baseItem)
|
private ChapterInfo Map(Chapter chapterInfo, string baseItemPath)
|
||||||
{
|
{
|
||||||
var info = new ChapterInfo()
|
var chapterEntity = new ChapterInfo()
|
||||||
{
|
{
|
||||||
StartPositionTicks = chapterInfo.StartPositionTicks,
|
StartPositionTicks = chapterInfo.StartPositionTicks,
|
||||||
ImageDateModified = chapterInfo.ImageDateModified.GetValueOrDefault(),
|
ImageDateModified = chapterInfo.ImageDateModified.GetValueOrDefault(),
|
||||||
ImagePath = chapterInfo.ImagePath,
|
ImagePath = chapterInfo.ImagePath,
|
||||||
Name = chapterInfo.Name,
|
Name = chapterInfo.Name,
|
||||||
};
|
};
|
||||||
info.ImageTag = _imageProcessor.GetImageCacheTag(baseItem, info);
|
chapterEntity.ImageTag = _imageProcessor.GetImageCacheTag(baseItemPath, chapterEntity.ImageDateModified);
|
||||||
return info;
|
return chapterEntity;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ namespace Jellyfin.Server.Implementations.Item;
|
|||||||
/// Manager for handling Media Attachments.
|
/// Manager for handling Media Attachments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dbProvider">Efcore Factory.</param>
|
/// <param name="dbProvider">Efcore Factory.</param>
|
||||||
public class MediaAttachmentManager(IDbContextFactory<JellyfinDbContext> dbProvider) : IMediaAttachmentManager
|
public class MediaAttachmentRepository(IDbContextFactory<JellyfinDbContext> dbProvider) : IMediaAttachmentRepository
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SaveMediaAttachments(
|
public void SaveMediaAttachments(
|
@ -13,12 +13,12 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
namespace Jellyfin.Server.Implementations.Item;
|
namespace Jellyfin.Server.Implementations.Item;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MediaStreamManager"/> class.
|
/// Initializes a new instance of the <see cref="MediaStreamRepository"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dbProvider"></param>
|
/// <param name="dbProvider">The EFCore db factory.</param>
|
||||||
/// <param name="serverApplicationHost"></param>
|
/// <param name="serverApplicationHost">The Application host.</param>
|
||||||
/// <param name="localization"></param>
|
/// <param name="localization">The Localisation Provider.</param>
|
||||||
public class MediaStreamManager(IDbContextFactory<JellyfinDbContext> dbProvider, IServerApplicationHost serverApplicationHost, ILocalizationManager localization) : IMediaStreamManager
|
public class MediaStreamRepository(IDbContextFactory<JellyfinDbContext> dbProvider, IServerApplicationHost serverApplicationHost, ILocalizationManager localization) : IMediaStreamRepository
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken)
|
public void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken)
|
@ -16,13 +16,13 @@ namespace Jellyfin.Server.Implementations.Item;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dbProvider">Efcore Factory.</param>
|
/// <param name="dbProvider">Efcore Factory.</param>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Initializes a new instance of the <see cref="PeopleManager"/> class.
|
/// Initializes a new instance of the <see cref="PeopleRepository"/> class.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="dbProvider">The EFCore Context factory.</param>
|
public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider) : IPeopleRepository
|
||||||
public class PeopleManager(IDbContextFactory<JellyfinDbContext> dbProvider) : IPeopleManager
|
|
||||||
{
|
{
|
||||||
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider = dbProvider;
|
private readonly IDbContextFactory<JellyfinDbContext> _dbProvider = dbProvider;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery filter)
|
public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery filter)
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = _dbProvider.CreateDbContext();
|
||||||
@ -37,6 +37,7 @@ public class PeopleManager(IDbContextFactory<JellyfinDbContext> dbProvider) : IP
|
|||||||
return dbQuery.ToList().Select(Map).ToImmutableArray();
|
return dbQuery.ToList().Select(Map).ToImmutableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter)
|
public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter)
|
||||||
{
|
{
|
||||||
using var context = _dbProvider.CreateDbContext();
|
using var context = _dbProvider.CreateDbContext();
|
@ -106,7 +106,7 @@ public class JellyfinDbContext : DbContext
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DbSet<BaseItem> BaseItems => Set<BaseItem>();
|
public DbSet<BaseItemEntity> BaseItems => Set<BaseItemEntity>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
/// Gets the <see cref="DbSet{TEntity}"/> containing the user data.
|
||||||
|
@ -8,10 +8,10 @@ namespace Jellyfin.Server.Implementations.ModelConfiguration;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration for BaseItem.
|
/// Configuration for BaseItem.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BaseItemConfiguration : IEntityTypeConfiguration<BaseItem>
|
public class BaseItemConfiguration : IEntityTypeConfiguration<BaseItemEntity>
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Configure(EntityTypeBuilder<BaseItem> builder)
|
public void Configure(EntityTypeBuilder<BaseItemEntity> builder)
|
||||||
{
|
{
|
||||||
builder.HasNoKey();
|
builder.HasNoKey();
|
||||||
builder.HasIndex(e => e.Path);
|
builder.HasIndex(e => e.Path);
|
||||||
|
@ -13,7 +13,7 @@ public class BaseItemProviderConfiguration : IEntityTypeConfiguration<BaseItemPr
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Configure(EntityTypeBuilder<BaseItemProvider> builder)
|
public void Configure(EntityTypeBuilder<BaseItemProvider> builder)
|
||||||
{
|
{
|
||||||
builder.HasNoKey();
|
builder.HasKey(e => new { e.ItemId, e.ProviderId });
|
||||||
builder.HasOne(e => e.Item);
|
builder.HasOne(e => e.Item);
|
||||||
builder.HasIndex(e => new { e.ProviderId, e.ProviderValue, e.ItemId });
|
builder.HasIndex(e => new { e.ProviderId, e.ProviderValue, e.ItemId });
|
||||||
}
|
}
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Controller.Chapters;
|
|
||||||
using MediaBrowser.Controller.Persistence;
|
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Providers.Chapters
|
|
||||||
{
|
|
||||||
public class ChapterManager : IChapterManager
|
|
||||||
{
|
|
||||||
public ChapterManager(IDbContextFactory<JellyfinDbContext> dbProvider)
|
|
||||||
{
|
|
||||||
_itemRepo = itemRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters)
|
|
||||||
{
|
|
||||||
_itemRepo.SaveChapters(itemId, chapters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using MediaBrowser.Model.Dto;
|
|
||||||
using MediaBrowser.Model.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Chapters
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interface IChapterManager.
|
|
||||||
/// </summary>
|
|
||||||
public interface IChapterManager
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the chapters.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="itemId">The item.</param>
|
|
||||||
/// <param name="chapters">The set of chapters.</param>
|
|
||||||
void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets all chapters associated with the baseItem.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="baseItem">The baseitem.</param>
|
|
||||||
/// <returns>A readonly list of chapter instances.</returns>
|
|
||||||
IReadOnlyList<ChapterInfo> GetChapters(BaseItemDto baseItem);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a single chapter of a BaseItem on a specific index.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="baseItem">The baseitem.</param>
|
|
||||||
/// <param name="index">The index of that chapter.</param>
|
|
||||||
/// <returns>A chapter instance.</returns>
|
|
||||||
ChapterInfo? GetChapter(BaseItemDto baseItem, int index);
|
|
||||||
}
|
|
||||||
}
|
|
49
MediaBrowser.Controller/Chapters/IChapterRepository.cs
Normal file
49
MediaBrowser.Controller/Chapters/IChapterRepository.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MediaBrowser.Model.Dto;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Chapters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface IChapterManager.
|
||||||
|
/// </summary>
|
||||||
|
public interface IChapterRepository
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the chapters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="itemId">The item.</param>
|
||||||
|
/// <param name="chapters">The set of chapters.</param>
|
||||||
|
void SaveChapters(Guid itemId, IReadOnlyList<ChapterInfo> chapters);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all chapters associated with the baseItem.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseItem">The baseitem.</param>
|
||||||
|
/// <returns>A readonly list of chapter instances.</returns>
|
||||||
|
IReadOnlyList<ChapterInfo> GetChapters(BaseItemDto baseItem);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a single chapter of a BaseItem on a specific index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseItem">The baseitem.</param>
|
||||||
|
/// <param name="index">The index of that chapter.</param>
|
||||||
|
/// <returns>A chapter instance.</returns>
|
||||||
|
ChapterInfo? GetChapter(BaseItemDto baseItem, int index);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all chapters associated with the baseItem.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseItemId">The BaseItems id.</param>
|
||||||
|
/// <returns>A readonly list of chapter instances.</returns>
|
||||||
|
IReadOnlyList<ChapterInfo> GetChapters(Guid baseItemId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a single chapter of a BaseItem on a specific index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseItemId">The BaseItems id.</param>
|
||||||
|
/// <param name="index">The index of that chapter.</param>
|
||||||
|
/// <returns>A chapter instance.</returns>
|
||||||
|
ChapterInfo? GetChapter(Guid baseItemId, int index);
|
||||||
|
}
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Drawing
|
namespace MediaBrowser.Controller.Drawing
|
||||||
@ -57,6 +58,22 @@ namespace MediaBrowser.Controller.Drawing
|
|||||||
/// <returns>BlurHash.</returns>
|
/// <returns>BlurHash.</returns>
|
||||||
string GetImageBlurHash(string path, ImageDimensions imageDimensions);
|
string GetImageBlurHash(string path, ImageDimensions imageDimensions);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the image cache tag.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseItemPath">The items basePath.</param>
|
||||||
|
/// <param name="imageDateModified">The image last modification date.</param>
|
||||||
|
/// <returns>Guid.</returns>
|
||||||
|
string? GetImageCacheTag(string baseItemPath, DateTime imageDateModified);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the image cache tag.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="image">The image.</param>
|
||||||
|
/// <returns>Guid.</returns>
|
||||||
|
string? GetImageCacheTag(BaseItemDto item, ChapterInfo image);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the image cache tag.
|
/// Gets the image cache tag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -65,6 +82,14 @@ namespace MediaBrowser.Controller.Drawing
|
|||||||
/// <returns>Guid.</returns>
|
/// <returns>Guid.</returns>
|
||||||
string GetImageCacheTag(BaseItem item, ItemImageInfo image);
|
string GetImageCacheTag(BaseItem item, ItemImageInfo image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the image cache tag.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
/// <param name="image">The image.</param>
|
||||||
|
/// <returns>Guid.</returns>
|
||||||
|
string GetImageCacheTag(BaseItemDto item, ItemImageInfo image);
|
||||||
|
|
||||||
string? GetImageCacheTag(BaseItem item, ChapterInfo chapter);
|
string? GetImageCacheTag(BaseItem item, ChapterInfo chapter);
|
||||||
|
|
||||||
string? GetImageCacheTag(User user);
|
string? GetImageCacheTag(User user);
|
||||||
|
@ -16,6 +16,7 @@ using Jellyfin.Data.Enums;
|
|||||||
using Jellyfin.Extensions;
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Channels;
|
using MediaBrowser.Controller.Channels;
|
||||||
|
using MediaBrowser.Controller.Chapters;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
@ -479,6 +480,8 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
public static IItemRepository ItemRepository { get; set; }
|
public static IItemRepository ItemRepository { get; set; }
|
||||||
|
|
||||||
|
public static IChapterRepository ChapterRepository { get; set; }
|
||||||
|
|
||||||
public static IFileSystem FileSystem { get; set; }
|
public static IFileSystem FileSystem { get; set; }
|
||||||
|
|
||||||
public static IUserDataManager UserDataManager { get; set; }
|
public static IUserDataManager UserDataManager { get; set; }
|
||||||
@ -2031,7 +2034,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
{
|
{
|
||||||
if (imageType == ImageType.Chapter)
|
if (imageType == ImageType.Chapter)
|
||||||
{
|
{
|
||||||
var chapter = ItemRepository.GetChapter(this, imageIndex);
|
var chapter = ChapterRepository.GetChapter(this.Id, imageIndex);
|
||||||
|
|
||||||
if (chapter is null)
|
if (chapter is null)
|
||||||
{
|
{
|
||||||
@ -2081,7 +2084,7 @@ namespace MediaBrowser.Controller.Entities
|
|||||||
|
|
||||||
if (image.Type == ImageType.Chapter)
|
if (image.Type == ImageType.Chapter)
|
||||||
{
|
{
|
||||||
var chapters = ItemRepository.GetChapters(this);
|
var chapters = ChapterRepository.GetChapters(this.Id);
|
||||||
for (var i = 0; i < chapters.Count; i++)
|
for (var i = 0; i < chapters.Count; i++)
|
||||||
{
|
{
|
||||||
if (chapters[i].ImagePath == image.Path)
|
if (chapters[i].ImagePath == image.Path)
|
||||||
|
@ -52,7 +52,6 @@ public interface IItemRepository : IDisposable
|
|||||||
/// <returns>List<Guid>.</returns>
|
/// <returns>List<Guid>.</returns>
|
||||||
IReadOnlyList<Guid> GetItemIdsList(InternalItemsQuery filter);
|
IReadOnlyList<Guid> GetItemIdsList(InternalItemsQuery filter);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the item list.
|
/// Gets the item list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
57
MediaBrowser.Controller/Persistence/IItemTypeLookup.cs
Normal file
57
MediaBrowser.Controller/Persistence/IItemTypeLookup.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Jellyfin.Data.Enums;
|
||||||
|
using MediaBrowser.Model.Querying;
|
||||||
|
|
||||||
|
namespace MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides static lookup data for <see cref="ItemFields"/> and <see cref="BaseItemKind"/> for the domain.
|
||||||
|
/// </summary>
|
||||||
|
public interface IItemTypeLookup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all values of the ItemFields type.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<ItemFields> AllItemFields { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered Programs.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ProgramTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that should be excluded from parent lookup.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ProgramExcludeParentTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered to be provided by services.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ServiceTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that have a StartDate.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> StartDateTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered Series.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> SeriesTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are not to be evaluated for Artists.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ArtistExcludeParentTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets all BaseItemKinds that are considered Artists.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<BaseItemKind> ArtistsTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets mapping for all BaseItemKinds and their expected serialisaition target.
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<BaseItemKind, string?> BaseItemKindNames { get; }
|
||||||
|
}
|
@ -9,9 +9,8 @@ using MediaBrowser.Model.Entities;
|
|||||||
|
|
||||||
namespace MediaBrowser.Controller.Persistence;
|
namespace MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
public interface IMediaAttachmentManager
|
public interface IMediaAttachmentRepository
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the media attachments.
|
/// Gets the media attachments.
|
||||||
/// </summary>
|
/// </summary>
|
@ -9,14 +9,17 @@ using MediaBrowser.Model.Entities;
|
|||||||
|
|
||||||
namespace MediaBrowser.Controller.Persistence;
|
namespace MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
public interface IMediaStreamManager
|
/// <summary>
|
||||||
|
/// Provides methods for accessing MediaStreams.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMediaStreamRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the media streams.
|
/// Gets the media streams.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filter">The query.</param>
|
/// <param name="filter">The query.</param>
|
||||||
/// <returns>IEnumerable{MediaStream}.</returns>
|
/// <returns>IEnumerable{MediaStream}.</returns>
|
||||||
List<MediaStream> GetMediaStreams(MediaStreamQuery filter);
|
IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery filter);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the media streams.
|
/// Saves the media streams.
|
@ -8,7 +8,7 @@ using MediaBrowser.Controller.Entities;
|
|||||||
|
|
||||||
namespace MediaBrowser.Controller.Persistence;
|
namespace MediaBrowser.Controller.Persistence;
|
||||||
|
|
||||||
public interface IPeopleManager
|
public interface IPeopleRepository
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the people.
|
/// Gets the people.
|
||||||
@ -30,5 +30,4 @@ public interface IPeopleManager
|
|||||||
/// <param name="filter">The query.</param>
|
/// <param name="filter">The query.</param>
|
||||||
/// <returns>List<System.String>.</returns>
|
/// <returns>List<System.String>.</returns>
|
||||||
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter);
|
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter);
|
||||||
|
|
||||||
}
|
}
|
@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
private readonly IEncodingManager _encodingManager;
|
private readonly IEncodingManager _encodingManager;
|
||||||
private readonly IServerConfigurationManager _config;
|
private readonly IServerConfigurationManager _config;
|
||||||
private readonly ISubtitleManager _subtitleManager;
|
private readonly ISubtitleManager _subtitleManager;
|
||||||
private readonly IChapterManager _chapterManager;
|
private readonly IChapterRepository _chapterManager;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly AudioResolver _audioResolver;
|
private readonly AudioResolver _audioResolver;
|
||||||
private readonly SubtitleResolver _subtitleResolver;
|
private readonly SubtitleResolver _subtitleResolver;
|
||||||
@ -54,7 +54,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
IEncodingManager encodingManager,
|
IEncodingManager encodingManager,
|
||||||
IServerConfigurationManager config,
|
IServerConfigurationManager config,
|
||||||
ISubtitleManager subtitleManager,
|
ISubtitleManager subtitleManager,
|
||||||
IChapterManager chapterManager,
|
IChapterRepository chapterManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
AudioResolver audioResolver,
|
AudioResolver audioResolver,
|
||||||
SubtitleResolver subtitleResolver)
|
SubtitleResolver subtitleResolver)
|
||||||
|
@ -61,7 +61,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
/// <param name="encodingManager">Instance of the <see cref="IEncodingManager"/> interface.</param>
|
/// <param name="encodingManager">Instance of the <see cref="IEncodingManager"/> interface.</param>
|
||||||
/// <param name="config">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
/// <param name="config">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
||||||
/// <param name="subtitleManager">Instance of the <see cref="ISubtitleManager"/> interface.</param>
|
/// <param name="subtitleManager">Instance of the <see cref="ISubtitleManager"/> interface.</param>
|
||||||
/// <param name="chapterManager">Instance of the <see cref="IChapterManager"/> interface.</param>
|
/// <param name="chapterManager">Instance of the <see cref="IChapterRepository"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/>.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/>.</param>
|
||||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||||
@ -76,7 +76,7 @@ namespace MediaBrowser.Providers.MediaInfo
|
|||||||
IEncodingManager encodingManager,
|
IEncodingManager encodingManager,
|
||||||
IServerConfigurationManager config,
|
IServerConfigurationManager config,
|
||||||
ISubtitleManager subtitleManager,
|
ISubtitleManager subtitleManager,
|
||||||
IChapterManager chapterManager,
|
IChapterRepository chapterManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
|
@ -15,6 +15,7 @@ using MediaBrowser.Controller.Configuration;
|
|||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
@ -403,10 +404,34 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable
|
|||||||
return _imageEncoder.GetImageBlurHash(xComp, yComp, path);
|
return _imageEncoder.GetImageBlurHash(xComp, yComp, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string GetImageCacheTag(string baseItemPath, DateTime imageDateModified)
|
||||||
|
=> (baseItemPath + imageDateModified.Ticks).GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string GetImageCacheTag(BaseItem item, ItemImageInfo image)
|
public string GetImageCacheTag(BaseItem item, ItemImageInfo image)
|
||||||
=> (item.Path + image.DateModified.Ticks).GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
=> (item.Path + image.DateModified.Ticks).GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string GetImageCacheTag(BaseItemDto item, ItemImageInfo image)
|
||||||
|
=> (item.Path + image.DateModified.Ticks).GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public string? GetImageCacheTag(BaseItemDto item, ChapterInfo chapter)
|
||||||
|
{
|
||||||
|
if (chapter.ImagePath is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetImageCacheTag(item, new ItemImageInfo
|
||||||
|
{
|
||||||
|
Path = chapter.ImagePath,
|
||||||
|
Type = ImageType.Chapter,
|
||||||
|
DateModified = chapter.ImageDateModified
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string? GetImageCacheTag(BaseItem item, ChapterInfo chapter)
|
public string? GetImageCacheTag(BaseItem item, ChapterInfo chapter)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user