mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-17 15:53:42 +01:00
@@ -1,5 +1,4 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Channels
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{DynamicImageInfo}.</returns>
|
||||
/// <returns>Task{DynamicImageResponse}.</returns>
|
||||
Task<DynamicImageResponse> GetChannelImage(ImageType type, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
@@ -20,20 +19,12 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <value>The supported input formats.</value>
|
||||
IReadOnlyCollection<string> SupportedInputFormats { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image enhancers.
|
||||
/// </summary>
|
||||
/// <value>The image enhancers.</value>
|
||||
IReadOnlyCollection<IImageEnhancer> ImageEnhancers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether [supports image collage creation].
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [supports image collage creation]; otherwise, <c>false</c>.</value>
|
||||
bool SupportsImageCollageCreation { get; }
|
||||
|
||||
IImageEncoder ImageEncoder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dimensions of the image.
|
||||
/// </summary>
|
||||
@@ -58,14 +49,6 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <returns>ImageDimensions</returns>
|
||||
ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported enhancers.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns>IEnumerable{IImageEnhancer}.</returns>
|
||||
IEnumerable<IImageEnhancer> GetSupportedEnhancers(BaseItem item, ImageType imageType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image cache tag.
|
||||
/// </summary>
|
||||
@@ -75,15 +58,6 @@ namespace MediaBrowser.Controller.Drawing
|
||||
string GetImageCacheTag(BaseItem item, ItemImageInfo image);
|
||||
string GetImageCacheTag(BaseItem item, ChapterInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the image cache tag.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="image">The image.</param>
|
||||
/// <param name="imageEnhancers">The image enhancers.</param>
|
||||
/// <returns>Guid.</returns>
|
||||
string GetImageCacheTag(BaseItem item, ItemImageInfo image, IReadOnlyCollection<IImageEnhancer> imageEnhancers);
|
||||
|
||||
/// <summary>
|
||||
/// Processes the image.
|
||||
/// </summary>
|
||||
@@ -99,15 +73,6 @@ namespace MediaBrowser.Controller.Drawing
|
||||
/// <returns>Task.</returns>
|
||||
Task<(string path, string mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the enhanced image.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <returns>Task{System.String}.</returns>
|
||||
Task<string> GetEnhancedImage(BaseItem item, ImageType imageType, int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the supported image output formats.
|
||||
/// </summary>
|
||||
|
||||
@@ -19,8 +19,6 @@ namespace MediaBrowser.Controller.Drawing
|
||||
return GetSizeEstimate(options);
|
||||
}
|
||||
|
||||
public static IImageProcessor ImageProcessor { get; set; }
|
||||
|
||||
private static ImageDimensions GetSizeEstimate(ImageProcessingOptions options)
|
||||
{
|
||||
if (options.Width.HasValue && options.Height.HasValue)
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
|
||||
namespace MediaBrowser.Controller.Drawing
|
||||
@@ -34,8 +33,6 @@ namespace MediaBrowser.Controller.Drawing
|
||||
|
||||
public int Quality { get; set; }
|
||||
|
||||
public IReadOnlyCollection<IImageEnhancer> Enhancers { get; set; }
|
||||
|
||||
public IReadOnlyCollection<ImageFormat> SupportedOutputFormats { get; set; }
|
||||
|
||||
public bool AddPlayedIndicator { get; set; }
|
||||
|
||||
@@ -198,6 +198,7 @@ namespace MediaBrowser.Controller.Entities.Audio
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.RequiresRefresh();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// Class BaseItem
|
||||
/// </summary>
|
||||
public abstract class BaseItem : IHasProviderIds, IHasLookupInfo<ItemLookupInfo>
|
||||
public abstract class BaseItem : IHasProviderIds, IHasLookupInfo<ItemLookupInfo>, IEquatable<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// The supported image extensions
|
||||
@@ -387,15 +387,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
while (thisMarker < s1.Length)
|
||||
{
|
||||
if (thisMarker >= s1.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
char thisCh = s1[thisMarker];
|
||||
|
||||
var thisChunk = new StringBuilder();
|
||||
bool isNumeric = char.IsDigit(thisCh);
|
||||
|
||||
while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0])))
|
||||
while (thisMarker < s1.Length && char.IsDigit(thisCh) == isNumeric)
|
||||
{
|
||||
thisChunk.Append(thisCh);
|
||||
thisMarker++;
|
||||
@@ -406,7 +403,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
}
|
||||
|
||||
var isNumeric = thisChunk.Length > 0 && char.IsDigit(thisChunk[0]);
|
||||
list.Add(new Tuple<StringBuilder, bool>(thisChunk, isNumeric));
|
||||
}
|
||||
|
||||
@@ -2194,13 +2190,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <summary>
|
||||
/// Do whatever refreshing is necessary when the filesystem pertaining to this item has changed.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public virtual void ChangedExternally()
|
||||
{
|
||||
ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(new DirectoryService(FileSystem))
|
||||
{
|
||||
|
||||
}, RefreshPriority.High);
|
||||
ProviderManager.QueueRefresh(Id, new MetadataRefreshOptions(new DirectoryService(FileSystem)), RefreshPriority.High);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2231,7 +2223,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
existingImage.Width = image.Width;
|
||||
existingImage.Height = image.Height;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var current = ImageInfos;
|
||||
@@ -2274,7 +2265,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public void DeleteImage(ImageType type, int index)
|
||||
{
|
||||
var info = GetImageInfo(type, index);
|
||||
@@ -2312,7 +2302,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that images within the item are still on the file system
|
||||
/// Validates that images within the item are still on the filesystem.
|
||||
/// </summary>
|
||||
public bool ValidateImages(IDirectoryService directoryService)
|
||||
{
|
||||
@@ -2606,7 +2596,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called before any metadata refresh and returns true or false indicating if changes were made
|
||||
/// This is called before any metadata refresh and returns true if changes were made.
|
||||
/// </summary>
|
||||
public virtual bool BeforeMetadataRefresh(bool replaceAllMetdata)
|
||||
{
|
||||
@@ -2666,36 +2656,43 @@ namespace MediaBrowser.Controller.Entities
|
||||
newOptions.ForceSave = true;
|
||||
ownedItem.Genres = item.Genres;
|
||||
}
|
||||
|
||||
if (!item.Studios.SequenceEqual(ownedItem.Studios, StringComparer.Ordinal))
|
||||
{
|
||||
newOptions.ForceSave = true;
|
||||
ownedItem.Studios = item.Studios;
|
||||
}
|
||||
|
||||
if (!item.ProductionLocations.SequenceEqual(ownedItem.ProductionLocations, StringComparer.Ordinal))
|
||||
{
|
||||
newOptions.ForceSave = true;
|
||||
ownedItem.ProductionLocations = item.ProductionLocations;
|
||||
}
|
||||
|
||||
if (item.CommunityRating != ownedItem.CommunityRating)
|
||||
{
|
||||
ownedItem.CommunityRating = item.CommunityRating;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (item.CriticRating != ownedItem.CriticRating)
|
||||
{
|
||||
ownedItem.CriticRating = item.CriticRating;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(item.Overview, ownedItem.Overview, StringComparison.Ordinal))
|
||||
{
|
||||
ownedItem.Overview = item.Overview;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(item.OfficialRating, ownedItem.OfficialRating, StringComparison.Ordinal))
|
||||
{
|
||||
ownedItem.OfficialRating = item.OfficialRating;
|
||||
newOptions.ForceSave = true;
|
||||
}
|
||||
|
||||
if (!string.Equals(item.CustomRating, ownedItem.CustomRating, StringComparison.Ordinal))
|
||||
{
|
||||
ownedItem.CustomRating = item.CustomRating;
|
||||
@@ -2904,11 +2901,17 @@ namespace MediaBrowser.Controller.Entities
|
||||
}
|
||||
|
||||
public virtual bool IsHD => Height >= 720;
|
||||
|
||||
public bool IsShortcut { get; set; }
|
||||
|
||||
public string ShortcutPath { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public Guid[] ExtraIds { get; set; }
|
||||
|
||||
public virtual long GetRunTimeTicksForPlayState()
|
||||
{
|
||||
return RunTimeTicks ?? 0;
|
||||
@@ -2918,5 +2921,17 @@ namespace MediaBrowser.Controller.Entities
|
||||
public static readonly IReadOnlyCollection<ExtraType> DisplayExtraTypes = new[] { Model.Entities.ExtraType.BehindTheScenes, Model.Entities.ExtraType.Clip, Model.Entities.ExtraType.DeletedScene, Model.Entities.ExtraType.Interview, Model.Entities.ExtraType.Sample, Model.Entities.ExtraType.Scene };
|
||||
|
||||
public virtual bool SupportsExternalTransfer => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is BaseItem baseItem && this.Equals(baseItem);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(BaseItem item) => Object.Equals(Id, item?.Id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode() => HashCode.Combine(Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesPresentationUniqueKey { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string SeriesName { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid SeriesId { get; set; }
|
||||
|
||||
@@ -22,10 +24,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
|
||||
public string FindSeriesName()
|
||||
{
|
||||
return SeriesName;
|
||||
}
|
||||
|
||||
public string FindSeriesPresentationUniqueKey()
|
||||
{
|
||||
return SeriesPresentationUniqueKey;
|
||||
|
||||
@@ -322,10 +322,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
ProviderManager.OnRefreshProgress(this, 5);
|
||||
}
|
||||
|
||||
//build a dictionary of the current children we have now by Id so we can compare quickly and easily
|
||||
// Build a dictionary of the current children we have now by Id so we can compare quickly and easily
|
||||
var currentChildren = GetActualChildrenDictionary();
|
||||
|
||||
//create a list for our validated children
|
||||
// Create a list for our validated children
|
||||
var newItems = new List<BaseItem>();
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -391,7 +391,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
var folder = this;
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double newPct = .80 * p + 10;
|
||||
double newPct = 0.80 * p + 10;
|
||||
progress.Report(newPct);
|
||||
ProviderManager.OnRefreshProgress(folder, newPct);
|
||||
});
|
||||
@@ -421,7 +421,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
var folder = this;
|
||||
innerProgress.RegisterAction(p =>
|
||||
{
|
||||
double newPct = .10 * p + 90;
|
||||
double newPct = 0.10 * p + 90;
|
||||
progress.Report(newPct);
|
||||
if (recursive)
|
||||
{
|
||||
@@ -807,11 +807,45 @@ namespace MediaBrowser.Controller.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
private static BaseItem[] SortItemsByRequest(InternalItemsQuery query, IReadOnlyList<BaseItem> items)
|
||||
{
|
||||
var ids = query.ItemIds;
|
||||
int size = items.Count;
|
||||
|
||||
// ids can potentially contain non-unique guids, but query result cannot,
|
||||
// so we include only first occurrence of each guid
|
||||
var positions = new Dictionary<Guid, int>(size);
|
||||
int index = 0;
|
||||
for (int i = 0; i < ids.Length; i++)
|
||||
{
|
||||
if (positions.TryAdd(ids[i], index))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
var newItems = new BaseItem[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
newItems[positions[item.Id]] = item;
|
||||
}
|
||||
|
||||
return newItems;
|
||||
}
|
||||
|
||||
public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
|
||||
{
|
||||
if (query.ItemIds.Length > 0)
|
||||
{
|
||||
return LibraryManager.GetItemsResult(query);
|
||||
var result = LibraryManager.GetItemsResult(query);
|
||||
|
||||
if (query.OrderBy.Count == 0 && query.ItemIds.Length > 1)
|
||||
{
|
||||
result.Items = SortItemsByRequest(query, result.Items);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return GetItemsInternal(query);
|
||||
@@ -823,7 +857,14 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
if (query.ItemIds.Length > 0)
|
||||
{
|
||||
return LibraryManager.GetItemList(query);
|
||||
var result = LibraryManager.GetItemList(query);
|
||||
|
||||
if (query.OrderBy.Count == 0 && query.ItemIds.Length > 1)
|
||||
{
|
||||
return SortItemsByRequest(query, result);
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
return GetItemsInternal(query).Items;
|
||||
|
||||
@@ -135,57 +135,4 @@ namespace MediaBrowser.Controller.Entities
|
||||
return hasChanges;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the small Person stub that is attached to BaseItems
|
||||
/// </summary>
|
||||
public class PersonInfo : IHasProviderIds
|
||||
{
|
||||
public PersonInfo()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the role.
|
||||
/// </summary>
|
||||
/// <value>The role.</value>
|
||||
public string Role { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sort order - ascending
|
||||
/// </summary>
|
||||
/// <value>The sort order.</value>
|
||||
public int? SortOrder { get; set; }
|
||||
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="string" /> that represents this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public bool IsType(string type)
|
||||
{
|
||||
return string.Equals(Type, type, StringComparison.OrdinalIgnoreCase) || string.Equals(Role, type, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
63
MediaBrowser.Controller/Entities/PersonInfo.cs
Normal file
63
MediaBrowser.Controller/Entities/PersonInfo.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a small Person stub that is attached to BaseItems.
|
||||
/// </summary>
|
||||
public sealed class PersonInfo : IHasProviderIds
|
||||
{
|
||||
public PersonInfo()
|
||||
{
|
||||
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the role.
|
||||
/// </summary>
|
||||
/// <value>The role.</value>
|
||||
public string Role { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ascending sort order.
|
||||
/// </summary>
|
||||
/// <value>The sort order.</value>
|
||||
public int? SortOrder { get; set; }
|
||||
|
||||
public string ImageUrl { get; set; }
|
||||
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="string" /> that represents this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public bool IsType(string type)
|
||||
{
|
||||
return string.Equals(Type, type, StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(Role, type, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,10 +41,10 @@ namespace MediaBrowser.Controller.Entities
|
||||
public override double GetDefaultPrimaryImageAspectRatio()
|
||||
{
|
||||
// REVIEW: @bond
|
||||
if (Width.HasValue && Height.HasValue)
|
||||
if (Width != 0 && Height != 0)
|
||||
{
|
||||
double width = Width.Value;
|
||||
double height = Height.Value;
|
||||
double width = Width;
|
||||
double height = Height;
|
||||
|
||||
if (Orientation.HasValue)
|
||||
{
|
||||
@@ -67,8 +67,6 @@ namespace MediaBrowser.Controller.Entities
|
||||
return base.GetDefaultPrimaryImageAspectRatio();
|
||||
}
|
||||
|
||||
public new int? Width { get; set; }
|
||||
public new int? Height { get; set; }
|
||||
public string CameraMake { get; set; }
|
||||
public string CameraModel { get; set; }
|
||||
public string Software { get; set; }
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.LiveTv;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
@@ -13,24 +13,37 @@ namespace MediaBrowser.Controller.Extensions
|
||||
public const string FfmpegProbeSizeKey = "FFmpeg:probesize";
|
||||
|
||||
/// <summary>
|
||||
/// The key for the FFmpeg analyse duration option.
|
||||
/// The key for the FFmpeg analyze duration option.
|
||||
/// </summary>
|
||||
public const string FfmpegAnalyzeDurationKey = "FFmpeg:analyzeduration";
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the FFmpeg probe size from the <see cref="IConfiguration" />.
|
||||
/// The key for a setting that indicates whether playlists should allow duplicate entries.
|
||||
/// </summary>
|
||||
/// <param name="configuration">This configuration.</param>
|
||||
public const string PlaylistsAllowDuplicatesKey = "playlists:allowDuplicates";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FFmpeg probe size from the <see cref="IConfiguration" />.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to read the setting from.</param>
|
||||
/// <returns>The FFmpeg probe size option.</returns>
|
||||
public static string GetFFmpegProbeSize(this IConfiguration configuration)
|
||||
=> configuration[FfmpegProbeSizeKey];
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the FFmpeg analyse duration from the <see cref="IConfiguration" />.
|
||||
/// Gets the FFmpeg analyze duration from the <see cref="IConfiguration" />.
|
||||
/// </summary>
|
||||
/// <param name="configuration">This configuration.</param>
|
||||
/// <returns>The FFmpeg analyse duration option.</returns>
|
||||
/// <param name="configuration">The configuration to read the setting from.</param>
|
||||
/// <returns>The FFmpeg analyze duration option.</returns>
|
||||
public static string GetFFmpegAnalyzeDuration(this IConfiguration configuration)
|
||||
=> configuration[FfmpegAnalyzeDurationKey];
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether playlists should allow duplicate entries from the <see cref="IConfiguration"/>.
|
||||
/// </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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,8 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="introProviders">The intro providers.</param>
|
||||
/// <param name="itemComparers">The item comparers.</param>
|
||||
/// <param name="postscanTasks">The postscan tasks.</param>
|
||||
void AddParts(IEnumerable<IResolverIgnoreRule> rules,
|
||||
void AddParts(
|
||||
IEnumerable<IResolverIgnoreRule> rules,
|
||||
IEnumerable<IItemResolver> resolvers,
|
||||
IEnumerable<IIntroProvider> introProviders,
|
||||
IEnumerable<IBaseItemComparer> itemComparers,
|
||||
@@ -349,9 +350,6 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <returns><c>true</c> if [is audio file] [the specified path]; otherwise, <c>false</c>.</returns>
|
||||
bool IsAudioFile(string path);
|
||||
|
||||
bool IsAudioFile(string path, LibraryOptions libraryOptions);
|
||||
bool IsVideoFile(string path, LibraryOptions libraryOptions);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the season number from path.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable SA1600
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public Profiler(string name, ILogger logger)
|
||||
public Profiler(string name, ILogger<Profiler> logger)
|
||||
{
|
||||
this._name = name;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -26,4 +27,16 @@
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Code Analyzers-->
|
||||
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -316,11 +316,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
|
||||
{
|
||||
var size = new ImageDimensions
|
||||
{
|
||||
Width = VideoStream.Width.Value,
|
||||
Height = VideoStream.Height.Value
|
||||
};
|
||||
var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
|
||||
|
||||
var newSize = DrawingUtils.Resize(size,
|
||||
BaseRequest.Width ?? 0,
|
||||
@@ -346,11 +342,7 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
{
|
||||
if (VideoStream != null && VideoStream.Width.HasValue && VideoStream.Height.HasValue)
|
||||
{
|
||||
var size = new ImageDimensions
|
||||
{
|
||||
Width = VideoStream.Width.Value,
|
||||
Height = VideoStream.Height.Value
|
||||
};
|
||||
var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
|
||||
|
||||
var newSize = DrawingUtils.Resize(size,
|
||||
BaseRequest.Width ?? 0,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.Controller.MediaEncoding
|
||||
@@ -90,6 +89,15 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||
framerate = val;
|
||||
}
|
||||
}
|
||||
else if (part.StartsWith("fps=", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var rate = part.Split(new[] { '=' }, 2)[^1];
|
||||
|
||||
if (float.TryParse(rate, NumberStyles.Any, _usCulture, out var val))
|
||||
{
|
||||
framerate = val;
|
||||
}
|
||||
}
|
||||
else if (state.RunTimeTicks.HasValue &&
|
||||
part.StartsWith("time=", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Net
|
||||
/// <summary>
|
||||
/// The _active connections
|
||||
/// </summary>
|
||||
protected readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>> ActiveConnections =
|
||||
private readonly List<Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>> _activeConnections =
|
||||
new List<Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>>();
|
||||
|
||||
/// <summary>
|
||||
@@ -100,9 +100,9 @@ namespace MediaBrowser.Controller.Net
|
||||
InitialDelayMs = dueTimeMs
|
||||
};
|
||||
|
||||
lock (ActiveConnections)
|
||||
lock (_activeConnections)
|
||||
{
|
||||
ActiveConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>(message.Connection, cancellationTokenSource, state));
|
||||
_activeConnections.Add(new Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>(message.Connection, cancellationTokenSource, state));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,9 +110,9 @@ namespace MediaBrowser.Controller.Net
|
||||
{
|
||||
Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>[] tuples;
|
||||
|
||||
lock (ActiveConnections)
|
||||
lock (_activeConnections)
|
||||
{
|
||||
tuples = ActiveConnections
|
||||
tuples = _activeConnections
|
||||
.Where(c =>
|
||||
{
|
||||
if (c.Item1.State == WebSocketState.Open && !c.Item2.IsCancellationRequested)
|
||||
@@ -180,9 +180,9 @@ namespace MediaBrowser.Controller.Net
|
||||
/// <param name="message">The message.</param>
|
||||
private void Stop(WebSocketMessageInfo message)
|
||||
{
|
||||
lock (ActiveConnections)
|
||||
lock (_activeConnections)
|
||||
{
|
||||
var connection = ActiveConnections.FirstOrDefault(c => c.Item1 == message.Connection);
|
||||
var connection = _activeConnections.FirstOrDefault(c => c.Item1 == message.Connection);
|
||||
|
||||
if (connection != null)
|
||||
{
|
||||
@@ -212,9 +212,9 @@ namespace MediaBrowser.Controller.Net
|
||||
//TODO Investigate and properly fix.
|
||||
}
|
||||
|
||||
lock (ActiveConnections)
|
||||
lock (_activeConnections)
|
||||
{
|
||||
ActiveConnections.Remove(connection);
|
||||
_activeConnections.Remove(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,9 +226,9 @@ namespace MediaBrowser.Controller.Net
|
||||
{
|
||||
if (dispose)
|
||||
{
|
||||
lock (ActiveConnections)
|
||||
lock (_activeConnections)
|
||||
{
|
||||
foreach (var connection in ActiveConnections.ToArray())
|
||||
foreach (var connection in _activeConnections.ToArray())
|
||||
{
|
||||
DisposeConnection(connection);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#nullable enable
|
||||
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Services;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@@ -7,6 +9,6 @@ namespace MediaBrowser.Controller.Net
|
||||
public interface IAuthService
|
||||
{
|
||||
void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues);
|
||||
User Authenticate(HttpRequest request, IAuthenticationAttributes authAttribtues);
|
||||
User? Authenticate(HttpRequest request, IAuthenticationAttributes authAttribtues);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Services;
|
||||
|
||||
namespace MediaBrowser.Controller.Net
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Net.WebSockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.Services;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace MediaBrowser.Controller.Net
|
||||
|
||||
@@ -3,8 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using MediaBrowser.Model.IO;
|
||||
|
||||
namespace MediaBrowser.Controller.Net
|
||||
{
|
||||
public class StaticResultOptions
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Persistence
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Playlists
|
||||
/// <param name="itemIds">The item ids.</param>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
void AddToPlaylist(string playlistId, IEnumerable<Guid> itemIds, Guid userId);
|
||||
void AddToPlaylist(string playlistId, ICollection<Guid> itemIds, Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// Removes from playlist.
|
||||
|
||||
@@ -4,16 +4,22 @@ using System.Threading.Tasks;
|
||||
namespace MediaBrowser.Controller.Plugins
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IServerEntryPoint
|
||||
/// Represents an entry point for a module in the application. This interface is scanned for automatically and
|
||||
/// provides a hook to initialize the module at application start.
|
||||
/// The entry point can additionally be flagged as a pre-startup task by implementing the
|
||||
/// <see cref="IRunBeforeStartup"/> interface.
|
||||
/// </summary>
|
||||
public interface IServerEntryPoint : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Runs this instance.
|
||||
/// Run the initialization for this module. This method is invoked at application start.
|
||||
/// </summary>
|
||||
Task RunAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that a <see cref="IServerEntryPoint"/> should be invoked as a pre-startup task.
|
||||
/// </summary>
|
||||
public interface IRunBeforeStartup
|
||||
{
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// </summary>
|
||||
/// <value>The artist provider ids.</value>
|
||||
public Dictionary<string, string> ArtistProviderIds { get; set; }
|
||||
|
||||
public List<SongInfo> SongInfos { get; set; }
|
||||
|
||||
public AlbumInfo()
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class BoxSetInfo : ItemLookupInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
entries = _fileSystem.GetFileSystemEntries(path).ToArray();
|
||||
|
||||
//_cache.TryAdd(path, entries);
|
||||
_cache[path] = entries;
|
||||
}
|
||||
|
||||
@@ -56,7 +55,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
|
||||
if (file != null && file.Exists)
|
||||
{
|
||||
//_fileCache.TryAdd(path, file);
|
||||
_fileCache[path] = file;
|
||||
}
|
||||
else
|
||||
@@ -66,7 +64,6 @@ namespace MediaBrowser.Controller.Providers
|
||||
}
|
||||
|
||||
return file;
|
||||
//return _fileSystem.GetFileInfo(path);
|
||||
}
|
||||
|
||||
public List<string> GetFilePaths(string path)
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class DynamicImageInfo
|
||||
{
|
||||
public string ImageId { get; set; }
|
||||
public ImageType Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
public class DynamicImageResponse
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
public MediaProtocol Protocol { get; set; }
|
||||
|
||||
public Stream Stream { get; set; }
|
||||
|
||||
public ImageFormat Format { get; set; }
|
||||
|
||||
public bool HasImage { get; set; }
|
||||
|
||||
public void SetFormatFromMimeType(string mimeType)
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public int? IndexNumberEnd { get; set; }
|
||||
|
||||
public bool IsMissingEpisode { get; set; }
|
||||
|
||||
public string SeriesDisplayOrder { get; set; }
|
||||
|
||||
public EpisodeInfo()
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class ExtraInfo
|
||||
{
|
||||
public string Path { get; set; }
|
||||
|
||||
public LocationType LocationType { get; set; }
|
||||
|
||||
public bool IsDownloadable { get; set; }
|
||||
|
||||
public ExtraType ExtraType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public enum ExtraSource
|
||||
{
|
||||
Local = 1,
|
||||
Metadata = 2,
|
||||
Remote = 3
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
where TItemType : BaseItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Fetches the asynchronous.
|
||||
/// Fetches the metadata asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="options">The options.</param>
|
||||
|
||||
@@ -6,10 +6,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
public interface IDirectoryService
|
||||
{
|
||||
FileSystemMetadata[] GetFileSystemEntries(string path);
|
||||
|
||||
List<FileSystemMetadata> GetFiles(string path);
|
||||
|
||||
FileSystemMetadata GetFile(string path);
|
||||
|
||||
List<string> GetFilePaths(string path);
|
||||
|
||||
List<string> GetFilePaths(string path, bool clearCache);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IExtrasProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||
bool Supports(BaseItem item);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a marker interface that will cause a provider to run even if IsLocked=true
|
||||
/// This is a marker interface that will cause a provider to run even if an item is locked from changes.
|
||||
/// </summary>
|
||||
public interface IForcedProvider
|
||||
{
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IImageEnhancer
|
||||
{
|
||||
/// <summary>
|
||||
/// Return true only if the given image for the given item will be enhanced by this enhancer.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns><c>true</c> if this enhancer will enhance the supplied image for the supplied item, <c>false</c> otherwise</returns>
|
||||
bool Supports(BaseItem item, ImageType imageType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the priority or order in which this enhancer should be run.
|
||||
/// </summary>
|
||||
/// <value>The priority.</value>
|
||||
MetadataProviderPriority Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Return a key incorporating all configuration information related to this item
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <returns>Cache key relating to the current state of this item and configuration</returns>
|
||||
string GetConfigurationCacheKey(BaseItem item, ImageType imageType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the enhanced image.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <param name="originalImageSize">Size of the original image.</param>
|
||||
/// <returns>ImageSize.</returns>
|
||||
ImageDimensions GetEnhancedImageSize(BaseItem item, ImageType imageType, int imageIndex, ImageDimensions originalImageSize);
|
||||
|
||||
EnhancedImageInfo GetEnhancedImageInfo(BaseItem item, string inputFile, ImageType imageType, int imageIndex);
|
||||
|
||||
/// <summary>
|
||||
/// Enhances the image async.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="inputFile">The input file.</param>
|
||||
/// <param name="outputFile">The output file.</param>
|
||||
/// <param name="imageType">Type of the image.</param>
|
||||
/// <param name="imageIndex">Index of the image.</param>
|
||||
/// <returns>Task{Image}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
Task EnhanceImageAsync(BaseItem item, string inputFile, string outputFile, ImageType imageType, int imageIndex);
|
||||
}
|
||||
|
||||
public class EnhancedImageInfo
|
||||
{
|
||||
public bool RequiresTransparency { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ using MediaBrowser.Controller.Entities;
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProvider
|
||||
/// Interface IImageProvider.
|
||||
/// </summary>
|
||||
public interface IImageProvider
|
||||
{
|
||||
@@ -14,10 +14,10 @@ namespace MediaBrowser.Controller.Providers
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Supportses the specified item.
|
||||
/// Supports the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
|
||||
/// <returns><c>true</c> if the provider supports the item.</returns>
|
||||
bool Supports(BaseItem item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface ILocalImageFileProvider : ILocalImageProvider
|
||||
{
|
||||
List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is just a marker interface
|
||||
/// This is just a marker interface.
|
||||
/// </summary>
|
||||
public interface ILocalImageProvider : IImageProvider
|
||||
{
|
||||
List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// <param name="info">The information.</param>
|
||||
/// <param name="directoryService">The directory service.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{MetadataResult{`0}}.</returns>
|
||||
Task<MetadataResult<TItemType>> GetMetadata(ItemInfo info,
|
||||
/// <returns>Task{MetadataResult{0}}.</returns>
|
||||
Task<MetadataResult<TItemType>> GetMetadata(
|
||||
ItemInfo info,
|
||||
IDirectoryService directoryService,
|
||||
CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// Determines whether this instance can refresh the specified item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <returns><c>true</c> if this instance can refresh the specified item; otherwise, <c>false</c>.</returns>
|
||||
/// <returns><c>true</c> if this instance can refresh the specified item.</returns>
|
||||
bool CanRefresh(BaseItem item);
|
||||
|
||||
bool CanRefreshPrimary(Type type);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public interface IPreRefreshProvider : ICustomMetadataProvider
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ using MediaBrowser.Model.Providers;
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IProviderManager
|
||||
/// Interface IProviderManager.
|
||||
/// </summary>
|
||||
public interface IProviderManager
|
||||
{
|
||||
@@ -159,13 +159,17 @@ namespace MediaBrowser.Controller.Providers
|
||||
Dictionary<Guid, Guid> GetRefreshQueue();
|
||||
|
||||
void OnRefreshStart(BaseItem item);
|
||||
|
||||
void OnRefreshProgress(BaseItem item, double progress);
|
||||
|
||||
void OnRefreshComplete(BaseItem item);
|
||||
|
||||
double? GetRefreshProgress(Guid id);
|
||||
|
||||
event EventHandler<GenericEventArgs<BaseItem>> RefreshStarted;
|
||||
|
||||
event EventHandler<GenericEventArgs<BaseItem>> RefreshCompleted;
|
||||
|
||||
event EventHandler<GenericEventArgs<Tuple<BaseItem, double>>> RefreshProgress;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ using MediaBrowser.Model.Providers;
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IImageProvider
|
||||
/// Interface IImageProvider.
|
||||
/// </summary>
|
||||
public interface IRemoteImageProvider : IImageProvider
|
||||
{
|
||||
|
||||
@@ -23,10 +23,15 @@ namespace MediaBrowser.Controller.Providers
|
||||
}
|
||||
|
||||
public Type ItemType { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public string ContainingFolderPath { get; set; }
|
||||
|
||||
public VideoType VideoType { get; set; }
|
||||
|
||||
public bool IsInMixedFolder { get; set; }
|
||||
|
||||
public bool IsPlaceHolder { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,29 +11,37 @@ namespace MediaBrowser.Controller.Providers
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata language.
|
||||
/// </summary>
|
||||
/// <value>The metadata language.</value>
|
||||
public string MetadataLanguage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the metadata country code.
|
||||
/// </summary>
|
||||
/// <value>The metadata country code.</value>
|
||||
public string MetadataCountryCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the provider ids.
|
||||
/// </summary>
|
||||
/// <value>The provider ids.</value>
|
||||
public Dictionary<string, string> ProviderIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the year.
|
||||
/// </summary>
|
||||
/// <value>The year.</value>
|
||||
public int? Year { get; set; }
|
||||
|
||||
public int? IndexNumber { get; set; }
|
||||
|
||||
public int? ParentIndexNumber { get; set; }
|
||||
|
||||
public DateTime? PremiereDate { get; set; }
|
||||
|
||||
public bool IsAutomated { get; set; }
|
||||
|
||||
public ItemLookupInfo()
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public class LocalImageInfo
|
||||
{
|
||||
public FileSystemMetadata FileInfo { get; set; }
|
||||
|
||||
public ImageType Type { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines when a provider should execute, relative to others
|
||||
/// </summary>
|
||||
public enum MetadataProviderPriority
|
||||
{
|
||||
// Run this provider at the beginning
|
||||
/// <summary>
|
||||
/// The first
|
||||
/// </summary>
|
||||
First = 1,
|
||||
|
||||
// Run this provider after all first priority providers
|
||||
/// <summary>
|
||||
/// The second
|
||||
/// </summary>
|
||||
Second = 2,
|
||||
|
||||
// Run this provider after all second priority providers
|
||||
/// <summary>
|
||||
/// The third
|
||||
/// </summary>
|
||||
Third = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The fourth
|
||||
/// </summary>
|
||||
Fourth = 4,
|
||||
|
||||
Fifth = 5,
|
||||
|
||||
// Run this provider last
|
||||
/// <summary>
|
||||
/// The last
|
||||
/// </summary>
|
||||
Last = 999
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,13 @@ namespace MediaBrowser.Controller.Providers
|
||||
public bool ReplaceAllMetadata { get; set; }
|
||||
|
||||
public MetadataRefreshMode MetadataRefreshMode { get; set; }
|
||||
|
||||
public RemoteSearchResult SearchResult { get; set; }
|
||||
|
||||
public string[] RefreshPaths { get; set; }
|
||||
|
||||
public bool ForceSave { get; set; }
|
||||
|
||||
public bool EnableRemoteContentProbe { get; set; }
|
||||
|
||||
public MetadataRefreshOptions(IDirectoryService directoryService)
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace MediaBrowser.Controller.Providers
|
||||
public class MetadataResult<T>
|
||||
{
|
||||
public List<LocalImageInfo> Images { get; set; }
|
||||
|
||||
public List<UserItemData> UserDataList { get; set; }
|
||||
|
||||
public MetadataResult()
|
||||
@@ -19,10 +20,15 @@ namespace MediaBrowser.Controller.Providers
|
||||
public List<PersonInfo> People { get; set; }
|
||||
|
||||
public bool HasMetadata { get; set; }
|
||||
|
||||
public T Item { get; set; }
|
||||
|
||||
public string ResultLanguage { get; set; }
|
||||
|
||||
public string Provider { get; set; }
|
||||
|
||||
public bool QueriedById { get; set; }
|
||||
|
||||
public void AddPerson(PersonInfo p)
|
||||
{
|
||||
if (People == null)
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class MovieInfo : ItemLookupInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,5 @@ namespace MediaBrowser.Controller.Providers
|
||||
{
|
||||
public class PersonLookupInfo : ItemLookupInfo
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ namespace MediaBrowser.Controller.Providers
|
||||
public Guid ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If set will only search within the given provider
|
||||
/// Will only search within the given provider when set.
|
||||
/// </summary>
|
||||
public string SearchProviderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether [include disabled providers].
|
||||
/// Gets or sets a value indicating whether disabled providers should be included.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [include disabled providers]; otherwise, <c>false</c>.</value>
|
||||
/// <value><c>true</c> if disabled providers should be included.</value>
|
||||
public bool IncludeDisabledProviders { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,8 @@ namespace MediaBrowser.Controller.Session
|
||||
|
||||
public BaseItem FullNowPlayingItem { get; set; }
|
||||
|
||||
public BaseItemDto NowViewingItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the device id.
|
||||
/// </summary>
|
||||
@@ -126,12 +128,6 @@ namespace MediaBrowser.Controller.Session
|
||||
[JsonIgnore]
|
||||
public ISessionController[] SessionControllers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application icon URL.
|
||||
/// </summary>
|
||||
/// <value>The application icon URL.</value>
|
||||
public string AppIconUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the supported commands.
|
||||
/// </summary>
|
||||
@@ -245,11 +241,6 @@ namespace MediaBrowser.Controller.Session
|
||||
SessionControllers = controllers.ToArray();
|
||||
}
|
||||
|
||||
public bool ContainsUser(string userId)
|
||||
{
|
||||
return ContainsUser(new Guid(userId));
|
||||
}
|
||||
|
||||
public bool ContainsUser(Guid userId)
|
||||
{
|
||||
if (UserId.Equals(userId))
|
||||
@@ -259,7 +250,7 @@ namespace MediaBrowser.Controller.Session
|
||||
|
||||
foreach (var additionalUser in AdditionalUsers)
|
||||
{
|
||||
if (userId.Equals(userId))
|
||||
if (additionalUser.UserId.Equals(userId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -321,7 +312,7 @@ namespace MediaBrowser.Controller.Session
|
||||
|
||||
var newPositionTicks = positionTicks + ProgressIncrement;
|
||||
var item = progressInfo.Item;
|
||||
long? runtimeTicks = item == null ? null : item.RunTimeTicks;
|
||||
long? runtimeTicks = item?.RunTimeTicks;
|
||||
|
||||
// Don't report beyond the runtime
|
||||
if (runtimeTicks.HasValue && newPositionTicks >= runtimeTicks.Value)
|
||||
|
||||
135
MediaBrowser.Controller/Sorting/AlphanumComparator.cs
Normal file
135
MediaBrowser.Controller/Sorting/AlphanumComparator.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
public class AlphanumComparator : IComparer<string?>
|
||||
{
|
||||
public static int CompareValues(string? s1, string? s2)
|
||||
{
|
||||
if (s1 == null && s2 == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (s1 == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (s2 == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int len1 = s1.Length;
|
||||
int len2 = s2.Length;
|
||||
|
||||
// Early return for empty strings
|
||||
if (len1 == 0 && len2 == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (len1 == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (len2 == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pos1 = 0;
|
||||
int pos2 = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int start1 = pos1;
|
||||
int start2 = pos2;
|
||||
|
||||
bool isNum1 = char.IsDigit(s1[pos1++]);
|
||||
bool isNum2 = char.IsDigit(s2[pos2++]);
|
||||
|
||||
while (pos1 < len1 && char.IsDigit(s1[pos1]) == isNum1)
|
||||
{
|
||||
pos1++;
|
||||
}
|
||||
|
||||
while (pos2 < len2 && char.IsDigit(s2[pos2]) == isNum2)
|
||||
{
|
||||
pos2++;
|
||||
}
|
||||
|
||||
var span1 = s1.AsSpan(start1, pos1 - start1);
|
||||
var span2 = s2.AsSpan(start2, pos2 - start2);
|
||||
|
||||
if (isNum1 && isNum2)
|
||||
{
|
||||
// Trim leading zeros so we can compare the length
|
||||
// of the strings to find the largest number
|
||||
span1 = span1.TrimStart('0');
|
||||
span2 = span2.TrimStart('0');
|
||||
var span1Len = span1.Length;
|
||||
var span2Len = span2.Length;
|
||||
if (span1Len < span2Len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (span1Len > span2Len)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (span1Len >= 20) // Number is probably too big for a ulong
|
||||
{
|
||||
// Trim all the first digits that are the same
|
||||
int i = 0;
|
||||
while (i < span1Len && span1[i] == span2[i])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
// If there are no more digits it's the same number
|
||||
if (i == span1Len)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only need to compare the most significant digit
|
||||
span1 = span1.Slice(i, 1);
|
||||
span2 = span2.Slice(i, 1);
|
||||
}
|
||||
|
||||
if (!ulong.TryParse(span1, out var num1)
|
||||
|| !ulong.TryParse(span2, out var num2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (num1 < num2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (num1 > num2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int result = span1.CompareTo(span2, StringComparison.InvariantCulture);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} while (pos1 < len1 && pos2 < len2);
|
||||
|
||||
return len1 - len2;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
return CompareValues(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,137 +7,25 @@ namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
public static class SortExtensions
|
||||
{
|
||||
private static readonly AlphanumComparator _comparer = new AlphanumComparator();
|
||||
public static IEnumerable<T> OrderByString<T>(this IEnumerable<T> list, Func<T, string> getName)
|
||||
{
|
||||
return list.OrderBy(getName, new AlphanumComparator());
|
||||
return list.OrderBy(getName, _comparer);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> OrderByStringDescending<T>(this IEnumerable<T> list, Func<T, string> getName)
|
||||
{
|
||||
return list.OrderByDescending(getName, new AlphanumComparator());
|
||||
return list.OrderByDescending(getName, _comparer);
|
||||
}
|
||||
|
||||
public static IOrderedEnumerable<T> ThenByString<T>(this IOrderedEnumerable<T> list, Func<T, string> getName)
|
||||
{
|
||||
return list.ThenBy(getName, new AlphanumComparator());
|
||||
return list.ThenBy(getName, _comparer);
|
||||
}
|
||||
|
||||
public static IOrderedEnumerable<T> ThenByStringDescending<T>(this IOrderedEnumerable<T> list, Func<T, string> getName)
|
||||
{
|
||||
return list.ThenByDescending(getName, new AlphanumComparator());
|
||||
}
|
||||
|
||||
private class AlphanumComparator : IComparer<string>
|
||||
{
|
||||
private enum ChunkType { Alphanumeric, Numeric };
|
||||
|
||||
private static bool InChunk(char ch, char otherCh)
|
||||
{
|
||||
var type = ChunkType.Alphanumeric;
|
||||
|
||||
if (char.IsDigit(otherCh))
|
||||
{
|
||||
type = ChunkType.Numeric;
|
||||
}
|
||||
|
||||
if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
|
||||
|| (type == ChunkType.Numeric && !char.IsDigit(ch)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int CompareValues(string s1, string s2)
|
||||
{
|
||||
if (s1 == null || s2 == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int thisMarker = 0, thisNumericChunk = 0;
|
||||
int thatMarker = 0, thatNumericChunk = 0;
|
||||
|
||||
while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
|
||||
{
|
||||
if (thisMarker >= s1.Length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (thatMarker >= s2.Length)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
char thisCh = s1[thisMarker];
|
||||
char thatCh = s2[thatMarker];
|
||||
|
||||
var thisChunk = new StringBuilder();
|
||||
var thatChunk = new StringBuilder();
|
||||
|
||||
while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || InChunk(thisCh, thisChunk[0])))
|
||||
{
|
||||
thisChunk.Append(thisCh);
|
||||
thisMarker++;
|
||||
|
||||
if (thisMarker < s1.Length)
|
||||
{
|
||||
thisCh = s1[thisMarker];
|
||||
}
|
||||
}
|
||||
|
||||
while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || InChunk(thatCh, thatChunk[0])))
|
||||
{
|
||||
thatChunk.Append(thatCh);
|
||||
thatMarker++;
|
||||
|
||||
if (thatMarker < s2.Length)
|
||||
{
|
||||
thatCh = s2[thatMarker];
|
||||
}
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
// If both chunks contain numeric characters, sort them numerically
|
||||
if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
|
||||
{
|
||||
if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (thisNumericChunk < thatNumericChunk)
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
|
||||
if (thisNumericChunk > thatNumericChunk)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = thisChunk.ToString().CompareTo(thatChunk.ToString());
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int Compare(string x, string y)
|
||||
{
|
||||
return CompareValues(x, y);
|
||||
}
|
||||
return list.ThenByDescending(getName, _comparer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
public static class SortHelper
|
||||
{
|
||||
private enum ChunkType { Alphanumeric, Numeric };
|
||||
|
||||
public static bool InChunk(char ch, char otherCh)
|
||||
{
|
||||
var type = ChunkType.Alphanumeric;
|
||||
|
||||
if (char.IsDigit(otherCh))
|
||||
{
|
||||
type = ChunkType.Numeric;
|
||||
}
|
||||
|
||||
if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
|
||||
|| (type == ChunkType.Numeric && !char.IsDigit(ch)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user