mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-18 00:06:27 +01:00
Merge branch 'master' into sort-nfo-data
This commit is contained in:
@@ -1,20 +1,31 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Authentication
|
||||
namespace MediaBrowser.Controller.Authentication;
|
||||
|
||||
/// <summary>
|
||||
/// A class representing an authentication result.
|
||||
/// </summary>
|
||||
public class AuthenticationResult
|
||||
{
|
||||
public class AuthenticationResult
|
||||
{
|
||||
public UserDto User { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the user.
|
||||
/// </summary>
|
||||
public UserDto User { get; set; }
|
||||
|
||||
public SessionInfo SessionInfo { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the session info.
|
||||
/// </summary>
|
||||
public SessionInfoDto SessionInfo { get; set; }
|
||||
|
||||
public string AccessToken { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the access token.
|
||||
/// </summary>
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
public string ServerId { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the server id.
|
||||
/// </summary>
|
||||
public string ServerId { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -1,81 +1,117 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Dtos;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Entities.Security;
|
||||
using Jellyfin.Data.Events;
|
||||
using Jellyfin.Data.Queries;
|
||||
using MediaBrowser.Model.Devices;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Session;
|
||||
|
||||
namespace MediaBrowser.Controller.Devices
|
||||
namespace MediaBrowser.Controller.Devices;
|
||||
|
||||
/// <summary>
|
||||
/// Device manager interface.
|
||||
/// </summary>
|
||||
public interface IDeviceManager
|
||||
{
|
||||
public interface IDeviceManager
|
||||
{
|
||||
event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
||||
/// <summary>
|
||||
/// Event handler for updated device options.
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new device.
|
||||
/// </summary>
|
||||
/// <param name="device">The device to create.</param>
|
||||
/// <returns>A <see cref="Task{Device}"/> representing the creation of the device.</returns>
|
||||
Task<Device> CreateDevice(Device device);
|
||||
/// <summary>
|
||||
/// Creates a new device.
|
||||
/// </summary>
|
||||
/// <param name="device">The device to create.</param>
|
||||
/// <returns>A <see cref="Task{Device}"/> representing the creation of the device.</returns>
|
||||
Task<Device> CreateDevice(Device device);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="capabilities">The capabilities.</param>
|
||||
void SaveCapabilities(string deviceId, ClientCapabilities capabilities);
|
||||
/// <summary>
|
||||
/// Saves the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="capabilities">The capabilities.</param>
|
||||
void SaveCapabilities(string deviceId, ClientCapabilities capabilities);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <returns>ClientCapabilities.</returns>
|
||||
ClientCapabilities GetCapabilities(string deviceId);
|
||||
/// <summary>
|
||||
/// Gets the capabilities.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <returns>ClientCapabilities.</returns>
|
||||
ClientCapabilities GetCapabilities(string? deviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the device information.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>DeviceInfo.</returns>
|
||||
DeviceInfo GetDevice(string id);
|
||||
/// <summary>
|
||||
/// Gets the device information.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>DeviceInfoDto.</returns>
|
||||
DeviceInfoDto? GetDevice(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets devices based on the provided query.
|
||||
/// </summary>
|
||||
/// <param name="query">The device query.</param>
|
||||
/// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the devices.</returns>
|
||||
QueryResult<Device> GetDevices(DeviceQuery query);
|
||||
/// <summary>
|
||||
/// Gets devices based on the provided query.
|
||||
/// </summary>
|
||||
/// <param name="query">The device query.</param>
|
||||
/// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the devices.</returns>
|
||||
QueryResult<Device> GetDevices(DeviceQuery query);
|
||||
|
||||
QueryResult<DeviceInfo> GetDeviceInfos(DeviceQuery query);
|
||||
/// <summary>
|
||||
/// Gets device information based on the provided query.
|
||||
/// </summary>
|
||||
/// <param name="query">The device query.</param>
|
||||
/// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the device information.</returns>
|
||||
QueryResult<DeviceInfo> GetDeviceInfos(DeviceQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the devices.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user's id, or <c>null</c>.</param>
|
||||
/// <returns>IEnumerable<DeviceInfo>.</returns>
|
||||
QueryResult<DeviceInfo> GetDevicesForUser(Guid? userId);
|
||||
/// <summary>
|
||||
/// Gets the device information.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user's id, or <c>null</c>.</param>
|
||||
/// <returns>IEnumerable<DeviceInfoDto>.</returns>
|
||||
QueryResult<DeviceInfoDto> GetDevicesForUser(Guid? userId);
|
||||
|
||||
Task DeleteDevice(Device device);
|
||||
/// <summary>
|
||||
/// Deletes a device.
|
||||
/// </summary>
|
||||
/// <param name="device">The device.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the deletion of the device.</returns>
|
||||
Task DeleteDevice(Device device);
|
||||
|
||||
Task UpdateDevice(Device device);
|
||||
/// <summary>
|
||||
/// Updates a device.
|
||||
/// </summary>
|
||||
/// <param name="device">The device.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the update of the device.</returns>
|
||||
Task UpdateDevice(Device device);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance [can access device] the specified user identifier.
|
||||
/// </summary>
|
||||
/// <param name="user">The user to test.</param>
|
||||
/// <param name="deviceId">The device id to test.</param>
|
||||
/// <returns>Whether the user can access the device.</returns>
|
||||
bool CanAccessDevice(User user, string deviceId);
|
||||
/// <summary>
|
||||
/// Determines whether this instance [can access device] the specified user identifier.
|
||||
/// </summary>
|
||||
/// <param name="user">The user to test.</param>
|
||||
/// <param name="deviceId">The device id to test.</param>
|
||||
/// <returns>Whether the user can access the device.</returns>
|
||||
bool CanAccessDevice(User user, string deviceId);
|
||||
|
||||
Task UpdateDeviceOptions(string deviceId, string deviceName);
|
||||
/// <summary>
|
||||
/// Updates the options of a device.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">The device name.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the update of the device options.</returns>
|
||||
Task UpdateDeviceOptions(string deviceId, string? deviceName);
|
||||
|
||||
DeviceOptions GetDeviceOptions(string deviceId);
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the options of a device.
|
||||
/// </summary>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <returns><see cref="DeviceOptions"/> of the device.</returns>
|
||||
DeviceOptionsDto? GetDeviceOptions(string deviceId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dto for client capabilities.
|
||||
/// </summary>
|
||||
/// <param name="capabilities">The client capabilities.</param>
|
||||
/// <returns><see cref="ClientCapabilitiesDto"/> of the device.</returns>
|
||||
ClientCapabilitiesDto ToClientCapabilitiesDto(ClientCapabilities capabilities);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
@@ -57,6 +58,22 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <returns>BlurHash.</returns>
|
||||
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>
|
||||
/// Gets the image cache tag.
|
||||
/// </summary>
|
||||
@@ -65,6 +82,14 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <returns>Guid.</returns>
|
||||
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(User user);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class AggregateFolder : Folder
|
||||
{
|
||||
private readonly object _childIdsLock = new object();
|
||||
private readonly Lock _childIdsLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The _virtual children.
|
||||
@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return CreateResolveArgs(directoryService, true).FileSystemChildren;
|
||||
}
|
||||
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
protected override IReadOnlyList<BaseItem> LoadChildren()
|
||||
{
|
||||
lock (_childIdsLock)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
IReadOnlyList<string> Artists { get; set; }
|
||||
}
|
||||
|
||||
public static class Extentions
|
||||
public static class Extensions
|
||||
{
|
||||
public static IEnumerable<string> GetAllArtists<T>(this T item)
|
||||
where T : IHasArtist, IHasAlbumArtist
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// <summary>
|
||||
/// Class MusicAlbum.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
|
||||
{
|
||||
public MusicAlbum()
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// <summary>
|
||||
/// Class MusicArtist.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class MusicArtist : Folder, IItemByName, IHasMusicGenres, IHasDualAccess, IHasLookupInfo<ArtistInfo>
|
||||
{
|
||||
[JsonIgnore]
|
||||
@@ -84,7 +85,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return !IsAccessedByName;
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
if (query.IncludeItemTypes.Length == 0)
|
||||
{
|
||||
@@ -110,15 +111,15 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return base.IsSaveLocalMetadataEnabled();
|
||||
}
|
||||
|
||||
protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||
protected override async Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
|
||||
{
|
||||
if (IsAccessedByName)
|
||||
{
|
||||
// Should never get in here anyway
|
||||
return Task.CompletedTask;
|
||||
return;
|
||||
}
|
||||
|
||||
return base.ValidateChildrenInternal(progress, recursive, refreshChildMetadata, false, refreshOptions, directoryService, cancellationToken);
|
||||
await base.ValidateChildrenInternal(progress, recursive, refreshChildMetadata, false, refreshOptions, directoryService, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public override List<string> GetUserDataKeys()
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
/// <summary>
|
||||
/// Class MusicGenre.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class MusicGenre : BaseItem, IItemByName
|
||||
{
|
||||
[JsonIgnore]
|
||||
@@ -64,7 +65,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return true;
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.GenreIds = new[] { Id };
|
||||
query.IncludeItemTypes = new[] { BaseItemKind.MusicVideo, BaseItemKind.Audio, BaseItemKind.MusicAlbum, BaseItemKind.MusicArtist };
|
||||
|
||||
@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class AudioBook : Audio.Audio, IHasSeries, IHasLookupInfo<SongInfo>
|
||||
{
|
||||
[JsonIgnore]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -16,6 +17,7 @@ using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Chapters;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
@@ -480,6 +482,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public static IItemRepository ItemRepository { get; set; }
|
||||
|
||||
public static IChapterRepository ChapterRepository { get; set; }
|
||||
|
||||
public static IFileSystem FileSystem { get; set; }
|
||||
|
||||
public static IUserDataManager UserDataManager { get; set; }
|
||||
@@ -1042,7 +1046,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return PlayAccess.Full;
|
||||
}
|
||||
|
||||
public virtual List<MediaStream> GetMediaStreams()
|
||||
public virtual IReadOnlyList<MediaStream> GetMediaStreams()
|
||||
{
|
||||
return MediaSourceManager.GetMediaStreams(new MediaStreamQuery
|
||||
{
|
||||
@@ -1055,7 +1059,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
public virtual IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
if (SourceType == SourceType.Channel)
|
||||
{
|
||||
@@ -1089,7 +1093,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return 1;
|
||||
}).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0)
|
||||
.ThenByDescending(i => i, new MediaSourceWidthComparator())
|
||||
.ToList();
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<(BaseItem Item, MediaSourceType MediaSourceType)> GetAllItemsForMediaSources()
|
||||
@@ -1609,7 +1613,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
var parent = GetParents().FirstOrDefault() ?? this;
|
||||
if (parent is UserRootFolder or AggregateFolder)
|
||||
if (parent is UserRootFolder or AggregateFolder or UserView)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -1781,7 +1785,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
Studios = [..current, name];
|
||||
Studios = [.. current, name];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1795,7 +1799,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Adds a genre to the item.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <exception cref="ArgumentNullException">Throwns if name is null.</exception>
|
||||
/// <exception cref="ArgumentNullException">Throws if name is null.</exception>
|
||||
public void AddGenre(string name)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(name);
|
||||
@@ -1803,7 +1807,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
var genres = Genres;
|
||||
if (!genres.Contains(name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Genres = [..genres, name];
|
||||
Genres = [.. genres, name];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1821,7 +1825,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(user);
|
||||
|
||||
var data = UserDataManager.GetUserData(user, this);
|
||||
var data = UserDataManager.GetUserData(user, this) ?? new UserItemData()
|
||||
{
|
||||
Key = GetUserDataKeys().First(),
|
||||
};
|
||||
|
||||
if (datePlayed.HasValue)
|
||||
{
|
||||
@@ -1974,11 +1981,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public void AddImage(ItemImageInfo image)
|
||||
{
|
||||
ImageInfos = [..ImageInfos, image];
|
||||
ImageInfos = [.. ImageInfos, image];
|
||||
}
|
||||
|
||||
public virtual Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
=> LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken);
|
||||
public virtual async Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
|
||||
=> await LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
/// <summary>
|
||||
/// Validates that images within the item are still on the filesystem.
|
||||
@@ -2031,7 +2038,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
if (imageType == ImageType.Chapter)
|
||||
{
|
||||
var chapter = ItemRepository.GetChapter(this, imageIndex);
|
||||
var chapter = ChapterRepository.GetChapter(this.Id, imageIndex);
|
||||
|
||||
if (chapter is null)
|
||||
{
|
||||
@@ -2081,7 +2088,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (image.Type == ImageType.Chapter)
|
||||
{
|
||||
var chapters = ItemRepository.GetChapters(this);
|
||||
var chapters = ChapterRepository.GetChapters(this.Id);
|
||||
for (var i = 0; i < chapters.Count; i++)
|
||||
{
|
||||
if (chapters[i].ImagePath == image.Path)
|
||||
@@ -2367,7 +2374,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
protected Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
protected async Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
|
||||
{
|
||||
var newOptions = new MetadataRefreshOptions(options)
|
||||
{
|
||||
@@ -2428,10 +2435,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
return ownedItem.RefreshMetadata(newOptions, cancellationToken);
|
||||
await ownedItem.RefreshMetadata(newOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
|
||||
protected async Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var newOptions = new MetadataRefreshOptions(options)
|
||||
{
|
||||
@@ -2441,9 +2448,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
var id = LibraryManager.GetNewItemId(path, typeof(Video));
|
||||
|
||||
// Try to retrieve it from the db. If we don't find it, use the resolved version
|
||||
var video = LibraryManager.GetItemById(id) as Video;
|
||||
|
||||
if (video is null)
|
||||
if (LibraryManager.GetItemById(id) is not Video video)
|
||||
{
|
||||
video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
|
||||
|
||||
@@ -2452,15 +2457,15 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (video is null)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (video.OwnerId.IsEmpty())
|
||||
{
|
||||
video.OwnerId = this.Id;
|
||||
video.OwnerId = Id;
|
||||
}
|
||||
|
||||
return RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken);
|
||||
await RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public string GetEtag(User user)
|
||||
@@ -2524,7 +2529,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="children">Media children.</param>
|
||||
/// <returns><c>true</c> if the rating was updated; otherwise <c>false</c>.</returns>
|
||||
public bool UpdateRatingToItems(IList<BaseItem> children)
|
||||
public bool UpdateRatingToItems(IReadOnlyList<BaseItem> children)
|
||||
{
|
||||
var currentOfficialRating = OfficialRating;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using MediaBrowser.Controller.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class Book : BaseItem, IHasLookupInfo<BookInfo>, IHasSeries
|
||||
{
|
||||
public Book()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security;
|
||||
@@ -11,6 +12,7 @@ using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Dataflow;
|
||||
using J2N.Collections.Generic.Extensions;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
@@ -247,7 +249,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// We want this synchronous.
|
||||
/// </summary>
|
||||
/// <returns>Returns children.</returns>
|
||||
protected virtual List<BaseItem> LoadChildren()
|
||||
protected virtual IReadOnlyList<BaseItem> LoadChildren()
|
||||
{
|
||||
// logger.LogDebug("Loading children from {0} {1} {2}", GetType().Name, Id, Path);
|
||||
// just load our children from the repo - the library will be validated and maintained in other processes
|
||||
@@ -450,7 +452,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (newItems.Count > 0)
|
||||
{
|
||||
LibraryManager.CreateItems(newItems, this, cancellationToken);
|
||||
LibraryManager.CreateOrUpdateItems(newItems, this, cancellationToken);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -528,13 +530,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
private Task RefreshMetadataRecursive(IList<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
private async Task RefreshMetadataRecursive(IList<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
return RunTasks(
|
||||
await RunTasks(
|
||||
(baseItem, innerProgress) => RefreshChildMetadata(baseItem, refreshOptions, recursive && baseItem.IsFolder, innerProgress, cancellationToken),
|
||||
children,
|
||||
progress,
|
||||
cancellationToken);
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
@@ -575,13 +577,13 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <param name="progress">The progress.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task.</returns>
|
||||
private Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
|
||||
{
|
||||
return RunTasks(
|
||||
await RunTasks(
|
||||
(folder, innerProgress) => folder.ValidateChildrenInternal(innerProgress, true, false, false, null, directoryService, cancellationToken),
|
||||
children,
|
||||
progress,
|
||||
cancellationToken);
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -659,7 +661,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Get our children from the repo - stubbed for now.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
protected List<BaseItem> GetCachedChildren()
|
||||
protected IReadOnlyList<BaseItem> GetCachedChildren()
|
||||
{
|
||||
return ItemRepository.GetItemList(new InternalItemsQuery
|
||||
{
|
||||
@@ -1240,11 +1242,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.GenreIds.Count > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.VideoTypes.Length > 0)
|
||||
{
|
||||
return false;
|
||||
@@ -1283,14 +1280,14 @@ namespace MediaBrowser.Controller.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
public IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(user);
|
||||
|
||||
return GetChildren(user, includeLinkedChildren, new InternalItemsQuery(user));
|
||||
}
|
||||
|
||||
public virtual List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
public virtual IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(user);
|
||||
|
||||
@@ -1304,7 +1301,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
AddChildren(user, includeLinkedChildren, result, false, query);
|
||||
|
||||
return result.Values.ToList();
|
||||
return result.Values.ToArray();
|
||||
}
|
||||
|
||||
protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
@@ -1369,7 +1366,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
public virtual IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(user);
|
||||
|
||||
@@ -1377,35 +1374,35 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
AddChildren(user, true, result, true, query);
|
||||
|
||||
return result.Values;
|
||||
return result.Values.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the recursive children.
|
||||
/// </summary>
|
||||
/// <returns>IList{BaseItem}.</returns>
|
||||
public IList<BaseItem> GetRecursiveChildren()
|
||||
public IReadOnlyList<BaseItem> GetRecursiveChildren()
|
||||
{
|
||||
return GetRecursiveChildren(true);
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetRecursiveChildren(bool includeLinkedChildren)
|
||||
public IReadOnlyList<BaseItem> GetRecursiveChildren(bool includeLinkedChildren)
|
||||
{
|
||||
return GetRecursiveChildren(i => true, includeLinkedChildren);
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
|
||||
public IReadOnlyList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter)
|
||||
{
|
||||
return GetRecursiveChildren(filter, true);
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter, bool includeLinkedChildren)
|
||||
public IReadOnlyList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter, bool includeLinkedChildren)
|
||||
{
|
||||
var result = new Dictionary<Guid, BaseItem>();
|
||||
|
||||
AddChildrenToList(result, includeLinkedChildren, true, filter);
|
||||
|
||||
return result.Values.ToList();
|
||||
return result.Values.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1556,11 +1553,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Gets the linked children.
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
public IEnumerable<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
|
||||
public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
|
||||
{
|
||||
return LinkedChildren
|
||||
.Select(i => new Tuple<LinkedChild, BaseItem>(i, GetLinkedChild(i)))
|
||||
.Where(i => i.Item2 is not null);
|
||||
.Where(i => i.Item2 is not null)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// Class Genre.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class Genre : BaseItem, IItemByName
|
||||
{
|
||||
/// <summary>
|
||||
@@ -61,7 +62,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.GenreIds = new[] { Id };
|
||||
query.ExcludeItemTypes = new[]
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="enablePathSubstitution"><c>true</c> to enable path substitution, <c>false</c> to not.</param>
|
||||
/// <returns>A list of media sources.</returns>
|
||||
List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
|
||||
IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
|
||||
|
||||
List<MediaStream> GetMediaStreams();
|
||||
IReadOnlyList<MediaStream> GetMediaStreams();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public interface IItemByName
|
||||
{
|
||||
IList<BaseItem> GetTaggedItems(InternalItemsQuery query);
|
||||
IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query);
|
||||
}
|
||||
|
||||
public interface IHasDualAccess : IItemByName
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
IncludeItemTypes = Array.Empty<BaseItemKind>();
|
||||
ItemIds = Array.Empty<Guid>();
|
||||
MediaTypes = Array.Empty<MediaType>();
|
||||
MinSimilarityScore = 20;
|
||||
OfficialRatings = Array.Empty<string>();
|
||||
OrderBy = Array.Empty<(ItemSortBy, SortOrder)>();
|
||||
PersonIds = Array.Empty<Guid>();
|
||||
@@ -71,8 +70,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public User? User { get; set; }
|
||||
|
||||
public BaseItem? SimilarTo { get; set; }
|
||||
|
||||
public bool? IsFolder { get; set; }
|
||||
|
||||
public bool? IsFavorite { get; set; }
|
||||
@@ -295,8 +292,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public DtoOptions DtoOptions { get; set; }
|
||||
|
||||
public int MinSimilarityScore { get; set; }
|
||||
|
||||
public string? HasNoAudioTrackWithLanguage { get; set; }
|
||||
|
||||
public string? HasNoInternalSubtitleTrackWithLanguage { get; set; }
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
@@ -12,7 +11,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public LinkedChild()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public string Path { get; set; }
|
||||
@@ -21,9 +19,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public string LibraryItemId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the linked item id.
|
||||
/// </summary>
|
||||
@@ -31,6 +26,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
public static LinkedChild Create(BaseItem item)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(item);
|
||||
|
||||
var child = new LinkedChild
|
||||
{
|
||||
Path = item.Path,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Entities;
|
||||
@@ -91,7 +92,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return Enumerable.Empty<BaseItem>();
|
||||
}
|
||||
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
protected override IReadOnlyList<BaseItem> LoadChildren()
|
||||
{
|
||||
if (IsLegacyBoxSet)
|
||||
{
|
||||
@@ -99,7 +100,7 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
}
|
||||
|
||||
// Save a trip to the database
|
||||
return new List<BaseItem>();
|
||||
return [];
|
||||
}
|
||||
|
||||
public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
|
||||
@@ -127,16 +128,16 @@ namespace MediaBrowser.Controller.Entities.Movies
|
||||
return LibraryManager.Sort(items, user, new[] { sortBy }, SortOrder.Ascending);
|
||||
}
|
||||
|
||||
public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
{
|
||||
var children = base.GetChildren(user, includeLinkedChildren, query);
|
||||
return Sort(children, user).ToList();
|
||||
return Sort(children, user).ToArray();
|
||||
}
|
||||
|
||||
public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
{
|
||||
var children = base.GetRecursiveChildren(user, query);
|
||||
return Sort(children, user).ToList();
|
||||
return Sort(children, user).ToArray();
|
||||
}
|
||||
|
||||
public BoxSetInfo GetLookupInfo()
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
public static class PeopleHelper
|
||||
{
|
||||
public static void AddPerson(List<PersonInfo> people, PersonInfo person)
|
||||
public static void AddPerson(ICollection<PersonInfo> people, PersonInfo person)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(person);
|
||||
ArgumentException.ThrowIfNullOrEmpty(person.Name);
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// This is the full Person object that can be retrieved with all of it's data.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class Person : BaseItem, IItemByName, IHasLookupInfo<PersonLookupInfo>
|
||||
{
|
||||
/// <summary>
|
||||
@@ -62,7 +63,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return value;
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.PersonIds = new[] { Id };
|
||||
|
||||
|
||||
@@ -17,8 +17,14 @@ namespace MediaBrowser.Controller.Entities
|
||||
public PersonInfo()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
Id = Guid.NewGuid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets the PersonId.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class PhotoAlbum : Folder
|
||||
{
|
||||
[JsonIgnore]
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// Class Studio.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class Studio : BaseItem, IItemByName
|
||||
{
|
||||
/// <summary>
|
||||
@@ -63,7 +64,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
query.StudioIds = new[] { Id };
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Text.Json.Serialization;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Extensions;
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Querying;
|
||||
@@ -19,6 +20,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
/// <summary>
|
||||
/// Class Season.
|
||||
/// </summary>
|
||||
[RequiresSourceSerialisation]
|
||||
public class Season : Folder, IHasSeries, IHasLookupInfo<SeasonInfo>
|
||||
{
|
||||
[JsonIgnore]
|
||||
@@ -132,7 +134,7 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
var series = Series;
|
||||
if (series is not null)
|
||||
{
|
||||
return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000", CultureInfo.InvariantCulture);
|
||||
return series.PresentationUniqueKey + "-" + IndexNumber.Value.ToString("000", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,12 +189,12 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||
return list;
|
||||
}
|
||||
|
||||
public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
{
|
||||
return GetSeasons(user, new DtoOptions(true));
|
||||
}
|
||||
|
||||
public List<BaseItem> GetSeasons(User user, DtoOptions options)
|
||||
public IReadOnlyList<BaseItem> GetSeasons(User user, DtoOptions options)
|
||||
{
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class UserRootFolder : Folder
|
||||
{
|
||||
private readonly object _childIdsLock = new object();
|
||||
private readonly Lock _childIdsLock = new();
|
||||
private List<Guid> _childrenIds = null;
|
||||
|
||||
/// <summary>
|
||||
@@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
protected override List<BaseItem> LoadChildren()
|
||||
protected override IReadOnlyList<BaseItem> LoadChildren()
|
||||
{
|
||||
lock (_childIdsLock)
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
{
|
||||
query.SetUser(user);
|
||||
query.Recursive = true;
|
||||
@@ -145,7 +145,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
protected override IReadOnlyList<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
{
|
||||
return GetChildren(user, false);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return ConvertToResult(_libraryManager.GetItemList(query));
|
||||
}
|
||||
|
||||
private QueryResult<BaseItem> ConvertToResult(List<BaseItem> items)
|
||||
private QueryResult<BaseItem> ConvertToResult(IReadOnlyList<BaseItem> items)
|
||||
{
|
||||
return new QueryResult<BaseItem>(items);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// Class Year.
|
||||
/// </summary>
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class Year : BaseItem, IItemByName
|
||||
{
|
||||
[JsonIgnore]
|
||||
@@ -55,7 +56,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
return true;
|
||||
}
|
||||
|
||||
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
public IReadOnlyList<BaseItem> GetTaggedItems(InternalItemsQuery query)
|
||||
{
|
||||
if (!int.TryParse(Name, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using MediaBrowser.Controller.Authentication;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Controller.Events.Authentication;
|
||||
@@ -29,7 +28,7 @@ public class AuthenticationResultEventArgs : EventArgs
|
||||
/// <summary>
|
||||
/// Gets or sets the session information.
|
||||
/// </summary>
|
||||
public SessionInfo? SessionInfo { get; set; }
|
||||
public SessionInfoDto? SessionInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server id.
|
||||
|
||||
@@ -39,16 +39,16 @@ namespace MediaBrowser.Controller.Extensions
|
||||
/// </summary>
|
||||
public const string FfmpegAnalyzeDurationKey = "FFmpeg:analyzeduration";
|
||||
|
||||
/// <summary>
|
||||
/// The key for the FFmpeg image extraction performance tradeoff option.
|
||||
/// </summary>
|
||||
public const string FfmpegImgExtractPerfTradeoffKey = "FFmpeg:imgExtractPerfTradeoff";
|
||||
|
||||
/// <summary>
|
||||
/// The key for the FFmpeg path option.
|
||||
/// </summary>
|
||||
public const string FfmpegPathKey = "ffmpeg";
|
||||
|
||||
/// <summary>
|
||||
/// The key for a setting that indicates whether playlists should allow duplicate entries.
|
||||
/// </summary>
|
||||
public const string PlaylistsAllowDuplicatesKey = "playlists:allowDuplicates";
|
||||
|
||||
/// <summary>
|
||||
/// The key for a setting that indicates whether kestrel should bind to a unix socket.
|
||||
/// </summary>
|
||||
@@ -108,12 +108,12 @@ namespace MediaBrowser.Controller.Extensions
|
||||
=> configuration.GetValue<bool>(FfmpegSkipValidationKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether playlists should allow duplicate entries from the <see cref="IConfiguration"/>.
|
||||
/// Gets a value indicating whether the server should trade off for performance during FFmpeg image extraction.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to read the setting from.</param>
|
||||
/// <returns>True if playlists should allow duplicates, otherwise false.</returns>
|
||||
public static bool DoPlaylistsAllowDuplicates(this IConfiguration configuration)
|
||||
=> configuration.GetValue<bool>(PlaylistsAllowDuplicatesKey);
|
||||
/// <returns><c>true</c> if the server should trade off for performance during FFmpeg image extraction, otherwise <c>false</c>.</returns>
|
||||
public static bool GetFFmpegImgExtractPerfTradeoff(this IConfiguration configuration)
|
||||
=> configuration.GetValue<bool>(FfmpegImgExtractPerfTradeoffKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether kestrel should bind to a unix socket from the <see cref="IConfiguration" />.
|
||||
|
||||
@@ -258,7 +258,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="items">Items to create.</param>
|
||||
/// <param name="parent">Parent of new items.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
void CreateItems(IReadOnlyList<BaseItem> items, BaseItem? parent, CancellationToken cancellationToken);
|
||||
void CreateOrUpdateItems(IReadOnlyList<BaseItem> items, BaseItem? parent, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the item.
|
||||
@@ -483,21 +483,21 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>List<PersonInfo>.</returns>
|
||||
List<PersonInfo> GetPeople(BaseItem item);
|
||||
IReadOnlyList<PersonInfo> GetPeople(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<PersonInfo>.</returns>
|
||||
List<PersonInfo> GetPeople(InternalPeopleQuery query);
|
||||
IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<Person>.</returns>
|
||||
List<Person> GetPeopleItems(InternalPeopleQuery query);
|
||||
IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the people.
|
||||
@@ -513,21 +513,21 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="people">The people.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The async task.</returns>
|
||||
Task UpdatePeopleAsync(BaseItem item, List<PersonInfo> people, CancellationToken cancellationToken);
|
||||
Task UpdatePeopleAsync(BaseItem item, IReadOnlyList<PersonInfo> people, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item ids.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<Guid>.</returns>
|
||||
List<Guid> GetItemIds(InternalItemsQuery query);
|
||||
IReadOnlyList<Guid> GetItemIds(InternalItemsQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people names.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<System.String>.</returns>
|
||||
List<string> GetPeopleNames(InternalPeopleQuery query);
|
||||
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the items.
|
||||
@@ -553,9 +553,9 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>QueryResult<BaseItem>.</returns>
|
||||
List<BaseItem> GetItemList(InternalItemsQuery query);
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query);
|
||||
|
||||
List<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent);
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, bool allowExternalContent);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
@@ -563,7 +563,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="query">The query to use.</param>
|
||||
/// <param name="parents">Items to use for query.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents);
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items result.
|
||||
|
||||
@@ -29,31 +29,31 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <returns>IEnumerable<MediaStream>.</returns>
|
||||
List<MediaStream> GetMediaStreams(Guid itemId);
|
||||
IReadOnlyList<MediaStream> GetMediaStreams(Guid itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable<MediaStream>.</returns>
|
||||
List<MediaStream> GetMediaStreams(MediaStreamQuery query);
|
||||
IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <returns>IEnumerable<MediaAttachment>.</returns>
|
||||
List<MediaAttachment> GetMediaAttachments(Guid itemId);
|
||||
IReadOnlyList<MediaAttachment> GetMediaAttachments(Guid itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable<MediaAttachment>.</returns>
|
||||
List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query);
|
||||
IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the playack media sources.
|
||||
/// Gets the playback media sources.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="user">User to use for operation.</param>
|
||||
@@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="cancellationToken">CancellationToken to use for operation.</param>
|
||||
/// <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>
|
||||
/// Gets the static media sources.
|
||||
@@ -70,7 +70,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="enablePathSubstitution">Option to enable path substitution.</param>
|
||||
/// <param name="user">User to use for operation.</param>
|
||||
/// <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>
|
||||
/// Gets the static media source.
|
||||
@@ -123,7 +123,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="info">The <see cref="ActiveRecordingInfo"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
|
||||
/// <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>
|
||||
/// Closes the media source.
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions);
|
||||
IReadOnlyList<BaseItem> GetInstantMixFromItem(BaseItem item, User? user, DtoOptions dtoOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instant mix from artist.
|
||||
@@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions);
|
||||
IReadOnlyList<BaseItem> GetInstantMixFromArtist(MusicArtist artist, User? user, DtoOptions dtoOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instant mix from genre.
|
||||
@@ -35,6 +35,6 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="user">The user to use.</param>
|
||||
/// <param name="dtoOptions">The options to use.</param>
|
||||
/// <returns>List of items.</returns>
|
||||
List<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions);
|
||||
IReadOnlyList<BaseItem> GetInstantMixFromGenres(IEnumerable<string> genres, User? user, DtoOptions dtoOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <returns>User data.</returns>
|
||||
UserItemData GetUserData(User user, BaseItem item);
|
||||
UserItemData? GetUserData(User user, BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
@@ -52,7 +52,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="item">Item to use.</param>
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <returns>User data dto.</returns>
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, User user);
|
||||
UserItemDataDto? GetUserDataDto(BaseItem item, User user);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data dto.
|
||||
@@ -62,7 +62,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="user">User to use.</param>
|
||||
/// <param name="options">Dto options to use.</param>
|
||||
/// <returns>User data dto.</returns>
|
||||
UserItemDataDto GetUserDataDto(BaseItem item, BaseItemDto? itemDto, User user, DtoOptions options);
|
||||
UserItemDataDto? GetUserDataDto(BaseItem item, BaseItemDto? itemDto, User user, DtoOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Updates playstate for an item and returns true or false indicating if it was played to completion.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -119,13 +120,10 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
return "TvChannel";
|
||||
}
|
||||
|
||||
public IEnumerable<BaseItem> GetTaggedItems()
|
||||
=> Enumerable.Empty<BaseItem>();
|
||||
public IEnumerable<BaseItem> GetTaggedItems() => [];
|
||||
|
||||
public override List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
public override IReadOnlyList<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution)
|
||||
{
|
||||
var list = new List<MediaSourceInfo>();
|
||||
|
||||
var info = new MediaSourceInfo
|
||||
{
|
||||
Id = Id.ToString("N", CultureInfo.InvariantCulture),
|
||||
@@ -138,14 +136,12 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
IsInfiniteStream = RunTimeTicks is null
|
||||
};
|
||||
|
||||
list.Add(info);
|
||||
|
||||
return list;
|
||||
return [info];
|
||||
}
|
||||
|
||||
public override List<MediaStream> GetMediaStreams()
|
||||
public override IReadOnlyList<MediaStream> GetMediaStreams()
|
||||
{
|
||||
return new List<MediaStream>();
|
||||
return [];
|
||||
}
|
||||
|
||||
protected override string GetInternalMetadataPath(string basePath)
|
||||
|
||||
@@ -18,6 +18,7 @@ using MediaBrowser.Model.Providers;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
[Common.RequiresSourceSerialisation]
|
||||
public class LiveTvProgram : BaseItem, IHasLookupInfo<ItemLookupInfo>, IHasStartDate, IHasProgramAttributes
|
||||
{
|
||||
private const string EmbyServiceName = "Emby";
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Controller</PackageId>
|
||||
<VersionPrefix>10.10.0</VersionPrefix>
|
||||
<VersionPrefix>10.11.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
@@ -34,7 +34,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
|
||||
@@ -193,6 +193,8 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
public bool EnableAudioVbrEncoding { get; set; }
|
||||
|
||||
public bool AlwaysBurnInSubtitleWhenTranscoding { get; set; }
|
||||
|
||||
public string GetOption(string qualifier, string name)
|
||||
{
|
||||
var value = GetOption(qualifier + "-" + name);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,8 @@ namespace MediaBrowser.Controller.MediaEncoding;
|
||||
public sealed class TranscodingJob : IDisposable
|
||||
{
|
||||
private readonly ILogger<TranscodingJob> _logger;
|
||||
private readonly object _processLock = new();
|
||||
private readonly object _timerLock = new();
|
||||
private readonly Lock _processLock = new();
|
||||
private readonly Lock _timerLock = new();
|
||||
|
||||
private Timer? _killTimer;
|
||||
|
||||
|
||||
@@ -46,12 +46,22 @@ public interface IMediaSegmentManager
|
||||
Task DeleteSegmentAsync(Guid segmentId);
|
||||
|
||||
/// <summary>
|
||||
/// Obtains all segments accociated with the itemId.
|
||||
/// Obtains all segments associated with the itemId.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The id of the <see cref="BaseItem"/>.</param>
|
||||
/// <param name="typeFilter">filteres all media segments of the given type to be included. If null all types are included.</param>
|
||||
/// <param name="typeFilter">filters all media segments of the given type to be included. If null all types are included.</param>
|
||||
/// <param name="filterByProvider">When set filters the segments to only return those that which providers are currently enabled on their library.</param>
|
||||
/// <returns>An enumerator of <see cref="MediaSegmentDto"/>'s.</returns>
|
||||
Task<IEnumerable<MediaSegmentDto>> GetSegmentsAsync(Guid itemId, IEnumerable<MediaSegmentType>? typeFilter);
|
||||
Task<IEnumerable<MediaSegmentDto>> GetSegmentsAsync(Guid itemId, IEnumerable<MediaSegmentType>? typeFilter, bool filterByProvider = true);
|
||||
|
||||
/// <summary>
|
||||
/// Obtains all segments associated with the itemId.
|
||||
/// </summary>
|
||||
/// <param name="item">The <see cref="BaseItem"/>.</param>
|
||||
/// <param name="typeFilter">filters all media segments of the given type to be included. If null all types are included.</param>
|
||||
/// <param name="filterByProvider">When set filters the segments to only return those that which providers are currently enabled on their library.</param>
|
||||
/// <returns>An enumerator of <see cref="MediaSegmentDto"/>'s.</returns>
|
||||
Task<IEnumerable<MediaSegmentDto>> GetSegmentsAsync(BaseItem item, IEnumerable<MediaSegmentType>? typeFilter, bool filterByProvider = true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets information about any media segments stored for the given itemId.
|
||||
@@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Net
|
||||
SingleWriter = false
|
||||
});
|
||||
|
||||
private readonly object _activeConnectionsLock = new();
|
||||
private readonly Lock _activeConnectionsLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// The _active connections.
|
||||
|
||||
@@ -24,9 +24,9 @@ namespace MediaBrowser.Controller.Net
|
||||
DateTime LastActivityDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date of last Keeplive received.
|
||||
/// Gets or sets the date of last Keepalive received.
|
||||
/// </summary>
|
||||
/// <value>The date of last Keeplive received.</value>
|
||||
/// <value>The date of last Keepalive received.</value>
|
||||
DateTime LastKeepAliveDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Session;
|
||||
|
||||
namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound;
|
||||
@@ -8,13 +9,13 @@ namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound;
|
||||
/// <summary>
|
||||
/// Sessions message.
|
||||
/// </summary>
|
||||
public class SessionsMessage : OutboundWebSocketMessage<IReadOnlyList<SessionInfo>>
|
||||
public class SessionsMessage : OutboundWebSocketMessage<IReadOnlyList<SessionInfoDto>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionsMessage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="data">Session info.</param>
|
||||
public SessionsMessage(IReadOnlyList<SessionInfo> data)
|
||||
public SessionsMessage(IReadOnlyList<SessionInfoDto> data)
|
||||
: base(data)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -7,157 +7,82 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence
|
||||
namespace MediaBrowser.Controller.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Provides an interface to implement an Item repository.
|
||||
/// </summary>
|
||||
public interface IItemRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an interface to implement an Item repository.
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
public interface IItemRepository : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Deletes the item.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
void DeleteItem(Guid id);
|
||||
/// <param name="id">The identifier.</param>
|
||||
void DeleteItem(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the items.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveItems(IReadOnlyList<BaseItem> items, CancellationToken cancellationToken);
|
||||
/// <summary>
|
||||
/// Saves the items.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveItems(IReadOnlyList<BaseItem> items, CancellationToken cancellationToken);
|
||||
|
||||
void SaveImages(BaseItem item);
|
||||
void SaveImages(BaseItem item);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem RetrieveItem(Guid id);
|
||||
/// <summary>
|
||||
/// Retrieves the item.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
BaseItem RetrieveItem(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets chapters for an item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns>The list of chapter info.</returns>
|
||||
List<ChapterInfo> GetChapters(BaseItem item);
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>QueryResult<BaseItem>.</returns>
|
||||
QueryResult<BaseItem> GetItems(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a single chapter for an item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="index">The chapter index.</param>
|
||||
/// <returns>The chapter info at the specified index.</returns>
|
||||
ChapterInfo GetChapter(BaseItem item, int index);
|
||||
/// <summary>
|
||||
/// Gets the item ids list.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>List<Guid>.</returns>
|
||||
IReadOnlyList<Guid> GetItemIdsList(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the chapters.
|
||||
/// </summary>
|
||||
/// <param name="id">The item id.</param>
|
||||
/// <param name="chapters">The list of chapters to save.</param>
|
||||
void SaveChapters(Guid id, IReadOnlyList<ChapterInfo> chapters);
|
||||
/// <summary>
|
||||
/// Gets the item list.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>List<BaseItem>.</returns>
|
||||
IReadOnlyList<BaseItem> GetItemList(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable{MediaStream}.</returns>
|
||||
List<MediaStream> GetMediaStreams(MediaStreamQuery query);
|
||||
/// <summary>
|
||||
/// Updates the inherited values.
|
||||
/// </summary>
|
||||
void UpdateInheritedValues();
|
||||
|
||||
/// <summary>
|
||||
/// Saves the media streams.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="streams">The streams.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken);
|
||||
int GetCount(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>IEnumerable{MediaAttachment}.</returns>
|
||||
List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query);
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="attachments">The attachments.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveMediaAttachments(Guid id, IReadOnlyList<MediaAttachment> attachments, CancellationToken cancellationToken);
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the items.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>QueryResult<BaseItem>.</returns>
|
||||
QueryResult<BaseItem> GetItems(InternalItemsQuery query);
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item ids list.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<Guid>.</returns>
|
||||
List<Guid> GetItemIdsList(InternalItemsQuery query);
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<PersonInfo>.</returns>
|
||||
List<PersonInfo> GetPeople(InternalPeopleQuery query);
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the people.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <param name="people">The people.</param>
|
||||
void UpdatePeople(Guid itemId, List<PersonInfo> people);
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people names.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<System.String>.</returns>
|
||||
List<string> GetPeopleNames(InternalPeopleQuery query);
|
||||
IReadOnlyList<string> GetMusicGenreNames();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item list.
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<BaseItem>.</returns>
|
||||
List<BaseItem> GetItemList(InternalItemsQuery query);
|
||||
IReadOnlyList<string> GetStudioNames();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the inherited values.
|
||||
/// </summary>
|
||||
void UpdateInheritedValues();
|
||||
IReadOnlyList<string> GetGenreNames();
|
||||
|
||||
int GetCount(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetGenres(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetMusicGenres(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetStudios(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetArtists(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAlbumArtists(InternalItemsQuery query);
|
||||
|
||||
QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetAllArtists(InternalItemsQuery query);
|
||||
|
||||
List<string> GetMusicGenreNames();
|
||||
|
||||
List<string> GetStudioNames();
|
||||
|
||||
List<string> GetGenreNames();
|
||||
|
||||
List<string> GetAllArtistNames();
|
||||
}
|
||||
IReadOnlyList<string> GetAllArtistNames();
|
||||
}
|
||||
|
||||
22
MediaBrowser.Controller/Persistence/IItemTypeLookup.cs
Normal file
22
MediaBrowser.Controller/Persistence/IItemTypeLookup.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
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 serialisation target types for music related kinds.
|
||||
/// </summary>
|
||||
IReadOnlyList<string> MusicGenreTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets mapping for all BaseItemKinds and their expected serialization target.
|
||||
/// </summary>
|
||||
IReadOnlyDictionary<BaseItemKind, string> BaseItemKindNames { get; }
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence;
|
||||
|
||||
public interface IMediaAttachmentRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>IEnumerable{MediaAttachment}.</returns>
|
||||
IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the media attachments.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="attachments">The attachments.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveMediaAttachments(Guid id, IReadOnlyList<MediaAttachment> attachments, CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for accessing MediaStreams.
|
||||
/// </summary>
|
||||
public interface IMediaStreamRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the media streams.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>IEnumerable{MediaStream}.</returns>
|
||||
IReadOnlyList<MediaStream> GetMediaStreams(MediaStreamQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the media streams.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="streams">The streams.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveMediaStreams(Guid id, IReadOnlyList<MediaStream> streams, CancellationToken cancellationToken);
|
||||
}
|
||||
33
MediaBrowser.Controller/Persistence/IPeopleRepository.cs
Normal file
33
MediaBrowser.Controller/Persistence/IPeopleRepository.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence;
|
||||
|
||||
public interface IPeopleRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the people.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>The list of people matching the filter.</returns>
|
||||
IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the people.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The item identifier.</param>
|
||||
/// <param name="people">The people.</param>
|
||||
void UpdatePeople(Guid itemId, IReadOnlyList<PersonInfo> people);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the people names.
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>The list of people names matching the filter.</returns>
|
||||
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an interface to implement a UserData repository.
|
||||
/// </summary>
|
||||
public interface IUserDataRepository : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Saves the user data.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="userData">The user data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveUserData(long userId, string key, UserItemData userData, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>The user data.</returns>
|
||||
UserItemData GetUserData(long userId, string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="keys">The keys.</param>
|
||||
/// <returns>The user data.</returns>
|
||||
UserItemData GetUserData(long userId, List<string> keys);
|
||||
|
||||
/// <summary>
|
||||
/// Return all user data associated with the given user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <returns>The list of user item data.</returns>
|
||||
List<UserItemData> GetAllUserData(long userId);
|
||||
|
||||
/// <summary>
|
||||
/// Save all user data associated with the given user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="userData">The user item data.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
void SaveAllUserData(long userId, UserItemData[] userData, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -92,8 +92,9 @@ namespace MediaBrowser.Controller.Playlists
|
||||
/// <param name="playlistId">The playlist identifier.</param>
|
||||
/// <param name="entryId">The entry identifier.</param>
|
||||
/// <param name="newIndex">The new index.</param>
|
||||
/// <param name="callingUserId">The calling user.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task MoveItemAsync(string playlistId, string entryId, int newIndex);
|
||||
Task MoveItemAsync(string playlistId, string entryId, int newIndex, Guid callingUserId);
|
||||
|
||||
/// <summary>
|
||||
/// Removed all playlists of a user.
|
||||
|
||||
@@ -137,27 +137,27 @@ namespace MediaBrowser.Controller.Playlists
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override List<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery query)
|
||||
{
|
||||
return GetPlayableItems(user, query);
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||
protected override IReadOnlyList<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public override IEnumerable<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query)
|
||||
{
|
||||
return GetPlayableItems(user, query);
|
||||
}
|
||||
|
||||
public IEnumerable<Tuple<LinkedChild, BaseItem>> GetManageableItems()
|
||||
public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetManageableItems()
|
||||
{
|
||||
return GetLinkedChildrenInfos();
|
||||
}
|
||||
|
||||
private List<BaseItem> GetPlayableItems(User user, InternalItemsQuery query)
|
||||
private IReadOnlyList<BaseItem> GetPlayableItems(User user, InternalItemsQuery query)
|
||||
{
|
||||
query ??= new InternalItemsQuery(user);
|
||||
|
||||
|
||||
@@ -77,7 +77,8 @@ namespace MediaBrowser.Controller.Providers
|
||||
Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Saves the image.
|
||||
/// Saves the image by giving the image path on filesystem.
|
||||
/// This method will remove the image on the source path after saving it to the destination.
|
||||
/// </summary>
|
||||
/// <param name="item">Image to save.</param>
|
||||
/// <param name="source">Source of image.</param>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma warning disable CA1002, CA2227, CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
@@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
// Images aren't always used so the allocation is a waste a lot of the time
|
||||
private List<LocalImageInfo> _images;
|
||||
private List<(string Url, ImageType Type)> _remoteImages;
|
||||
private List<PersonInfo> _people;
|
||||
|
||||
public MetadataResult()
|
||||
{
|
||||
@@ -21,17 +23,21 @@ namespace MediaBrowser.Controller.Providers
|
||||
|
||||
public List<LocalImageInfo> Images
|
||||
{
|
||||
get => _images ??= new List<LocalImageInfo>();
|
||||
get => _images ??= [];
|
||||
set => _images = value;
|
||||
}
|
||||
|
||||
public List<(string Url, ImageType Type)> RemoteImages
|
||||
{
|
||||
get => _remoteImages ??= new List<(string Url, ImageType Type)>();
|
||||
get => _remoteImages ??= [];
|
||||
set => _remoteImages = value;
|
||||
}
|
||||
|
||||
public List<PersonInfo> People { get; set; }
|
||||
public IReadOnlyList<PersonInfo> People
|
||||
{
|
||||
get => _people;
|
||||
set => _people = value?.ToList();
|
||||
}
|
||||
|
||||
public bool HasMetadata { get; set; }
|
||||
|
||||
@@ -47,7 +53,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
People ??= new List<PersonInfo>();
|
||||
|
||||
PeopleHelper.AddPerson(People, p);
|
||||
PeopleHelper.AddPerson(_people, p);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -61,7 +67,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
}
|
||||
else
|
||||
{
|
||||
People.Clear();
|
||||
_people.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
||||
using Jellyfin.Data.Entities.Security;
|
||||
using MediaBrowser.Controller.Authentication;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Session;
|
||||
using MediaBrowser.Model.SyncPlay;
|
||||
|
||||
@@ -292,6 +293,17 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <returns>SessionInfo.</returns>
|
||||
SessionInfo GetSession(string deviceId, string client, string version);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all sessions available to a user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The session identifier.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="activeWithinSeconds">Active within session limit.</param>
|
||||
/// <param name="controllableUserToCheck">Filter for sessions remote controllable for this user.</param>
|
||||
/// <param name="isApiKey">Is the request authenticated with API key.</param>
|
||||
/// <returns>IReadOnlyList{SessionInfoDto}.</returns>
|
||||
IReadOnlyList<SessionInfoDto> GetSessions(Guid userId, string deviceId, int? activeWithinSeconds, Guid? controllableUserToCheck, bool isApiKey);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the session by authentication token.
|
||||
/// </summary>
|
||||
@@ -312,7 +324,7 @@ namespace MediaBrowser.Controller.Session
|
||||
Task<SessionInfo> GetSessionByAuthenticationToken(Device info, string deviceId, string remoteEndpoint, string appVersion);
|
||||
|
||||
/// <summary>
|
||||
/// Logouts the specified access token.
|
||||
/// Logs out the specified access token.
|
||||
/// </summary>
|
||||
/// <param name="accessToken">The access token.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the log out process.</returns>
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -27,28 +25,45 @@ namespace MediaBrowser.Controller.Session
|
||||
private readonly ISessionManager _sessionManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly object _progressLock = new object();
|
||||
private readonly Lock _progressLock = new();
|
||||
private Timer _progressTimer;
|
||||
private PlaybackProgressInfo _lastProgressInfo;
|
||||
|
||||
private bool _disposed = false;
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SessionInfo"/> class.
|
||||
/// </summary>
|
||||
/// <param name="sessionManager">Instance of <see cref="ISessionManager"/> interface.</param>
|
||||
/// <param name="logger">Instance of <see cref="ILogger"/> interface.</param>
|
||||
public SessionInfo(ISessionManager sessionManager, ILogger logger)
|
||||
{
|
||||
_sessionManager = sessionManager;
|
||||
_logger = logger;
|
||||
|
||||
AdditionalUsers = Array.Empty<SessionUserInfo>();
|
||||
AdditionalUsers = [];
|
||||
PlayState = new PlayerStateInfo();
|
||||
SessionControllers = Array.Empty<ISessionController>();
|
||||
NowPlayingQueue = Array.Empty<QueueItem>();
|
||||
NowPlayingQueueFullItems = Array.Empty<BaseItemDto>();
|
||||
SessionControllers = [];
|
||||
NowPlayingQueue = [];
|
||||
NowPlayingQueueFullItems = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the play state.
|
||||
/// </summary>
|
||||
/// <value>The play state.</value>
|
||||
public PlayerStateInfo PlayState { get; set; }
|
||||
|
||||
public SessionUserInfo[] AdditionalUsers { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the additional users.
|
||||
/// </summary>
|
||||
/// <value>The additional users.</value>
|
||||
public IReadOnlyList<SessionUserInfo> AdditionalUsers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client capabilities.
|
||||
/// </summary>
|
||||
/// <value>The client capabilities.</value>
|
||||
public ClientCapabilities Capabilities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -67,7 +82,7 @@ namespace MediaBrowser.Controller.Session
|
||||
{
|
||||
if (Capabilities is null)
|
||||
{
|
||||
return Array.Empty<MediaType>();
|
||||
return [];
|
||||
}
|
||||
|
||||
return Capabilities.PlayableMediaTypes;
|
||||
@@ -134,9 +149,17 @@ namespace MediaBrowser.Controller.Session
|
||||
/// <value>The now playing item.</value>
|
||||
public BaseItemDto NowPlayingItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the now playing queue full items.
|
||||
/// </summary>
|
||||
/// <value>The now playing queue full items.</value>
|
||||
[JsonIgnore]
|
||||
public BaseItem FullNowPlayingItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the now viewing item.
|
||||
/// </summary>
|
||||
/// <value>The now viewing item.</value>
|
||||
public BaseItemDto NowViewingItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -156,8 +179,12 @@ namespace MediaBrowser.Controller.Session
|
||||
/// </summary>
|
||||
/// <value>The session controller.</value>
|
||||
[JsonIgnore]
|
||||
public ISessionController[] SessionControllers { get; set; }
|
||||
public IReadOnlyList<ISessionController> SessionControllers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the transcoding info.
|
||||
/// </summary>
|
||||
/// <value>The transcoding info.</value>
|
||||
public TranscodingInfo TranscodingInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -177,7 +204,7 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
}
|
||||
|
||||
if (controllers.Length > 0)
|
||||
if (controllers.Count > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -186,6 +213,10 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the session supports media control.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this session supports media control; otherwise, <c>false</c>.</value>
|
||||
public bool SupportsMediaControl
|
||||
{
|
||||
get
|
||||
@@ -208,6 +239,10 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the session supports remote control.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this session supports remote control; otherwise, <c>false</c>.</value>
|
||||
public bool SupportsRemoteControl
|
||||
{
|
||||
get
|
||||
@@ -230,16 +265,40 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the now playing queue.
|
||||
/// </summary>
|
||||
/// <value>The now playing queue.</value>
|
||||
public IReadOnlyList<QueueItem> NowPlayingQueue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the now playing queue full items.
|
||||
/// </summary>
|
||||
/// <value>The now playing queue full items.</value>
|
||||
public IReadOnlyList<BaseItemDto> NowPlayingQueueFullItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the session has a custom device name.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this session has a custom device name; otherwise, <c>false</c>.</value>
|
||||
public bool HasCustomDeviceName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the playlist item id.
|
||||
/// </summary>
|
||||
/// <value>The playlist item id.</value>
|
||||
public string PlaylistItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server id.
|
||||
/// </summary>
|
||||
/// <value>The server id.</value>
|
||||
public string ServerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the user primary image tag.
|
||||
/// </summary>
|
||||
/// <value>The user primary image tag.</value>
|
||||
public string UserPrimaryImageTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -247,8 +306,14 @@ namespace MediaBrowser.Controller.Session
|
||||
/// </summary>
|
||||
/// <value>The supported commands.</value>
|
||||
public IReadOnlyList<GeneralCommandType> SupportedCommands
|
||||
=> Capabilities is null ? Array.Empty<GeneralCommandType>() : Capabilities.SupportedCommands;
|
||||
=> Capabilities is null ? [] : Capabilities.SupportedCommands;
|
||||
|
||||
/// <summary>
|
||||
/// Ensures a controller of type exists.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Class to register.</typeparam>
|
||||
/// <param name="factory">The factory.</param>
|
||||
/// <returns>Tuple{ISessionController, bool}.</returns>
|
||||
public Tuple<ISessionController, bool> EnsureController<T>(Func<SessionInfo, ISessionController> factory)
|
||||
{
|
||||
var controllers = SessionControllers.ToList();
|
||||
@@ -261,18 +326,27 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
|
||||
var newController = factory(this);
|
||||
_logger.LogDebug("Creating new {0}", newController.GetType().Name);
|
||||
_logger.LogDebug("Creating new {Factory}", newController.GetType().Name);
|
||||
controllers.Add(newController);
|
||||
|
||||
SessionControllers = controllers.ToArray();
|
||||
SessionControllers = [.. controllers];
|
||||
return new Tuple<ISessionController, bool>(newController, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a controller to the session.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller.</param>
|
||||
public void AddController(ISessionController controller)
|
||||
{
|
||||
SessionControllers = [..SessionControllers, controller];
|
||||
SessionControllers = [.. SessionControllers, controller];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the session contains a user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id to check.</param>
|
||||
/// <returns><c>true</c> if this session contains the user; otherwise, <c>false</c>.</returns>
|
||||
public bool ContainsUser(Guid userId)
|
||||
{
|
||||
if (UserId.Equals(userId))
|
||||
@@ -291,6 +365,11 @@ namespace MediaBrowser.Controller.Session
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts automatic progressing.
|
||||
/// </summary>
|
||||
/// <param name="progressInfo">The playback progress info.</param>
|
||||
/// <value>The supported commands.</value>
|
||||
public void StartAutomaticProgress(PlaybackProgressInfo progressInfo)
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -359,6 +438,9 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops automatic progressing.
|
||||
/// </summary>
|
||||
public void StopAutomaticProgress()
|
||||
{
|
||||
lock (_progressLock)
|
||||
@@ -373,6 +455,10 @@ namespace MediaBrowser.Controller.Session
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the instance async.
|
||||
/// </summary>
|
||||
/// <returns>ValueTask.</returns>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
_disposed = true;
|
||||
@@ -380,7 +466,7 @@ namespace MediaBrowser.Controller.Session
|
||||
StopAutomaticProgress();
|
||||
|
||||
var controllers = SessionControllers.ToList();
|
||||
SessionControllers = Array.Empty<ISessionController>();
|
||||
SessionControllers = [];
|
||||
|
||||
foreach (var controller in controllers)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Library;
|
||||
namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a BaseItem comparer that requires a User to perform it's comparison.
|
||||
/// Represents a BaseItem comparer that requires a User to perform its comparison.
|
||||
/// </summary>
|
||||
public interface IUserBaseItemComparer : IBaseItemComparer
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ public class StreamState : EncodingJobInfo, IDisposable
|
||||
public VideoRequestDto? VideoRequest => Request as VideoRequestDto;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the direct stream provicer.
|
||||
/// Gets or sets the direct stream provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Deprecated.
|
||||
|
||||
@@ -46,8 +46,10 @@ public interface ITrickplayManager
|
||||
/// <summary>
|
||||
/// Gets the item ids of all items with trickplay info.
|
||||
/// </summary>
|
||||
/// <param name="limit">The limit of items to return.</param>
|
||||
/// <param name="offset">The offset to start the query at.</param>
|
||||
/// <returns>The list of item ids that have trickplay info.</returns>
|
||||
public Task<IReadOnlyList<Guid>> GetTrickplayItemsAsync();
|
||||
Task<IReadOnlyList<TrickplayInfo>> GetTrickplayItemsAsync(int limit, int offset);
|
||||
|
||||
/// <summary>
|
||||
/// Saves trickplay info.
|
||||
|
||||
Reference in New Issue
Block a user