aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api')
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs10
-rw-r--r--MediaBrowser.Api/BaseApiService.cs10
-rw-r--r--MediaBrowser.Api/ChannelService.cs7
-rw-r--r--MediaBrowser.Api/ConfigurationService.cs10
-rw-r--r--MediaBrowser.Api/Devices/DeviceService.cs29
-rw-r--r--MediaBrowser.Api/DisplayPreferencesService.cs8
-rw-r--r--MediaBrowser.Api/EnvironmentService.cs29
-rw-r--r--MediaBrowser.Api/FilterService.cs11
-rw-r--r--MediaBrowser.Api/IHasDtoOptions.cs1
-rw-r--r--MediaBrowser.Api/IHasItemFields.cs3
-rw-r--r--MediaBrowser.Api/Images/ImageByNameService.cs10
-rw-r--r--MediaBrowser.Api/Images/ImageRequest.cs12
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs203
-rw-r--r--MediaBrowser.Api/Images/RemoteImageService.cs6
-rw-r--r--MediaBrowser.Api/ItemLookupService.cs6
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs50
-rw-r--r--MediaBrowser.Api/Library/LibraryStructureService.cs8
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs39
-rw-r--r--MediaBrowser.Api/LocalizationService.cs12
-rw-r--r--MediaBrowser.Api/Movies/CollectionService.cs1
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs27
-rw-r--r--MediaBrowser.Api/Movies/TrailersService.cs7
-rw-r--r--MediaBrowser.Api/Music/AlbumsService.cs16
-rw-r--r--MediaBrowser.Api/Music/InstantMixService.cs2
-rw-r--r--MediaBrowser.Api/PackageService.cs36
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs29
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs5
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs42
-rw-r--r--MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs6
-rw-r--r--MediaBrowser.Api/Playback/Hls/VideoHlsService.cs4
-rw-r--r--MediaBrowser.Api/Playback/MediaInfoService.cs41
-rw-r--r--MediaBrowser.Api/Playback/Progressive/AudioService.cs4
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs10
-rw-r--r--MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs6
-rw-r--r--MediaBrowser.Api/Playback/Progressive/VideoService.cs5
-rw-r--r--MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs6
-rw-r--r--MediaBrowser.Api/Playback/StreamRequest.cs6
-rw-r--r--MediaBrowser.Api/Playback/StreamState.cs2
-rw-r--r--MediaBrowser.Api/Playback/UniversalAudioService.cs21
-rw-r--r--MediaBrowser.Api/PlaylistService.cs5
-rw-r--r--MediaBrowser.Api/PluginService.cs31
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs12
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs2
-rw-r--r--MediaBrowser.Api/SearchService.cs11
-rw-r--r--MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs32
-rw-r--r--MediaBrowser.Api/Sessions/SessionService.cs9
-rw-r--r--MediaBrowser.Api/SimilarItemsHelper.cs15
-rw-r--r--MediaBrowser.Api/Subtitles/SubtitleService.cs2
-rw-r--r--MediaBrowser.Api/SuggestionsService.cs6
-rw-r--r--MediaBrowser.Api/SyncPlay/SyncPlayService.cs104
-rw-r--r--MediaBrowser.Api/System/ActivityLogService.cs2
-rw-r--r--MediaBrowser.Api/System/ActivityLogWebSocketListener.cs4
-rw-r--r--MediaBrowser.Api/System/SystemService.cs13
-rw-r--r--MediaBrowser.Api/TranscodingJob.cs8
-rw-r--r--MediaBrowser.Api/TvShowsService.cs33
-rw-r--r--MediaBrowser.Api/UserLibrary/ArtistsService.cs4
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs9
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs25
-rw-r--r--MediaBrowser.Api/UserLibrary/GenresService.cs6
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs29
-rw-r--r--MediaBrowser.Api/UserLibrary/PersonsService.cs6
-rw-r--r--MediaBrowser.Api/UserLibrary/PlaystateService.cs12
-rw-r--r--MediaBrowser.Api/UserLibrary/StudiosService.cs6
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs22
-rw-r--r--MediaBrowser.Api/UserLibrary/UserViewsService.cs4
-rw-r--r--MediaBrowser.Api/UserLibrary/YearsService.cs6
-rw-r--r--MediaBrowser.Api/UserService.cs72
67 files changed, 704 insertions, 526 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 6691080bc..b041effb2 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -31,7 +31,7 @@ namespace MediaBrowser.Api
/// <summary>
/// The logger.
/// </summary>
- private ILogger _logger;
+ private ILogger<ApiEntryPoint> _logger;
/// <summary>
/// The configuration manager.
@@ -43,7 +43,7 @@ namespace MediaBrowser.Api
private readonly IMediaSourceManager _mediaSourceManager;
/// <summary>
- /// The active transcoding jobs
+ /// The active transcoding jobs.
/// </summary>
private readonly List<TranscodingJob> _activeTranscodingJobs = new List<TranscodingJob>();
@@ -284,8 +284,8 @@ namespace MediaBrowser.Api
Width = state.OutputWidth,
Height = state.OutputHeight,
AudioChannels = state.OutputAudioChannels,
- IsAudioDirect = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase),
- IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase),
+ IsAudioDirect = EncodingHelper.IsCopyCodec(state.OutputAudioCodec),
+ IsVideoDirect = EncodingHelper.IsCopyCodec(state.OutputVideoCodec),
TranscodeReasons = state.TranscodeReasons
});
}
@@ -293,7 +293,7 @@ namespace MediaBrowser.Api
/// <summary>
/// <summary>
- /// The progressive
+ /// The progressive.
/// </summary>
/// Called when [transcode failed to start].
/// </summary>
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 2cd68ac1b..63a31a745 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -16,7 +17,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class BaseApiService
+ /// Class BaseApiService.
/// </summary>
public abstract class BaseApiService : IService, IRequiresRequest
{
@@ -94,8 +95,8 @@ namespace MediaBrowser.Api
var authenticatedUser = auth.User;
// If they're going to update the record of another user, they must be an administrator
- if ((!userId.Equals(auth.UserId) && !authenticatedUser.Policy.IsAdministrator)
- || (restrictUserPreferences && !authenticatedUser.Policy.EnableUserPreferenceAccess))
+ if ((!userId.Equals(auth.UserId) && !authenticatedUser.HasPermission(PermissionKind.IsAdministrator))
+ || (restrictUserPreferences && !authenticatedUser.EnableUserPreferenceAccess))
{
throw new SecurityException("Unauthorized access.");
}
@@ -267,7 +268,6 @@ namespace MediaBrowser.Api
Name = name.Replace(BaseItem.SlugChar, '&'),
IncludeItemTypes = new[] { typeof(T).Name },
DtoOptions = dtoOptions
-
}).OfType<T>().FirstOrDefault();
result ??= libraryManager.GetItemList(new InternalItemsQuery
@@ -275,7 +275,6 @@ namespace MediaBrowser.Api
Name = name.Replace(BaseItem.SlugChar, '/'),
IncludeItemTypes = new[] { typeof(T).Name },
DtoOptions = dtoOptions
-
}).OfType<T>().FirstOrDefault();
result ??= libraryManager.GetItemList(new InternalItemsQuery
@@ -283,7 +282,6 @@ namespace MediaBrowser.Api
Name = name.Replace(BaseItem.SlugChar, '?'),
IncludeItemTypes = new[] { typeof(T).Name },
DtoOptions = dtoOptions
-
}).OfType<T>().FirstOrDefault();
return result;
diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs
index fd9b8c396..8c336b1c9 100644
--- a/MediaBrowser.Api/ChannelService.cs
+++ b/MediaBrowser.Api/ChannelService.cs
@@ -36,7 +36,7 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -90,7 +90,7 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -149,7 +149,7 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -240,7 +240,6 @@ namespace MediaBrowser.Api
{
Fields = request.GetItemFields()
}
-
};
foreach (var filter in request.GetFilters())
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index 316be04a0..19369ccca 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -11,13 +11,12 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetConfiguration
+ /// Class GetConfiguration.
/// </summary>
[Route("/System/Configuration", "GET", Summary = "Gets application configuration")]
[Authenticated]
public class GetConfiguration : IReturn<ServerConfiguration>
{
-
}
[Route("/System/Configuration/{Key}", "GET", Summary = "Gets a named configuration")]
@@ -29,7 +28,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdateConfiguration
+ /// Class UpdateConfiguration.
/// </summary>
[Route("/System/Configuration", "POST", Summary = "Updates application configuration")]
[Authenticated(Roles = "Admin")]
@@ -51,7 +50,6 @@ namespace MediaBrowser.Api
[Authenticated(Roles = "Admin")]
public class GetDefaultMetadataOptions : IReturn<MetadataOptions>
{
-
}
[Route("/System/MediaEncoder/Path", "POST", Summary = "Updates the path to the media encoder")]
@@ -67,12 +65,12 @@ namespace MediaBrowser.Api
public class ConfigurationService : BaseApiService
{
/// <summary>
- /// The _json serializer
+ /// The _json serializer.
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
- /// The _configuration manager
+ /// The _configuration manager.
/// </summary>
private readonly IServerConfigurationManager _configurationManager;
diff --git a/MediaBrowser.Api/Devices/DeviceService.cs b/MediaBrowser.Api/Devices/DeviceService.cs
index 53eb9667d..18860983e 100644
--- a/MediaBrowser.Api/Devices/DeviceService.cs
+++ b/MediaBrowser.Api/Devices/DeviceService.cs
@@ -1,4 +1,3 @@
-using System.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Net;
@@ -40,33 +39,6 @@ namespace MediaBrowser.Api.Devices
public string Id { get; set; }
}
- [Route("/Devices/CameraUploads", "GET", Summary = "Gets camera upload history for a device")]
- [Authenticated]
- public class GetCameraUploads : IReturn<ContentUploadHistory>
- {
- [ApiMember(Name = "Id", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string DeviceId { get; set; }
- }
-
- [Route("/Devices/CameraUploads", "POST", Summary = "Uploads content")]
- [Authenticated]
- public class PostCameraUpload : IRequiresRequestStream, IReturnVoid
- {
- [ApiMember(Name = "DeviceId", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string DeviceId { get; set; }
-
- [ApiMember(Name = "Album", Description = "Album", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Album { get; set; }
-
- [ApiMember(Name = "Name", Description = "Name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Name { get; set; }
-
- [ApiMember(Name = "Id", Description = "Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Id { get; set; }
-
- public Stream RequestStream { get; set; }
- }
-
[Route("/Devices/Options", "POST", Summary = "Updates device options")]
[Authenticated(Roles = "Admin")]
public class PostDeviceOptions : DeviceOptions, IReturnVoid
@@ -120,7 +92,6 @@ namespace MediaBrowser.Api.Devices
var sessions = _authRepo.Get(new AuthenticationInfoQuery
{
DeviceId = request.Id
-
}).Items;
foreach (var session in sessions)
diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs
index 62c4ff43f..c3ed40ad3 100644
--- a/MediaBrowser.Api/DisplayPreferencesService.cs
+++ b/MediaBrowser.Api/DisplayPreferencesService.cs
@@ -10,7 +10,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class UpdateDisplayPreferences
+ /// Class UpdateDisplayPreferences.
/// </summary>
[Route("/DisplayPreferences/{DisplayPreferencesId}", "POST", Summary = "Updates a user's display preferences for an item")]
public class UpdateDisplayPreferences : DisplayPreferences, IReturnVoid
@@ -44,17 +44,17 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class DisplayPreferencesService
+ /// Class DisplayPreferencesService.
/// </summary>
[Authenticated]
public class DisplayPreferencesService : BaseApiService
{
/// <summary>
- /// The _display preferences manager
+ /// The _display preferences manager.
/// </summary>
private readonly IDisplayPreferencesRepository _displayPreferencesManager;
/// <summary>
- /// The _json serializer
+ /// The _json serializer.
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs
index d199ce154..720a71025 100644
--- a/MediaBrowser.Api/EnvironmentService.cs
+++ b/MediaBrowser.Api/EnvironmentService.cs
@@ -12,7 +12,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetDirectoryContents
+ /// Class GetDirectoryContents.
/// </summary>
[Route("/Environment/DirectoryContents", "GET", Summary = "Gets the contents of a given directory in the file system")]
public class GetDirectoryContents : IReturn<List<FileSystemEntryInfo>>
@@ -50,6 +50,7 @@ namespace MediaBrowser.Api
public string Path { get; set; }
public bool ValidateWriteable { get; set; }
+
public bool? IsFile { get; set; }
}
@@ -66,7 +67,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetDrives
+ /// Class GetDrives.
/// </summary>
[Route("/Environment/Drives", "GET", Summary = "Gets available drives from the server's file system")]
public class GetDrives : IReturn<List<FileSystemEntryInfo>>
@@ -74,7 +75,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetNetworkComputers
+ /// Class GetNetworkComputers.
/// </summary>
[Route("/Environment/NetworkDevices", "GET", Summary = "Gets a list of devices on the network")]
public class GetNetworkDevices : IReturn<List<FileSystemEntryInfo>>
@@ -100,11 +101,10 @@ namespace MediaBrowser.Api
[Route("/Environment/DefaultDirectoryBrowser", "GET", Summary = "Gets the parent path of a given path")]
public class GetDefaultDirectoryBrowser : IReturn<DefaultDirectoryBrowserInfo>
{
-
}
/// <summary>
- /// Class EnvironmentService
+ /// Class EnvironmentService.
/// </summary>
[Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)]
public class EnvironmentService : BaseApiService
@@ -113,7 +113,7 @@ namespace MediaBrowser.Api
private const string UncSeparatorString = "\\";
/// <summary>
- /// The _network manager
+ /// The _network manager.
/// </summary>
private readonly INetworkManager _networkManager;
private readonly IFileSystem _fileSystem;
@@ -221,17 +221,12 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Gets the list that is returned when an empty path is supplied
+ /// Gets the list that is returned when an empty path is supplied.
/// </summary>
/// <returns>IEnumerable{FileSystemEntryInfo}.</returns>
private IEnumerable<FileSystemEntryInfo> GetDrives()
{
- return _fileSystem.GetDrives().Select(d => new FileSystemEntryInfo
- {
- Name = d.Name,
- Path = d.FullName,
- Type = FileSystemEntryType.Directory
- });
+ return _fileSystem.GetDrives().Select(d => new FileSystemEntryInfo(d.Name, d.FullName, FileSystemEntryType.Directory));
}
/// <summary>
@@ -261,13 +256,7 @@ namespace MediaBrowser.Api
return request.IncludeDirectories || !isDirectory;
});
- return entries.Select(f => new FileSystemEntryInfo
- {
- Name = f.Name,
- Path = f.FullName,
- Type = f.IsDirectory ? FileSystemEntryType.Directory : FileSystemEntryType.File
-
- });
+ return entries.Select(f => new FileSystemEntryInfo(f.Name, f.FullName, f.IsDirectory ? FileSystemEntryType.Directory : FileSystemEntryType.File));
}
public object Get(GetParentPath request)
diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs
index 5eb72cdb1..dcfdcbfed 100644
--- a/MediaBrowser.Api/FilterService.cs
+++ b/MediaBrowser.Api/FilterService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
@@ -72,11 +73,17 @@ namespace MediaBrowser.Api
}
public bool? IsAiring { get; set; }
+
public bool? IsMovie { get; set; }
+
public bool? IsSports { get; set; }
+
public bool? IsKids { get; set; }
+
public bool? IsNews { get; set; }
+
public bool? IsSeries { get; set; }
+
public bool? Recursive { get; set; }
}
@@ -118,7 +125,7 @@ namespace MediaBrowser.Api
IncludeItemTypes = request.GetIncludeItemTypes(),
DtoOptions = new Controller.Dto.DtoOptions
{
- Fields = new ItemFields[] { },
+ Fields = Array.Empty<ItemFields>(),
EnableImages = false,
EnableUserData = false
},
@@ -149,7 +156,6 @@ namespace MediaBrowser.Api
{
Name = i.Item1.Name,
Id = i.Item1.Id
-
}).ToArray();
}
else
@@ -158,7 +164,6 @@ namespace MediaBrowser.Api
{
Name = i.Item1.Name,
Id = i.Item1.Id
-
}).ToArray();
}
diff --git a/MediaBrowser.Api/IHasDtoOptions.cs b/MediaBrowser.Api/IHasDtoOptions.cs
index 03d3b3692..33d498e8b 100644
--- a/MediaBrowser.Api/IHasDtoOptions.cs
+++ b/MediaBrowser.Api/IHasDtoOptions.cs
@@ -3,6 +3,7 @@ namespace MediaBrowser.Api
public interface IHasDtoOptions : IHasItemFields
{
bool? EnableImages { get; set; }
+
bool? EnableUserData { get; set; }
int? ImageTypeLimit { get; set; }
diff --git a/MediaBrowser.Api/IHasItemFields.cs b/MediaBrowser.Api/IHasItemFields.cs
index 85b4a7e2d..ad4f1b489 100644
--- a/MediaBrowser.Api/IHasItemFields.cs
+++ b/MediaBrowser.Api/IHasItemFields.cs
@@ -5,7 +5,7 @@ using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api
{
/// <summary>
- /// Interface IHasItemFields
+ /// Interface IHasItemFields.
/// </summary>
public interface IHasItemFields
{
@@ -43,7 +43,6 @@ namespace MediaBrowser.Api
}
return null;
-
}).Where(i => i.HasValue).Select(i => i.Value).ToArray();
}
}
diff --git a/MediaBrowser.Api/Images/ImageByNameService.cs b/MediaBrowser.Api/Images/ImageByNameService.cs
index 45b7d0c10..2d405ac3d 100644
--- a/MediaBrowser.Api/Images/ImageByNameService.cs
+++ b/MediaBrowser.Api/Images/ImageByNameService.cs
@@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Images
{
/// <summary>
- /// Class GetGeneralImage
+ /// Class GetGeneralImage.
/// </summary>
[Route("/Images/General/{Name}/{Type}", "GET", Summary = "Gets a general image by name")]
public class GetGeneralImage
@@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class GetRatingImage
+ /// Class GetRatingImage.
/// </summary>
[Route("/Images/Ratings/{Theme}/{Name}", "GET", Summary = "Gets a rating image by name")]
public class GetRatingImage
@@ -54,7 +54,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class GetMediaInfoImage
+ /// Class GetMediaInfoImage.
/// </summary>
[Route("/Images/MediaInfo/{Theme}/{Name}", "GET", Summary = "Gets a media info image by name")]
public class GetMediaInfoImage
@@ -93,12 +93,12 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class ImageByNameService
+ /// Class ImageByNameService.
/// </summary>
public class ImageByNameService : BaseApiService
{
/// <summary>
- /// The _app paths
+ /// The _app paths.
/// </summary>
private readonly IServerApplicationPaths _appPaths;
diff --git a/MediaBrowser.Api/Images/ImageRequest.cs b/MediaBrowser.Api/Images/ImageRequest.cs
index 71ff09b63..0f3455548 100644
--- a/MediaBrowser.Api/Images/ImageRequest.cs
+++ b/MediaBrowser.Api/Images/ImageRequest.cs
@@ -4,30 +4,30 @@ using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Images
{
/// <summary>
- /// Class ImageRequest
+ /// Class ImageRequest.
/// </summary>
public class ImageRequest : DeleteImageRequest
{
/// <summary>
- /// The max width
+ /// The max width.
/// </summary>
[ApiMember(Name = "MaxWidth", Description = "The maximum image width to return.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? MaxWidth { get; set; }
/// <summary>
- /// The max height
+ /// The max height.
/// </summary>
[ApiMember(Name = "MaxHeight", Description = "The maximum image height to return.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? MaxHeight { get; set; }
/// <summary>
- /// The width
+ /// The width.
/// </summary>
[ApiMember(Name = "Width", Description = "The fixed image width to return.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Width { get; set; }
/// <summary>
- /// The height
+ /// The height.
/// </summary>
[ApiMember(Name = "Height", Description = "The fixed image height to return.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Height { get; set; }
@@ -79,7 +79,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class DeleteImageRequest
+ /// Class DeleteImageRequest.
/// </summary>
public class DeleteImageRequest
{
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 2e9b3e6cb..8426a9a4f 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
@@ -17,9 +18,11 @@ using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Net;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
+using User = Jellyfin.Data.Entities.User;
namespace MediaBrowser.Api.Images
{
@@ -55,7 +58,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class UpdateItemImageIndex
+ /// Class UpdateItemImageIndex.
/// </summary>
[Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST", Summary = "Updates the index for an item image")]
[Authenticated(Roles = "admin")]
@@ -91,7 +94,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class GetPersonImage
+ /// Class GetPersonImage.
/// </summary>
[Route("/Artists/{Name}/Images/{Type}", "GET")]
[Route("/Artists/{Name}/Images/{Type}/{Index}", "GET")]
@@ -128,7 +131,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class GetUserImage
+ /// Class GetUserImage.
/// </summary>
[Route("/Users/{Id}/Images/{Type}", "GET")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "GET")]
@@ -145,7 +148,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class DeleteItemImage
+ /// Class DeleteItemImage.
/// </summary>
[Route("/Items/{Id}/Images/{Type}", "DELETE")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "DELETE")]
@@ -161,7 +164,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class DeleteUserImage
+ /// Class DeleteUserImage.
/// </summary>
[Route("/Users/{Id}/Images/{Type}", "DELETE")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")]
@@ -177,7 +180,7 @@ namespace MediaBrowser.Api.Images
}
/// <summary>
- /// Class PostUserImage
+ /// Class PostUserImage.
/// </summary>
[Route("/Users/{Id}/Images/{Type}", "POST")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "POST")]
@@ -192,14 +195,14 @@ namespace MediaBrowser.Api.Images
public string Id { get; set; }
/// <summary>
- /// The raw Http Request Input Stream
+ /// The raw Http Request Input Stream.
/// </summary>
/// <value>The request stream.</value>
public Stream RequestStream { get; set; }
}
/// <summary>
- /// Class PostItemImage
+ /// Class PostItemImage.
/// </summary>
[Route("/Items/{Id}/Images/{Type}", "POST")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "POST")]
@@ -214,14 +217,14 @@ namespace MediaBrowser.Api.Images
public string Id { get; set; }
/// <summary>
- /// The raw Http Request Input Stream
+ /// The raw Http Request Input Stream.
/// </summary>
/// <value>The request stream.</value>
public Stream RequestStream { get; set; }
}
/// <summary>
- /// Class ImageService
+ /// Class ImageService.
/// </summary>
public class ImageService : BaseApiService
{
@@ -280,9 +283,16 @@ namespace MediaBrowser.Api.Images
public List<ImageInfo> GetItemImageInfos(BaseItem item)
{
var list = new List<ImageInfo>();
-
var itemImages = item.ImageInfos;
+ if (itemImages.Length == 0)
+ {
+ // short-circuit
+ return list;
+ }
+
+ _libraryManager.UpdateImages(item); // this makes sure dimensions and hashes are correct
+
foreach (var image in itemImages)
{
if (!item.AllowsMultipleImages(image.Type))
@@ -323,6 +333,7 @@ namespace MediaBrowser.Api.Images
{
int? width = null;
int? height = null;
+ string blurhash = null;
long length = 0;
try
@@ -332,10 +343,9 @@ namespace MediaBrowser.Api.Images
var fileInfo = _fileSystem.GetFileInfo(info.Path);
length = fileInfo.Length;
- ImageDimensions size = _imageProcessor.GetImageDimensions(item, info);
- _libraryManager.UpdateImages(item);
- width = size.Width;
- height = size.Height;
+ blurhash = info.BlurHash;
+ width = info.Width;
+ height = info.Height;
if (width <= 0 || height <= 0)
{
@@ -358,6 +368,7 @@ namespace MediaBrowser.Api.Images
ImageType = info.Type,
ImageTag = _imageProcessor.GetImageCacheTag(item, info),
Size = length,
+ BlurHash = blurhash,
Width = width,
Height = height
};
@@ -399,14 +410,14 @@ namespace MediaBrowser.Api.Images
{
var item = _userManager.GetUserById(request.Id);
- return GetImage(request, Guid.Empty, item, false);
+ return GetImage(request, item, false);
}
public object Head(GetUserImage request)
{
var item = _userManager.GetUserById(request.Id);
- return GetImage(request, Guid.Empty, item, true);
+ return GetImage(request, item, true);
}
public object Get(GetItemByNameImage request)
@@ -439,9 +450,9 @@ namespace MediaBrowser.Api.Images
request.Type = Enum.Parse<ImageType>(GetPathValue(3).ToString(), true);
- var item = _userManager.GetUserById(id);
+ var user = _userManager.GetUserById(id);
- return PostImage(item, request.RequestStream, request.Type, Request.ContentType);
+ return PostImage(user, request.RequestStream, Request.ContentType);
}
/// <summary>
@@ -468,9 +479,17 @@ namespace MediaBrowser.Api.Images
var userId = request.Id;
AssertCanUpdateUser(_authContext, _userManager, userId, true);
- var item = _userManager.GetUserById(userId);
+ var user = _userManager.GetUserById(userId);
+ try
+ {
+ File.Delete(user.ProfileImage.Path);
+ }
+ catch (IOException e)
+ {
+ Logger.LogError(e, "Error deleting user profile image:");
+ }
- item.DeleteImage(request.Type, request.Index ?? 0);
+ _userManager.ClearProfileImage(user);
}
/// <summary>
@@ -555,18 +574,17 @@ namespace MediaBrowser.Api.Images
var imageInfo = GetImageInfo(request, item);
if (imageInfo == null)
{
- var displayText = item == null ? itemId.ToString() : item.Name;
- throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", displayText, request.Type));
+ throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", item.Name, request.Type));
}
- bool cropwhitespace;
+ bool cropWhitespace;
if (request.CropWhitespace.HasValue)
{
- cropwhitespace = request.CropWhitespace.Value;
+ cropWhitespace = request.CropWhitespace.Value;
}
else
{
- cropwhitespace = request.Type == ImageType.Logo || request.Type == ImageType.Art;
+ cropWhitespace = request.Type == ImageType.Logo || request.Type == ImageType.Art;
}
var outputFormats = GetOutputFormats(request);
@@ -589,13 +607,90 @@ namespace MediaBrowser.Api.Images
itemId,
request,
imageInfo,
- cropwhitespace,
+ cropWhitespace,
outputFormats,
cacheDuration,
responseHeaders,
isHeadRequest);
}
+ public Task<object> GetImage(ImageRequest request, User user, bool isHeadRequest)
+ {
+ var imageInfo = GetImageInfo(request, user);
+
+ TimeSpan? cacheDuration = null;
+
+ if (!string.IsNullOrEmpty(request.Tag))
+ {
+ cacheDuration = TimeSpan.FromDays(365);
+ }
+
+ var responseHeaders = new Dictionary<string, string>
+ {
+ {"transferMode.dlna.org", "Interactive"},
+ {"realTimeInfo.dlna.org", "DLNA.ORG_TLAG=*"}
+ };
+
+ var outputFormats = GetOutputFormats(request);
+
+ return GetImageResult(user.Id,
+ request,
+ imageInfo,
+ outputFormats,
+ cacheDuration,
+ responseHeaders,
+ isHeadRequest);
+ }
+
+ private async Task<object> GetImageResult(
+ Guid itemId,
+ ImageRequest request,
+ ItemImageInfo info,
+ IReadOnlyCollection<ImageFormat> supportedFormats,
+ TimeSpan? cacheDuration,
+ IDictionary<string, string> headers,
+ bool isHeadRequest)
+ {
+ info.Type = ImageType.Profile;
+ var options = new ImageProcessingOptions
+ {
+ CropWhiteSpace = true,
+ Height = request.Height,
+ ImageIndex = request.Index ?? 0,
+ Image = info,
+ Item = null, // Hack alert
+ ItemId = itemId,
+ MaxHeight = request.MaxHeight,
+ MaxWidth = request.MaxWidth,
+ Quality = request.Quality ?? 100,
+ Width = request.Width,
+ AddPlayedIndicator = request.AddPlayedIndicator,
+ PercentPlayed = 0,
+ UnplayedCount = request.UnplayedCount,
+ Blur = request.Blur,
+ BackgroundColor = request.BackgroundColor,
+ ForegroundLayer = request.ForegroundLayer,
+ SupportedOutputFormats = supportedFormats
+ };
+
+ var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);
+
+ headers[HeaderNames.Vary] = HeaderNames.Accept;
+
+ return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
+ {
+ CacheDuration = cacheDuration,
+ ResponseHeaders = headers,
+ ContentType = imageResult.Item2,
+ DateLastModified = imageResult.Item3,
+ IsHeadRequest = isHeadRequest,
+ Path = imageResult.Item1,
+
+ FileShare = FileShare.Read
+
+ }).ConfigureAwait(false);
+ }
+
private async Task<object> GetImageResult(
BaseItem item,
Guid itemId,
@@ -648,7 +743,6 @@ namespace MediaBrowser.Api.Images
Path = imageResult.Item1,
FileShare = FileShare.Read
-
}).ConfigureAwait(false);
}
@@ -733,13 +827,35 @@ namespace MediaBrowser.Api.Images
/// <param name="request">The request.</param>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
- private ItemImageInfo GetImageInfo(ImageRequest request, BaseItem item)
+ private static ItemImageInfo GetImageInfo(ImageRequest request, BaseItem item)
{
var index = request.Index ?? 0;
return item.GetImageInfo(request.Type, index);
}
+ private static ItemImageInfo GetImageInfo(ImageRequest request, User user)
+ {
+ var info = new ItemImageInfo
+ {
+ Path = user.ProfileImage.Path,
+ Type = ImageType.Primary,
+ DateModified = user.ProfileImage.LastModified,
+ };
+
+ if (request.Width.HasValue)
+ {
+ info.Width = request.Width.Value;
+ }
+
+ if (request.Height.HasValue)
+ {
+ info.Height = request.Height.Value;
+ }
+
+ return info;
+ }
+
/// <summary>
/// Posts the image.
/// </summary>
@@ -750,22 +866,41 @@ namespace MediaBrowser.Api.Images
/// <returns>Task.</returns>
public async Task PostImage(BaseItem entity, Stream inputStream, ImageType imageType, string mimeType)
{
+ var memoryStream = await GetMemoryStream(inputStream);
+
+ // Handle image/png; charset=utf-8
+ mimeType = mimeType.Split(';').FirstOrDefault();
+
+ await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
+
+ entity.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ }
+
+ private static async Task<MemoryStream> GetMemoryStream(Stream inputStream)
+ {
using var reader = new StreamReader(inputStream);
var text = await reader.ReadToEndAsync().ConfigureAwait(false);
var bytes = Convert.FromBase64String(text);
-
- var memoryStream = new MemoryStream(bytes)
+ return new MemoryStream(bytes)
{
Position = 0
};
+ }
+
+ private async Task PostImage(User user, Stream inputStream, string mimeType)
+ {
+ var memoryStream = await GetMemoryStream(inputStream);
// Handle image/png; charset=utf-8
mimeType = mimeType.Split(';').FirstOrDefault();
+ var userDataPath = Path.Combine(ServerConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, user.Username);
+ user.ProfileImage = new Jellyfin.Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType)));
- await _providerManager.SaveImage(entity, memoryStream, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
-
- entity.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
+ await _providerManager
+ .SaveImage(user, memoryStream, mimeType, user.ProfileImage.Path)
+ .ConfigureAwait(false);
+ await _userManager.UpdateUserAsync(user);
}
}
}
diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs
index 23bf54712..86464b4b9 100644
--- a/MediaBrowser.Api/Images/RemoteImageService.cs
+++ b/MediaBrowser.Api/Images/RemoteImageService.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Images
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -147,13 +147,11 @@ namespace MediaBrowser.Api.Images
{
var item = _libraryManager.GetItemById(request.Id);
- var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery
+ var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery(request.ProviderName)
{
- ProviderName = request.ProviderName,
IncludeAllLanguages = request.IncludeAllLanguages,
IncludeDisabledProviders = true,
ImageType = request.Type
-
}, CancellationToken.None).ConfigureAwait(false);
var imagesList = images.ToArray();
diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs
index 68e3dfa59..862411209 100644
--- a/MediaBrowser.Api/ItemLookupService.cs
+++ b/MediaBrowser.Api/ItemLookupService.cs
@@ -220,7 +220,7 @@ namespace MediaBrowser.Api
{
var item = _libraryManager.GetItemById(new Guid(request.Id));
- //foreach (var key in request.ProviderIds)
+ // foreach (var key in request.ProviderIds)
//{
// var value = key.Value;
@@ -233,8 +233,8 @@ namespace MediaBrowser.Api
// Since the refresh process won't erase provider Ids, we need to set this explicitly now.
item.ProviderIds = request.ProviderIds;
- //item.ProductionYear = request.ProductionYear;
- //item.Name = request.Name;
+ // item.ProductionYear = request.ProductionYear;
+ // item.Name = request.Name;
return _providerManager.RefreshFullItem(
item,
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index c0146dfee..6555864dc 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -6,6 +6,7 @@ using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
using MediaBrowser.Api.Movies;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
@@ -14,7 +15,6 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
-using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
@@ -27,6 +27,12 @@ using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
+using Book = MediaBrowser.Controller.Entities.Book;
+using Episode = MediaBrowser.Controller.Entities.TV.Episode;
+using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
+using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
+using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
+using Series = MediaBrowser.Controller.Entities.TV.Series;
namespace MediaBrowser.Api.Library
{
@@ -43,7 +49,7 @@ namespace MediaBrowser.Api.Library
}
/// <summary>
- /// Class GetCriticReviews
+ /// Class GetCriticReviews.
/// </summary>
[Route("/Items/{Id}/CriticReviews", "GET", Summary = "Gets critic reviews for an item")]
[Authenticated]
@@ -64,7 +70,7 @@ namespace MediaBrowser.Api.Library
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -72,7 +78,7 @@ namespace MediaBrowser.Api.Library
}
/// <summary>
- /// Class GetThemeSongs
+ /// Class GetThemeSongs.
/// </summary>
[Route("/Items/{Id}/ThemeSongs", "GET", Summary = "Gets theme songs for an item")]
[Authenticated]
@@ -97,7 +103,7 @@ namespace MediaBrowser.Api.Library
}
/// <summary>
- /// Class GetThemeVideos
+ /// Class GetThemeVideos.
/// </summary>
[Route("/Items/{Id}/ThemeVideos", "GET", Summary = "Gets theme videos for an item")]
[Authenticated]
@@ -122,7 +128,7 @@ namespace MediaBrowser.Api.Library
}
/// <summary>
- /// Class GetThemeVideos
+ /// Class GetThemeVideos.
/// </summary>
[Route("/Items/{Id}/ThemeMedia", "GET", Summary = "Gets theme videos and songs for an item")]
[Authenticated]
@@ -199,7 +205,7 @@ namespace MediaBrowser.Api.Library
}
/// <summary>
- /// Class GetPhyscialPaths
+ /// Class GetPhyscialPaths.
/// </summary>
[Route("/Library/PhysicalPaths", "GET", Summary = "Gets a list of physical paths from virtual folders")]
[Authenticated(Roles = "Admin")]
@@ -279,34 +285,43 @@ namespace MediaBrowser.Api.Library
public class GetLibraryOptionsInfo : IReturn<LibraryOptionsResult>
{
public string LibraryContentType { get; set; }
+
public bool IsNewLibrary { get; set; }
}
public class LibraryOptionInfo
{
public string Name { get; set; }
+
public bool DefaultEnabled { get; set; }
}
public class LibraryOptionsResult
{
public LibraryOptionInfo[] MetadataSavers { get; set; }
+
public LibraryOptionInfo[] MetadataReaders { get; set; }
+
public LibraryOptionInfo[] SubtitleFetchers { get; set; }
+
public LibraryTypeOptions[] TypeOptions { get; set; }
}
public class LibraryTypeOptions
{
public string Type { get; set; }
+
public LibraryOptionInfo[] MetadataFetchers { get; set; }
+
public LibraryOptionInfo[] ImageFetchers { get; set; }
+
public ImageType[] SupportedImageTypes { get; set; }
+
public ImageOption[] DefaultImageOptions { get; set; }
}
/// <summary>
- /// Class LibraryService
+ /// Class LibraryService.
/// </summary>
public class LibraryService : BaseApiService
{
@@ -350,6 +365,7 @@ namespace MediaBrowser.Api.Library
_moviesServiceLogger = moviesServiceLogger;
}
+ // Content Types available for each Library
private string[] GetRepresentativeItemTypes(string contentType)
{
return contentType switch
@@ -359,7 +375,7 @@ namespace MediaBrowser.Api.Library
CollectionType.Movies => new[] {"Movie"},
CollectionType.TvShows => new[] {"Series", "Season", "Episode"},
CollectionType.Books => new[] {"Book"},
- CollectionType.Music => new[] {"MusicAlbum", "MusicArtist", "Audio", "MusicVideo"},
+ CollectionType.Music => new[] {"MusicArtist", "MusicAlbum", "Audio", "MusicVideo"},
CollectionType.HomeVideos => new[] {"Video", "Photo"},
CollectionType.Photos => new[] {"Video", "Photo"},
CollectionType.MusicVideos => new[] {"MusicVideo"},
@@ -425,7 +441,6 @@ namespace MediaBrowser.Api.Library
return string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase)
|| string.Equals(name, "Screen Grabber", StringComparison.OrdinalIgnoreCase)
|| string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase)
- || string.Equals(name, "Emby Designs", StringComparison.OrdinalIgnoreCase)
|| string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase);
}
@@ -556,7 +571,6 @@ namespace MediaBrowser.Api.Library
_authContext)
{
Request = Request,
-
}.GetSimilarItemsResult(request);
}
@@ -654,8 +668,7 @@ namespace MediaBrowser.Api.Library
{
EnableImages = false
}
-
- }).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray();
+ }).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProvider.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray();
foreach (var item in series)
{
@@ -683,16 +696,15 @@ namespace MediaBrowser.Api.Library
{
EnableImages = false
}
-
});
if (!string.IsNullOrWhiteSpace(request.ImdbId))
{
- movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase)).ToList();
+ movies = movies.Where(i => string.Equals(request.ImdbId, i.GetProviderId(MetadataProvider.Imdb), StringComparison.OrdinalIgnoreCase)).ToList();
}
else if (!string.IsNullOrWhiteSpace(request.TmdbId))
{
- movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase)).ToList();
+ movies = movies.Where(i => string.Equals(request.TmdbId, i.GetProviderId(MetadataProvider.Tmdb), StringComparison.OrdinalIgnoreCase)).ToList();
}
else
{
@@ -763,8 +775,8 @@ namespace MediaBrowser.Api.Library
{
try
{
- _activityManager.Create(new Jellyfin.Data.Entities.ActivityLog(
- string.Format(_localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Name, item.Name),
+ _activityManager.Create(new ActivityLog(
+ string.Format(_localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Username, item.Name),
"UserDownloadingContent",
auth.UserId)
{
@@ -1033,6 +1045,7 @@ namespace MediaBrowser.Api.Library
{
break;
}
+
item = parent;
}
@@ -1090,6 +1103,7 @@ namespace MediaBrowser.Api.Library
{
break;
}
+
item = parent;
}
diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs
index 1e300814f..b69550ed1 100644
--- a/MediaBrowser.Api/Library/LibraryStructureService.cs
+++ b/MediaBrowser.Api/Library/LibraryStructureService.cs
@@ -19,7 +19,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Library
{
/// <summary>
- /// Class GetDefaultVirtualFolders
+ /// Class GetDefaultVirtualFolders.
/// </summary>
[Route("/Library/VirtualFolders", "GET")]
public class GetVirtualFolders : IReturn<List<VirtualFolderInfo>>
@@ -166,18 +166,18 @@ namespace MediaBrowser.Api.Library
}
/// <summary>
- /// Class LibraryStructureService
+ /// Class LibraryStructureService.
/// </summary>
[Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)]
public class LibraryStructureService : BaseApiService
{
/// <summary>
- /// The _app paths
+ /// The _app paths.
/// </summary>
private readonly IServerApplicationPaths _appPaths;
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly ILibraryMonitor _libraryMonitor;
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 5fe4c0cca..830372dd8 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -7,6 +7,7 @@ using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using MediaBrowser.Api.UserLibrary;
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
@@ -30,7 +31,7 @@ using Microsoft.Net.Http.Headers;
namespace MediaBrowser.Api.LiveTv
{
/// <summary>
- /// This is insecure right now to avoid windows phone refactoring
+ /// This is insecure right now to avoid windows phone refactoring.
/// </summary>
[Route("/LiveTv/Info", "GET", Summary = "Gets available live tv services.")]
[Authenticated]
@@ -71,7 +72,7 @@ namespace MediaBrowser.Api.LiveTv
public bool? IsSports { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -99,7 +100,7 @@ namespace MediaBrowser.Api.LiveTv
public string EnableImageTypes { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -187,7 +188,7 @@ namespace MediaBrowser.Api.LiveTv
public string EnableImageTypes { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -199,10 +200,15 @@ namespace MediaBrowser.Api.LiveTv
public bool? EnableUserData { get; set; }
public bool? IsMovie { get; set; }
+
public bool? IsSeries { get; set; }
+
public bool? IsKids { get; set; }
+
public bool? IsSports { get; set; }
+
public bool? IsNews { get; set; }
+
public bool? IsLibraryItem { get; set; }
public GetRecordings()
@@ -249,7 +255,7 @@ namespace MediaBrowser.Api.LiveTv
public string EnableImageTypes { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -347,6 +353,7 @@ namespace MediaBrowser.Api.LiveTv
[ApiMember(Name = "HasAired", Description = "Optional. Filter by programs that have completed airing, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasAired { get; set; }
+
public bool? IsAiring { get; set; }
[ApiMember(Name = "MaxStartDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
@@ -406,10 +413,11 @@ namespace MediaBrowser.Api.LiveTv
public bool? EnableUserData { get; set; }
public string SeriesTimerId { get; set; }
+
public Guid LibrarySeriesId { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -472,7 +480,7 @@ namespace MediaBrowser.Api.LiveTv
public string GenreIds { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -600,7 +608,9 @@ namespace MediaBrowser.Api.LiveTv
public class AddListingProvider : ListingsProviderInfo, IReturn<ListingsProviderInfo>
{
public bool ValidateLogin { get; set; }
+
public bool ValidateListings { get; set; }
+
public string Pw { get; set; }
}
@@ -649,15 +659,20 @@ namespace MediaBrowser.Api.LiveTv
{
[ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query")]
public string ProviderId { get; set; }
+
public string TunerChannelId { get; set; }
+
public string ProviderChannelId { get; set; }
}
public class ChannelMappingOptions
{
public List<TunerChannelMapping> TunerChannels { get; set; }
+
public List<NameIdPair> ProviderChannels { get; set; }
+
public NameValuePair[] Mappings { get; set; }
+
public string ProviderName { get; set; }
}
@@ -665,6 +680,7 @@ namespace MediaBrowser.Api.LiveTv
public class GetLiveStreamFile
{
public string Id { get; set; }
+
public string Container { get; set; }
}
@@ -678,7 +694,6 @@ namespace MediaBrowser.Api.LiveTv
[Authenticated]
public class GetTunerHostTypes : IReturn<List<NameIdPair>>
{
-
}
[Route("/LiveTv/Tuners/Discvover", "GET")]
@@ -825,7 +840,6 @@ namespace MediaBrowser.Api.LiveTv
{
Name = i.Name,
Id = i.Id
-
}).ToList(),
Mappings = mappings,
@@ -844,7 +858,6 @@ namespace MediaBrowser.Api.LiveTv
{
Url = "https://json.schedulesdirect.org/20141201/available/countries",
BufferContent = false
-
}).ConfigureAwait(false);
return ResultFactory.GetResult(Request, response, "application/json");
@@ -859,7 +872,7 @@ namespace MediaBrowser.Api.LiveTv
throw new SecurityException("Anonymous live tv management is not allowed.");
}
- if (!user.Policy.EnableLiveTvManagement)
+ if (!user.HasPermission(PermissionKind.EnableLiveTvManagement))
{
throw new SecurityException("The current user does not have permission to manage live tv.");
}
@@ -957,7 +970,6 @@ namespace MediaBrowser.Api.LiveTv
SortBy = request.GetOrderBy(),
SortOrder = request.SortOrder ?? SortOrder.Ascending,
AddCurrentProgram = request.AddCurrentProgram
-
}, options, CancellationToken.None);
var user = request.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(request.UserId);
@@ -1112,7 +1124,6 @@ namespace MediaBrowser.Api.LiveTv
Fields = request.GetItemFields(),
ImageTypeLimit = request.ImageTypeLimit,
EnableImages = request.EnableImages
-
}, options);
return ToOptimizedResult(result);
@@ -1151,7 +1162,6 @@ namespace MediaBrowser.Api.LiveTv
SeriesTimerId = request.SeriesTimerId,
IsActive = request.IsActive,
IsScheduled = request.IsScheduled
-
}, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
@@ -1187,7 +1197,6 @@ namespace MediaBrowser.Api.LiveTv
{
SortOrder = request.SortOrder,
SortBy = request.SortBy
-
}, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
diff --git a/MediaBrowser.Api/LocalizationService.cs b/MediaBrowser.Api/LocalizationService.cs
index 6a69d2656..d6b5f5195 100644
--- a/MediaBrowser.Api/LocalizationService.cs
+++ b/MediaBrowser.Api/LocalizationService.cs
@@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetCultures
+ /// Class GetCultures.
/// </summary>
[Route("/Localization/Cultures", "GET", Summary = "Gets known cultures")]
public class GetCultures : IReturn<CultureDto[]>
@@ -16,7 +16,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetCountries
+ /// Class GetCountries.
/// </summary>
[Route("/Localization/Countries", "GET", Summary = "Gets known countries")]
public class GetCountries : IReturn<CountryInfo[]>
@@ -24,7 +24,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class ParentalRatings
+ /// Class ParentalRatings.
/// </summary>
[Route("/Localization/ParentalRatings", "GET", Summary = "Gets known parental ratings")]
public class GetParentalRatings : IReturn<ParentalRating[]>
@@ -32,7 +32,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class ParentalRatings
+ /// Class ParentalRatings.
/// </summary>
[Route("/Localization/Options", "GET", Summary = "Gets localization options")]
public class GetLocalizationOptions : IReturn<LocalizationOption[]>
@@ -40,13 +40,13 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class CulturesService
+ /// Class CulturesService.
/// </summary>
[Authenticated(AllowBeforeStartupWizard = true)]
public class LocalizationService : BaseApiService
{
/// <summary>
- /// The _localization
+ /// The _localization.
/// </summary>
private readonly ILocalizationManager _localization;
diff --git a/MediaBrowser.Api/Movies/CollectionService.cs b/MediaBrowser.Api/Movies/CollectionService.cs
index 95a37dfc5..e9629439d 100644
--- a/MediaBrowser.Api/Movies/CollectionService.cs
+++ b/MediaBrowser.Api/Movies/CollectionService.cs
@@ -79,7 +79,6 @@ namespace MediaBrowser.Api.Movies
ParentId = parentId,
ItemIdList = SplitValue(request.Ids, ','),
UserIds = new[] { userId }
-
});
var dtoOptions = GetDtoOptions(_authContext, request);
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index cdd027634..34cccffa3 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -2,11 +2,11 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using Jellyfin.Data.Entities;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Net;
@@ -15,6 +15,8 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
+using Movie = MediaBrowser.Controller.Entities.Movies.Movie;
namespace MediaBrowser.Api.Movies
{
@@ -63,13 +65,13 @@ namespace MediaBrowser.Api.Movies
}
/// <summary>
- /// Class MoviesService
+ /// Class MoviesService.
/// </summary>
[Authenticated]
public class MoviesService : BaseApiService
{
/// <summary>
- /// The _user manager
+ /// The _user manager.
/// </summary>
private readonly IUserManager _userManager;
@@ -159,8 +161,8 @@ namespace MediaBrowser.Api.Movies
IncludeItemTypes = new[]
{
typeof(Movie).Name,
- //typeof(Trailer).Name,
- //typeof(LiveTvProgram).Name
+ // typeof(Trailer).Name,
+ // typeof(LiveTvProgram).Name
},
// IsMovie = true
OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
@@ -192,7 +194,6 @@ namespace MediaBrowser.Api.Movies
ParentId = parentIdGuid,
Recursive = true,
DtoOptions = dtoOptions
-
});
var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList();
@@ -251,7 +252,12 @@ namespace MediaBrowser.Api.Movies
return categories.OrderBy(i => i.RecommendationType);
}
- private IEnumerable<RecommendationDto> GetWithDirector(User user, IEnumerable<string> names, int itemLimit, DtoOptions dtoOptions, RecommendationType type)
+ private IEnumerable<RecommendationDto> GetWithDirector(
+ User user,
+ IEnumerable<string> names,
+ int itemLimit,
+ DtoOptions dtoOptions,
+ RecommendationType type)
{
var itemTypes = new List<string> { typeof(Movie).Name };
if (ServerConfigurationManager.Configuration.EnableExternalContentInSuggestions)
@@ -272,8 +278,7 @@ namespace MediaBrowser.Api.Movies
IsMovie = true,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
-
- }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
+ }).GroupBy(i => i.GetProviderId(MetadataProvider.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
.Select(x => x.First())
.Take(itemLimit)
.ToList();
@@ -313,8 +318,7 @@ namespace MediaBrowser.Api.Movies
IsMovie = true,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
-
- }).GroupBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
+ }).GroupBy(i => i.GetProviderId(MetadataProvider.Imdb) ?? Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))
.Select(x => x.First())
.Take(itemLimit)
.ToList();
@@ -353,7 +357,6 @@ namespace MediaBrowser.Api.Movies
SimilarTo = item,
EnableGroupByMetadataKey = true,
DtoOptions = dtoOptions
-
});
if (similar.Count > 0)
diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs
index 0b5334235..ca9f9d03b 100644
--- a/MediaBrowser.Api/Movies/TrailersService.cs
+++ b/MediaBrowser.Api/Movies/TrailersService.cs
@@ -18,18 +18,18 @@ namespace MediaBrowser.Api.Movies
}
/// <summary>
- /// Class TrailersService
+ /// Class TrailersService.
/// </summary>
[Authenticated]
public class TrailersService : BaseApiService
{
/// <summary>
- /// The _user manager
+ /// The _user manager.
/// </summary>
private readonly IUserManager _userManager;
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
@@ -82,7 +82,6 @@ namespace MediaBrowser.Api.Movies
_authContext)
{
Request = Request,
-
}.Get(getItems);
}
}
diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs
index 58c95d053..74d3cce12 100644
--- a/MediaBrowser.Api/Music/AlbumsService.cs
+++ b/MediaBrowser.Api/Music/AlbumsService.cs
@@ -27,16 +27,16 @@ namespace MediaBrowser.Api.Music
public class AlbumsService : BaseApiService
{
/// <summary>
- /// The _user manager
+ /// The _user manager.
/// </summary>
private readonly IUserManager _userManager;
/// <summary>
- /// The _user data repository
+ /// The _user data repository.
/// </summary>
private readonly IUserDataManager _userDataRepository;
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly IItemRepository _itemRepo;
@@ -67,12 +67,13 @@ namespace MediaBrowser.Api.Music
{
var dtoOptions = GetDtoOptions(_authContext, request);
- var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
+ var result = SimilarItemsHelper.GetSimilarItemsResult(
+ dtoOptions,
+ _userManager,
_itemRepo,
_libraryManager,
_userDataRepository,
_dtoService,
- Logger,
request, new[] { typeof(MusicArtist) },
SimilarItemsHelper.GetSimiliarityScore);
@@ -88,12 +89,13 @@ namespace MediaBrowser.Api.Music
{
var dtoOptions = GetDtoOptions(_authContext, request);
- var result = SimilarItemsHelper.GetSimilarItemsResult(dtoOptions, _userManager,
+ var result = SimilarItemsHelper.GetSimilarItemsResult(
+ dtoOptions,
+ _userManager,
_itemRepo,
_libraryManager,
_userDataRepository,
_dtoService,
- Logger,
request, new[] { typeof(MusicAlbum) },
GetAlbumSimilarityScore);
diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs
index cacec8d64..ebd3eb64a 100644
--- a/MediaBrowser.Api/Music/InstantMixService.cs
+++ b/MediaBrowser.Api/Music/InstantMixService.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
+using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -191,6 +192,5 @@ namespace MediaBrowser.Api.Music
return result;
}
-
}
}
diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs
index 444354a99..a84556fcc 100644
--- a/MediaBrowser.Api/PackageService.cs
+++ b/MediaBrowser.Api/PackageService.cs
@@ -13,8 +13,20 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
+ [Route("/Repositories", "GET", Summary = "Gets all package repositories")]
+ [Authenticated]
+ public class GetRepositories : IReturnVoid
+ {
+ }
+
+ [Route("/Repositories", "POST", Summary = "Sets the enabled and existing package repositories")]
+ [Authenticated]
+ public class SetRepositories : List<RepositoryInfo>, IReturnVoid
+ {
+ }
+
/// <summary>
- /// Class GetPackage
+ /// Class GetPackage.
/// </summary>
[Route("/Packages/{Name}", "GET", Summary = "Gets a package, by name or assembly guid")]
[Authenticated]
@@ -36,7 +48,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetPackages
+ /// Class GetPackages.
/// </summary>
[Route("/Packages", "GET", Summary = "Gets available packages")]
[Authenticated]
@@ -45,7 +57,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class InstallPackage
+ /// Class InstallPackage.
/// </summary>
[Route("/Packages/Installed/{Name}", "POST", Summary = "Installs a package")]
[Authenticated(Roles = "Admin")]
@@ -74,7 +86,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class CancelPackageInstallation
+ /// Class CancelPackageInstallation.
/// </summary>
[Route("/Packages/Installing/{Id}", "DELETE", Summary = "Cancels a package installation")]
[Authenticated(Roles = "Admin")]
@@ -89,11 +101,12 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class PackageService
+ /// Class PackageService.
/// </summary>
public class PackageService : BaseApiService
{
private readonly IInstallationManager _installationManager;
+ private readonly IServerConfigurationManager _serverConfigurationManager;
public PackageService(
ILogger<PackageService> logger,
@@ -103,6 +116,19 @@ namespace MediaBrowser.Api
: base(logger, serverConfigurationManager, httpResultFactory)
{
_installationManager = installationManager;
+ _serverConfigurationManager = serverConfigurationManager;
+ }
+
+ public object Get(GetRepositories request)
+ {
+ var result = _serverConfigurationManager.Configuration.PluginRepositories;
+ return ToOptimizedResult(result);
+ }
+
+ public void Post(SetRepositories request)
+ {
+ _serverConfigurationManager.Configuration.PluginRepositories = request;
+ _serverConfigurationManager.SaveConfiguration();
}
/// <summary>
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index f796aa486..84ed5dcac 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -7,6 +7,7 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
@@ -27,7 +28,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Playback
{
/// <summary>
- /// Class BaseStreamingService
+ /// Class BaseStreamingService.
/// </summary>
public abstract class BaseStreamingService : BaseApiService
{
@@ -193,10 +194,10 @@ namespace MediaBrowser.Api.Playback
await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false);
- if (state.VideoRequest != null && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (state.VideoRequest != null && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
{
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
- if (auth.User != null && !auth.User.Policy.EnableVideoPlaybackTranscoding)
+ if (auth.User != null && !auth.User.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
{
ApiEntryPoint.Instance.OnTranscodeFailedToStart(outputPath, TranscodingJobType, state);
@@ -215,7 +216,7 @@ namespace MediaBrowser.Api.Playback
UseShellExecute = false,
// Must consume both stdout and stderr or deadlocks may occur
- //RedirectStandardOutput = true,
+ // RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
@@ -243,9 +244,9 @@ namespace MediaBrowser.Api.Playback
var logFilePrefix = "ffmpeg-transcode";
if (state.VideoRequest != null
- && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ && EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
{
- logFilePrefix = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase)
+ logFilePrefix = EncodingHelper.IsCopyCodec(state.OutputAudioCodec)
? "ffmpeg-remux" : "ffmpeg-directstream";
}
@@ -302,6 +303,7 @@ namespace MediaBrowser.Api.Playback
{
StartThrottler(state, transcodingJob);
}
+
Logger.LogDebug("StartFfMpeg() finished successfully");
return transcodingJob;
@@ -328,7 +330,7 @@ namespace MediaBrowser.Api.Playback
state.RunTimeTicks.Value >= TimeSpan.FromMinutes(5).Ticks &&
state.IsInputVideo &&
state.VideoType == VideoType.VideoFile &&
- !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase);
+ !EncodingHelper.IsCopyCodec(state.OutputVideoCodec);
}
return false;
@@ -607,6 +609,7 @@ namespace MediaBrowser.Api.Playback
{
throw new ArgumentException("Invalid timeseek header");
}
+
int index = value.IndexOf('-');
value = index == -1
? value.Substring(Npt.Length)
@@ -638,8 +641,10 @@ namespace MediaBrowser.Api.Playback
{
throw new ArgumentException("Invalid timeseek header");
}
+
timeFactor /= 60;
}
+
return TimeSpan.FromSeconds(secondsSum).Ticks;
}
@@ -684,7 +689,7 @@ namespace MediaBrowser.Api.Playback
state.User = UserManager.GetUserById(auth.UserId);
}
- //if ((Request.UserAgent ?? string.Empty).IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
+ // if ((Request.UserAgent ?? string.Empty).IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
// (Request.UserAgent ?? string.Empty).IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 ||
// (Request.UserAgent ?? string.Empty).IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
//{
@@ -715,9 +720,9 @@ namespace MediaBrowser.Api.Playback
state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
- //var primaryImage = item.GetImageInfo(ImageType.Primary, 0) ??
+ // var primaryImage = item.GetImageInfo(ImageType.Primary, 0) ??
// item.Parents.Select(i => i.GetImageInfo(ImageType.Primary, 0)).FirstOrDefault(i => i != null);
- //if (primaryImage != null)
+ // if (primaryImage != null)
//{
// state.AlbumCoverPath = primaryImage.Path;
//}
@@ -791,7 +796,7 @@ namespace MediaBrowser.Api.Playback
EncodingHelper.TryStreamCopy(state);
}
- if (state.OutputVideoBitrate.HasValue && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (state.OutputVideoBitrate.HasValue && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
{
var resolution = ResolutionNormalizer.Normalize(
state.VideoStream?.BitRate,
@@ -884,7 +889,7 @@ namespace MediaBrowser.Api.Playback
if (transcodingProfile != null)
{
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
- //state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
+ // state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
if (state.VideoRequest != null)
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 627421aac..418cd92b3 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -20,7 +20,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Playback.Hls
{
/// <summary>
- /// Class BaseHlsService
+ /// Class BaseHlsService.
/// </summary>
public abstract class BaseHlsService : BaseStreamingService
{
@@ -146,6 +146,7 @@ namespace MediaBrowser.Api.Playback.Hls
{
ApiEntryPoint.Instance.OnTranscodeEndRequest(job);
}
+
return ResultFactory.GetResult(GetLivePlaylistText(playlist, state.SegmentLength), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
}
@@ -178,7 +179,7 @@ namespace MediaBrowser.Api.Playback.Hls
var newDuration = "#EXT-X-TARGETDURATION:" + segmentLength.ToString(CultureInfo.InvariantCulture);
text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength - 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
- //text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
+ // text = text.Replace("#EXT-X-TARGETDURATION:" + (segmentLength + 1).ToString(CultureInfo.InvariantCulture), newDuration, StringComparison.OrdinalIgnoreCase);
return text;
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index b8ea9c6da..fe5f980b1 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -234,6 +234,7 @@ namespace MediaBrowser.Api.Playback.Hls
Logger.LogDebug("Starting transcoding because segmentGap is {0} and max allowed gap is {1}. requestedIndex={2}", requestedIndex - currentTranscodingIndex.Value, segmentGapRequiringTranscodingChange, requestedIndex);
startTranscoding = true;
}
+
if (startTranscoding)
{
// If the playlist doesn't already exist, startup ffmpeg
@@ -257,7 +258,7 @@ namespace MediaBrowser.Api.Playback.Hls
throw;
}
- //await WaitForMinimumSegmentCount(playlistPath, 1, cancellationTokenSource.Token).ConfigureAwait(false);
+ // await WaitForMinimumSegmentCount(playlistPath, 1, cancellationTokenSource.Token).ConfigureAwait(false);
}
else
{
@@ -277,8 +278,8 @@ namespace MediaBrowser.Api.Playback.Hls
}
}
- //Logger.LogInformation("waiting for {0}", segmentPath);
- //while (!File.Exists(segmentPath))
+ // Logger.LogInformation("waiting for {0}", segmentPath);
+ // while (!File.Exists(segmentPath))
//{
// await Task.Delay(50, cancellationToken).ConfigureAwait(false);
//}
@@ -518,6 +519,7 @@ namespace MediaBrowser.Api.Playback.Hls
{
Logger.LogDebug("serving {0} as it's on disk and transcoding stopped", segmentPath);
}
+
cancellationToken.ThrowIfCancellationRequested();
}
else
@@ -700,12 +702,12 @@ namespace MediaBrowser.Api.Playback.Hls
return false;
}
- if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
{
return false;
}
- if (string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(state.OutputAudioCodec))
{
return false;
}
@@ -717,7 +719,7 @@ namespace MediaBrowser.Api.Playback.Hls
// Having problems in android
return false;
- //return state.VideoRequest.VideoBitRate.HasValue;
+ // return state.VideoRequest.VideoBitRate.HasValue;
}
/// <summary>
@@ -728,7 +730,7 @@ namespace MediaBrowser.Api.Playback.Hls
private int? GetOutputVideoCodecLevel(StreamState state)
{
string levelString;
- if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)
+ if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& state.VideoStream.Level.HasValue)
{
levelString = state.VideoStream?.Level.ToString();
@@ -872,9 +874,8 @@ namespace MediaBrowser.Api.Playback.Hls
if (framerate.HasValue)
{
- builder.Append(",FRAME-RATE=\"")
- .Append(framerate.Value)
- .Append('"');
+ builder.Append(",FRAME-RATE=")
+ .Append(framerate.Value);
}
}
@@ -888,11 +889,10 @@ namespace MediaBrowser.Api.Playback.Hls
{
if (state.OutputWidth.HasValue && state.OutputHeight.HasValue)
{
- builder.Append(",RESOLUTION=\"")
+ builder.Append(",RESOLUTION=")
.Append(state.OutputWidth.GetValueOrDefault())
.Append('x')
- .Append(state.OutputHeight.GetValueOrDefault())
- .Append('"');
+ .Append(state.OutputHeight.GetValueOrDefault());
}
}
@@ -974,7 +974,7 @@ namespace MediaBrowser.Api.Playback.Hls
var queryStringIndex = Request.RawUrl.IndexOf('?');
var queryString = queryStringIndex == -1 ? string.Empty : Request.RawUrl.Substring(queryStringIndex);
- //if ((Request.UserAgent ?? string.Empty).IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1)
+ // if ((Request.UserAgent ?? string.Empty).IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1)
//{
// queryString = string.Empty;
//}
@@ -1008,7 +1008,7 @@ namespace MediaBrowser.Api.Playback.Hls
if (!state.IsOutputVideo)
{
- if (string.Equals(audioCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(audioCodec))
{
return "-acodec copy";
}
@@ -1036,11 +1036,11 @@ namespace MediaBrowser.Api.Playback.Hls
return string.Join(" ", audioTranscodeParams.ToArray());
}
- if (string.Equals(audioCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(audioCodec))
{
var videoCodec = EncodingHelper.GetVideoEncoder(state, encodingOptions);
- if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.EnableBreakOnNonKeyFrames(videoCodec))
+ if (EncodingHelper.IsCopyCodec(videoCodec) && state.EnableBreakOnNonKeyFrames(videoCodec))
{
return "-codec:a:0 copy -copypriorss:a:0 0";
}
@@ -1091,7 +1091,7 @@ namespace MediaBrowser.Api.Playback.Hls
// }
// See if we can save come cpu cycles by avoiding encoding
- if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(codec))
{
if (state.VideoStream != null && !string.Equals(state.VideoStream.NalLengthSize, "0", StringComparison.OrdinalIgnoreCase))
{
@@ -1102,7 +1102,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
}
- //args += " -flags -global_header";
+ // args += " -flags -global_header";
}
else
{
@@ -1144,7 +1144,7 @@ namespace MediaBrowser.Api.Playback.Hls
args += " " + keyFrameArg + gopArg;
}
- //args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0";
+ // args += " -mixed-refs 0 -refs 3 -x264opts b_pyramid=0:weightb=0:weightp=0";
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
@@ -1166,7 +1166,7 @@ namespace MediaBrowser.Api.Playback.Hls
args += " -start_at_zero";
}
- //args += " -flags -global_header";
+ // args += " -flags -global_header";
}
if (!string.IsNullOrEmpty(state.OutputVideoSync))
diff --git a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
index 87ccde2e0..8a3d00283 100644
--- a/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
+++ b/MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs
@@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Playback.Hls
{
/// <summary>
- /// Class GetHlsAudioSegment
+ /// Class GetHlsAudioSegment.
/// </summary>
// Can't require authentication just yet due to seeing some requests come from Chrome without full query string
//[Authenticated]
@@ -37,7 +37,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
/// <summary>
- /// Class GetHlsVideoSegment
+ /// Class GetHlsVideoSegment.
/// </summary>
[Route("/Videos/{Id}/hls/{PlaylistId}/stream.m3u8", "GET")]
[Authenticated]
@@ -66,7 +66,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
/// <summary>
- /// Class GetHlsVideoSegment
+ /// Class GetHlsVideoSegment.
/// </summary>
// Can't require authentication just yet due to seeing some requests come from Chrome without full query string
//[Authenticated]
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index d1c53c1c1..9562f9953 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Api.Playback.Hls
}
/// <summary>
- /// Class VideoHlsService
+ /// Class VideoHlsService.
/// </summary>
[Authenticated]
public class VideoHlsService : BaseHlsService
@@ -72,7 +72,7 @@ namespace MediaBrowser.Api.Playback.Hls
{
var codec = EncodingHelper.GetAudioEncoder(state);
- if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(codec))
{
return "-codec:a:0 copy";
}
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index e2d771ec6..b7ca1a031 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -9,6 +9,7 @@ using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
@@ -400,21 +401,24 @@ namespace MediaBrowser.Api.Playback
if (item is Audio)
{
- Logger.LogInformation("User policy for {0}. EnableAudioPlaybackTranscoding: {1}", user.Name, user.Policy.EnableAudioPlaybackTranscoding);
+ Logger.LogInformation(
+ "User policy for {0}. EnableAudioPlaybackTranscoding: {1}",
+ user.Username,
+ user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding));
}
else
{
Logger.LogInformation("User policy for {0}. EnablePlaybackRemuxing: {1} EnableVideoPlaybackTranscoding: {2} EnableAudioPlaybackTranscoding: {3}",
- user.Name,
- user.Policy.EnablePlaybackRemuxing,
- user.Policy.EnableVideoPlaybackTranscoding,
- user.Policy.EnableAudioPlaybackTranscoding);
+ user.Username,
+ user.HasPermission(PermissionKind.EnablePlaybackRemuxing),
+ user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding),
+ user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding));
}
// Beginning of Playback Determination: Attempt DirectPlay first
if (mediaSource.SupportsDirectPlay)
{
- if (mediaSource.IsRemote && user.Policy.ForceRemoteSourceTranscoding)
+ if (mediaSource.IsRemote && user.HasPermission(PermissionKind.ForceRemoteSourceTranscoding))
{
mediaSource.SupportsDirectPlay = false;
}
@@ -428,14 +432,16 @@ namespace MediaBrowser.Api.Playback
if (item is Audio)
{
- if (!user.Policy.EnableAudioPlaybackTranscoding)
+ if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding))
{
options.ForceDirectPlay = true;
}
}
else if (item is Video)
{
- if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing)
+ if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding)
+ && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding)
+ && !user.HasPermission(PermissionKind.EnablePlaybackRemuxing))
{
options.ForceDirectPlay = true;
}
@@ -463,7 +469,7 @@ namespace MediaBrowser.Api.Playback
if (mediaSource.SupportsDirectStream)
{
- if (mediaSource.IsRemote && user.Policy.ForceRemoteSourceTranscoding)
+ if (mediaSource.IsRemote && user.HasPermission(PermissionKind.ForceRemoteSourceTranscoding))
{
mediaSource.SupportsDirectStream = false;
}
@@ -473,14 +479,16 @@ namespace MediaBrowser.Api.Playback
if (item is Audio)
{
- if (!user.Policy.EnableAudioPlaybackTranscoding)
+ if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding))
{
options.ForceDirectStream = true;
}
}
else if (item is Video)
{
- if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing)
+ if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding)
+ && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding)
+ && !user.HasPermission(PermissionKind.EnablePlaybackRemuxing))
{
options.ForceDirectStream = true;
}
@@ -512,7 +520,7 @@ namespace MediaBrowser.Api.Playback
? streamBuilder.BuildAudioItem(options)
: streamBuilder.BuildVideoItem(options);
- if (mediaSource.IsRemote && user.Policy.ForceRemoteSourceTranscoding)
+ if (mediaSource.IsRemote && user.HasPermission(PermissionKind.ForceRemoteSourceTranscoding))
{
if (streamInfo != null)
{
@@ -543,10 +551,12 @@ namespace MediaBrowser.Api.Playback
{
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
}
+
if (!allowAudioStreamCopy)
{
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
}
+
mediaSource.TranscodingContainer = streamInfo.Container;
mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;
}
@@ -576,10 +586,10 @@ namespace MediaBrowser.Api.Playback
}
}
- private long? GetMaxBitrate(long? clientMaxBitrate, User user)
+ private long? GetMaxBitrate(long? clientMaxBitrate, Jellyfin.Data.Entities.User user)
{
var maxBitrate = clientMaxBitrate;
- var remoteClientMaxBitrate = user?.Policy.RemoteClientBitrateLimit ?? 0;
+ var remoteClientMaxBitrate = user?.RemoteClientBitrateLimit ?? 0;
if (remoteClientMaxBitrate <= 0)
{
@@ -638,7 +648,6 @@ namespace MediaBrowser.Api.Playback
}
return 1;
-
}).ThenBy(i =>
{
// Let's assume direct streaming a file is just as desirable as direct playing a remote url
@@ -648,7 +657,6 @@ namespace MediaBrowser.Api.Playback
}
return 1;
-
}).ThenBy(i =>
{
return i.Protocol switch
@@ -664,7 +672,6 @@ namespace MediaBrowser.Api.Playback
}
return 1;
-
}).ThenBy(originalList.IndexOf)
.ToArray();
}
diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
index 34c7986ca..d51787df2 100644
--- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
@@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Playback.Progressive
{
/// <summary>
- /// Class GetAudioStream
+ /// Class GetAudioStream.
/// </summary>
[Route("/Audio/{Id}/stream.{Container}", "GET", Summary = "Gets an audio stream")]
[Route("/Audio/{Id}/stream", "GET", Summary = "Gets an audio stream")]
@@ -26,7 +26,7 @@ namespace MediaBrowser.Api.Playback.Progressive
}
/// <summary>
- /// Class AudioService
+ /// Class AudioService.
/// </summary>
// TODO: In order to autheneticate this in the future, Dlna playback will require updating
//[Authenticated]
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index c7bf055fb..2ebf0e420 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -21,7 +21,7 @@ using Microsoft.Net.Http.Headers;
namespace MediaBrowser.Api.Playback.Progressive
{
/// <summary>
- /// Class BaseProgressiveStreamingService
+ /// Class BaseProgressiveStreamingService.
/// </summary>
public abstract class BaseProgressiveStreamingService : BaseStreamingService
{
@@ -88,14 +88,17 @@ namespace MediaBrowser.Api.Playback.Progressive
{
return ".ts";
}
+
if (string.Equals(videoCodec, "theora", StringComparison.OrdinalIgnoreCase))
{
return ".ogv";
}
+
if (string.Equals(videoCodec, "vpx", StringComparison.OrdinalIgnoreCase))
{
return ".webm";
}
+
if (string.Equals(videoCodec, "wmv", StringComparison.OrdinalIgnoreCase))
{
return ".asf";
@@ -111,14 +114,17 @@ namespace MediaBrowser.Api.Playback.Progressive
{
return ".aac";
}
+
if (string.Equals("mp3", audioCodec, StringComparison.OrdinalIgnoreCase))
{
return ".mp3";
}
+
if (string.Equals("vorbis", audioCodec, StringComparison.OrdinalIgnoreCase))
{
return ".ogg";
}
+
if (string.Equals("wma", audioCodec, StringComparison.OrdinalIgnoreCase))
{
return ".wma";
@@ -231,7 +237,7 @@ namespace MediaBrowser.Api.Playback.Progressive
}
//// Not static but transcode cache file exists
- //if (isTranscodeCached && state.VideoRequest == null)
+ // if (isTranscodeCached && state.VideoRequest == null)
//{
// var contentType = state.GetMimeType(outputPath);
diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
index a53b848f9..b70fff128 100644
--- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
+++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs
@@ -23,6 +23,7 @@ namespace MediaBrowser.Api.Playback.Progressive
private long _bytesWritten = 0;
public long StartPosition { get; set; }
+
public bool AllowEndOfFile = true;
private readonly IDirectStreamProvider _directStreamProvider;
@@ -96,8 +97,8 @@ namespace MediaBrowser.Api.Playback.Progressive
bytesRead = await CopyToInternalAsyncWithSyncRead(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
}
- //var position = fs.Position;
- //_logger.LogDebug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path);
+ // var position = fs.Position;
+ // _logger.LogDebug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path);
if (bytesRead == 0)
{
@@ -105,6 +106,7 @@ namespace MediaBrowser.Api.Playback.Progressive
{
eofCount++;
}
+
await Task.Delay(100, cancellationToken).ConfigureAwait(false);
}
else
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index 4de81655c..c3f6b905c 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Playback.Progressive
{
/// <summary>
- /// Class GetVideoStream
+ /// Class GetVideoStream.
/// </summary>
[Route("/Videos/{Id}/stream.mpegts", "GET")]
[Route("/Videos/{Id}/stream.ts", "GET")]
@@ -59,11 +59,10 @@ namespace MediaBrowser.Api.Playback.Progressive
[Route("/Videos/{Id}/stream", "HEAD")]
public class GetVideoStream : VideoStreamRequest
{
-
}
/// <summary>
- /// Class VideoService
+ /// Class VideoService.
/// </summary>
// TODO: In order to autheneticate this in the future, Dlna playback will require updating
//[Authenticated]
diff --git a/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs b/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs
index 3b8b29995..7e2e337ad 100644
--- a/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs
+++ b/MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs
@@ -8,17 +8,17 @@ using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Playback
{
/// <summary>
- /// Class StaticRemoteStreamWriter
+ /// Class StaticRemoteStreamWriter.
/// </summary>
public class StaticRemoteStreamWriter : IAsyncStreamWriter, IHasHeaders
{
/// <summary>
- /// The _input stream
+ /// The _input stream.
/// </summary>
private readonly HttpResponseInfo _response;
/// <summary>
- /// The _options
+ /// The _options.
/// </summary>
private readonly IDictionary<string, string> _options = new Dictionary<string, string>();
diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs
index 9ba8eda91..67c334e48 100644
--- a/MediaBrowser.Api/Playback/StreamRequest.cs
+++ b/MediaBrowser.Api/Playback/StreamRequest.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Playback
{
/// <summary>
- /// Class StreamRequest
+ /// Class StreamRequest.
/// </summary>
public class StreamRequest : BaseEncodingJobOptions
{
@@ -12,11 +12,15 @@ namespace MediaBrowser.Api.Playback
public string DeviceProfileId { get; set; }
public string Params { get; set; }
+
public string PlaySessionId { get; set; }
+
public string Tag { get; set; }
+
public string SegmentContainer { get; set; }
public int? SegmentLength { get; set; }
+
public int? MinSegments { get; set; }
}
diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs
index d5d2f58c0..c244b0033 100644
--- a/MediaBrowser.Api/Playback/StreamState.cs
+++ b/MediaBrowser.Api/Playback/StreamState.cs
@@ -42,7 +42,7 @@ namespace MediaBrowser.Api.Playback
return Request.SegmentLength.Value;
}
- if (string.Equals(OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase))
+ if (EncodingHelper.IsCopyCodec(OutputVideoCodec))
{
var userAgent = UserAgent ?? string.Empty;
diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs
index a3b319d44..d5d78cf37 100644
--- a/MediaBrowser.Api/Playback/UniversalAudioService.cs
+++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs
@@ -37,10 +37,13 @@ namespace MediaBrowser.Api.Playback
public string DeviceId { get; set; }
public Guid UserId { get; set; }
+
public string AudioCodec { get; set; }
+
public string Container { get; set; }
public int? MaxAudioChannels { get; set; }
+
public int? TranscodingAudioChannels { get; set; }
public long? MaxStreamingBitrate { get; set; }
@@ -49,12 +52,17 @@ namespace MediaBrowser.Api.Playback
public long? StartTimeTicks { get; set; }
public string TranscodingContainer { get; set; }
+
public string TranscodingProtocol { get; set; }
+
public int? MaxAudioSampleRate { get; set; }
+
public int? MaxAudioBitDepth { get; set; }
public bool EnableRedirection { get; set; }
+
public bool EnableRemoteMedia { get; set; }
+
public bool BreakOnNonKeyFrames { get; set; }
public BaseUniversalRequest()
@@ -114,16 +122,27 @@ namespace MediaBrowser.Api.Playback
}
protected IHttpClient HttpClient { get; private set; }
+
protected IUserManager UserManager { get; private set; }
+
protected ILibraryManager LibraryManager { get; private set; }
+
protected IIsoManager IsoManager { get; private set; }
+
protected IMediaEncoder MediaEncoder { get; private set; }
+
protected IFileSystem FileSystem { get; private set; }
+
protected IDlnaManager DlnaManager { get; private set; }
+
protected IDeviceManager DeviceManager { get; private set; }
+
protected IMediaSourceManager MediaSourceManager { get; private set; }
+
protected IJsonSerializer JsonSerializer { get; private set; }
+
protected IAuthorizationContext AuthorizationContext { get; private set; }
+
protected INetworkManager NetworkManager { get; private set; }
public Task<object> Get(GetUniversalAudioStream request)
@@ -259,7 +278,6 @@ namespace MediaBrowser.Api.Playback
UserId = request.UserId,
DeviceProfile = deviceProfile,
MediaSourceId = request.MediaSourceId
-
}).ConfigureAwait(false);
var mediaSource = playbackInfoResult.MediaSources[0];
@@ -329,6 +347,7 @@ namespace MediaBrowser.Api.Playback
{
return await service.Head(newRequest).ConfigureAwait(false);
}
+
return await service.Get(newRequest).ConfigureAwait(false);
}
else
diff --git a/MediaBrowser.Api/PlaylistService.cs b/MediaBrowser.Api/PlaylistService.cs
index 953b00e35..5513c0892 100644
--- a/MediaBrowser.Api/PlaylistService.cs
+++ b/MediaBrowser.Api/PlaylistService.cs
@@ -95,14 +95,14 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -161,7 +161,6 @@ namespace MediaBrowser.Api
ItemIdList = GetGuids(request.Ids),
UserId = request.UserId,
MediaType = request.MediaType
-
}).ConfigureAwait(false);
return ToOptimizedResult(result);
diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs
index 7f74511ee..7d976ceaa 100644
--- a/MediaBrowser.Api/PluginService.cs
+++ b/MediaBrowser.Api/PluginService.cs
@@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class Plugins
+ /// Class Plugins.
/// </summary>
[Route("/Plugins", "GET", Summary = "Gets a list of currently installed plugins")]
[Authenticated]
@@ -25,7 +25,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UninstallPlugin
+ /// Class UninstallPlugin.
/// </summary>
[Route("/Plugins/{Id}", "DELETE", Summary = "Uninstalls a plugin")]
[Authenticated(Roles = "Admin")]
@@ -40,7 +40,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetPluginConfiguration
+ /// Class GetPluginConfiguration.
/// </summary>
[Route("/Plugins/{Id}/Configuration", "GET", Summary = "Gets a plugin's configuration")]
[Authenticated]
@@ -55,7 +55,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdatePluginConfiguration
+ /// Class UpdatePluginConfiguration.
/// </summary>
[Route("/Plugins/{Id}/Configuration", "POST", Summary = "Updates a plugin's configuration")]
[Authenticated]
@@ -69,13 +69,13 @@ namespace MediaBrowser.Api
public string Id { get; set; }
/// <summary>
- /// The raw Http Request Input Stream
+ /// The raw Http Request Input Stream.
/// </summary>
/// <value>The request stream.</value>
public Stream RequestStream { get; set; }
}
- //TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins,
+ // TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins,
// delete all these registration endpoints. They are only kept for compatibility.
[Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)]
[Authenticated]
@@ -86,7 +86,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetPluginSecurityInfo
+ /// Class GetPluginSecurityInfo.
/// </summary>
[Route("/Plugins/SecurityInfo", "GET", Summary = "Gets plugin registration information", IsHidden = true)]
[Authenticated]
@@ -95,7 +95,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdatePluginSecurityInfo
+ /// Class UpdatePluginSecurityInfo.
/// </summary>
[Route("/Plugins/SecurityInfo", "POST", Summary = "Updates plugin registration information", IsHidden = true)]
[Authenticated(Roles = "Admin")]
@@ -115,38 +115,47 @@ namespace MediaBrowser.Api
public class RegistrationInfo
{
public string Name { get; set; }
+
public DateTime ExpirationDate { get; set; }
+
public bool IsTrial { get; set; }
+
public bool IsRegistered { get; set; }
}
public class MBRegistrationRecord
{
public DateTime ExpirationDate { get; set; }
+
public bool IsRegistered { get; set; }
+
public bool RegChecked { get; set; }
+
public bool RegError { get; set; }
+
public bool TrialVersion { get; set; }
+
public bool IsValid { get; set; }
}
public class PluginSecurityInfo
{
public string SupporterKey { get; set; }
+
public bool IsMBSupporter { get; set; }
}
/// <summary>
- /// Class PluginsService
+ /// Class PluginsService.
/// </summary>
public class PluginService : BaseApiService
{
/// <summary>
- /// The _json serializer
+ /// The _json serializer.
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
- /// The _app host
+ /// The _app host.
/// </summary>
private readonly IApplicationHost _appHost;
private readonly IInstallationManager _installationManager;
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
index e08a8482e..86b00316a 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
@@ -11,7 +11,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.ScheduledTasks
{
/// <summary>
- /// Class GetScheduledTask
+ /// Class GetScheduledTask.
/// </summary>
[Route("/ScheduledTasks/{Id}", "GET", Summary = "Gets a scheduled task, by Id")]
public class GetScheduledTask : IReturn<TaskInfo>
@@ -25,7 +25,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
/// <summary>
- /// Class GetScheduledTasks
+ /// Class GetScheduledTasks.
/// </summary>
[Route("/ScheduledTasks", "GET", Summary = "Gets scheduled tasks")]
public class GetScheduledTasks : IReturn<TaskInfo[]>
@@ -38,7 +38,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
/// <summary>
- /// Class StartScheduledTask
+ /// Class StartScheduledTask.
/// </summary>
[Route("/ScheduledTasks/Running/{Id}", "POST", Summary = "Starts a scheduled task")]
public class StartScheduledTask : IReturnVoid
@@ -52,7 +52,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
/// <summary>
- /// Class StopScheduledTask
+ /// Class StopScheduledTask.
/// </summary>
[Route("/ScheduledTasks/Running/{Id}", "DELETE", Summary = "Stops a scheduled task")]
public class StopScheduledTask : IReturnVoid
@@ -66,7 +66,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
/// <summary>
- /// Class UpdateScheduledTaskTriggers
+ /// Class UpdateScheduledTaskTriggers.
/// </summary>
[Route("/ScheduledTasks/{Id}/Triggers", "POST", Summary = "Updates the triggers for a scheduled task")]
public class UpdateScheduledTaskTriggers : List<TaskTriggerInfo>, IReturnVoid
@@ -80,7 +80,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
/// <summary>
- /// Class ScheduledTasksService
+ /// Class ScheduledTasksService.
/// </summary>
[Authenticated(Roles = "Admin")]
public class ScheduledTaskService : BaseApiService
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
index 14b9b3618..25dd39f2d 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
@@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.ScheduledTasks
{
/// <summary>
- /// Class ScheduledTasksWebSocketListener
+ /// Class ScheduledTasksWebSocketListener.
/// </summary>
public class ScheduledTasksWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<TaskInfo>, WebSocketListenerState>
{
diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs
index e9d339c6e..64ee69300 100644
--- a/MediaBrowser.Api/SearchService.cs
+++ b/MediaBrowser.Api/SearchService.cs
@@ -18,7 +18,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetSearchHints
+ /// Class GetSearchHints.
/// </summary>
[Route("/Search/Hints", "GET", Summary = "Gets search hints based on a search term")]
public class GetSearchHints : IReturn<SearchHintResult>
@@ -31,7 +31,7 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -45,7 +45,7 @@ namespace MediaBrowser.Api
public Guid UserId { get; set; }
/// <summary>
- /// Search characters used to find items
+ /// Search characters used to find items.
/// </summary>
/// <value>The index by.</value>
[ApiMember(Name = "SearchTerm", Description = "The search term to filter on", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -104,13 +104,13 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class SearchService
+ /// Class SearchService.
/// </summary>
[Authenticated]
public class SearchService : BaseApiService
{
/// <summary>
- /// The _search engine
+ /// The _search engine.
/// </summary>
private readonly ISearchEngine _searchEngine;
private readonly ILibraryManager _libraryManager;
@@ -180,7 +180,6 @@ namespace MediaBrowser.Api
IsNews = request.IsNews,
IsSeries = request.IsSeries,
IsSports = request.IsSports
-
});
return new SearchHintResult
diff --git a/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs
index 0e74c9267..2400d6def 100644
--- a/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs
+++ b/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs
@@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.Sessions
{
/// <summary>
- /// Class SessionInfoWebSocketListener
+ /// Class SessionInfoWebSocketListener.
/// </summary>
public class SessionInfoWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SessionInfo>, WebSocketListenerState>
{
@@ -19,7 +19,7 @@ namespace MediaBrowser.Api.Sessions
protected override string Name => "Sessions";
/// <summary>
- /// The _kernel
+ /// The _kernel.
/// </summary>
private readonly ISessionManager _sessionManager;
@@ -40,39 +40,39 @@ namespace MediaBrowser.Api.Sessions
_sessionManager.SessionActivity += OnSessionManagerSessionActivity;
}
- private void OnSessionManagerSessionActivity(object sender, SessionEventArgs e)
+ private async void OnSessionManagerSessionActivity(object sender, SessionEventArgs e)
{
- SendData(false);
+ await SendData(false).ConfigureAwait(false);
}
- private void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e)
+ private async void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e)
{
- SendData(true);
+ await SendData(true).ConfigureAwait(false);
}
- private void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e)
+ private async void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e)
{
- SendData(!e.IsAutomated);
+ await SendData(!e.IsAutomated).ConfigureAwait(false);
}
- private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
+ private async void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e)
{
- SendData(true);
+ await SendData(true).ConfigureAwait(false);
}
- private void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e)
+ private async void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e)
{
- SendData(true);
+ await SendData(true).ConfigureAwait(false);
}
- private void OnSessionManagerSessionEnded(object sender, SessionEventArgs e)
+ private async void OnSessionManagerSessionEnded(object sender, SessionEventArgs e)
{
- SendData(true);
+ await SendData(true).ConfigureAwait(false);
}
- private void OnSessionManagerSessionStarted(object sender, SessionEventArgs e)
+ private async void OnSessionManagerSessionStarted(object sender, SessionEventArgs e)
{
- SendData(true);
+ await SendData(true).ConfigureAwait(false);
}
/// <summary>
diff --git a/MediaBrowser.Api/Sessions/SessionService.cs b/MediaBrowser.Api/Sessions/SessionService.cs
index 020bb5042..50adc5698 100644
--- a/MediaBrowser.Api/Sessions/SessionService.cs
+++ b/MediaBrowser.Api/Sessions/SessionService.cs
@@ -2,6 +2,7 @@ using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Library;
@@ -45,14 +46,14 @@ namespace MediaBrowser.Api.Sessions
public string Id { get; set; }
/// <summary>
- /// Artist, Genre, Studio, Person, or any kind of BaseItem
+ /// Artist, Genre, Studio, Person, or any kind of BaseItem.
/// </summary>
/// <value>The type of the item.</value>
[ApiMember(Name = "ItemType", Description = "The type of item to browse to.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string ItemType { get; set; }
/// <summary>
- /// Artist name, genre name, item Id, etc
+ /// Artist name, genre name, item Id, etc.
/// </summary>
/// <value>The item identifier.</value>
[ApiMember(Name = "ItemId", Description = "The Id of the item.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
@@ -326,12 +327,12 @@ namespace MediaBrowser.Api.Sessions
var user = _userManager.GetUserById(request.ControllableByUserId);
- if (!user.Policy.EnableRemoteControlOfOtherUsers)
+ if (!user.HasPermission(PermissionKind.EnableRemoteControlOfOtherUsers))
{
result = result.Where(i => i.UserId.Equals(Guid.Empty) || i.ContainsUser(request.ControllableByUserId));
}
- if (!user.Policy.EnableSharedDeviceControl)
+ if (!user.HasPermission(PermissionKind.EnableSharedDeviceControl))
{
result = result.Where(i => !i.UserId.Equals(Guid.Empty));
}
diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs
index 44bb24ef2..84abf7b8d 100644
--- a/MediaBrowser.Api/SimilarItemsHelper.cs
+++ b/MediaBrowser.Api/SimilarItemsHelper.cs
@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class BaseGetSimilarItemsFromItem
+ /// Class BaseGetSimilarItemsFromItem.
/// </summary>
public class BaseGetSimilarItemsFromItem : BaseGetSimilarItems
{
@@ -50,14 +50,14 @@ namespace MediaBrowser.Api
public Guid UserId { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -65,11 +65,11 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class SimilarItemsHelper
+ /// Class SimilarItemsHelper.
/// </summary>
public static class SimilarItemsHelper
{
- internal static QueryResult<BaseItemDto> GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, ILogger logger, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
+ internal static QueryResult<BaseItemDto> GetSimilarItemsResult(DtoOptions dtoOptions, IUserManager userManager, IItemRepository itemRepository, ILibraryManager libraryManager, IUserDataManager userDataRepository, IDtoService dtoService, BaseGetSimilarItemsFromItem request, Type[] includeTypes, Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)
{
var user = !request.UserId.Equals(Guid.Empty) ? userManager.GetUserById(request.UserId) : null;
@@ -179,18 +179,22 @@ namespace MediaBrowser.Api
{
return 5;
}
+
if (string.Equals(i.Type, PersonType.Actor, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Actor, StringComparison.OrdinalIgnoreCase))
{
return 3;
}
+
if (string.Equals(i.Type, PersonType.Composer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Composer, StringComparison.OrdinalIgnoreCase))
{
return 3;
}
+
if (string.Equals(i.Type, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.GuestStar, StringComparison.OrdinalIgnoreCase))
{
return 3;
}
+
if (string.Equals(i.Type, PersonType.Writer, StringComparison.OrdinalIgnoreCase) || string.Equals(i.Role, PersonType.Writer, StringComparison.OrdinalIgnoreCase))
{
return 2;
@@ -218,6 +222,5 @@ namespace MediaBrowser.Api
return points;
}
-
}
}
diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs
index f2968c6b5..a70da8e56 100644
--- a/MediaBrowser.Api/Subtitles/SubtitleService.cs
+++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs
@@ -97,6 +97,7 @@ namespace MediaBrowser.Api.Subtitles
[ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool CopyTimestamps { get; set; }
+
public bool AddVttTimeMap { get; set; }
}
@@ -214,6 +215,7 @@ namespace MediaBrowser.Api.Subtitles
{
request.Format = "json";
}
+
if (string.IsNullOrEmpty(request.Format))
{
var item = (Video)_libraryManager.GetItemById(request.Id);
diff --git a/MediaBrowser.Api/SuggestionsService.cs b/MediaBrowser.Api/SuggestionsService.cs
index 91f85db6f..17afa8e79 100644
--- a/MediaBrowser.Api/SuggestionsService.cs
+++ b/MediaBrowser.Api/SuggestionsService.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -17,10 +18,15 @@ namespace MediaBrowser.Api
public class GetSuggestedItems : IReturn<QueryResult<BaseItemDto>>
{
public string MediaType { get; set; }
+
public string Type { get; set; }
+
public Guid UserId { get; set; }
+
public bool EnableTotalRecordCount { get; set; }
+
public int? StartIndex { get; set; }
+
public int? Limit { get; set; }
public string[] GetMediaTypes()
diff --git a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs
index 1e14ea552..daa1b521f 100644
--- a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs
+++ b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs
@@ -11,93 +11,66 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.SyncPlay
{
- [Route("/SyncPlay/{SessionId}/NewGroup", "POST", Summary = "Create a new SyncPlay group")]
+ [Route("/SyncPlay/New", "POST", Summary = "Create a new SyncPlay group")]
[Authenticated]
- public class SyncPlayNewGroup : IReturnVoid
+ public class SyncPlayNew : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
}
- [Route("/SyncPlay/{SessionId}/JoinGroup", "POST", Summary = "Join an existing SyncPlay group")]
+ [Route("/SyncPlay/Join", "POST", Summary = "Join an existing SyncPlay group")]
[Authenticated]
- public class SyncPlayJoinGroup : IReturnVoid
+ public class SyncPlayJoin : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
-
/// <summary>
/// Gets or sets the Group id.
/// </summary>
/// <value>The Group id to join.</value>
[ApiMember(Name = "GroupId", Description = "Group Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string GroupId { get; set; }
-
- /// <summary>
- /// Gets or sets the playing item id.
- /// </summary>
- /// <value>The client's currently playing item id.</value>
- [ApiMember(Name = "PlayingItemId", Description = "Client's playing item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string PlayingItemId { get; set; }
}
- [Route("/SyncPlay/{SessionId}/LeaveGroup", "POST", Summary = "Leave joined SyncPlay group")]
+ [Route("/SyncPlay/Leave", "POST", Summary = "Leave joined SyncPlay group")]
[Authenticated]
- public class SyncPlayLeaveGroup : IReturnVoid
+ public class SyncPlayLeave : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
}
- [Route("/SyncPlay/{SessionId}/ListGroups", "POST", Summary = "List SyncPlay groups")]
+ [Route("/SyncPlay/List", "GET", Summary = "List SyncPlay groups")]
[Authenticated]
- public class SyncPlayListGroups : IReturnVoid
+ public class SyncPlayList : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
-
/// <summary>
/// Gets or sets the filter item id.
/// </summary>
/// <value>The filter item id.</value>
- [ApiMember(Name = "FilterItemId", Description = "Filter by item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ [ApiMember(Name = "FilterItemId", Description = "Filter by item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string FilterItemId { get; set; }
}
- [Route("/SyncPlay/{SessionId}/PlayRequest", "POST", Summary = "Request play in SyncPlay group")]
+ [Route("/SyncPlay/Play", "POST", Summary = "Request play in SyncPlay group")]
[Authenticated]
- public class SyncPlayPlayRequest : IReturnVoid
+ public class SyncPlayPlay : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
}
- [Route("/SyncPlay/{SessionId}/PauseRequest", "POST", Summary = "Request pause in SyncPlay group")]
+ [Route("/SyncPlay/Pause", "POST", Summary = "Request pause in SyncPlay group")]
[Authenticated]
- public class SyncPlayPauseRequest : IReturnVoid
+ public class SyncPlayPause : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
}
- [Route("/SyncPlay/{SessionId}/SeekRequest", "POST", Summary = "Request seek in SyncPlay group")]
+ [Route("/SyncPlay/Seek", "POST", Summary = "Request seek in SyncPlay group")]
[Authenticated]
- public class SyncPlaySeekRequest : IReturnVoid
+ public class SyncPlaySeek : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
-
[ApiMember(Name = "PositionTicks", IsRequired = true, DataType = "long", ParameterType = "query", Verb = "POST")]
public long PositionTicks { get; set; }
}
- [Route("/SyncPlay/{SessionId}/BufferingRequest", "POST", Summary = "Request group wait in SyncPlay group while buffering")]
+ [Route("/SyncPlay/Buffering", "POST", Summary = "Request group wait in SyncPlay group while buffering")]
[Authenticated]
- public class SyncPlayBufferingRequest : IReturnVoid
+ public class SyncPlayBuffering : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
-
/// <summary>
/// Gets or sets the date used to pin PositionTicks in time.
/// </summary>
@@ -109,20 +82,17 @@ namespace MediaBrowser.Api.SyncPlay
public long PositionTicks { get; set; }
/// <summary>
- /// Gets or sets whether this is a buffering or a buffering-done request.
+ /// Gets or sets whether this is a buffering or a ready request.
/// </summary>
/// <value><c>true</c> if buffering is complete; <c>false</c> otherwise.</value>
[ApiMember(Name = "BufferingDone", IsRequired = true, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool BufferingDone { get; set; }
}
- [Route("/SyncPlay/{SessionId}/UpdatePing", "POST", Summary = "Update session ping")]
+ [Route("/SyncPlay/Ping", "POST", Summary = "Update session ping")]
[Authenticated]
- public class SyncPlayUpdatePing : IReturnVoid
+ public class SyncPlayPing : IReturnVoid
{
- [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string SessionId { get; set; }
-
[ApiMember(Name = "Ping", IsRequired = true, DataType = "double", ParameterType = "query", Verb = "POST")]
public double Ping { get; set; }
}
@@ -158,7 +128,7 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayNewGroup request)
+ public void Post(SyncPlayNew request)
{
var currentSession = GetSession(_sessionContext);
_syncPlayManager.NewGroup(currentSession, CancellationToken.None);
@@ -168,30 +138,20 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayJoinGroup request)
+ public void Post(SyncPlayJoin request)
{
var currentSession = GetSession(_sessionContext);
Guid groupId;
- Guid playingItemId = Guid.Empty;
-
if (!Guid.TryParse(request.GroupId, out groupId))
{
Logger.LogError("JoinGroup: {0} is not a valid format for GroupId. Ignoring request.", request.GroupId);
return;
}
- // Both null and empty strings mean that client isn't playing anything
- if (!string.IsNullOrEmpty(request.PlayingItemId) && !Guid.TryParse(request.PlayingItemId, out playingItemId))
- {
- Logger.LogError("JoinGroup: {0} is not a valid format for PlayingItemId. Ignoring request.", request.PlayingItemId);
- return;
- }
-
var joinRequest = new JoinGroupRequest()
{
- GroupId = groupId,
- PlayingItemId = playingItemId
+ GroupId = groupId
};
_syncPlayManager.JoinGroup(currentSession, groupId, joinRequest, CancellationToken.None);
@@ -201,7 +161,7 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayLeaveGroup request)
+ public void Post(SyncPlayLeave request)
{
var currentSession = GetSession(_sessionContext);
_syncPlayManager.LeaveGroup(currentSession, CancellationToken.None);
@@ -212,7 +172,7 @@ namespace MediaBrowser.Api.SyncPlay
/// </summary>
/// <param name="request">The request.</param>
/// <value>The requested list of groups.</value>
- public List<GroupInfoView> Post(SyncPlayListGroups request)
+ public List<GroupInfoView> Get(SyncPlayList request)
{
var currentSession = GetSession(_sessionContext);
var filterItemId = Guid.Empty;
@@ -229,7 +189,7 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayPlayRequest request)
+ public void Post(SyncPlayPlay request)
{
var currentSession = GetSession(_sessionContext);
var syncPlayRequest = new PlaybackRequest()
@@ -243,7 +203,7 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayPauseRequest request)
+ public void Post(SyncPlayPause request)
{
var currentSession = GetSession(_sessionContext);
var syncPlayRequest = new PlaybackRequest()
@@ -257,7 +217,7 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlaySeekRequest request)
+ public void Post(SyncPlaySeek request)
{
var currentSession = GetSession(_sessionContext);
var syncPlayRequest = new PlaybackRequest()
@@ -272,12 +232,12 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayBufferingRequest request)
+ public void Post(SyncPlayBuffering request)
{
var currentSession = GetSession(_sessionContext);
var syncPlayRequest = new PlaybackRequest()
{
- Type = request.BufferingDone ? PlaybackRequestType.BufferingDone : PlaybackRequestType.Buffering,
+ Type = request.BufferingDone ? PlaybackRequestType.Ready : PlaybackRequestType.Buffer,
When = DateTime.Parse(request.When),
PositionTicks = request.PositionTicks
};
@@ -288,12 +248,12 @@ namespace MediaBrowser.Api.SyncPlay
/// Handles the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SyncPlayUpdatePing request)
+ public void Post(SyncPlayPing request)
{
var currentSession = GetSession(_sessionContext);
var syncPlayRequest = new PlaybackRequest()
{
- Type = PlaybackRequestType.UpdatePing,
+ Type = PlaybackRequestType.Ping,
Ping = Convert.ToInt64(request.Ping)
};
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
diff --git a/MediaBrowser.Api/System/ActivityLogService.cs b/MediaBrowser.Api/System/ActivityLogService.cs
index a6bacad4f..7ca31c21a 100644
--- a/MediaBrowser.Api/System/ActivityLogService.cs
+++ b/MediaBrowser.Api/System/ActivityLogService.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Api.System
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
index 8e4860be4..39976371a 100644
--- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
+++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
@@ -8,7 +8,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.System
{
/// <summary>
- /// Class SessionInfoWebSocketListener
+ /// Class SessionInfoWebSocketListener.
/// </summary>
public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener<ActivityLogEntry[], WebSocketListenerState>
{
@@ -19,7 +19,7 @@ namespace MediaBrowser.Api.System
protected override string Name => "ActivityLogEntry";
/// <summary>
- /// The _kernel
+ /// The _kernel.
/// </summary>
private readonly IActivityManager _activityManager;
diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index c57cc93d5..e0e20d828 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -18,30 +18,27 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.System
{
/// <summary>
- /// Class GetSystemInfo
+ /// Class GetSystemInfo.
/// </summary>
[Route("/System/Info", "GET", Summary = "Gets information about the server")]
[Authenticated(EscapeParentalControl = true, AllowBeforeStartupWizard = true)]
public class GetSystemInfo : IReturn<SystemInfo>
{
-
}
[Route("/System/Info/Public", "GET", Summary = "Gets public information about the server")]
public class GetPublicSystemInfo : IReturn<PublicSystemInfo>
{
-
}
[Route("/System/Ping", "POST")]
[Route("/System/Ping", "GET")]
public class PingSystem : IReturnVoid
{
-
}
/// <summary>
- /// Class RestartApplication
+ /// Class RestartApplication.
/// </summary>
[Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")]
[Authenticated(Roles = "Admin", AllowLocal = true)]
@@ -83,16 +80,15 @@ namespace MediaBrowser.Api.System
[Authenticated]
public class GetWakeOnLanInfo : IReturn<WakeOnLanInfo[]>
{
-
}
/// <summary>
- /// Class SystemInfoService
+ /// Class SystemInfoService.
/// </summary>
public class SystemService : BaseApiService
{
/// <summary>
- /// The _app host
+ /// The _app host.
/// </summary>
private readonly IServerApplicationHost _appHost;
private readonly IApplicationPaths _appPaths;
@@ -153,7 +149,6 @@ namespace MediaBrowser.Api.System
DateModified = _fileSystem.GetLastWriteTimeUtc(i),
Name = i.Name,
Size = i.Length
-
}).OrderByDescending(i => i.DateModified)
.ThenByDescending(i => i.DateCreated)
.ThenBy(i => i.Name)
diff --git a/MediaBrowser.Api/TranscodingJob.cs b/MediaBrowser.Api/TranscodingJob.cs
index 8c24e3ce1..bfc311a27 100644
--- a/MediaBrowser.Api/TranscodingJob.cs
+++ b/MediaBrowser.Api/TranscodingJob.cs
@@ -32,6 +32,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The path.</value>
public MediaSourceInfo MediaSource { get; set; }
+
public string Path { get; set; }
/// <summary>
/// Gets or sets the type.
@@ -43,6 +44,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The process.</value>
public Process Process { get; set; }
+
public ILogger Logger { get; private set; }
/// <summary>
/// Gets or sets the active request count.
@@ -62,18 +64,23 @@ namespace MediaBrowser.Api
public object ProcessLock = new object();
public bool HasExited { get; set; }
+
public bool IsUserPaused { get; set; }
public string Id { get; set; }
public float? Framerate { get; set; }
+
public double? CompletionPercentage { get; set; }
public long? BytesDownloaded { get; set; }
+
public long? BytesTranscoded { get; set; }
+
public int? BitRate { get; set; }
public long? TranscodingPositionTicks { get; set; }
+
public long? DownloadPositionTicks { get; set; }
public TranscodingThrottler TranscodingThrottler { get; set; }
@@ -81,6 +88,7 @@ namespace MediaBrowser.Api
private readonly object _timerLock = new object();
public DateTime LastPingDate { get; set; }
+
public int PingTimeout { get; set; }
public TranscodingJob(ILogger logger)
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index cd8e8dfbe..165abd613 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -19,7 +19,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetNextUpEpisodes
+ /// Class GetNextUpEpisodes.
/// </summary>
[Route("/Shows/NextUp", "GET", Summary = "Gets a list of next up episodes")]
public class GetNextUpEpisodes : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
@@ -39,14 +39,14 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -73,6 +73,7 @@ namespace MediaBrowser.Api
[ApiMember(Name = "EnableUserData", Description = "Optional, include user data", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? EnableUserData { get; set; }
+
public bool EnableTotalRecordCount { get; set; }
public GetNextUpEpisodes()
@@ -99,14 +100,14 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -143,7 +144,7 @@ namespace MediaBrowser.Api
public Guid UserId { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -175,7 +176,7 @@ namespace MediaBrowser.Api
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
@@ -211,7 +212,7 @@ namespace MediaBrowser.Api
public Guid UserId { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -243,18 +244,18 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class TvShowsService
+ /// Class TvShowsService.
/// </summary>
[Authenticated]
public class TvShowsService : BaseApiService
{
/// <summary>
- /// The _user manager
+ /// The _user manager.
/// </summary>
private readonly IUserManager _userManager;
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
@@ -306,7 +307,6 @@ namespace MediaBrowser.Api
ParentId = parentIdGuid,
Recursive = true,
DtoOptions = options
-
});
var returnItems = _dtoService.GetBaseItemDtos(itemsResult, options, user);
@@ -378,7 +378,7 @@ namespace MediaBrowser.Api
{
var user = _userManager.GetUserById(request.UserId);
- var series = GetSeries(request.Id, user);
+ var series = GetSeries(request.Id);
if (series == null)
{
@@ -390,7 +390,6 @@ namespace MediaBrowser.Api
IsMissing = request.IsMissing,
IsSpecialSeason = request.IsSpecialSeason,
AdjacentTo = request.AdjacentTo
-
});
var dtoOptions = GetDtoOptions(_authContext, request);
@@ -404,7 +403,7 @@ namespace MediaBrowser.Api
};
}
- private Series GetSeries(string seriesId, User user)
+ private Series GetSeries(string seriesId)
{
if (!string.IsNullOrWhiteSpace(seriesId))
{
@@ -433,7 +432,7 @@ namespace MediaBrowser.Api
}
else if (request.Season.HasValue)
{
- var series = GetSeries(request.Id, user);
+ var series = GetSeries(request.Id);
if (series == null)
{
@@ -446,7 +445,7 @@ namespace MediaBrowser.Api
}
else
{
- var series = GetSeries(request.Id, user);
+ var series = GetSeries(request.Id);
if (series == null)
{
diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
index bef91d54d..9875e0208 100644
--- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetArtists
+ /// Class GetArtists.
/// </summary>
[Route("/Artists", "GET", Summary = "Gets all artists from a given item, folder, or the entire library")]
public class GetArtists : GetItemsByName
@@ -45,7 +45,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class ArtistsService
+ /// Class ArtistsService.
/// </summary>
[Authenticated]
public class ArtistsService : BaseItemsByNameService<MusicArtist>
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 559082ff4..fd639caf1 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -14,7 +15,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class BaseItemsByNameService
+ /// Class BaseItemsByNameService.
/// </summary>
/// <typeparam name="TItemType">The type of the T item type.</typeparam>
public abstract class BaseItemsByNameService<TItemType> : BaseApiService
@@ -51,7 +52,7 @@ namespace MediaBrowser.Api.UserLibrary
protected IUserManager UserManager { get; }
/// <summary>
- /// Gets the library manager
+ /// Gets the library manager.
/// </summary>
protected ILibraryManager LibraryManager { get; }
@@ -209,6 +210,7 @@ namespace MediaBrowser.Api.UserLibrary
{
SetItemCounts(dto, i.Item2);
}
+
return dto;
});
@@ -321,7 +323,6 @@ namespace MediaBrowser.Api.UserLibrary
{
ibnItems = ibnItems.Take(request.Limit.Value);
}
-
}
var tuples = ibnItems.Select(i => new Tuple<BaseItem, List<BaseItem>>(i, new List<BaseItem>()));
@@ -375,7 +376,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetItemsByName
+ /// Class GetItemsByName.
/// </summary>
public class GetItemsByName : BaseItemsRequest, IReturn<QueryResult<BaseItemDto>>
{
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
index 7561b5c89..344861a49 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
@@ -111,14 +111,14 @@ namespace MediaBrowser.Api.UserLibrary
public int? StartIndex { get; set; }
/// <summary>
- /// The maximum number of items to return
+ /// The maximum number of items to return.
/// </summary>
/// <value>The limit.</value>
[ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? Limit { get; set; }
/// <summary>
- /// Whether or not to perform the query recursively
+ /// Whether or not to perform the query recursively.
/// </summary>
/// <value><c>true</c> if recursive; otherwise, <c>false</c>.</value>
[ApiMember(Name = "Recursive", Description = "When searching within folders, this determines whether or not the search will be recursive. true/false", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
@@ -141,7 +141,7 @@ namespace MediaBrowser.Api.UserLibrary
public string ParentId { get; set; }
/// <summary>
- /// Fields to return within the items, in addition to basic information
+ /// Fields to return within the items, in addition to basic information.
/// </summary>
/// <value>The fields.</value>
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -162,14 +162,14 @@ namespace MediaBrowser.Api.UserLibrary
public string IncludeItemTypes { get; set; }
/// <summary>
- /// Filters to apply to the results
+ /// Filters to apply to the results.
/// </summary>
/// <value>The filters.</value>
[ApiMember(Name = "Filters", Description = "Optional. Specify additional filters to apply. This allows multiple, comma delimeted. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Filters { get; set; }
/// <summary>
- /// Gets or sets the Isfavorite option
+ /// Gets or sets the Isfavorite option.
/// </summary>
/// <value>IsFavorite</value>
[ApiMember(Name = "IsFavorite", Description = "Optional filter by items that are marked as favorite, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
@@ -190,7 +190,7 @@ namespace MediaBrowser.Api.UserLibrary
public string ImageTypes { get; set; }
/// <summary>
- /// What to sort the results by
+ /// What to sort the results by.
/// </summary>
/// <value>The sort by.</value>
[ApiMember(Name = "SortBy", Description = "Optional. Specify one or more sort orders, comma delimeted. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -200,7 +200,7 @@ namespace MediaBrowser.Api.UserLibrary
public bool? IsPlayed { get; set; }
/// <summary>
- /// Limit results to items containing specific genres
+ /// Limit results to items containing specific genres.
/// </summary>
/// <value>The genres.</value>
[ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -215,7 +215,7 @@ namespace MediaBrowser.Api.UserLibrary
public string Tags { get; set; }
/// <summary>
- /// Limit results to items containing specific years
+ /// Limit results to items containing specific years.
/// </summary>
/// <value>The years.</value>
[ApiMember(Name = "Years", Description = "Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -234,7 +234,7 @@ namespace MediaBrowser.Api.UserLibrary
public string EnableImageTypes { get; set; }
/// <summary>
- /// Limit results to items containing a specific person
+ /// Limit results to items containing a specific person.
/// </summary>
/// <value>The person.</value>
[ApiMember(Name = "Person", Description = "Optional. If specified, results will be filtered to include only those containing the specified person.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -244,14 +244,14 @@ namespace MediaBrowser.Api.UserLibrary
public string PersonIds { get; set; }
/// <summary>
- /// If the Person filter is used, this can also be used to restrict to a specific person type
+ /// If the Person filter is used, this can also be used to restrict to a specific person type.
/// </summary>
/// <value>The type of the person.</value>
[ApiMember(Name = "PersonTypes", Description = "Optional. If specified, along with Person, results will be filtered to include only those containing the specified person and PersonType. Allows multiple, comma-delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string PersonTypes { get; set; }
/// <summary>
- /// Limit results to items containing specific studios
+ /// Limit results to items containing specific studios.
/// </summary>
/// <value>The studios.</value>
[ApiMember(Name = "Studios", Description = "Optional. If specified, results will be filtered based on studio. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
@@ -322,8 +322,11 @@ namespace MediaBrowser.Api.UserLibrary
public bool? CollapseBoxSetItems { get; set; }
public int? MinWidth { get; set; }
+
public int? MinHeight { get; set; }
+
public int? MaxWidth { get; set; }
+
public int? MaxHeight { get; set; }
/// <summary>
diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs
index 1fa272a5f..7bdfbac98 100644
--- a/MediaBrowser.Api/UserLibrary/GenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GenresService.cs
@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetGenres
+ /// Class GetGenres.
/// </summary>
[Route("/Genres", "GET", Summary = "Gets all genres from a given item, folder, or the entire library")]
public class GetGenres : GetItemsByName
@@ -22,7 +22,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetGenre
+ /// Class GetGenre.
/// </summary>
[Route("/Genres/{Name}", "GET", Summary = "Gets a genre, by name")]
public class GetGenre : IReturn<BaseItemDto>
@@ -43,7 +43,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GenresService
+ /// Class GenresService.
/// </summary>
[Authenticated]
public class GenresService : BaseItemsByNameService<Genre>
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index f3c0441e1..7efe0552c 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -2,10 +2,11 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using Jellyfin.Data.Entities;
+using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dto;
@@ -14,11 +15,12 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging;
+using MusicAlbum = MediaBrowser.Controller.Entities.Audio.MusicAlbum;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetItems
+ /// Class GetItems.
/// </summary>
[Route("/Items", "GET", Summary = "Gets items based on a query.")]
[Route("/Users/{UserId}/Items", "GET", Summary = "Gets items based on a query.")]
@@ -32,18 +34,18 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class ItemsService
+ /// Class ItemsService.
/// </summary>
[Authenticated]
public class ItemsService : BaseApiService
{
/// <summary>
- /// The _user manager
+ /// The _user manager.
/// </summary>
private readonly IUserManager _userManager;
/// <summary>
- /// The _library manager
+ /// The _library manager.
/// </summary>
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localization;
@@ -86,7 +88,7 @@ namespace MediaBrowser.Api.UserLibrary
var ancestorIds = Array.Empty<Guid>();
- var excludeFolderIds = user.Configuration.LatestItemsExcludes;
+ var excludeFolderIds = user.GetPreference(PreferenceKind.LatestItemExcludes);
if (parentIdGuid.Equals(Guid.Empty) && excludeFolderIds.Length > 0)
{
ancestorIds = _libraryManager.GetUserRootFolder().GetChildren(user, true)
@@ -211,14 +213,14 @@ namespace MediaBrowser.Api.UserLibrary
request.IncludeItemTypes = "Playlist";
}
- bool isInEnabledFolder = user.Policy.EnabledFolders.Any(i => new Guid(i) == item.Id)
+ bool isInEnabledFolder = user.GetPreference(PreferenceKind.EnabledFolders).Any(i => new Guid(i) == item.Id)
// Assume all folders inside an EnabledChannel are enabled
- || user.Policy.EnabledChannels.Any(i => new Guid(i) == item.Id);
+ || user.GetPreference(PreferenceKind.EnabledChannels).Any(i => new Guid(i) == item.Id);
var collectionFolders = _libraryManager.GetCollectionFolders(item);
foreach (var collectionFolder in collectionFolders)
{
- if (user.Policy.EnabledFolders.Contains(
+ if (user.GetPreference(PreferenceKind.EnabledFolders).Contains(
collectionFolder.Id.ToString("N", CultureInfo.InvariantCulture),
StringComparer.OrdinalIgnoreCase))
{
@@ -226,9 +228,12 @@ namespace MediaBrowser.Api.UserLibrary
}
}
- if (!(item is UserRootFolder) && !user.Policy.EnableAllFolders && !isInEnabledFolder && !user.Policy.EnableAllChannels)
+ if (!(item is UserRootFolder)
+ && !isInEnabledFolder
+ && !user.HasPermission(PermissionKind.EnableAllFolders)
+ && !user.HasPermission(PermissionKind.EnableAllChannels))
{
- Logger.LogWarning("{UserName} is not permitted to access Library {ItemName}.", user.Name, item.Name);
+ Logger.LogWarning("{UserName} is not permitted to access Library {ItemName}.", user.Username, item.Name);
return new QueryResult<BaseItem>
{
Items = Array.Empty<BaseItem>(),
@@ -491,7 +496,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class DateCreatedComparer
+ /// Class DateCreatedComparer.
/// </summary>
public class DateCreatedComparer : IComparer<BaseItem>
{
diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs
index 3204e5219..7924339ed 100644
--- a/MediaBrowser.Api/UserLibrary/PersonsService.cs
+++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs
@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetPersons
+ /// Class GetPersons.
/// </summary>
[Route("/Persons", "GET", Summary = "Gets all persons from a given item, folder, or the entire library")]
public class GetPersons : GetItemsByName
@@ -22,7 +22,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetPerson
+ /// Class GetPerson.
/// </summary>
[Route("/Persons/{Name}", "GET", Summary = "Gets a person, by name")]
public class GetPerson : IReturn<BaseItemDto>
@@ -43,7 +43,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class PersonsService
+ /// Class PersonsService.
/// </summary>
[Authenticated]
public class PersonsService : BaseItemsByNameService<Person>
diff --git a/MediaBrowser.Api/UserLibrary/PlaystateService.cs b/MediaBrowser.Api/UserLibrary/PlaystateService.cs
index d0faca163..d809cc2e7 100644
--- a/MediaBrowser.Api/UserLibrary/PlaystateService.cs
+++ b/MediaBrowser.Api/UserLibrary/PlaystateService.cs
@@ -1,8 +1,8 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
+using Jellyfin.Data.Entities;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
@@ -14,7 +14,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class MarkPlayedItem
+ /// Class MarkPlayedItem.
/// </summary>
[Route("/Users/{UserId}/PlayedItems/{Id}", "POST", Summary = "Marks an item as played")]
public class MarkPlayedItem : IReturn<UserItemDataDto>
@@ -38,7 +38,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class MarkUnplayedItem
+ /// Class MarkUnplayedItem.
/// </summary>
[Route("/Users/{UserId}/PlayedItems/{Id}", "DELETE", Summary = "Marks an item as unplayed")]
public class MarkUnplayedItem : IReturn<UserItemDataDto>
@@ -81,7 +81,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class OnPlaybackStart
+ /// Class OnPlaybackStart.
/// </summary>
[Route("/Users/{UserId}/PlayingItems/{Id}", "POST", Summary = "Reports that a user has begun playing an item")]
public class OnPlaybackStart : IReturnVoid
@@ -123,7 +123,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class OnPlaybackProgress
+ /// Class OnPlaybackProgress.
/// </summary>
[Route("/Users/{UserId}/PlayingItems/{Id}/Progress", "POST", Summary = "Reports a user's playback progress")]
public class OnPlaybackProgress : IReturnVoid
@@ -181,7 +181,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class OnPlaybackStopped
+ /// Class OnPlaybackStopped.
/// </summary>
[Route("/Users/{UserId}/PlayingItems/{Id}", "DELETE", Summary = "Reports that a user has stopped playing an item")]
public class OnPlaybackStopped : IReturnVoid
diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs
index 683ce5d09..66350955f 100644
--- a/MediaBrowser.Api/UserLibrary/StudiosService.cs
+++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs
@@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetStudios
+ /// Class GetStudios.
/// </summary>
[Route("/Studios", "GET", Summary = "Gets all studios from a given item, folder, or the entire library")]
public class GetStudios : GetItemsByName
@@ -21,7 +21,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetStudio
+ /// Class GetStudio.
/// </summary>
[Route("/Studios/{Name}", "GET", Summary = "Gets a studio, by name")]
public class GetStudio : IReturn<BaseItemDto>
@@ -42,7 +42,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class StudiosService
+ /// Class StudiosService.
/// </summary>
[Authenticated]
public class StudiosService : BaseItemsByNameService<Studio>
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 7fa750adb..f9cbba410 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -20,7 +20,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetItem
+ /// Class GetItem.
/// </summary>
[Route("/Users/{UserId}/Items/{Id}", "GET", Summary = "Gets an item from a user's library")]
public class GetItem : IReturn<BaseItemDto>
@@ -41,7 +41,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetItem
+ /// Class GetItem.
/// </summary>
[Route("/Users/{UserId}/Items/Root", "GET", Summary = "Gets the root folder from a user's library")]
public class GetRootFolder : IReturn<BaseItemDto>
@@ -55,7 +55,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetIntros
+ /// Class GetIntros.
/// </summary>
[Route("/Users/{UserId}/Items/{Id}/Intros", "GET", Summary = "Gets intros to play before the main media item plays")]
public class GetIntros : IReturn<QueryResult<BaseItemDto>>
@@ -76,7 +76,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class MarkFavoriteItem
+ /// Class MarkFavoriteItem.
/// </summary>
[Route("/Users/{UserId}/FavoriteItems/{Id}", "POST", Summary = "Marks an item as a favorite")]
public class MarkFavoriteItem : IReturn<UserItemDataDto>
@@ -97,7 +97,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class UnmarkFavoriteItem
+ /// Class UnmarkFavoriteItem.
/// </summary>
[Route("/Users/{UserId}/FavoriteItems/{Id}", "DELETE", Summary = "Unmarks an item as a favorite")]
public class UnmarkFavoriteItem : IReturn<UserItemDataDto>
@@ -118,7 +118,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class ClearUserItemRating
+ /// Class ClearUserItemRating.
/// </summary>
[Route("/Users/{UserId}/Items/{Id}/Rating", "DELETE", Summary = "Deletes a user's saved personal rating for an item")]
public class DeleteUserItemRating : IReturn<UserItemDataDto>
@@ -139,7 +139,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class UpdateUserItemRating
+ /// Class UpdateUserItemRating.
/// </summary>
[Route("/Users/{UserId}/Items/{Id}/Rating", "POST", Summary = "Updates a user's rating for an item")]
public class UpdateUserItemRating : IReturn<UserItemDataDto>
@@ -167,7 +167,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetLocalTrailers
+ /// Class GetLocalTrailers.
/// </summary>
[Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET", Summary = "Gets local trailers for an item")]
public class GetLocalTrailers : IReturn<BaseItemDto[]>
@@ -188,7 +188,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetSpecialFeatures
+ /// Class GetSpecialFeatures.
/// </summary>
[Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET", Summary = "Gets special features for an item")]
public class GetSpecialFeatures : IReturn<BaseItemDto[]>
@@ -259,7 +259,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class UserLibraryService
+ /// Class UserLibraryService.
/// </summary>
[Authenticated]
public class UserLibraryService : BaseApiService
@@ -312,7 +312,7 @@ namespace MediaBrowser.Api.UserLibrary
if (!request.IsPlayed.HasValue)
{
- if (user.Configuration.HidePlayedInLatest)
+ if (user.HidePlayedInLatest)
{
request.IsPlayed = false;
}
diff --git a/MediaBrowser.Api/UserLibrary/UserViewsService.cs b/MediaBrowser.Api/UserLibrary/UserViewsService.cs
index 0fffb0622..6f1620ddd 100644
--- a/MediaBrowser.Api/UserLibrary/UserViewsService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserViewsService.cs
@@ -27,6 +27,7 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "IncludeExternalContent", Description = "Whether or not to include external views such as channels or live tv", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? IncludeExternalContent { get; set; }
+
public bool IncludeHidden { get; set; }
public string PresetViews { get; set; }
@@ -80,6 +81,7 @@ namespace MediaBrowser.Api.UserLibrary
{
query.IncludeExternalContent = request.IncludeExternalContent.Value;
}
+
query.IncludeHidden = request.IncludeHidden;
if (!string.IsNullOrWhiteSpace(request.PresetViews))
@@ -129,7 +131,6 @@ namespace MediaBrowser.Api.UserLibrary
{
Name = i.Name,
Id = i.Id.ToString("N", CultureInfo.InvariantCulture)
-
})
.OrderBy(i => i.Name)
.ToArray();
@@ -141,6 +142,7 @@ namespace MediaBrowser.Api.UserLibrary
class SpecialViewOption
{
public string Name { get; set; }
+
public string Id { get; set; }
}
}
diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs
index d023ee90a..0523f89fa 100644
--- a/MediaBrowser.Api/UserLibrary/YearsService.cs
+++ b/MediaBrowser.Api/UserLibrary/YearsService.cs
@@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
- /// Class GetYears
+ /// Class GetYears.
/// </summary>
[Route("/Years", "GET", Summary = "Gets all years from a given item, folder, or the entire library")]
public class GetYears : GetItemsByName
@@ -21,7 +21,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class GetYear
+ /// Class GetYear.
/// </summary>
[Route("/Years/{Year}", "GET", Summary = "Gets a year")]
public class GetYear : IReturn<BaseItemDto>
@@ -42,7 +42,7 @@ namespace MediaBrowser.Api.UserLibrary
}
/// <summary>
- /// Class YearsService
+ /// Class YearsService.
/// </summary>
[Authenticated]
public class YearsService : BaseItemsByNameService<Year>
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 78fc6c694..6e9d788dc 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
+using Jellyfin.Data.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Authentication;
@@ -18,7 +19,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetUsers
+ /// Class GetUsers.
/// </summary>
[Route("/Users", "GET", Summary = "Gets a list of users")]
[Authenticated]
@@ -40,7 +41,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class GetUser
+ /// Class GetUser.
/// </summary>
[Route("/Users/{Id}", "GET", Summary = "Gets a user by Id")]
[Authenticated(EscapeParentalControl = true)]
@@ -55,7 +56,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class DeleteUser
+ /// Class DeleteUser.
/// </summary>
[Route("/Users/{Id}", "DELETE", Summary = "Deletes a user")]
[Authenticated(Roles = "Admin")]
@@ -70,7 +71,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class AuthenticateUser
+ /// Class AuthenticateUser.
/// </summary>
[Route("/Users/{Id}/Authenticate", "POST", Summary = "Authenticates a user")]
public class AuthenticateUser : IReturn<AuthenticationResult>
@@ -94,7 +95,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class AuthenticateUser
+ /// Class AuthenticateUser.
/// </summary>
[Route("/Users/AuthenticateByName", "POST", Summary = "Authenticates a user")]
public class AuthenticateUserByName : IReturn<AuthenticationResult>
@@ -118,7 +119,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdateUserPassword
+ /// Class UpdateUserPassword.
/// </summary>
[Route("/Users/{Id}/Password", "POST", Summary = "Updates a user's password")]
[Authenticated]
@@ -148,7 +149,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdateUserEasyPassword
+ /// Class UpdateUserEasyPassword.
/// </summary>
[Route("/Users/{Id}/EasyPassword", "POST", Summary = "Updates a user's easy password")]
[Authenticated]
@@ -176,7 +177,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdateUser
+ /// Class UpdateUser.
/// </summary>
[Route("/Users/{Id}", "POST", Summary = "Updates a user")]
[Authenticated]
@@ -185,7 +186,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdateUser
+ /// Class UpdateUser.
/// </summary>
[Route("/Users/{Id}/Policy", "POST", Summary = "Updates a user policy")]
[Authenticated(Roles = "admin")]
@@ -196,7 +197,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UpdateUser
+ /// Class UpdateUser.
/// </summary>
[Route("/Users/{Id}/Configuration", "POST", Summary = "Updates a user configuration")]
[Authenticated]
@@ -207,7 +208,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class CreateUser
+ /// Class CreateUser.
/// </summary>
[Route("/Users/New", "POST", Summary = "Creates a user")]
[Authenticated(Roles = "Admin")]
@@ -235,7 +236,7 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// Class UsersService
+ /// Class UsersService.
/// </summary>
public class UserService : BaseApiService
{
@@ -300,12 +301,12 @@ namespace MediaBrowser.Api
if (request.IsDisabled.HasValue)
{
- users = users.Where(i => i.Policy.IsDisabled == request.IsDisabled.Value);
+ users = users.Where(i => i.HasPermission(PermissionKind.IsDisabled) == request.IsDisabled.Value);
}
if (request.IsHidden.HasValue)
{
- users = users.Where(i => i.Policy.IsHidden == request.IsHidden.Value);
+ users = users.Where(i => i.HasPermission(PermissionKind.IsHidden) == request.IsHidden.Value);
}
if (filterByDevice)
@@ -322,12 +323,12 @@ namespace MediaBrowser.Api
{
if (!_networkManager.IsInLocalNetwork(Request.RemoteIp))
{
- users = users.Where(i => i.Policy.EnableRemoteAccess);
+ users = users.Where(i => i.HasPermission(PermissionKind.EnableRemoteAccess));
}
}
var result = users
- .OrderBy(u => u.Name)
+ .OrderBy(u => u.Username)
.Select(i => _userManager.GetUserDto(i, Request.RemoteIp))
.ToArray();
@@ -364,15 +365,8 @@ namespace MediaBrowser.Api
public Task DeleteAsync(DeleteUser request)
{
- var user = _userManager.GetUserById(request.Id);
-
- if (user == null)
- {
- throw new ResourceNotFoundException("User not found");
- }
-
- _sessionMananger.RevokeUserTokens(user.Id, null);
- _userManager.DeleteUser(user);
+ _userManager.DeleteUser(request.Id);
+ _sessionMananger.RevokeUserTokens(request.Id, null);
return Task.CompletedTask;
}
@@ -397,7 +391,7 @@ namespace MediaBrowser.Api
// Password should always be null
return Post(new AuthenticateUserByName
{
- Username = user.Name,
+ Username = user.Username,
Password = null,
Pw = request.Pw
});
@@ -456,7 +450,12 @@ namespace MediaBrowser.Api
}
else
{
- var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPw, request.CurrentPassword, Request.RemoteIp, false).ConfigureAwait(false);
+ var success = await _userManager.AuthenticateUser(
+ user.Username,
+ request.CurrentPw,
+ request.CurrentPassword,
+ Request.RemoteIp,
+ false).ConfigureAwait(false);
if (success == null)
{
@@ -506,10 +505,10 @@ namespace MediaBrowser.Api
var user = _userManager.GetUserById(id);
- if (string.Equals(user.Name, dtoUser.Name, StringComparison.Ordinal))
+ if (string.Equals(user.Username, dtoUser.Name, StringComparison.Ordinal))
{
- _userManager.UpdateUser(user);
- _userManager.UpdateConfiguration(user, dtoUser.Configuration);
+ await _userManager.UpdateUserAsync(user);
+ _userManager.UpdateConfiguration(user.Id, dtoUser.Configuration);
}
else
{
@@ -560,7 +559,6 @@ namespace MediaBrowser.Api
AssertCanUpdateUser(_authContext, _userManager, request.Id, false);
_userManager.UpdateConfiguration(request.Id, request);
-
}
public void Post(UpdateUserPolicy request)
@@ -568,24 +566,24 @@ namespace MediaBrowser.Api
var user = _userManager.GetUserById(request.Id);
// If removing admin access
- if (!request.IsAdministrator && user.Policy.IsAdministrator)
+ if (!request.IsAdministrator && user.HasPermission(PermissionKind.IsAdministrator))
{
- if (_userManager.Users.Count(i => i.Policy.IsAdministrator) == 1)
+ if (_userManager.Users.Count(i => i.HasPermission(PermissionKind.IsAdministrator)) == 1)
{
throw new ArgumentException("There must be at least one user in the system with administrative access.");
}
}
// If disabling
- if (request.IsDisabled && user.Policy.IsAdministrator)
+ if (request.IsDisabled && user.HasPermission(PermissionKind.IsAdministrator))
{
throw new ArgumentException("Administrators cannot be disabled.");
}
// If disabling
- if (request.IsDisabled && !user.Policy.IsDisabled)
+ if (request.IsDisabled && !user.HasPermission(PermissionKind.IsDisabled))
{
- if (_userManager.Users.Count(i => !i.Policy.IsDisabled) == 1)
+ if (_userManager.Users.Count(i => !i.HasPermission(PermissionKind.IsDisabled)) == 1)
{
throw new ArgumentException("There must be at least one enabled user in the system.");
}
@@ -594,7 +592,7 @@ namespace MediaBrowser.Api
_sessionMananger.RevokeUserTokens(user.Id, currentToken);
}
- _userManager.UpdateUserPolicy(request.Id, request);
+ _userManager.UpdatePolicy(request.Id, request);
}
}
}