mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-08 16:58:50 +01:00
Merge remote-tracking branch 'upstream/master' into search-rebased
This commit is contained in:
@@ -216,6 +216,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
[JsonIgnore]
|
||||
public string OriginalTitle { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string OriginalLanguage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
|
||||
@@ -1593,17 +1593,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
public List<BaseItem> GetLinkedChildren()
|
||||
{
|
||||
var linkedChildren = LinkedChildren;
|
||||
var list = new List<BaseItem>(linkedChildren.Length);
|
||||
|
||||
foreach (var i in linkedChildren)
|
||||
var resolved = ResolveLinkedChildren(LinkedChildren);
|
||||
var list = new List<BaseItem>(resolved.Count);
|
||||
foreach (var (_, item) in resolved)
|
||||
{
|
||||
var child = GetLinkedChild(i);
|
||||
|
||||
if (child is not null)
|
||||
{
|
||||
list.Add(child);
|
||||
}
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -1704,12 +1698,74 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
|
||||
{
|
||||
return LinkedChildren
|
||||
.Select(i => new Tuple<LinkedChild, BaseItem>(i, GetLinkedChild(i)))
|
||||
.Where(i => i.Item2 is not null)
|
||||
return ResolveLinkedChildren(LinkedChildren)
|
||||
.Select(t => new Tuple<LinkedChild, BaseItem>(t.Info, t.Item))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves a list of <see cref="LinkedChild"/> entries to their <see cref="BaseItem"/> targets,
|
||||
/// batching the database lookup across all entries with a known ItemId.
|
||||
/// Entries without a usable ItemId fall back to the per-entry <see cref="BaseItem.GetLinkedChild"/>
|
||||
/// path (legacy path-based resolution).
|
||||
/// </summary>
|
||||
/// <param name="linkedChildren">Linked children to resolve.</param>
|
||||
/// <returns>Each input entry paired with its resolved item; entries that fail to resolve are dropped.</returns>
|
||||
private List<(LinkedChild Info, BaseItem Item)> ResolveLinkedChildren(IReadOnlyList<LinkedChild> linkedChildren)
|
||||
{
|
||||
var resolved = new List<(LinkedChild Info, BaseItem Item)>(linkedChildren.Count);
|
||||
if (linkedChildren.Count == 0)
|
||||
{
|
||||
return resolved;
|
||||
}
|
||||
|
||||
var idsToBatch = new HashSet<Guid>();
|
||||
foreach (var info in linkedChildren)
|
||||
{
|
||||
if (info.ItemId.HasValue && !info.ItemId.Value.IsEmpty())
|
||||
{
|
||||
idsToBatch.Add(info.ItemId.Value);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<Guid, BaseItem> byId = null;
|
||||
if (idsToBatch.Count > 0)
|
||||
{
|
||||
var batched = LibraryManager.GetItemList(new InternalItemsQuery
|
||||
{
|
||||
ItemIds = [.. idsToBatch]
|
||||
});
|
||||
byId = new Dictionary<Guid, BaseItem>(batched.Count);
|
||||
foreach (var item in batched)
|
||||
{
|
||||
byId[item.Id] = item;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var info in linkedChildren)
|
||||
{
|
||||
BaseItem item = null;
|
||||
if (byId is not null && info.ItemId.HasValue && byId.TryGetValue(info.ItemId.Value, out var batchedItem))
|
||||
{
|
||||
item = batchedItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ItemId is missing/empty or the batched query couldn't return the item
|
||||
// (e.g. it has been removed). Fall back to per-entry resolution, which also
|
||||
// handles legacy path-based linked children.
|
||||
item = GetLinkedChild(info);
|
||||
}
|
||||
|
||||
if (item is not null)
|
||||
{
|
||||
resolved.Add((info, item));
|
||||
}
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
|
||||
{
|
||||
var changesFound = false;
|
||||
|
||||
@@ -22,30 +22,30 @@ public interface IPathManager
|
||||
/// <param name="mediaSourceId">The media source id.</param>
|
||||
/// <param name="streamIndex">The stream index.</param>
|
||||
/// <param name="extension">The subtitle file extension.</param>
|
||||
/// <returns>The absolute path.</returns>
|
||||
public string GetSubtitlePath(string mediaSourceId, int streamIndex, string extension);
|
||||
/// <returns>The absolute path, or <c>null</c> if <paramref name="mediaSourceId"/> is not a valid GUID.</returns>
|
||||
public string? GetSubtitlePath(string mediaSourceId, int streamIndex, string extension);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the subtitle file.
|
||||
/// </summary>
|
||||
/// <param name="mediaSourceId">The media source id.</param>
|
||||
/// <returns>The absolute path.</returns>
|
||||
public string GetSubtitleFolderPath(string mediaSourceId);
|
||||
/// <returns>The absolute path, or <c>null</c> if <paramref name="mediaSourceId"/> is not a valid GUID.</returns>
|
||||
public string? GetSubtitleFolderPath(string mediaSourceId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the attachment file.
|
||||
/// </summary>
|
||||
/// <param name="mediaSourceId">The media source id.</param>
|
||||
/// <param name="fileName">The attachmentFileName index.</param>
|
||||
/// <returns>The absolute path.</returns>
|
||||
public string GetAttachmentPath(string mediaSourceId, string fileName);
|
||||
/// <returns>The absolute path, or <c>null</c> if <paramref name="mediaSourceId"/> is not a valid GUID.</returns>
|
||||
public string? GetAttachmentPath(string mediaSourceId, string fileName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the attachment folder.
|
||||
/// </summary>
|
||||
/// <param name="mediaSourceId">The media source id.</param>
|
||||
/// <returns>The absolute path.</returns>
|
||||
public string GetAttachmentFolderPath(string mediaSourceId);
|
||||
/// <returns>The absolute path, or <c>null</c> if <paramref name="mediaSourceId"/> is not a valid GUID.</returns>
|
||||
public string? GetAttachmentFolderPath(string mediaSourceId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chapter images data path.
|
||||
|
||||
@@ -177,6 +177,13 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <returns>Task.</returns>
|
||||
Task ValidateTopLibraryFolders(CancellationToken cancellationToken, bool removeRoot = false);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the cached ignore rule directory lookups.
|
||||
/// Call this before triggering a library scan or item refresh to ensure
|
||||
/// any changes to .ignore files are picked up.
|
||||
/// </summary>
|
||||
void ClearIgnoreRuleCache();
|
||||
|
||||
Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false);
|
||||
|
||||
/// <summary>
|
||||
@@ -558,7 +565,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="query">The query.</param>
|
||||
/// <returns>List<Person>.</returns>
|
||||
IReadOnlyList<Person> GetPeopleItems(InternalPeopleQuery query);
|
||||
QueryResult<BaseItem> GetPeopleItems(InternalPeopleQuery query);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the people.
|
||||
|
||||
@@ -24,14 +24,14 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Gets the users.
|
||||
/// </summary>
|
||||
/// <value>The users.</value>
|
||||
IEnumerable<User> Users { get; }
|
||||
/// <returns>The users.</returns>
|
||||
IEnumerable<User> GetUsers();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user ids.
|
||||
/// </summary>
|
||||
/// <value>The users ids.</value>
|
||||
IEnumerable<Guid> UsersIds { get; }
|
||||
/// <returns>The users ids.</returns>
|
||||
IEnumerable<Guid> GetUsersIds();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the user manager and ensures that a user exists.
|
||||
@@ -47,6 +47,12 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <exception cref="ArgumentException"><c>id</c> is an empty Guid.</exception>
|
||||
User? GetUserById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first available user.
|
||||
/// </summary>
|
||||
/// <returns>The first user, or <c>null</c> if no users exist.</returns>
|
||||
User? GetFirstUser();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the user by.
|
||||
/// </summary>
|
||||
@@ -57,12 +63,13 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Renames the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="userId">The UserId to change.</param>
|
||||
/// <param name="oldName">The old Username.</param>
|
||||
/// <param name="newName">The new name.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="ArgumentNullException">If user is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentException">If the provided user doesn't exist.</exception>
|
||||
Task RenameUser(User user, string newName);
|
||||
Task RenameUser(Guid userId, string oldName, string newName);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user.
|
||||
@@ -92,17 +99,17 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <summary>
|
||||
/// Resets the password.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="userId">The users Id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task ResetPassword(User user);
|
||||
Task ResetPassword(Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// Changes the password.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="userId">The users id.</param>
|
||||
/// <param name="newPassword">New password to use.</param>
|
||||
/// <returns>Awaitable task.</returns>
|
||||
Task ChangePassword(User user, string newPassword);
|
||||
Task ChangePassword(Guid userId, string newPassword);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user dto.
|
||||
|
||||
31
MediaBrowser.Controller/LiveTv/ISchedulesDirectService.cs
Normal file
31
MediaBrowser.Controller/LiveTv/ISchedulesDirectService.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.LiveTv;
|
||||
|
||||
/// <summary>
|
||||
/// Provides Schedules Direct specific operations.
|
||||
/// </summary>
|
||||
public interface ISchedulesDirectService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the available countries from the Schedules Direct API, using a file cache.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>A stream containing the raw JSON response.</returns>
|
||||
Task<Stream> GetAvailableCountries(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the Schedules Direct daily image download limit is currently active.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the image limit has been hit and has not yet reset; otherwise <c>false</c>.</returns>
|
||||
bool IsImageDailyLimitActive();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the Schedules Direct service is available.
|
||||
/// Returns <c>false</c> if a permanent account error has occurred or a transient backoff is active.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the service can accept requests; otherwise <c>false</c>.</returns>
|
||||
bool IsServiceAvailable();
|
||||
}
|
||||
@@ -37,6 +37,12 @@ public interface ITunerHostManager
|
||||
/// <returns>The <see cref="TunerHostInfo"/>s.</returns>
|
||||
IAsyncEnumerable<TunerHostInfo> DiscoverTuners(bool newDevicesOnly);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a tuner host by id, cleans up associated caches, and triggers a guide refresh.
|
||||
/// </summary>
|
||||
/// <param name="id">The tuner host id to delete.</param>
|
||||
void DeleteTunerHost(string? id);
|
||||
|
||||
/// <summary>
|
||||
/// Scans for tuner devices that have changed URLs.
|
||||
/// </summary>
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace MediaBrowser.Controller.LiveTv
|
||||
{
|
||||
if (double.TryParse(Number, CultureInfo.InvariantCulture, out double number))
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0:00000.0}", number) + "-" + (Name ?? string.Empty);
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0:0000000000.00000}", number) + "-" + (Name ?? string.Empty);
|
||||
}
|
||||
|
||||
return (Number ?? string.Empty) + "-" + (Name ?? string.Empty);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Controller</PackageId>
|
||||
<VersionPrefix>10.12.0</VersionPrefix>
|
||||
<VersionPrefix>12.0.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -91,6 +91,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
/// <value>The codec tag.</value>
|
||||
public string CodecTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rotation.
|
||||
/// </summary>
|
||||
/// <value>The video rotation angle, usually 0 or +-90/180.</value>
|
||||
public string Rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the framerate.
|
||||
/// </summary>
|
||||
|
||||
@@ -1645,10 +1645,9 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
|
||||
if (string.Equals(videoCodec, "h264_amf", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(videoCodec, "hevc_amf", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(videoCodec, "av1_amf", StringComparison.OrdinalIgnoreCase))
|
||||
|| string.Equals(videoCodec, "hevc_amf", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Override the too high default qmin 18 in transcoding preset
|
||||
// Override the too high default qmin 18 in transcoding preset in legacy h26x_amf
|
||||
return FormattableString.Invariant($" -rc cbr -qmin 0 -qmax 32 -b:v {bitrate} -maxrate {bitrate} -bufsize {bufsize}");
|
||||
}
|
||||
|
||||
@@ -1880,10 +1879,12 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
var sub2videoParam = enableSub2video ? ":sub2video=1" : string.Empty;
|
||||
|
||||
var fontPath = _pathManager.GetAttachmentFolderPath(state.MediaSource.Id);
|
||||
var fontParam = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
":fontsdir='{0}'",
|
||||
_mediaEncoder.EscapeSubtitleFilterPath(fontPath));
|
||||
var fontParam = fontPath is null
|
||||
? string.Empty
|
||||
: string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
":fontsdir='{0}'",
|
||||
_mediaEncoder.EscapeSubtitleFilterPath(fontPath));
|
||||
|
||||
if (state.SubtitleStream.IsExternal)
|
||||
{
|
||||
@@ -2466,6 +2467,17 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
}
|
||||
}
|
||||
|
||||
var requestedRotations = state.GetRequestedRotations(videoStream.Codec);
|
||||
if (requestedRotations.Length > 0)
|
||||
{
|
||||
var rotation = state.VideoStream?.Rotation ?? 0;
|
||||
if (rotation != 0
|
||||
&& !requestedRotations.Contains(rotation.ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Video width must fall within requested value
|
||||
if (request.MaxWidth.HasValue
|
||||
&& (!videoStream.Width.HasValue || videoStream.Width.Value > request.MaxWidth.Value))
|
||||
|
||||
@@ -571,62 +571,50 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
|
||||
public string[] GetRequestedProfiles(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.Profile))
|
||||
var profile = BaseRequest.Profile;
|
||||
|
||||
if (string.IsNullOrEmpty(profile) && !string.IsNullOrEmpty(codec))
|
||||
{
|
||||
return BaseRequest.Profile.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
profile = BaseRequest.GetOption(codec, "profile");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var profile = BaseRequest.GetOption(codec, "profile");
|
||||
|
||||
if (!string.IsNullOrEmpty(profile))
|
||||
{
|
||||
return profile.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
return (profile ?? string.Empty).Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetRequestedRangeTypes(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.VideoRangeType))
|
||||
var rangetype = BaseRequest.VideoRangeType;
|
||||
|
||||
if (string.IsNullOrEmpty(rangetype) && !string.IsNullOrEmpty(codec))
|
||||
{
|
||||
return BaseRequest.VideoRangeType.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
rangetype = BaseRequest.GetOption(codec, "rangetype");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var rangetype = BaseRequest.GetOption(codec, "rangetype");
|
||||
|
||||
if (!string.IsNullOrEmpty(rangetype))
|
||||
{
|
||||
return rangetype.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
return (rangetype ?? string.Empty).Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string[] GetRequestedCodecTags(string codec)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(BaseRequest.CodecTag))
|
||||
var codectag = BaseRequest.CodecTag;
|
||||
|
||||
if (string.IsNullOrEmpty(codectag) && !string.IsNullOrEmpty(codec))
|
||||
{
|
||||
return BaseRequest.CodecTag.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
codectag = BaseRequest.GetOption(codec, "codectag");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codec))
|
||||
{
|
||||
var codectag = BaseRequest.GetOption(codec, "codectag");
|
||||
return (codectag ?? string.Empty).Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(codectag))
|
||||
{
|
||||
return codectag.Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
public string[] GetRequestedRotations(string codec)
|
||||
{
|
||||
var rotation = BaseRequest.Rotation;
|
||||
|
||||
if (string.IsNullOrEmpty(rotation) && !string.IsNullOrEmpty(codec))
|
||||
{
|
||||
rotation = BaseRequest.GetOption(codec, "rotation");
|
||||
}
|
||||
|
||||
return Array.Empty<string>();
|
||||
return (rotation ?? string.Empty).Split(_separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
public string GetRequestedLevel(string codec)
|
||||
|
||||
@@ -40,11 +40,6 @@ namespace MediaBrowser.Controller.Net
|
||||
/// </summary>
|
||||
private readonly List<(IWebSocketConnection Connection, CancellationTokenSource CancellationTokenSource, TStateType State)> _activeConnections = new();
|
||||
|
||||
/// <summary>
|
||||
/// The logger.
|
||||
/// </summary>
|
||||
protected readonly ILogger<BasePeriodicWebSocketListener<TReturnDataType, TStateType>> Logger;
|
||||
|
||||
private readonly Task _messageConsumerTask;
|
||||
|
||||
protected BasePeriodicWebSocketListener(ILogger<BasePeriodicWebSocketListener<TReturnDataType, TStateType>> logger)
|
||||
@@ -56,6 +51,11 @@ namespace MediaBrowser.Controller.Net
|
||||
_messageConsumerTask = HandleMessages();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Logger.
|
||||
/// </summary>
|
||||
protected ILogger<BasePeriodicWebSocketListener<TReturnDataType, TStateType>> Logger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type used for the messages sent to the client.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#nullable disable
|
||||
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Querying;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence;
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for accessing Peoples.
|
||||
/// </summary>
|
||||
public interface IPeopleRepository
|
||||
{
|
||||
/// <summary>
|
||||
@@ -15,7 +17,7 @@ public interface IPeopleRepository
|
||||
/// </summary>
|
||||
/// <param name="filter">The query.</param>
|
||||
/// <returns>The list of people matching the filter.</returns>
|
||||
IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery filter);
|
||||
QueryResult<PersonInfo> GetPeople(InternalPeopleQuery filter);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the people.
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public IReadOnlyList<string> GetFilePaths(string path)
|
||||
=> GetFilePaths(path, false);
|
||||
|
||||
public IReadOnlyList<string> GetFilePaths(string path, bool clearCache, bool sort = false)
|
||||
public IReadOnlyList<string> GetFilePaths(string path, bool clearCache)
|
||||
{
|
||||
if (clearCache)
|
||||
{
|
||||
@@ -118,7 +118,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
try
|
||||
{
|
||||
return fileSystem.GetFilePaths(p).ToList();
|
||||
return fileSystem.GetFilePaths(p).OrderBy(x => x).ToList();
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
@@ -127,11 +127,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
},
|
||||
_fileSystem);
|
||||
|
||||
if (sort)
|
||||
{
|
||||
filePaths.Sort();
|
||||
}
|
||||
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
|
||||
IReadOnlyList<string> GetFilePaths(string path);
|
||||
|
||||
IReadOnlyList<string> GetFilePaths(string path, bool clearCache, bool sort = false);
|
||||
IReadOnlyList<string> GetFilePaths(string path, bool clearCache);
|
||||
|
||||
bool IsAccessible(string path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user