Ported new Item Repository architecture

This commit is contained in:
JPVenson 2024-10-09 10:41:54 +00:00
parent b09a41ad1f
commit 2014fa56b8
5 changed files with 20 additions and 69 deletions

View File

@ -5,6 +5,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -164,7 +165,7 @@ namespace Emby.Server.Implementations.Library
}); });
} }
public async Task<List<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken) public async Task<IReadOnlyList<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken)
{ {
var mediaSources = GetStaticMediaSources(item, enablePathSubstitution, user); var mediaSources = GetStaticMediaSources(item, enablePathSubstitution, user);
@ -217,7 +218,7 @@ namespace Emby.Server.Implementations.Library
list.Add(source); list.Add(source);
} }
return SortMediaSources(list); return SortMediaSources(list).ToImmutableList();
} }
/// <inheritdoc />> /// <inheritdoc />>
@ -458,7 +459,7 @@ namespace Emby.Server.Implementations.Library
} }
} }
private static List<MediaSourceInfo> SortMediaSources(IEnumerable<MediaSourceInfo> sources) private static IEnumerable<MediaSourceInfo> SortMediaSources(IEnumerable<MediaSourceInfo> sources)
{ {
return sources.OrderBy(i => return sources.OrderBy(i =>
{ {
@ -475,8 +476,7 @@ namespace Emby.Server.Implementations.Library
return stream?.Width ?? 0; return stream?.Width ?? 0;
}) })
.Where(i => i.Type != MediaSourceType.Placeholder) .Where(i => i.Type != MediaSourceType.Placeholder);
.ToList();
} }
public async Task<Tuple<LiveStreamResponse, IDirectStreamProvider>> OpenLiveStreamInternal(LiveStreamRequest request, CancellationToken cancellationToken) public async Task<Tuple<LiveStreamResponse, IDirectStreamProvider>> OpenLiveStreamInternal(LiveStreamRequest request, CancellationToken cancellationToken)
@ -811,7 +811,7 @@ namespace Emby.Server.Implementations.Library
return result.Item1; return result.Item1;
} }
public async Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken) public async Task<IReadOnlyList<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken)
{ {
var stream = new MediaSourceInfo var stream = new MediaSourceInfo
{ {
@ -834,10 +834,7 @@ namespace Emby.Server.Implementations.Library
await new LiveStreamHelper(_mediaEncoder, _logger, _appPaths) await new LiveStreamHelper(_mediaEncoder, _logger, _appPaths)
.AddMediaInfoWithProbe(stream, false, false, cancellationToken).ConfigureAwait(false); .AddMediaInfoWithProbe(stream, false, false, cancellationToken).ConfigureAwait(false);
return new List<MediaSourceInfo> return [stream];
{
stream
};
} }
public async Task CloseLiveStream(string id) public async Task CloseLiveStream(string id)

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
using Jellyfin.Api.Extensions; using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers; using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders; using Jellyfin.Api.ModelBinders;
@ -389,7 +391,7 @@ public class InstantMixController : BaseJellyfinApiController
return GetResult(items, user, limit, dtoOptions); return GetResult(items, user, limit, dtoOptions);
} }
private QueryResult<BaseItemDto> GetResult(List<BaseItem> items, User? user, int? limit, DtoOptions dtoOptions) private QueryResult<BaseItemDto> GetResult(IReadOnlyList<BaseItem> items, User? user, int? limit, DtoOptions dtoOptions)
{ {
var list = items; var list = items;
@ -397,7 +399,7 @@ public class InstantMixController : BaseJellyfinApiController
if (limit.HasValue && limit < list.Count) if (limit.HasValue && limit < list.Count)
{ {
list = list.GetRange(0, limit.Value); list = list.Take(limit.Value).ToImmutableArray();
} }
var returnList = _dtoService.GetBaseItemDtos(list, dtoOptions, user); var returnList = _dtoService.GetBaseItemDtos(list, dtoOptions, user);

View File

@ -132,7 +132,7 @@ public static class StreamingHelpers
mediaSource = string.IsNullOrEmpty(streamingRequest.MediaSourceId) mediaSource = string.IsNullOrEmpty(streamingRequest.MediaSourceId)
? mediaSources[0] ? mediaSources[0]
: mediaSources.Find(i => string.Equals(i.Id, streamingRequest.MediaSourceId, StringComparison.Ordinal)); : mediaSources.FirstOrDefault(i => string.Equals(i.Id, streamingRequest.MediaSourceId, StringComparison.Ordinal));
if (mediaSource is null && Guid.Parse(streamingRequest.MediaSourceId).Equals(streamingRequest.Id)) if (mediaSource is null && Guid.Parse(streamingRequest.MediaSourceId).Equals(streamingRequest.Id))
{ {

View File

@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="enablePathSubstitution">Option to enable path substitution.</param> /// <param name="enablePathSubstitution">Option to enable path substitution.</param>
/// <param name="cancellationToken">CancellationToken to use for operation.</param> /// <param name="cancellationToken">CancellationToken to use for operation.</param>
/// <returns>List of media sources wrapped in an awaitable task.</returns> /// <returns>List of media sources wrapped in an awaitable task.</returns>
Task<List<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken); Task<IReadOnlyList<MediaSourceInfo>> GetPlaybackMediaSources(BaseItem item, User user, bool allowMediaProbe, bool enablePathSubstitution, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Gets the static media sources. /// Gets the static media sources.
@ -70,7 +70,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="enablePathSubstitution">Option to enable path substitution.</param> /// <param name="enablePathSubstitution">Option to enable path substitution.</param>
/// <param name="user">User to use for operation.</param> /// <param name="user">User to use for operation.</param>
/// <returns>List of media sources.</returns> /// <returns>List of media sources.</returns>
List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null); IReadOnlyList<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null);
/// <summary> /// <summary>
/// Gets the static media source. /// Gets the static media source.
@ -123,7 +123,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="info">The <see cref="ActiveRecordingInfo"/>.</param> /// <param name="info">The <see cref="ActiveRecordingInfo"/>.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns>A task containing the <see cref="MediaSourceInfo"/>'s for the recording.</returns> /// <returns>A task containing the <see cref="MediaSourceInfo"/>'s for the recording.</returns>
Task<List<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken); Task<IReadOnlyList<MediaSourceInfo>> GetRecordingStreamMediaSources(ActiveRecordingInfo info, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Closes the media source. /// Closes the media source.

View File

@ -3,8 +3,10 @@ using System.Collections.Generic;
using AutoFixture; using AutoFixture;
using AutoFixture.AutoMoq; using AutoFixture.AutoMoq;
using Emby.Server.Implementations.Data; using Emby.Server.Implementations.Data;
using Jellyfin.Server.Implementations.Item;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Moq; using Moq;
@ -18,7 +20,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data
public const string MetaDataPath = "/meta/data/path"; public const string MetaDataPath = "/meta/data/path";
private readonly IFixture _fixture; private readonly IFixture _fixture;
private readonly SqliteItemRepository _sqliteItemRepository; private readonly BaseItemRepository _sqliteItemRepository;
public SqliteItemRepositoryTests() public SqliteItemRepositoryTests()
{ {
@ -40,7 +42,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data
_fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true }); _fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
_fixture.Inject(appHost); _fixture.Inject(appHost);
_fixture.Inject(config); _fixture.Inject(config);
_sqliteItemRepository = _fixture.Create<SqliteItemRepository>(); _sqliteItemRepository = _fixture.Create<BaseItemRepository>();
} }
public static TheoryData<string, ItemImageInfo> ItemImageInfoFromValueString_Valid_TestData() public static TheoryData<string, ItemImageInfo> ItemImageInfoFromValueString_Valid_TestData()
@ -101,7 +103,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data
[MemberData(nameof(ItemImageInfoFromValueString_Valid_TestData))] [MemberData(nameof(ItemImageInfoFromValueString_Valid_TestData))]
public void ItemImageInfoFromValueString_Valid_Success(string value, ItemImageInfo expected) public void ItemImageInfoFromValueString_Valid_Success(string value, ItemImageInfo expected)
{ {
var result = _sqliteItemRepository.ItemImageInfoFromValueString(value); var result = _sqliteItemRepository.ItemImageInfoFromValueString(value)!;
Assert.Equal(expected.Path, result.Path); Assert.Equal(expected.Path, result.Path);
Assert.Equal(expected.Type, result.Type); Assert.Equal(expected.Type, result.Type);
Assert.Equal(expected.DateModified, result.DateModified); Assert.Equal(expected.DateModified, result.DateModified);
@ -243,56 +245,6 @@ namespace Jellyfin.Server.Implementations.Tests.Data
Assert.Equal(expected, _sqliteItemRepository.SerializeImages(value)); Assert.Equal(expected, _sqliteItemRepository.SerializeImages(value));
} }
public static TheoryData<string, Dictionary<string, string>> DeserializeProviderIds_Valid_TestData()
{
var data = new TheoryData<string, Dictionary<string, string>>();
data.Add(
"Imdb=tt0119567",
new Dictionary<string, string>()
{
{ "Imdb", "tt0119567" },
});
data.Add(
"Imdb=tt0119567|Tmdb=330|TmdbCollection=328",
new Dictionary<string, string>()
{
{ "Imdb", "tt0119567" },
{ "Tmdb", "330" },
{ "TmdbCollection", "328" },
});
data.Add(
"MusicBrainzAlbum=9d363e43-f24f-4b39-bc5a-7ef305c677c7|MusicBrainzReleaseGroup=63eba062-847c-3b73-8b0f-6baf27bba6fa|AudioDbArtist=111352|AudioDbAlbum=2116560|MusicBrainzAlbumArtist=20244d07-534f-4eff-b4d4-930878889970",
new Dictionary<string, string>()
{
{ "MusicBrainzAlbum", "9d363e43-f24f-4b39-bc5a-7ef305c677c7" },
{ "MusicBrainzReleaseGroup", "63eba062-847c-3b73-8b0f-6baf27bba6fa" },
{ "AudioDbArtist", "111352" },
{ "AudioDbAlbum", "2116560" },
{ "MusicBrainzAlbumArtist", "20244d07-534f-4eff-b4d4-930878889970" },
});
return data;
}
[Theory]
[MemberData(nameof(DeserializeProviderIds_Valid_TestData))]
public void DeserializeProviderIds_Valid_Success(string value, Dictionary<string, string> expected)
{
var result = new ProviderIdsExtensionsTestsObject();
SqliteItemRepository.DeserializeProviderIds(value, result);
Assert.Equal(expected, result.ProviderIds);
}
[Theory]
[MemberData(nameof(DeserializeProviderIds_Valid_TestData))]
public void SerializeProviderIds_Valid_Success(string expected, Dictionary<string, string> values)
{
Assert.Equal(expected, SqliteItemRepository.SerializeProviderIds(values));
}
private sealed class ProviderIdsExtensionsTestsObject : IHasProviderIds private sealed class ProviderIdsExtensionsTestsObject : IHasProviderIds
{ {
public Dictionary<string, string> ProviderIds { get; set; } = new Dictionary<string, string>(); public Dictionary<string, string> ProviderIds { get; set; } = new Dictionary<string, string>();