mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-12-15 21:43:03 +03:00
Compare commits
10 Commits
v10.11.3
...
only-count
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a78c3385c9 | ||
|
|
daca285568 | ||
|
|
fbb9a0b2c7 | ||
|
|
29b3aa8543 | ||
|
|
94f3725208 | ||
|
|
0ee81e87be | ||
|
|
c491a918c2 | ||
|
|
1e7e46cb82 | ||
|
|
5ae444d96d | ||
|
|
ee7ad83427 |
@@ -497,8 +497,17 @@ namespace Emby.Server.Implementations.IO
|
||||
/// <inheritdoc />
|
||||
public virtual bool AreEqual(string path1, string path2)
|
||||
{
|
||||
return Path.TrimEndingDirectorySeparator(path1).Equals(
|
||||
Path.TrimEndingDirectorySeparator(path2),
|
||||
if (string.IsNullOrWhiteSpace(path1) || string.IsNullOrWhiteSpace(path2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var normalized1 = Path.TrimEndingDirectorySeparator(path1);
|
||||
var normalized2 = Path.TrimEndingDirectorySeparator(path2);
|
||||
|
||||
return string.Equals(
|
||||
normalized1,
|
||||
normalized2,
|
||||
_isEnvironmentCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
|
||||
@@ -347,8 +347,8 @@ pli||pi|Pali|pali
|
||||
pol||pl|Polish|polonais
|
||||
pon|||Pohnpeian|pohnpei
|
||||
por||pt|Portuguese|portugais
|
||||
por||pt-pt|Portuguese (Portugal)|portugais (pt-pt)
|
||||
por||pt-br|Portuguese (Brazil)|portugais (pt-br)
|
||||
pop||pt-pt|Portuguese (Portugal)|portugais (pt-pt)
|
||||
pob||pt-br|Portuguese (Brazil)|portugais (pt-br)
|
||||
pra|||Prakrit languages|prâkrit, langues
|
||||
pro|||Provençal, Old (to 1500)|provençal ancien (jusqu'à 1500)
|
||||
pus||ps|Pushto; Pashto|pachto
|
||||
|
||||
@@ -618,12 +618,18 @@ public sealed class BaseItemRepository
|
||||
{
|
||||
context.BaseItemProviders.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
||||
context.BaseItemImageInfos.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
||||
context.BaseItemMetadataFields.Where(e => e.ItemId == entity.Id).ExecuteDelete();
|
||||
|
||||
if (entity.Images is { Count: > 0 })
|
||||
{
|
||||
context.BaseItemImageInfos.AddRange(entity.Images);
|
||||
}
|
||||
|
||||
if (entity.LockedFields is { Count: > 0 })
|
||||
{
|
||||
context.BaseItemMetadataFields.AddRange(entity.LockedFields);
|
||||
}
|
||||
|
||||
context.BaseItems.Attach(entity).State = EntityState.Modified;
|
||||
}
|
||||
}
|
||||
@@ -1647,19 +1653,18 @@ public sealed class BaseItemRepository
|
||||
var tags = filter.Tags.ToList();
|
||||
var excludeTags = filter.ExcludeTags.ToList();
|
||||
|
||||
if (filter.IsMovie == true)
|
||||
if (filter.IsMovie.HasValue)
|
||||
{
|
||||
if (filter.IncludeItemTypes.Length == 0
|
||||
|| filter.IncludeItemTypes.Contains(BaseItemKind.Movie)
|
||||
|| filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
|
||||
var shouldIncludeAllMovieTypes = filter.IsMovie.Value
|
||||
&& (filter.IncludeItemTypes.Length == 0
|
||||
|| filter.IncludeItemTypes.Contains(BaseItemKind.Movie)
|
||||
|| filter.IncludeItemTypes.Contains(BaseItemKind.Trailer));
|
||||
|
||||
if (!shouldIncludeAllMovieTypes)
|
||||
{
|
||||
baseQuery = baseQuery.Where(e => e.IsMovie);
|
||||
baseQuery = baseQuery.Where(e => e.IsMovie == filter.IsMovie.Value);
|
||||
}
|
||||
}
|
||||
else if (filter.IsMovie.HasValue)
|
||||
{
|
||||
baseQuery = baseQuery.Where(e => e.IsMovie == filter.IsMovie);
|
||||
}
|
||||
|
||||
if (filter.IsSeries.HasValue)
|
||||
{
|
||||
|
||||
@@ -668,34 +668,22 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
var result = GetItems(new InternalItemsQuery(user)
|
||||
return LibraryManager.GetCount(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = false,
|
||||
Limit = 0,
|
||||
Parent = this,
|
||||
DtoOptions = new DtoOptions(false)
|
||||
{
|
||||
EnableImages = false
|
||||
}
|
||||
Parent = this
|
||||
});
|
||||
|
||||
return result.TotalRecordCount;
|
||||
}
|
||||
|
||||
public virtual int GetRecursiveChildCount(User user)
|
||||
{
|
||||
return GetItems(new InternalItemsQuery(user)
|
||||
return LibraryManager.GetCount(new InternalItemsQuery(user)
|
||||
{
|
||||
Recursive = true,
|
||||
Parent = this,
|
||||
IsFolder = false,
|
||||
IsVirtualItem = false,
|
||||
EnableTotalRecordCount = true,
|
||||
Limit = 0,
|
||||
DtoOptions = new DtoOptions(false)
|
||||
{
|
||||
EnableImages = false
|
||||
}
|
||||
}).TotalRecordCount;
|
||||
IsVirtualItem = false
|
||||
});
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> QueryRecursive(InternalItemsQuery query)
|
||||
@@ -1409,7 +1397,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
if (this is BoxSet && (query.OrderBy is null || query.OrderBy.Count == 0))
|
||||
{
|
||||
realChildren = realChildren
|
||||
.OrderBy(e => e.ProductionYear ?? int.MaxValue)
|
||||
.OrderBy(e => e.PremiereDate ?? DateTime.MaxValue)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,29 @@ public static class FileSystemHelper
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves a single link hop for the specified path.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns <c>null</c> if the path is not a symbolic link or the filesystem does not support link resolution (e.g., exFAT).
|
||||
/// </remarks>
|
||||
/// <param name="path">The file path to resolve.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="FileInfo"/> representing the next link target if the path is a link; otherwise, <c>null</c>.
|
||||
/// </returns>
|
||||
private static FileInfo? Resolve(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.ResolveLinkTarget(path, returnFinalTarget: false) as FileInfo;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// Filesystem doesn't support links (e.g., exFAT).
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target of the specified file link.
|
||||
/// </summary>
|
||||
@@ -84,23 +107,26 @@ public static class FileSystemHelper
|
||||
|
||||
if (!returnFinalTarget)
|
||||
{
|
||||
return File.ResolveLinkTarget(linkPath, returnFinalTarget: false) as FileInfo;
|
||||
return Resolve(linkPath);
|
||||
}
|
||||
|
||||
if (File.ResolveLinkTarget(linkPath, returnFinalTarget: false) is not FileInfo targetInfo)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!targetInfo.Exists)
|
||||
var targetInfo = Resolve(linkPath);
|
||||
if (targetInfo is null || !targetInfo.Exists)
|
||||
{
|
||||
return targetInfo;
|
||||
}
|
||||
|
||||
var currentPath = targetInfo.FullName;
|
||||
var visited = new HashSet<string>(StringComparer.Ordinal) { linkPath, currentPath };
|
||||
while (File.ResolveLinkTarget(currentPath, returnFinalTarget: false) is FileInfo linkInfo)
|
||||
|
||||
while (true)
|
||||
{
|
||||
var linkInfo = Resolve(currentPath);
|
||||
if (linkInfo is null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var targetPath = linkInfo.FullName;
|
||||
|
||||
// If an infinite loop is detected, return the file info for the
|
||||
|
||||
@@ -2378,6 +2378,13 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
var requestHasSDR = requestedRangeTypes.Contains(VideoRangeType.SDR.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||
var requestHasDOVI = requestedRangeTypes.Contains(VideoRangeType.DOVI.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// If SDR is the only supported range, we should not copy any of the HDR streams.
|
||||
// All the following copy check assumes at least one HDR format is supported.
|
||||
if (requestedRangeTypes.Length == 1 && requestHasSDR && videoStream.VideoRangeType != VideoRangeType.SDR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the client does not support DOVI and the video stream is DOVI without fallback, we should not copy it.
|
||||
if (!requestHasDOVI && videoStream.VideoRangeType == VideoRangeType.DOVI)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using BDInfo.IO;
|
||||
@@ -58,6 +59,8 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsHidden(ReadOnlySpan<char> name) => name.StartsWith('.');
|
||||
|
||||
/// <summary>
|
||||
/// Gets the directories.
|
||||
/// </summary>
|
||||
@@ -65,6 +68,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
||||
public IDirectoryInfo[] GetDirectories()
|
||||
{
|
||||
return _fileSystem.GetDirectories(_impl.FullName)
|
||||
.Where(d => !IsHidden(d.Name))
|
||||
.Select(x => new BdInfoDirectoryInfo(_fileSystem, x))
|
||||
.ToArray();
|
||||
}
|
||||
@@ -76,6 +80,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
||||
public IFileInfo[] GetFiles()
|
||||
{
|
||||
return _fileSystem.GetFiles(_impl.FullName)
|
||||
.Where(d => !IsHidden(d.Name))
|
||||
.Select(x => new BdInfoFileInfo(x))
|
||||
.ToArray();
|
||||
}
|
||||
@@ -88,6 +93,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
||||
public IFileInfo[] GetFiles(string searchPattern)
|
||||
{
|
||||
return _fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false, false)
|
||||
.Where(d => !IsHidden(d.Name))
|
||||
.Select(x => new BdInfoFileInfo(x))
|
||||
.ToArray();
|
||||
}
|
||||
@@ -105,6 +111,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
|
||||
new[] { searchPattern },
|
||||
false,
|
||||
searchOption == SearchOption.AllDirectories)
|
||||
.Where(d => !IsHidden(d.Name))
|
||||
.Select(x => new BdInfoFileInfo(x))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||
? "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_chapters -show_format"
|
||||
: "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_format";
|
||||
|
||||
if (!isAudio && _proberSupportsFirstVideoFrame)
|
||||
if (protocol == MediaProtocol.File && !isAudio && _proberSupportsFirstVideoFrame)
|
||||
{
|
||||
args += " -show_frames -only_first_vframe";
|
||||
}
|
||||
|
||||
@@ -151,9 +151,9 @@ namespace MediaBrowser.Providers.Manager
|
||||
.ConfigureAwait(false);
|
||||
updateType |= beforeSaveResult;
|
||||
|
||||
if (!isFirstRefresh)
|
||||
if (isFirstRefresh)
|
||||
{
|
||||
updateType = await SaveInternal(item, refreshOptions, updateType, isFirstRefresh, requiresRefresh, metadataResult, cancellationToken).ConfigureAwait(false);
|
||||
await SaveItemAsync(metadataResult, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Next run metadata providers
|
||||
|
||||
Reference in New Issue
Block a user