Merge branch 'master' into defer_image_fetching

This commit is contained in:
Joshua M. Boniface
2020-11-21 17:20:31 -05:00
committed by GitHub
685 changed files with 17649 additions and 14204 deletions

View File

@@ -0,0 +1,86 @@
using System;
using System.Linq;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.BaseItemManager
{
/// <inheritdoc />
public class BaseItemManager : IBaseItemManager
{
private readonly IServerConfigurationManager _serverConfigurationManager;
/// <summary>
/// Initializes a new instance of the <see cref="BaseItemManager"/> class.
/// </summary>
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
public BaseItemManager(IServerConfigurationManager serverConfigurationManager)
{
_serverConfigurationManager = serverConfigurationManager;
}
/// <inheritdoc />
public bool IsMetadataFetcherEnabled(BaseItem baseItem, LibraryOptions libraryOptions, string name)
{
if (baseItem is Channel)
{
// Hack alert.
return true;
}
if (baseItem.SourceType == SourceType.Channel)
{
// Hack alert.
return !baseItem.EnableMediaSourceDisplay;
}
var typeOptions = libraryOptions.GetTypeOptions(GetType().Name);
if (typeOptions != null)
{
return typeOptions.ImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
if (!libraryOptions.EnableInternetProviders)
{
return false;
}
var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, GetType().Name, StringComparison.OrdinalIgnoreCase));
return itemConfig == null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
/// <inheritdoc />
public bool IsImageFetcherEnabled(BaseItem baseItem, LibraryOptions libraryOptions, string name)
{
if (baseItem is Channel)
{
// Hack alert.
return true;
}
if (baseItem.SourceType == SourceType.Channel)
{
// Hack alert.
return !baseItem.EnableMediaSourceDisplay;
}
var typeOptions = libraryOptions.GetTypeOptions(GetType().Name);
if (typeOptions != null)
{
return typeOptions.ImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
if (!libraryOptions.EnableInternetProviders)
{
return false;
}
var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, GetType().Name, StringComparison.OrdinalIgnoreCase));
return itemConfig == null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
}
}

View File

@@ -0,0 +1,29 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.BaseItemManager
{
/// <summary>
/// The <c>BaseItem</c> manager.
/// </summary>
public interface IBaseItemManager
{
/// <summary>
/// Is metadata fetcher enabled.
/// </summary>
/// <param name="baseItem">The base item.</param>
/// <param name="libraryOptions">The library options.</param>
/// <param name="name">The metadata fetcher name.</param>
/// <returns><c>true</c> if metadata fetcher is enabled, else false.</returns>
bool IsMetadataFetcherEnabled(BaseItem baseItem, LibraryOptions libraryOptions, string name);
/// <summary>
/// Is image fetcher enabled.
/// </summary>
/// <param name="baseItem">The base item.</param>
/// <param name="libraryOptions">The library options.</param>
/// <param name="name">The image fetcher name.</param>
/// <returns><c>true</c> if image fetcher is enabled, else false.</returns>
bool IsImageFetcherEnabled(BaseItem baseItem, LibraryOptions libraryOptions, string name);
}
}

View File

@@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.Channels
/// Indicates if a sort ascending/descending toggle is supported or not.
/// </summary>
public bool SupportsSortOrderToggle { get; set; }
/// <summary>
/// Gets or sets the automatic refresh levels.
/// </summary>
@@ -53,6 +54,7 @@ namespace MediaBrowser.Controller.Channels
/// </summary>
/// <value>The daily download limit.</value>
public int? DailyDownloadLimit { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports downloading].
/// </summary>

View File

@@ -1,4 +1,5 @@
#pragma warning disable CS1591
#nullable enable
using System;
using System.Collections.Generic;
@@ -63,6 +64,7 @@ namespace MediaBrowser.Controller.Drawing
/// Create an image collage.
/// </summary>
/// <param name="options">The options to use when creating the collage.</param>
void CreateImageCollage(ImageCollageOptions options);
/// <param name="libraryName">Optional. </param>
void CreateImageCollage(ImageCollageOptions options, string? libraryName);
}
}

View File

@@ -1,4 +1,5 @@
#pragma warning disable CS1591
#nullable enable
using System;
using System.Collections.Generic;
@@ -75,7 +76,7 @@ namespace MediaBrowser.Controller.Drawing
/// </summary>
/// <param name="options">The options.</param>
/// <returns>Task.</returns>
Task<(string path, string mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options);
Task<(string path, string? mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options);
/// <summary>
/// Gets the supported image output formats.
@@ -87,7 +88,8 @@ namespace MediaBrowser.Controller.Drawing
/// Creates the image collage.
/// </summary>
/// <param name="options">The options.</param>
void CreateImageCollage(ImageCollageOptions options);
/// <param name="libraryName">The library name to draw onto the collage.</param>
void CreateImageCollage(ImageCollageOptions options, string? libraryName);
bool SupportsTransparency(string path);
}

View File

@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
@@ -15,9 +16,9 @@ namespace MediaBrowser.Controller.Dto
ItemFields.RefreshState
};
public ItemFields[] Fields { get; set; }
public IReadOnlyList<ItemFields> Fields { get; set; }
public ImageType[] ImageTypes { get; set; }
public IReadOnlyList<ImageType> ImageTypes { get; set; }
public int ImageTypeLimit { get; set; }

View File

@@ -90,7 +90,6 @@ namespace MediaBrowser.Controller.Entities.Audio
var songKey = IndexNumber.HasValue ? IndexNumber.Value.ToString("0000") : string.Empty;
if (ParentIndexNumber.HasValue)
{
songKey = ParentIndexNumber.Value.ToString("0000") + "-" + songKey;

View File

@@ -56,7 +56,7 @@ namespace MediaBrowser.Controller.Entities.Audio
{
if (query.IncludeItemTypes.Length == 0)
{
query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
query.IncludeItemTypes = new[] { nameof(Audio), nameof(MusicVideo), nameof(MusicAlbum) };
query.ArtistIds = new[] { Id };
}

View File

@@ -64,7 +64,7 @@ namespace MediaBrowser.Controller.Entities.Audio
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.GenreIds = new[] { Id };
query.IncludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
query.IncludeItemTypes = new[] { nameof(MusicVideo), nameof(Audio), nameof(MusicAlbum), nameof(MusicArtist) };
return LibraryManager.GetItemList(query);
}

View File

@@ -87,6 +87,8 @@ namespace MediaBrowser.Controller.Entities
public const string InterviewFolderName = "interviews";
public const string SceneFolderName = "scenes";
public const string SampleFolderName = "samples";
public const string ShortsFolderName = "shorts";
public const string FeaturettesFolderName = "featurettes";
public static readonly string[] AllExtrasTypesFolderNames = {
ExtrasFolderName,
@@ -94,7 +96,9 @@ namespace MediaBrowser.Controller.Entities
DeletedScenesFolderName,
InterviewFolderName,
SceneFolderName,
SampleFolderName
SampleFolderName,
ShortsFolderName,
FeaturettesFolderName
};
[JsonIgnore]
@@ -197,6 +201,7 @@ namespace MediaBrowser.Controller.Entities
public virtual bool SupportsRemoteImageDownloading => true;
private string _name;
/// <summary>
/// Gets or sets the name.
/// </summary>
@@ -458,60 +463,6 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore]
public string PrimaryImagePath => this.GetImagePath(ImageType.Primary);
public bool IsMetadataFetcherEnabled(LibraryOptions libraryOptions, string name)
{
if (SourceType == SourceType.Channel)
{
// hack alert
return !EnableMediaSourceDisplay;
}
var typeOptions = libraryOptions.GetTypeOptions(GetType().Name);
if (typeOptions != null)
{
return typeOptions.MetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
if (!libraryOptions.EnableInternetProviders)
{
return false;
}
var itemConfig = ConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, GetType().Name, StringComparison.OrdinalIgnoreCase));
return itemConfig == null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
public bool IsImageFetcherEnabled(LibraryOptions libraryOptions, string name)
{
if (this is Channel)
{
// hack alert
return true;
}
if (SourceType == SourceType.Channel)
{
// hack alert
return !EnableMediaSourceDisplay;
}
var typeOptions = libraryOptions.GetTypeOptions(GetType().Name);
if (typeOptions != null)
{
return typeOptions.ImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
if (!libraryOptions.EnableInternetProviders)
{
return false;
}
var itemConfig = ConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, GetType().Name, StringComparison.OrdinalIgnoreCase));
return itemConfig == null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
public virtual bool CanDelete()
{
if (SourceType == SourceType.Channel)
@@ -661,6 +612,7 @@ namespace MediaBrowser.Controller.Entities
}
private string _forcedSortName;
/// <summary>
/// Gets or sets the name of the forced sort.
/// </summary>
@@ -2604,7 +2556,7 @@ namespace MediaBrowser.Controller.Entities
{
if (!AllowsMultipleImages(type))
{
throw new ArgumentException("The change index operation is only applicable to backdrops and screenshots");
throw new ArgumentException("The change index operation is only applicable to backdrops and screen shots");
}
var info1 = GetImageInfo(type, index1);

View File

@@ -45,7 +45,8 @@ namespace MediaBrowser.Controller.Entities
{
if (file.StartsWith("http", System.StringComparison.OrdinalIgnoreCase))
{
item.SetImage(new ItemImageInfo
item.SetImage(
new ItemImageInfo
{
Path = file,
Type = imageType

View File

@@ -212,7 +212,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Loads our children. Validation will occur externally.
/// We want this sychronous.
/// We want this synchronous.
/// </summary>
protected virtual List<BaseItem> LoadChildren()
{
@@ -255,7 +255,8 @@ namespace MediaBrowser.Controller.Entities
var id = child.Id;
if (dictionary.ContainsKey(id))
{
Logger.LogError("Found folder containing items with duplicate id. Path: {path}, Child Name: {ChildName}",
Logger.LogError(
"Found folder containing items with duplicate id. Path: {path}, Child Name: {ChildName}",
Path ?? Name,
child.Path ?? child.Name);
}
@@ -717,7 +718,7 @@ namespace MediaBrowser.Controller.Entities
private bool RequiresPostFiltering2(InternalItemsQuery query)
{
if (query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], typeof(BoxSet).Name, StringComparison.OrdinalIgnoreCase))
if (query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase))
{
Logger.LogDebug("Query requires post-filtering due to BoxSet query");
return true;
@@ -807,7 +808,7 @@ namespace MediaBrowser.Controller.Entities
if (query.IsPlayed.HasValue)
{
if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes.Contains(typeof(Series).Name))
if (query.IncludeItemTypes.Length == 1 && query.IncludeItemTypes.Contains(nameof(Series)))
{
Logger.LogDebug("Query requires post-filtering due to IsPlayed");
return true;
@@ -979,7 +980,8 @@ namespace MediaBrowser.Controller.Entities
return items;
}
private static bool CollapseBoxSetItems(InternalItemsQuery query,
private static bool CollapseBoxSetItems(
InternalItemsQuery query,
BaseItem queryParent,
User user,
IServerConfigurationManager configurationManager)
@@ -1060,12 +1062,12 @@ namespace MediaBrowser.Controller.Entities
return false;
}
if (request.Genres.Length > 0)
if (request.Genres.Count > 0)
{
return false;
}
if (request.GenreIds.Length > 0)
if (request.GenreIds.Count > 0)
{
return false;
}
@@ -1170,7 +1172,7 @@ namespace MediaBrowser.Controller.Entities
return false;
}
if (request.GenreIds.Length > 0)
if (request.GenreIds.Count > 0)
{
return false;
}
@@ -1381,7 +1383,6 @@ namespace MediaBrowser.Controller.Entities
}
}
/// <summary>
/// Gets the linked children.
/// </summary>
@@ -1589,7 +1590,8 @@ namespace MediaBrowser.Controller.Entities
/// <param name="datePlayed">The date played.</param>
/// <param name="resetPosition">if set to <c>true</c> [reset position].</param>
/// <returns>Task.</returns>
public override void MarkPlayed(User user,
public override void MarkPlayed(
User user,
DateTime? datePlayed,
bool resetPosition)
{

View File

@@ -59,7 +59,13 @@ namespace MediaBrowser.Controller.Entities
public IList<BaseItem> GetTaggedItems(InternalItemsQuery query)
{
query.GenreIds = new[] { Id };
query.ExcludeItemTypes = new[] { typeof(MusicVideo).Name, typeof(Audio.Audio).Name, typeof(MusicAlbum).Name, typeof(MusicArtist).Name };
query.ExcludeItemTypes = new[]
{
nameof(MusicVideo),
nameof(Entities.Audio.Audio),
nameof(MusicAlbum),
nameof(MusicArtist)
};
return LibraryManager.GetItemList(query);
}

View File

@@ -21,7 +21,5 @@ namespace MediaBrowser.Controller.Entities
List<MediaSourceInfo> GetMediaSources(bool enablePathSubstitution);
List<MediaStream> GetMediaStreams();
}
}

View File

@@ -46,7 +46,7 @@ namespace MediaBrowser.Controller.Entities
public string[] ExcludeInheritedTags { get; set; }
public string[] Genres { get; set; }
public IReadOnlyList<string> Genres { get; set; }
public bool? IsSpecialSeason { get; set; }
@@ -116,7 +116,7 @@ namespace MediaBrowser.Controller.Entities
public Guid[] StudioIds { get; set; }
public Guid[] GenreIds { get; set; }
public IReadOnlyList<Guid> GenreIds { get; set; }
public ImageType[] ImageTypes { get; set; }
@@ -162,7 +162,7 @@ namespace MediaBrowser.Controller.Entities
public double? MinCommunityRating { get; set; }
public Guid[] ChannelIds { get; set; }
public IReadOnlyList<Guid> ChannelIds { get; set; }
public int? ParentIndexNumber { get; set; }

View File

@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System;
using Jellyfin.Data.Entities;
namespace MediaBrowser.Controller.Entities
{
@@ -23,6 +24,10 @@ namespace MediaBrowser.Controller.Entities
public string NameContains { get; set; }
public User User { get; set; }
public bool? IsFavorite { get; set; }
public InternalPeopleQuery()
{
PersonTypes = Array.Empty<string>();

View File

@@ -16,7 +16,6 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore]
public override Folder LatestItemsIndexContainer => AlbumEntity;
[JsonIgnore]
public PhotoAlbum AlbumEntity
{

View File

@@ -151,7 +151,7 @@ namespace MediaBrowser.Controller.Entities.TV
if (query.IncludeItemTypes.Length == 0)
{
query.IncludeItemTypes = new[] { typeof(Episode).Name };
query.IncludeItemTypes = new[] { nameof(Episode) };
}
query.IsVirtualItem = false;
@@ -207,7 +207,7 @@ namespace MediaBrowser.Controller.Entities.TV
query.AncestorWithPresentationUniqueKey = null;
query.SeriesPresentationUniqueKey = seriesKey;
query.IncludeItemTypes = new[] { typeof(Season).Name };
query.IncludeItemTypes = new[] { nameof(Season) };
query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
if (user != null && !user.DisplayMissingEpisodes)
@@ -233,7 +233,7 @@ namespace MediaBrowser.Controller.Entities.TV
if (query.IncludeItemTypes.Length == 0)
{
query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
query.IncludeItemTypes = new[] { nameof(Episode), nameof(Season) };
}
query.IsVirtualItem = false;
@@ -253,7 +253,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
IncludeItemTypes = new[] { nameof(Episode), nameof(Season) },
OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
};
@@ -364,7 +364,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
AncestorWithPresentationUniqueKey = queryFromSeries ? null : seriesKey,
SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null,
IncludeItemTypes = new[] { typeof(Episode).Name },
IncludeItemTypes = new[] { nameof(Episode) },
OrderBy = new[] { ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
};
@@ -450,7 +450,6 @@ namespace MediaBrowser.Controller.Entities.TV
});
}
protected override bool GetBlockUnratedValue(User user)
{
return user.GetPreference(PreferenceKind.BlockUnratedItems).Contains(UnratedItem.Series.ToString());

View File

@@ -142,7 +142,7 @@ namespace MediaBrowser.Controller.Entities
if (query.IncludeItemTypes.Length == 0)
{
query.IncludeItemTypes = new[] { typeof(Movie).Name };
query.IncludeItemTypes = new[] { nameof(Movie) };
}
return parent.QueryRecursive(query);
@@ -167,7 +167,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
query.IncludeItemTypes = new[] { typeof(Movie).Name };
query.IncludeItemTypes = new[] { nameof(Movie) };
return _libraryManager.GetItemsResult(query);
}
@@ -178,7 +178,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
query.IncludeItemTypes = new[] { typeof(Series).Name };
query.IncludeItemTypes = new[] { nameof(Series) };
return _libraryManager.GetItemsResult(query);
}
@@ -189,7 +189,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
query.IncludeItemTypes = new[] { typeof(Episode).Name };
query.IncludeItemTypes = new[] { nameof(Episode) };
return _libraryManager.GetItemsResult(query);
}
@@ -200,7 +200,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IncludeItemTypes = new[] { typeof(Movie).Name };
query.IncludeItemTypes = new[] { nameof(Movie) };
return _libraryManager.GetItemsResult(query);
}
@@ -208,7 +208,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMovieCollections(Folder parent, User user, InternalItemsQuery query)
{
query.Parent = null;
query.IncludeItemTypes = new[] { typeof(BoxSet).Name };
query.IncludeItemTypes = new[] { nameof(BoxSet) };
query.SetUser(user);
query.Recursive = true;
@@ -223,7 +223,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Movie).Name };
query.IncludeItemTypes = new[] { nameof(Movie) };
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -236,7 +236,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Movie).Name };
query.IncludeItemTypes = new[] { nameof(Movie) };
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -255,10 +255,9 @@ namespace MediaBrowser.Controller.Entities
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Movie).Name },
IncludeItemTypes = new[] { nameof(Movie) },
Recursive = true,
EnableTotalRecordCount = false
}).Items
.SelectMany(i => i.Genres)
.DistinctNames()
@@ -287,7 +286,7 @@ namespace MediaBrowser.Controller.Entities
query.GenreIds = new[] { displayParent.Id };
query.SetUser(user);
query.IncludeItemTypes = new[] { typeof(Movie).Name };
query.IncludeItemTypes = new[] { nameof(Movie) };
return _libraryManager.GetItemsResult(query);
}
@@ -334,7 +333,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Episode).Name };
query.IncludeItemTypes = new[] { nameof(Episode) };
query.IsVirtualItem = false;
return ConvertToResult(_libraryManager.GetItemList(query));
@@ -344,7 +343,8 @@ namespace MediaBrowser.Controller.Entities
{
var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows, string.Empty });
var result = _tvSeriesManager.GetNextUp(new NextUpQuery
var result = _tvSeriesManager.GetNextUp(
new NextUpQuery
{
Limit = query.Limit,
StartIndex = query.StartIndex,
@@ -362,7 +362,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
query.IncludeItemTypes = new[] { typeof(Episode).Name };
query.IncludeItemTypes = new[] { nameof(Episode) };
return ConvertToResult(_libraryManager.GetItemList(query));
}
@@ -373,7 +373,7 @@ namespace MediaBrowser.Controller.Entities
query.Parent = parent;
query.SetUser(user);
query.IncludeItemTypes = new[] { typeof(Series).Name };
query.IncludeItemTypes = new[] { nameof(Series) };
return _libraryManager.GetItemsResult(query);
}
@@ -382,7 +382,7 @@ namespace MediaBrowser.Controller.Entities
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Series).Name },
IncludeItemTypes = new[] { nameof(Series) },
Recursive = true,
EnableTotalRecordCount = false
}).Items
@@ -413,7 +413,7 @@ namespace MediaBrowser.Controller.Entities
query.GenreIds = new[] { displayParent.Id };
query.SetUser(user);
query.IncludeItemTypes = new[] { typeof(Series).Name };
query.IncludeItemTypes = new[] { nameof(Series) };
return _libraryManager.GetItemsResult(query);
}
@@ -444,7 +444,8 @@ namespace MediaBrowser.Controller.Entities
return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
}
public static QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items,
public static QueryResult<BaseItem> PostFilterAndSort(
IEnumerable<BaseItem> items,
BaseItem queryParent,
int? totalRecordLimit,
InternalItemsQuery query,
@@ -790,7 +791,7 @@ namespace MediaBrowser.Controller.Entities
}
// Apply genre filter
if (query.Genres.Length > 0 && !query.Genres.Any(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
if (query.Genres.Count > 0 && !query.Genres.Any(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
{
return false;
}
@@ -821,7 +822,7 @@ namespace MediaBrowser.Controller.Entities
}
// Apply genre filter
if (query.GenreIds.Length > 0 && !query.GenreIds.Any(id =>
if (query.GenreIds.Count > 0 && !query.GenreIds.Any(id =>
{
var genreItem = libraryManager.GetItemById(id);
return genreItem != null && item.Genres.Contains(genreItem.Name, StringComparer.OrdinalIgnoreCase);

View File

@@ -12,6 +12,9 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the display preferences for the user and client.
/// </summary>
/// <remarks>
/// This will create the display preferences if it does not exist, but it will not save automatically.
/// </remarks>
/// <param name="userId">The user's id.</param>
/// <param name="client">The client string.</param>
/// <returns>The associated display preferences.</returns>
@@ -20,6 +23,9 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the default item display preferences for the user and client.
/// </summary>
/// <remarks>
/// This will create the item display preferences if it does not exist, but it will not save automatically.
/// </remarks>
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="client">The client string.</param>

View File

@@ -111,5 +111,4 @@ namespace MediaBrowser.Controller.IO
return returnResult;
}
}
}

View File

@@ -6,8 +6,8 @@ using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller
{
@@ -56,10 +56,11 @@ namespace MediaBrowser.Controller
/// <summary>
/// Gets the system info.
/// </summary>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param>
/// <returns>SystemInfo.</returns>
Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken);
Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken = default);
Task<PublicSystemInfo> GetPublicSystemInfo(CancellationToken cancellationToken);
Task<PublicSystemInfo> GetPublicSystemInfo(CancellationToken cancellationToken = default);
/// <summary>
/// Gets all the local IP addresses of this API instance. Each address is validated by sending a 'ping' request
@@ -67,7 +68,7 @@ namespace MediaBrowser.Controller
/// </summary>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param>
/// <returns>A list containing all the local IP addresses of the server.</returns>
Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken);
Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken = default);
/// <summary>
/// Gets a local (LAN) URL that can be used to access the API. The hostname used is the first valid configured
@@ -75,7 +76,7 @@ namespace MediaBrowser.Controller
/// </summary>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param>
/// <returns>The server URL.</returns>
Task<string> GetLocalApiUrl(CancellationToken cancellationToken);
Task<string> GetLocalApiUrl(CancellationToken cancellationToken = default);
/// <summary>
/// Gets a localhost URL that can be used to access the API using the loop-back IP address (127.0.0.1)
@@ -119,5 +120,13 @@ namespace MediaBrowser.Controller
string ExpandVirtualPath(string path);
string ReverseVirtualPath(string path);
/// <summary>
/// Gets the list of local plugins.
/// </summary>
/// <param name="path">Plugin base directory.</param>
/// <param name="cleanup">Cleanup old plugins.</param>
/// <returns>Enumerable of local plugins.</returns>
IEnumerable<LocalPlugin> GetLocalPlugins(string path, bool cleanup = true);
}
}

View File

@@ -77,6 +77,7 @@ namespace MediaBrowser.Controller.Library
MusicArtist GetArtist(string name);
MusicArtist GetArtist(string name, DtoOptions options);
/// <summary>
/// Gets a Studio.
/// </summary>
@@ -234,6 +235,7 @@ namespace MediaBrowser.Controller.Library
/// Occurs when [item updated].
/// </summary>
event EventHandler<ItemChangeEventArgs> ItemUpdated;
/// <summary>
/// Occurs when [item removed].
/// </summary>
@@ -564,10 +566,13 @@ namespace MediaBrowser.Controller.Library
int GetCount(InternalItemsQuery query);
void AddExternalSubtitleStreams(List<MediaStream> streams,
void AddExternalSubtitleStreams(
List<MediaStream> streams,
string videoPath,
string[] files);
void RunMetadataSavers(IReadOnlyList<BaseItem> items, ItemUpdateType updateReason);
BaseItem GetParentItem(string parentId, Guid? userId);
}
}

View File

@@ -28,12 +28,14 @@ namespace MediaBrowser.Controller.Library
/// <param name="itemId">The item identifier.</param>
/// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
List<MediaStream> GetMediaStreams(Guid itemId);
/// <summary>
/// Gets the media streams.
/// </summary>
/// <param name="mediaSourceId">The media source identifier.</param>
/// <returns>IEnumerable&lt;MediaStream&gt;.</returns>
List<MediaStream> GetMediaStreams(string mediaSourceId);
/// <summary>
/// Gets the media streams.
/// </summary>
@@ -113,5 +115,7 @@ namespace MediaBrowser.Controller.Library
public interface IDirectStreamProvider
{
Task CopyToAsync(Stream stream, CancellationToken cancellationToken);
string GetFilePath();
}
}

View File

@@ -158,7 +158,8 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="userId">The user's Id.</param>
/// <param name="config">The request containing the new user configuration.</param>
void UpdateConfiguration(Guid userId, UserConfiguration config);
/// <returns>A task representing the update.</returns>
Task UpdateConfigurationAsync(Guid userId, UserConfiguration config);
/// <summary>
/// This method updates the user's policy.
@@ -167,12 +168,14 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="userId">The user's Id.</param>
/// <param name="policy">The request containing the new user policy.</param>
void UpdatePolicy(Guid userId, UserPolicy policy);
/// <returns>A task representing the update.</returns>
Task UpdatePolicyAsync(Guid userId, UserPolicy policy);
/// <summary>
/// Clears the user's profile image.
/// </summary>
/// <param name="user">The user.</param>
void ClearProfileImage(User user);
/// <returns>A task representing the clearing of the profile image.</returns>
Task ClearProfileImageAsync(User user);
}
}

View File

@@ -156,6 +156,7 @@ namespace MediaBrowser.Controller.Library
}
// REVIEW: @bond
/// <summary>
/// Gets the physical locations.
/// </summary>

View File

@@ -225,12 +225,13 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="fields">The fields.</param>
/// <param name="user">The user.</param>
/// <returns>Task.</returns>
Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> programs, ItemFields[] fields, User user = null);
Task AddInfoToProgramDto(IReadOnlyCollection<(BaseItem, BaseItemDto)> programs, IReadOnlyList<ItemFields> fields, User user = null);
/// <summary>
/// Saves the tuner host.
/// </summary>
Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true);
/// <summary>
/// Saves the listing provider.
/// </summary>

View File

@@ -56,7 +56,6 @@ namespace MediaBrowser.Controller.LiveTv
Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(string channelId, CancellationToken cancellationToken);
Task<List<TunerHostInfo>> DiscoverDevices(int discoveryDurationMs, CancellationToken cancellationToken);
}
public interface IConfigurableTunerHost

View File

@@ -42,6 +42,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The tuners.</value>
public List<LiveTvTunerInfo> Tuners { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is visible.
/// </summary>

View File

@@ -35,6 +35,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The overview.</value>
public string Overview { get; set; }
/// <summary>
/// Gets or sets the short overview.
/// </summary>
@@ -169,31 +170,37 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value>The production year.</value>
public int? ProductionYear { get; set; }
/// <summary>
/// Gets or sets the home page URL.
/// </summary>
/// <value>The home page URL.</value>
public string HomePageUrl { get; set; }
/// <summary>
/// Gets or sets the series identifier.
/// </summary>
/// <value>The series identifier.</value>
public string SeriesId { get; set; }
/// <summary>
/// Gets or sets the show identifier.
/// </summary>
/// <value>The show identifier.</value>
public string ShowId { get; set; }
/// <summary>
/// Gets or sets the season number.
/// </summary>
/// <value>The season number.</value>
public int? SeasonNumber { get; set; }
/// <summary>
/// Gets or sets the episode number.
/// </summary>
/// <value>The episode number.</value>
public int? EpisodeNumber { get; set; }
/// <summary>
/// Gets or sets the etag.
/// </summary>

View File

@@ -187,6 +187,7 @@ namespace MediaBrowser.Controller.LiveTv
/// </summary>
/// <value><c>null</c> if [has image] contains no value, <c>true</c> if [has image]; otherwise, <c>false</c>.</value>
public bool? HasImage { get; set; }
/// <summary>
/// Gets or sets the show identifier.
/// </summary>

View File

@@ -113,6 +113,7 @@ namespace MediaBrowser.Controller.LiveTv
// Program properties
public int? SeasonNumber { get; set; }
/// <summary>
/// Gets or sets the episode number.
/// </summary>

View File

@@ -14,8 +14,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="5.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
</ItemGroup>
@@ -29,7 +29,7 @@
</ItemGroup>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors Condition=" '$(Configuration)' == 'Release' ">true</TreatWarningsAsErrors>

File diff suppressed because it is too large Load Diff

View File

@@ -287,6 +287,11 @@ namespace MediaBrowser.Controller.MediaEncoding
return BaseRequest.AudioChannels;
}
if (BaseRequest.TranscodingMaxAudioChannels.HasValue)
{
return BaseRequest.TranscodingMaxAudioChannels;
}
if (!string.IsNullOrEmpty(codec))
{
var value = BaseRequest.GetOption(codec, "audiochannels");
@@ -342,7 +347,8 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
var newSize = DrawingUtils.Resize(size,
var newSize = DrawingUtils.Resize(
size,
BaseRequest.Width ?? 0,
BaseRequest.Height ?? 0,
BaseRequest.MaxWidth ?? 0,
@@ -368,7 +374,8 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var size = new ImageDimensions(VideoStream.Width.Value, VideoStream.Height.Value);
var newSize = DrawingUtils.Resize(size,
var newSize = DrawingUtils.Resize(
size,
BaseRequest.Width ?? 0,
BaseRequest.Height ?? 0,
BaseRequest.MaxWidth ?? 0,
@@ -402,7 +409,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
// Don't exceed what the encoder supports
// Seeing issues of attempting to encode to 88200
return Math.Min(44100, BaseRequest.AudioSampleRate.Value);
return BaseRequest.AudioSampleRate.Value;
}
return null;
@@ -586,6 +593,11 @@ namespace MediaBrowser.Controller.MediaEncoding
{
get
{
if (VideoStream == null)
{
return null;
}
if (EncodingHelper.IsCopyCodec(OutputVideoCodec))
{
return VideoStream?.Codec;
@@ -599,6 +611,11 @@ namespace MediaBrowser.Controller.MediaEncoding
{
get
{
if (AudioStream == null)
{
return null;
}
if (EncodingHelper.IsCopyCodec(OutputAudioCodec))
{
return AudioStream?.Codec;
@@ -697,10 +714,12 @@ namespace MediaBrowser.Controller.MediaEncoding
/// The progressive.
/// </summary>
Progressive,
/// <summary>
/// The HLS.
/// </summary>
Hls,
/// <summary>
/// The dash.
/// </summary>

View File

@@ -68,7 +68,8 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary>
/// Extracts the video images on interval.
/// </summary>
Task ExtractVideoImagesOnInterval(string[] inputFiles,
Task ExtractVideoImagesOnInterval(
string[] inputFiles,
string container,
MediaStream videoStream,
MediaProtocol protocol,

View File

@@ -93,7 +93,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if (part.StartsWith("fps=", StringComparison.OrdinalIgnoreCase))
{
var rate = part.Split(new[] { '=' }, 2)[^1];
var rate = part.Split('=', 2)[^1];
if (float.TryParse(rate, NumberStyles.Any, _usCulture, out var val))
{
@@ -103,7 +103,7 @@ namespace MediaBrowser.Controller.MediaEncoding
else if (state.RunTimeTicks.HasValue &&
part.StartsWith("time=", StringComparison.OrdinalIgnoreCase))
{
var time = part.Split(new[] { '=' }, 2).Last();
var time = part.Split('=', 2)[^1];
if (TimeSpan.TryParse(time, _usCulture, out var val))
{
@@ -116,7 +116,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if (part.StartsWith("size=", StringComparison.OrdinalIgnoreCase))
{
var size = part.Split(new[] { '=' }, 2).Last();
var size = part.Split('=', 2)[^1];
int? scale = null;
if (size.IndexOf("kb", StringComparison.OrdinalIgnoreCase) != -1)
@@ -135,7 +135,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
else if (part.StartsWith("bitrate=", StringComparison.OrdinalIgnoreCase))
{
var rate = part.Split(new[] { '=' }, 2).Last();
var rate = part.Split('=', 2)[^1];
int? scale = null;
if (rate.IndexOf("kbits/s", StringComparison.OrdinalIgnoreCase) != -1)

View File

@@ -1,10 +1,11 @@
#pragma warning disable CS1591
using System;
using Jellyfin.Data.Entities;
namespace MediaBrowser.Controller.Net
{
/// <summary>
/// The request authorization info.
/// </summary>
public class AuthorizationInfo
{
/// <summary>
@@ -43,6 +44,19 @@ namespace MediaBrowser.Controller.Net
/// <value>The token.</value>
public string Token { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the authorization is from an api key.
/// </summary>
public bool IsApiKey { get; set; }
/// <summary>
/// Gets or sets the user making the request.
/// </summary>
public User User { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the token is authenticated.
/// </summary>
public bool IsAuthenticated { get; set; }
}
}

View File

@@ -8,6 +8,7 @@ using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Session;
using Microsoft.Extensions.Logging;
namespace MediaBrowser.Controller.Net
@@ -28,10 +29,22 @@ namespace MediaBrowser.Controller.Net
new List<Tuple<IWebSocketConnection, CancellationTokenSource, TStateType>>();
/// <summary>
/// Gets the name.
/// Gets the type used for the messages sent to the client.
/// </summary>
/// <value>The name.</value>
protected abstract string Name { get; }
/// <value>The type.</value>
protected abstract SessionMessageType Type { get; }
/// <summary>
/// Gets the message type received from the client to start sending messages.
/// </summary>
/// <value>The type.</value>
protected abstract SessionMessageType StartType { get; }
/// <summary>
/// Gets the message type received from the client to stop sending messages.
/// </summary>
/// <value>The type.</value>
protected abstract SessionMessageType StopType { get; }
/// <summary>
/// Gets the data to send.
@@ -66,12 +79,12 @@ namespace MediaBrowser.Controller.Net
throw new ArgumentNullException(nameof(message));
}
if (string.Equals(message.MessageType, Name + "Start", StringComparison.OrdinalIgnoreCase))
if (message.MessageType == StartType)
{
Start(message);
}
if (string.Equals(message.MessageType, Name + "Stop", StringComparison.OrdinalIgnoreCase))
if (message.MessageType == StopType)
{
Stop(message);
}
@@ -159,7 +172,7 @@ namespace MediaBrowser.Controller.Net
new WebSocketMessage<TReturnDataType>
{
MessageId = Guid.NewGuid(),
MessageType = Name,
MessageType = Type,
Data = data
},
cancellationToken).ConfigureAwait(false);
@@ -176,7 +189,7 @@ namespace MediaBrowser.Controller.Net
}
catch (Exception ex)
{
Logger.LogError(ex, "Error sending web socket message {Name}", Name);
Logger.LogError(ex, "Error sending web socket message {Name}", Type);
DisposeConnection(tuple);
}
}

View File

@@ -16,12 +16,6 @@ namespace MediaBrowser.Controller.Net
/// </summary>
event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected;
/// <summary>
/// Inits this instance.
/// </summary>
/// <param name="listeners">The websocket listeners.</param>
void Init(IEnumerable<IWebSocketListener> listeners);
/// <summary>
/// The HTTP request handler.
/// </summary>

View File

@@ -100,6 +100,7 @@ namespace MediaBrowser.Controller.Persistence
/// <param name="query">The query.</param>
/// <returns>IEnumerable&lt;Guid&gt;.</returns>
QueryResult<Guid> GetItemIds(InternalItemsQuery query);
/// <summary>
/// Gets the items.
/// </summary>

View File

@@ -31,7 +31,7 @@ namespace MediaBrowser.Controller.Playlists
/// <param name="itemIds">The item ids.</param>
/// <param name="userId">The user identifier.</param>
/// <returns>Task.</returns>
Task AddToPlaylistAsync(Guid playlistId, ICollection<Guid> itemIds, Guid userId);
Task AddToPlaylistAsync(Guid playlistId, IReadOnlyCollection<Guid> itemIds, Guid userId);
/// <summary>
/// Removes from playlist.

View File

@@ -160,7 +160,7 @@ namespace MediaBrowser.Controller.Playlists
return LibraryManager.GetItemList(new InternalItemsQuery(user)
{
Recursive = true,
IncludeItemTypes = new[] { typeof(Audio).Name },
IncludeItemTypes = new[] { nameof(Audio) },
GenreIds = new[] { musicGenre.Id },
OrderBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
@@ -172,7 +172,7 @@ namespace MediaBrowser.Controller.Playlists
return LibraryManager.GetItemList(new InternalItemsQuery(user)
{
Recursive = true,
IncludeItemTypes = new[] { typeof(Audio).Name },
IncludeItemTypes = new[] { nameof(Audio) },
ArtistIds = new[] { musicArtist.Id },
OrderBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options

View File

@@ -19,6 +19,7 @@ namespace MediaBrowser.Controller.Resolvers
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
BaseItem ResolvePath(ItemResolveArgs args);
/// <summary>
/// Gets the priority.
/// </summary>
@@ -28,7 +29,8 @@ namespace MediaBrowser.Controller.Resolvers
public interface IMultiItemResolver
{
MultiItemResolverResult ResolveMultiple(Folder parent,
MultiItemResolverResult ResolveMultiple(
Folder parent,
List<FileSystemMetadata> files,
string collectionType,
IDirectoryService directoryService);

View File

@@ -3,6 +3,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Controller.Session
{
@@ -23,6 +24,6 @@ namespace MediaBrowser.Controller.Session
/// <summary>
/// Sends the message.
/// </summary>
Task SendMessage<T>(string name, Guid messageId, T data, CancellationToken cancellationToken);
Task SendMessage<T>(SessionMessageType name, Guid messageId, T data, CancellationToken cancellationToken);
}
}

View File

@@ -188,16 +188,16 @@ namespace MediaBrowser.Controller.Session
/// <param name="data">The data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SendMessageToAdminSessions<T>(string name, T data, CancellationToken cancellationToken);
Task SendMessageToAdminSessions<T>(SessionMessageType name, T data, CancellationToken cancellationToken);
/// <summary>
/// Sends the message to user sessions.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>Task.</returns>
Task SendMessageToUserSessions<T>(List<Guid> userIds, string name, T data, CancellationToken cancellationToken);
Task SendMessageToUserSessions<T>(List<Guid> userIds, SessionMessageType name, T data, CancellationToken cancellationToken);
Task SendMessageToUserSessions<T>(List<Guid> userIds, string name, Func<T> dataFn, CancellationToken cancellationToken);
Task SendMessageToUserSessions<T>(List<Guid> userIds, SessionMessageType name, Func<T> dataFn, CancellationToken cancellationToken);
/// <summary>
/// Sends the message to user device sessions.
@@ -208,7 +208,7 @@ namespace MediaBrowser.Controller.Session
/// <param name="data">The data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SendMessageToUserDeviceSessions<T>(string deviceId, string name, T data, CancellationToken cancellationToken);
Task SendMessageToUserDeviceSessions<T>(string deviceId, SessionMessageType name, T data, CancellationToken cancellationToken);
/// <summary>
/// Sends the restart required message.

View File

@@ -1,6 +1,7 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading;
@@ -22,7 +23,6 @@ namespace MediaBrowser.Controller.Session
private readonly ISessionManager _sessionManager;
private readonly ILogger _logger;
private readonly object _progressLock = new object();
private Timer _progressTimer;
private PlaybackProgressInfo _lastProgressInfo;
@@ -55,7 +55,7 @@ namespace MediaBrowser.Controller.Session
/// Gets or sets the playable media types.
/// </summary>
/// <value>The playable media types.</value>
public string[] PlayableMediaTypes
public IReadOnlyList<string> PlayableMediaTypes
{
get
{
@@ -231,8 +231,8 @@ namespace MediaBrowser.Controller.Session
/// Gets or sets the supported commands.
/// </summary>
/// <value>The supported commands.</value>
public string[] SupportedCommands
=> Capabilities == null ? Array.Empty<string>() : Capabilities.SupportedCommands;
public IReadOnlyList<GeneralCommandType> SupportedCommands
=> Capabilities == null ? Array.Empty<GeneralCommandType>() : Capabilities.SupportedCommands;
public Tuple<ISessionController, bool> EnsureController<T>(Func<SessionInfo, ISessionController> factory)
{

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
@@ -52,6 +53,14 @@ namespace MediaBrowser.Controller.Subtitles
/// </summary>
Task DownloadSubtitles(Video video, LibraryOptions libraryOptions, string subtitleId, CancellationToken cancellationToken);
/// <summary>
/// Upload new subtitle.
/// </summary>
/// <param name="video">The video the subtitle belongs to.</param>
/// <param name="response">The subtitle response.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
Task UploadSubtitle(Video video, SubtitleResponse response);
/// <summary>
/// Gets the remote subtitles.
/// </summary>

View File

@@ -14,12 +14,12 @@ namespace MediaBrowser.Controller.SyncPlay
public class GroupInfo
{
/// <summary>
/// Gets the default ping value used for sessions.
/// The default ping value used for sessions.
/// </summary>
public long DefaultPing { get; } = 500;
public const long DefaultPing = 500;
/// <summary>
/// Gets or sets the group identifier.
/// Gets the group identifier.
/// </summary>
/// <value>The group identifier.</value>
public Guid GroupId { get; } = Guid.NewGuid();
@@ -58,7 +58,8 @@ namespace MediaBrowser.Controller.SyncPlay
/// <summary>
/// Checks if a session is in this group.
/// </summary>
/// <value><c>true</c> if the session is in this group; <c>false</c> otherwise.</value>
/// <param name="sessionId">The session id to check.</param>
/// <returns><c>true</c> if the session is in this group; <c>false</c> otherwise.</returns>
public bool ContainsSession(string sessionId)
{
return Participants.ContainsKey(sessionId);
@@ -70,16 +71,14 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="session">The session.</param>
public void AddSession(SessionInfo session)
{
if (ContainsSession(session.Id))
{
return;
}
var member = new GroupMember();
member.Session = session;
member.Ping = DefaultPing;
member.IsBuffering = false;
Participants[session.Id] = member;
Participants.TryAdd(
session.Id,
new GroupMember
{
Session = session,
Ping = DefaultPing,
IsBuffering = false
});
}
/// <summary>
@@ -88,12 +87,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="session">The session.</param>
public void RemoveSession(SessionInfo session)
{
if (!ContainsSession(session.Id))
{
return;
}
Participants.Remove(session.Id, out _);
Participants.Remove(session.Id);
}
/// <summary>
@@ -103,18 +97,16 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="ping">The ping.</param>
public void UpdatePing(SessionInfo session, long ping)
{
if (!ContainsSession(session.Id))
if (Participants.TryGetValue(session.Id, out GroupMember value))
{
return;
value.Ping = ping;
}
Participants[session.Id].Ping = ping;
}
/// <summary>
/// Gets the highest ping in the group.
/// </summary>
/// <value name="session">The highest ping in the group.</value>
/// <returns>The highest ping in the group.</returns>
public long GetHighestPing()
{
long max = long.MinValue;
@@ -133,18 +125,16 @@ namespace MediaBrowser.Controller.SyncPlay
/// <param name="isBuffering">The state.</param>
public void SetBuffering(SessionInfo session, bool isBuffering)
{
if (!ContainsSession(session.Id))
if (Participants.TryGetValue(session.Id, out GroupMember value))
{
return;
value.IsBuffering = isBuffering;
}
Participants[session.Id].IsBuffering = isBuffering;
}
/// <summary>
/// Gets the group buffering state.
/// </summary>
/// <value><c>true</c> if there is a session buffering in the group; <c>false</c> otherwise.</value>
/// <returns><c>true</c> if there is a session buffering in the group; <c>false</c> otherwise.</returns>
public bool IsBuffering()
{
foreach (var session in Participants.Values)
@@ -161,7 +151,7 @@ namespace MediaBrowser.Controller.SyncPlay
/// <summary>
/// Checks if the group is empty.
/// </summary>
/// <value><c>true</c> if the group is empty; <c>false</c> otherwise.</value>
/// <returns><c>true</c> if the group is empty; <c>false</c> otherwise.</returns>
public bool IsEmpty()
{
return Participants.Count == 0;