aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api
diff options
context:
space:
mode:
authorstefan <stefan@hegedues.at>2018-09-12 19:26:21 +0200
committerstefan <stefan@hegedues.at>2018-09-12 19:26:21 +0200
commit48facb797ed912e4ea6b04b17d1ff190ac2daac4 (patch)
tree8dae77a31670a888d733484cb17dd4077d5444e8 /MediaBrowser.Api
parentc32d8656382a0eacb301692e0084377fc433ae9b (diff)
Update to 3.5.2 and .net core 2.1
Diffstat (limited to 'MediaBrowser.Api')
-rw-r--r--MediaBrowser.Api/ApiEntryPoint.cs3
-rw-r--r--MediaBrowser.Api/BaseApiService.cs91
-rw-r--r--MediaBrowser.Api/BrandingService.cs8
-rw-r--r--MediaBrowser.Api/ChannelService.cs145
-rw-r--r--MediaBrowser.Api/ConfigurationService.cs38
-rw-r--r--MediaBrowser.Api/Devices/DeviceService.cs87
-rw-r--r--MediaBrowser.Api/DisplayPreferencesService.cs2
-rw-r--r--MediaBrowser.Api/Dlna/DlnaServerService.cs263
-rw-r--r--MediaBrowser.Api/Dlna/DlnaService.cs89
-rw-r--r--MediaBrowser.Api/EnvironmentService.cs40
-rw-r--r--MediaBrowser.Api/FilterService.cs34
-rw-r--r--MediaBrowser.Api/GamesService.cs60
-rw-r--r--MediaBrowser.Api/Images/ImageRequest.cs8
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs154
-rw-r--r--MediaBrowser.Api/Images/RemoteImageService.cs23
-rw-r--r--MediaBrowser.Api/ItemLookupService.cs23
-rw-r--r--MediaBrowser.Api/ItemRefreshService.cs7
-rw-r--r--MediaBrowser.Api/ItemUpdateService.cs25
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs683
-rw-r--r--MediaBrowser.Api/Library/LibraryStructureService.cs24
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs291
-rw-r--r--MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs64
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj141
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.nuget.targets6
-rw-r--r--MediaBrowser.Api/Movies/CollectionService.cs24
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs59
-rw-r--r--MediaBrowser.Api/Music/AlbumsService.cs4
-rw-r--r--MediaBrowser.Api/Music/InstantMixService.cs21
-rw-r--r--MediaBrowser.Api/NewsService.cs2
-rw-r--r--MediaBrowser.Api/NotificationsService.cs183
-rw-r--r--MediaBrowser.Api/PackageService.cs20
-rw-r--r--MediaBrowser.Api/PlaylistService.cs29
-rw-r--r--MediaBrowser.Api/PluginService.cs48
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs2
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs12
-rw-r--r--MediaBrowser.Api/SearchService.cs31
-rw-r--r--MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs18
-rw-r--r--MediaBrowser.Api/Session/SessionsService.cs121
-rw-r--r--MediaBrowser.Api/SimilarItemsHelper.cs8
-rw-r--r--MediaBrowser.Api/Social/SharingService.cs178
-rw-r--r--MediaBrowser.Api/StartupWizardService.cs46
-rw-r--r--MediaBrowser.Api/Subtitles/SubtitleService.cs55
-rw-r--r--MediaBrowser.Api/SuggestionsService.cs12
-rw-r--r--MediaBrowser.Api/System/ActivityLogService.cs6
-rw-r--r--MediaBrowser.Api/System/ActivityLogWebSocketListener.cs12
-rw-r--r--MediaBrowser.Api/System/SystemInfoWebSocketListener.cs49
-rw-r--r--MediaBrowser.Api/System/SystemService.cs15
-rw-r--r--MediaBrowser.Api/TvShowsService.cs67
-rw-r--r--MediaBrowser.Api/UserLibrary/ArtistsService.cs14
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs167
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs62
-rw-r--r--MediaBrowser.Api/UserLibrary/GameGenresService.cs8
-rw-r--r--MediaBrowser.Api/UserLibrary/GenresService.cs8
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs93
-rw-r--r--MediaBrowser.Api/UserLibrary/MusicGenresService.cs8
-rw-r--r--MediaBrowser.Api/UserLibrary/PersonsService.cs60
-rw-r--r--MediaBrowser.Api/UserLibrary/StudiosService.cs13
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs119
-rw-r--r--MediaBrowser.Api/UserLibrary/UserViewsService.cs22
-rw-r--r--MediaBrowser.Api/UserLibrary/YearsService.cs9
-rw-r--r--MediaBrowser.Api/UserService.cs124
-rw-r--r--MediaBrowser.Api/VideosService.cs34
62 files changed, 1512 insertions, 2560 deletions
diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs
index 04cef60bfc..9676a2c2af 100644
--- a/MediaBrowser.Api/ApiEntryPoint.cs
+++ b/MediaBrowser.Api/ApiEntryPoint.cs
@@ -70,7 +70,7 @@ namespace MediaBrowser.Api
{
if (string.IsNullOrWhiteSpace(value))
{
- return new string[] { };
+ return Array.Empty<string>();
}
if (removeEmpty)
@@ -88,7 +88,6 @@ namespace MediaBrowser.Api
public void Dispose()
{
- GC.SuppressFinalize(this);
}
}
}
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 1629d49b49..db6af0c4bd 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -55,7 +55,7 @@ namespace MediaBrowser.Api
return Request.Headers[name];
}
- private static readonly string[] EmptyStringArray = new string[] { };
+ private static readonly string[] EmptyStringArray = Array.Empty<string>();
public static string[] SplitValue(string value, char delim)
{
if (string.IsNullOrWhiteSpace(value))
@@ -65,7 +65,13 @@ namespace MediaBrowser.Api
return value.Split(new[] { delim }, StringSplitOptions.RemoveEmptyEntries);
}
-
+
+ public static Guid[] GetGuids(string value)
+ {
+ // Unfortunately filtermenu.js was using |. This can be deprecated after a while.
+ return (value ?? string.Empty).Split(new[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries).Select(i => new Guid(i)).ToArray();
+ }
+
/// <summary>
/// To the optimized result.
/// </summary>
@@ -75,17 +81,17 @@ namespace MediaBrowser.Api
protected object ToOptimizedResult<T>(T result)
where T : class
{
- return ResultFactory.GetOptimizedResult(Request, result);
+ return ResultFactory.GetResult(Request, result);
}
- protected void AssertCanUpdateUser(IAuthorizationContext authContext, IUserManager userManager, string userId, bool restrictUserPreferences)
+ protected void AssertCanUpdateUser(IAuthorizationContext authContext, IUserManager userManager, Guid userId, bool restrictUserPreferences)
{
var auth = authContext.GetAuthorizationInfo(Request);
- var authenticatedUser = userManager.GetUserById(auth.UserId);
+ var authenticatedUser = auth.User;
// If they're going to update the record of another user, they must be an administrator
- if (!string.Equals(userId, auth.UserId, StringComparison.OrdinalIgnoreCase))
+ if (!userId.Equals(auth.UserId))
{
if (!authenticatedUser.Policy.IsAdministrator)
{
@@ -102,24 +108,12 @@ namespace MediaBrowser.Api
}
/// <summary>
- /// To the optimized serialized result using cache.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="result">The result.</param>
- /// <returns>System.Object.</returns>
- protected object ToOptimizedSerializedResultUsingCache<T>(T result)
- where T : class
- {
- return ToOptimizedResult(result);
- }
-
- /// <summary>
/// Gets the session.
/// </summary>
/// <returns>SessionInfo.</returns>
- protected async Task<SessionInfo> GetSession(ISessionContext sessionContext)
+ protected SessionInfo GetSession(ISessionContext sessionContext)
{
- var session = await sessionContext.GetSession(Request).ConfigureAwait(false);
+ var session = sessionContext.GetSession(Request);
if (session == null)
{
@@ -133,38 +127,37 @@ namespace MediaBrowser.Api
{
var options = new DtoOptions();
- var authInfo = authContext.GetAuthorizationInfo(Request);
-
- options.DeviceId = authInfo.DeviceId;
-
var hasFields = request as IHasItemFields;
if (hasFields != null)
{
options.Fields = hasFields.GetItemFields();
}
- var client = authInfo.Client ?? string.Empty;
- if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
+ if (!options.ContainsField(Model.Querying.ItemFields.RecursiveItemCount) || !options.ContainsField(Model.Querying.ItemFields.ChildCount))
{
- var list = options.Fields.ToList();
- list.Add(Model.Querying.ItemFields.RecursiveItemCount);
- options.Fields = list.ToArray(list.Count);
- }
+ var client = authContext.GetAuthorizationInfo(Request).Client ?? string.Empty;
+ if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ var list = options.Fields.ToList();
+ list.Add(Model.Querying.ItemFields.RecursiveItemCount);
+ options.Fields = list.ToArray(list.Count);
+ }
- if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
- client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
- {
- var list = options.Fields.ToList();
- list.Add(Model.Querying.ItemFields.ChildCount);
- options.Fields = list.ToArray(list.Count);
+ if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
+ client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
+ {
+ var list = options.Fields.ToList();
+ list.Add(Model.Querying.ItemFields.ChildCount);
+ options.Fields = list.ToArray(list.Count);
+ }
}
var hasDtoOptions = request as IHasDtoOptions;
@@ -289,7 +282,7 @@ namespace MediaBrowser.Api
IncludeItemTypes = new[] { typeof(T).Name },
DtoOptions = dtoOptions
- }).OfType<Person>().FirstOrDefault();
+ }).OfType<T>().FirstOrDefault();
if (result == null)
{
@@ -299,7 +292,7 @@ namespace MediaBrowser.Api
IncludeItemTypes = new[] { typeof(T).Name },
DtoOptions = dtoOptions
- }).OfType<Person>().FirstOrDefault();
+ }).OfType<T>().FirstOrDefault();
}
if (result == null)
@@ -310,10 +303,10 @@ namespace MediaBrowser.Api
IncludeItemTypes = new[] { typeof(T).Name },
DtoOptions = dtoOptions
- }).OfType<Person>().FirstOrDefault();
+ }).OfType<T>().FirstOrDefault();
}
- return result as T;
+ return result;
}
protected string GetPathValue(int index)
@@ -331,7 +324,7 @@ namespace MediaBrowser.Api
return pathInfo[index];
}
- private static List<string> Parse(string pathUri)
+ private List<string> Parse(string pathUri)
{
var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
diff --git a/MediaBrowser.Api/BrandingService.cs b/MediaBrowser.Api/BrandingService.cs
index 4602f56ed9..4eb69678a3 100644
--- a/MediaBrowser.Api/BrandingService.cs
+++ b/MediaBrowser.Api/BrandingService.cs
@@ -26,17 +26,15 @@ namespace MediaBrowser.Api
public object Get(GetBrandingOptions request)
{
- var result = _config.GetConfiguration<BrandingOptions>("branding");
-
- return ToOptimizedResult(result);
+ return _config.GetConfiguration<BrandingOptions>("branding");
}
public object Get(GetBrandingCss request)
{
var result = _config.GetConfiguration<BrandingOptions>("branding");
- // When null this throws a 405 error under Mono OSX, so default to empty string
- return ResultFactory.GetResult(result.CustomCss ?? string.Empty, "text/css");
+ // When null this throws a 405 error under Mono OSX, so default to empty string
+ return ResultFactory.GetResult(Request, result.CustomCss ?? string.Empty, "text/css");
}
}
}
diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs
index 2e8eb9e07d..0b9d5efa9f 100644
--- a/MediaBrowser.Api/ChannelService.cs
+++ b/MediaBrowser.Api/ChannelService.cs
@@ -11,6 +11,8 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Api.UserLibrary;
using MediaBrowser.Model.Services;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
namespace MediaBrowser.Api
{
@@ -21,8 +23,8 @@ namespace MediaBrowser.Api
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ [ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -41,6 +43,8 @@ namespace MediaBrowser.Api
[ApiMember(Name = "SupportsLatestItems", Description = "Optional. Filter by channels that support getting latest items.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool? SupportsLatestItems { get; set; }
+ public bool? SupportsMediaDeletion { get; set; }
+
/// <summary>
/// Gets or sets a value indicating whether this instance is favorite.
/// </summary>
@@ -74,7 +78,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -122,7 +126,7 @@ namespace MediaBrowser.Api
/// Gets the order by.
/// </summary>
/// <returns>IEnumerable{ItemSortBy}.</returns>
- public Tuple<string, SortOrder>[] GetOrderBy()
+ public ValueTuple<string, SortOrder>[] GetOrderBy()
{
return BaseItemsRequest.GetOrderBy(SortBy, SortOrder);
}
@@ -136,7 +140,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -178,21 +182,16 @@ namespace MediaBrowser.Api
}
}
- [Route("/Channels/Folder", "GET", Summary = "Gets the users channel folder, along with configured images")]
- public class GetChannelFolder : IReturn<BaseItemDto>
- {
- [ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
- }
-
[Authenticated]
public class ChannelService : BaseApiService
{
private readonly IChannelManager _channelManager;
+ private IUserManager _userManager;
- public ChannelService(IChannelManager channelManager)
+ public ChannelService(IChannelManager channelManager, IUserManager userManager)
{
_channelManager = channelManager;
+ _userManager = userManager;
}
public object Get(GetAllChannelFeatures request)
@@ -209,56 +208,132 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
- public object Get(GetChannelFolder request)
+ public object Get(GetChannels request)
{
- return ToOptimizedResult(_channelManager.GetChannelFolder(request.UserId, CancellationToken.None));
- }
-
- public async Task<object> Get(GetChannels request)
- {
- var result = await _channelManager.GetChannels(new ChannelQuery
+ var result = _channelManager.GetChannels(new ChannelQuery
{
Limit = request.Limit,
StartIndex = request.StartIndex,
UserId = request.UserId,
SupportsLatestItems = request.SupportsLatestItems,
+ SupportsMediaDeletion = request.SupportsMediaDeletion,
IsFavorite = request.IsFavorite
-
- }, CancellationToken.None).ConfigureAwait(false);
+ });
return ToOptimizedResult(result);
}
public async Task<object> Get(GetChannelItems request)
{
- var result = await _channelManager.GetChannelItems(new ChannelItemQuery
+ var user = request.UserId.Equals(Guid.Empty)
+ ? null
+ : _userManager.GetUserById(request.UserId);
+
+ var query = new InternalItemsQuery(user)
{
Limit = request.Limit,
StartIndex = request.StartIndex,
- UserId = request.UserId,
- ChannelId = request.Id,
- FolderId = request.FolderId,
+ ChannelIds = new Guid[] { new Guid(request.Id) },
+ ParentId = string.IsNullOrWhiteSpace(request.FolderId) ? Guid.Empty : new Guid(request.FolderId),
OrderBy = request.GetOrderBy(),
- Filters = request.GetFilters().ToArray(),
- Fields = request.GetItemFields()
+ DtoOptions = new Controller.Dto.DtoOptions
+ {
+ Fields = request.GetItemFields()
+ }
+
+ };
+
+ foreach (var filter in request.GetFilters())
+ {
+ switch (filter)
+ {
+ case ItemFilter.Dislikes:
+ query.IsLiked = false;
+ break;
+ case ItemFilter.IsFavorite:
+ query.IsFavorite = true;
+ break;
+ case ItemFilter.IsFavoriteOrLikes:
+ query.IsFavoriteOrLiked = true;
+ break;
+ case ItemFilter.IsFolder:
+ query.IsFolder = true;
+ break;
+ case ItemFilter.IsNotFolder:
+ query.IsFolder = false;
+ break;
+ case ItemFilter.IsPlayed:
+ query.IsPlayed = true;
+ break;
+ case ItemFilter.IsResumable:
+ query.IsResumable = true;
+ break;
+ case ItemFilter.IsUnplayed:
+ query.IsPlayed = false;
+ break;
+ case ItemFilter.Likes:
+ query.IsLiked = true;
+ break;
+ }
+ }
- }, CancellationToken.None).ConfigureAwait(false);
+ var result = await _channelManager.GetChannelItems(query, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
}
public async Task<object> Get(GetLatestChannelItems request)
{
- var result = await _channelManager.GetLatestChannelItems(new AllChannelMediaQuery
+ var user = request.UserId.Equals(Guid.Empty)
+ ? null
+ : _userManager.GetUserById(request.UserId);
+
+ var query = new InternalItemsQuery(user)
{
Limit = request.Limit,
StartIndex = request.StartIndex,
- ChannelIds = (request.ChannelIds ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(),
- UserId = request.UserId,
- Filters = request.GetFilters().ToArray(),
- Fields = request.GetItemFields()
+ ChannelIds = (request.ChannelIds ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(i => new Guid(i)).ToArray(),
+ DtoOptions = new Controller.Dto.DtoOptions
+ {
+ Fields = request.GetItemFields()
+ }
+ };
+
+ foreach (var filter in request.GetFilters())
+ {
+ switch (filter)
+ {
+ case ItemFilter.Dislikes:
+ query.IsLiked = false;
+ break;
+ case ItemFilter.IsFavorite:
+ query.IsFavorite = true;
+ break;
+ case ItemFilter.IsFavoriteOrLikes:
+ query.IsFavoriteOrLiked = true;
+ break;
+ case ItemFilter.IsFolder:
+ query.IsFolder = true;
+ break;
+ case ItemFilter.IsNotFolder:
+ query.IsFolder = false;
+ break;
+ case ItemFilter.IsPlayed:
+ query.IsPlayed = true;
+ break;
+ case ItemFilter.IsResumable:
+ query.IsResumable = true;
+ break;
+ case ItemFilter.IsUnplayed:
+ query.IsPlayed = false;
+ break;
+ case ItemFilter.Likes:
+ query.IsLiked = true;
+ break;
+ }
+ }
- }, CancellationToken.None).ConfigureAwait(false);
+ var result = await _channelManager.GetLatestChannelItems(query, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
}
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index 0023c13d78..9d14558e3b 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -4,14 +4,11 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Serialization;
-using System.Collections.Generic;
using System.IO;
-using System.Threading.Tasks;
-
-using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Services;
+using System.Threading.Tasks;
namespace MediaBrowser.Api
{
@@ -59,27 +56,13 @@ namespace MediaBrowser.Api
}
- [Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")]
- [Authenticated(Roles = "Admin")]
- public class GetMetadataPlugins : IReturn<MetadataPluginSummary[]>
- {
-
- }
-
- [Route("/System/Configuration/MetadataPlugins/Autoset", "POST")]
- [Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)]
- public class AutoSetMetadataOptions : IReturnVoid
- {
-
- }
-
[Route("/System/MediaEncoder/Path", "POST", Summary = "Updates the path to the media encoder")]
[Authenticated(Roles = "Admin", AllowBeforeStartupWizard = true)]
public class UpdateMediaEncoderPath : IReturnVoid
{
- [ApiMember(Name = "Path", Description = "Path", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "Path", Description = "Path", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Path { get; set; }
- [ApiMember(Name = "PathType", Description = "PathType", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "PathType", Description = "PathType", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string PathType { get; set; }
}
@@ -132,10 +115,6 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
- public void Post(AutoSetMetadataOptions request)
- {
- }
-
/// <summary>
/// Posts the specified configuraiton.
/// </summary>
@@ -150,24 +129,19 @@ namespace MediaBrowser.Api
_configurationManager.ReplaceConfiguration(config);
}
- public void Post(UpdateNamedConfiguration request)
+ public async Task Post(UpdateNamedConfiguration request)
{
var key = GetPathValue(2);
var configurationType = _configurationManager.GetConfigurationType(key);
- var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, configurationType);
+ var configuration = await _jsonSerializer.DeserializeFromStreamAsync(request.RequestStream, configurationType).ConfigureAwait(false);
_configurationManager.SaveConfiguration(key, configuration);
}
public object Get(GetDefaultMetadataOptions request)
{
- return ToOptimizedSerializedResultUsingCache(new MetadataOptions());
- }
-
- public object Get(GetMetadataPlugins request)
- {
- return ToOptimizedSerializedResultUsingCache(_providerManager.GetAllMetadataPlugins());
+ return ToOptimizedResult(new MetadataOptions());
}
}
}
diff --git a/MediaBrowser.Api/Devices/DeviceService.cs b/MediaBrowser.Api/Devices/DeviceService.cs
index c375e272a7..9cc16b4a1f 100644
--- a/MediaBrowser.Api/Devices/DeviceService.cs
+++ b/MediaBrowser.Api/Devices/DeviceService.cs
@@ -7,6 +7,8 @@ using MediaBrowser.Model.Session;
using System.IO;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
+using MediaBrowser.Controller.Security;
+using MediaBrowser.Controller.Session;
namespace MediaBrowser.Api.Devices
{
@@ -16,6 +18,22 @@ namespace MediaBrowser.Api.Devices
{
}
+ [Route("/Devices/Info", "GET", Summary = "Gets info for a device")]
+ [Authenticated(Roles = "Admin")]
+ public class GetDeviceInfo : IReturn<DeviceInfo>
+ {
+ [ApiMember(Name = "Id", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string Id { get; set; }
+ }
+
+ [Route("/Devices/Options", "GET", Summary = "Gets options for a device")]
+ [Authenticated(Roles = "Admin")]
+ public class GetDeviceOptions : IReturn<DeviceOptions>
+ {
+ [ApiMember(Name = "Id", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string Id { get; set; }
+ }
+
[Route("/Devices", "DELETE", Summary = "Deletes a device")]
public class DeleteDevice
{
@@ -35,37 +53,21 @@ namespace MediaBrowser.Api.Devices
[Authenticated]
public class PostCameraUpload : IRequiresRequestStream, IReturnVoid
{
- [ApiMember(Name = "DeviceId", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [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 = "GET")]
+ [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 = "GET")]
+ [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 = "GET")]
+ [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/Info", "GET", Summary = "Gets device info")]
- [Authenticated]
- public class GetDeviceInfo : IReturn<DeviceInfo>
- {
- [ApiMember(Name = "Id", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
- public string Id { get; set; }
- }
-
- [Route("/Devices/Capabilities", "GET", Summary = "Gets device capabilities")]
- [Authenticated]
- public class GetDeviceCapabilities : IReturn<ClientCapabilities>
- {
- [ApiMember(Name = "Id", Description = "Device Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
- public string Id { get; set; }
- }
-
[Route("/Devices/Options", "POST", Summary = "Updates device options")]
[Authenticated(Roles = "Admin")]
public class PostDeviceOptions : DeviceOptions, IReturnVoid
@@ -77,34 +79,34 @@ namespace MediaBrowser.Api.Devices
public class DeviceService : BaseApiService
{
private readonly IDeviceManager _deviceManager;
+ private readonly IAuthenticationRepository _authRepo;
+ private readonly ISessionManager _sessionManager;
- public DeviceService(IDeviceManager deviceManager)
+ public DeviceService(IDeviceManager deviceManager, IAuthenticationRepository authRepo, ISessionManager sessionManager)
{
_deviceManager = deviceManager;
+ _authRepo = authRepo;
+ _sessionManager = sessionManager;
}
public void Post(PostDeviceOptions request)
{
- _deviceManager.UpdateDeviceInfo(request.Id, new DeviceOptions
- {
- CustomName = request.CustomName,
- CameraUploadPath = request.CameraUploadPath
- });
+ _deviceManager.UpdateDeviceOptions(request.Id, request);
}
- public object Get(GetDeviceInfo request)
+ public object Get(GetDevices request)
{
- return ToOptimizedResult(_deviceManager.GetDevice(request.Id));
+ return ToOptimizedResult(_deviceManager.GetDevices(request));
}
- public object Get(GetDeviceCapabilities request)
+ public object Get(GetDeviceInfo request)
{
- return ToOptimizedResult(_deviceManager.GetCapabilities(request.Id));
+ return _deviceManager.GetDevice(request.Id);
}
- public object Get(GetDevices request)
+ public object Get(GetDeviceOptions request)
{
- return ToOptimizedResult(_deviceManager.GetDevices(request));
+ return _deviceManager.GetDeviceOptions(request.Id);
}
public object Get(GetCameraUploads request)
@@ -114,10 +116,19 @@ namespace MediaBrowser.Api.Devices
public void Delete(DeleteDevice request)
{
- _deviceManager.DeleteDevice(request.Id);
+ var sessions = _authRepo.Get(new AuthenticationInfoQuery
+ {
+ DeviceId = request.Id
+
+ }).Items;
+
+ foreach (var session in sessions)
+ {
+ _sessionManager.Logout(session);
+ }
}
- public void Post(PostCameraUpload request)
+ public Task Post(PostCameraUpload request)
{
var deviceId = Request.QueryString["DeviceId"];
var album = Request.QueryString["Album"];
@@ -126,29 +137,25 @@ namespace MediaBrowser.Api.Devices
if (Request.ContentType.IndexOf("multi", StringComparison.OrdinalIgnoreCase) == -1)
{
- var task = _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo
+ return _deviceManager.AcceptCameraUpload(deviceId, request.RequestStream, new LocalFileInfo
{
MimeType = Request.ContentType,
Album = album,
Name = name,
Id = id
});
-
- Task.WaitAll(task);
}
else
{
var file = Request.Files.Length == 0 ? null : Request.Files[0];
- var task = _deviceManager.AcceptCameraUpload(deviceId, file.InputStream, new LocalFileInfo
+ return _deviceManager.AcceptCameraUpload(deviceId, file.InputStream, new LocalFileInfo
{
MimeType = file.ContentType,
Album = album,
Name = name,
Id = id
});
-
- Task.WaitAll(task);
}
}
}
diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs
index 4f8cc52558..6bc2f7e4af 100644
--- a/MediaBrowser.Api/DisplayPreferencesService.cs
+++ b/MediaBrowser.Api/DisplayPreferencesService.cs
@@ -76,7 +76,7 @@ namespace MediaBrowser.Api
{
var result = _displayPreferencesManager.GetDisplayPreferences(request.Id, request.UserId, request.Client);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
diff --git a/MediaBrowser.Api/Dlna/DlnaServerService.cs b/MediaBrowser.Api/Dlna/DlnaServerService.cs
deleted file mode 100644
index 6a0cea4df9..0000000000
--- a/MediaBrowser.Api/Dlna/DlnaServerService.cs
+++ /dev/null
@@ -1,263 +0,0 @@
-using MediaBrowser.Controller.Dlna;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Threading.Tasks;
-
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Services;
-
-namespace MediaBrowser.Api.Dlna
-{
- [Route("/Dlna/{UuId}/description.xml", "GET", Summary = "Gets dlna server info")]
- [Route("/Dlna/{UuId}/description", "GET", Summary = "Gets dlna server info")]
- public class GetDescriptionXml
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/contentdirectory/contentdirectory.xml", "GET", Summary = "Gets dlna content directory xml")]
- [Route("/Dlna/{UuId}/contentdirectory/contentdirectory", "GET", Summary = "Gets dlna content directory xml")]
- public class GetContentDirectory
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/connectionmanager/connectionmanager.xml", "GET", Summary = "Gets dlna connection manager xml")]
- [Route("/Dlna/{UuId}/connectionmanager/connectionmanager", "GET", Summary = "Gets dlna connection manager xml")]
- public class GetConnnectionManager
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/mediareceiverregistrar/mediareceiverregistrar.xml", "GET", Summary = "Gets dlna mediareceiverregistrar xml")]
- [Route("/Dlna/{UuId}/mediareceiverregistrar/mediareceiverregistrar", "GET", Summary = "Gets dlna mediareceiverregistrar xml")]
- public class GetMediaReceiverRegistrar
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/contentdirectory/control", "POST", Summary = "Processes a control request")]
- public class ProcessContentDirectoryControlRequest : IRequiresRequestStream
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
-
- public Stream RequestStream { get; set; }
- }
-
- [Route("/Dlna/{UuId}/connectionmanager/control", "POST", Summary = "Processes a control request")]
- public class ProcessConnectionManagerControlRequest : IRequiresRequestStream
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
-
- public Stream RequestStream { get; set; }
- }
-
- [Route("/Dlna/{UuId}/mediareceiverregistrar/control", "POST", Summary = "Processes a control request")]
- public class ProcessMediaReceiverRegistrarControlRequest : IRequiresRequestStream
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
-
- public Stream RequestStream { get; set; }
- }
-
- [Route("/Dlna/{UuId}/mediareceiverregistrar/events", "SUBSCRIBE", Summary = "Processes an event subscription request")]
- [Route("/Dlna/{UuId}/mediareceiverregistrar/events", "UNSUBSCRIBE", Summary = "Processes an event subscription request")]
- public class ProcessMediaReceiverRegistrarEventRequest
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "SUBSCRIBE,UNSUBSCRIBE")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/contentdirectory/events", "SUBSCRIBE", Summary = "Processes an event subscription request")]
- [Route("/Dlna/{UuId}/contentdirectory/events", "UNSUBSCRIBE", Summary = "Processes an event subscription request")]
- public class ProcessContentDirectoryEventRequest
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "SUBSCRIBE,UNSUBSCRIBE")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/connectionmanager/events", "SUBSCRIBE", Summary = "Processes an event subscription request")]
- [Route("/Dlna/{UuId}/connectionmanager/events", "UNSUBSCRIBE", Summary = "Processes an event subscription request")]
- public class ProcessConnectionManagerEventRequest
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "SUBSCRIBE,UNSUBSCRIBE")]
- public string UuId { get; set; }
- }
-
- [Route("/Dlna/{UuId}/icons/{Filename}", "GET", Summary = "Gets a server icon")]
- [Route("/Dlna/icons/{Filename}", "GET", Summary = "Gets a server icon")]
- public class GetIcon
- {
- [ApiMember(Name = "UuId", Description = "Server UuId", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UuId { get; set; }
-
- [ApiMember(Name = "Filename", Description = "The icon filename", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Filename { get; set; }
- }
-
- public class DlnaServerService : BaseApiService
- {
- private readonly IDlnaManager _dlnaManager;
- private readonly IContentDirectory _contentDirectory;
- private readonly IConnectionManager _connectionManager;
- private readonly IMediaReceiverRegistrar _mediaReceiverRegistrar;
-
- private const string XMLContentType = "text/xml; charset=UTF-8";
- private readonly IMemoryStreamFactory _memoryStreamProvider;
-
- public DlnaServerService(IDlnaManager dlnaManager, IContentDirectory contentDirectory, IConnectionManager connectionManager, IMediaReceiverRegistrar mediaReceiverRegistrar, IMemoryStreamFactory memoryStreamProvider)
- {
- _dlnaManager = dlnaManager;
- _contentDirectory = contentDirectory;
- _connectionManager = connectionManager;
- _mediaReceiverRegistrar = mediaReceiverRegistrar;
- _memoryStreamProvider = memoryStreamProvider;
- }
-
- public object Get(GetDescriptionXml request)
- {
- var url = Request.AbsoluteUri;
- var serverAddress = url.Substring(0, url.IndexOf("/dlna/", StringComparison.OrdinalIgnoreCase));
- var xml = _dlnaManager.GetServerDescriptionXml(Request.Headers.ToDictionary(), request.UuId, serverAddress);
-
- return ResultFactory.GetResult(xml, XMLContentType);
- }
-
- public object Get(GetContentDirectory request)
- {
- var xml = _contentDirectory.GetServiceXml(Request.Headers.ToDictionary());
-
- return ResultFactory.GetResult(xml, XMLContentType);
- }
-
- public object Get(GetMediaReceiverRegistrar request)
- {
- var xml = _mediaReceiverRegistrar.GetServiceXml(Request.Headers.ToDictionary());
-
- return ResultFactory.GetResult(xml, XMLContentType);
- }
-
- public object Get(GetConnnectionManager request)
- {
- var xml = _connectionManager.GetServiceXml(Request.Headers.ToDictionary());
-
- return ResultFactory.GetResult(xml, XMLContentType);
- }
-
- public object Post(ProcessMediaReceiverRegistrarControlRequest request)
- {
- var response = PostAsync(request.RequestStream, _mediaReceiverRegistrar);
-
- return ResultFactory.GetResult(response.Xml, XMLContentType);
- }
-
- public object Post(ProcessContentDirectoryControlRequest request)
- {
- var response = PostAsync(request.RequestStream, _contentDirectory);
-
- return ResultFactory.GetResult(response.Xml, XMLContentType);
- }
-
- public object Post(ProcessConnectionManagerControlRequest request)
- {
- var response = PostAsync(request.RequestStream, _connectionManager);
-
- return ResultFactory.GetResult(response.Xml, XMLContentType);
- }
-
- private ControlResponse PostAsync(Stream requestStream, IUpnpService service)
- {
- var id = GetPathValue(2);
-
- return service.ProcessControlRequest(new ControlRequest
- {
- Headers = Request.Headers.ToDictionary(),
- InputXml = requestStream,
- TargetServerUuId = id,
- RequestedUrl = Request.AbsoluteUri
- });
- }
-
- public object Get(GetIcon request)
- {
- using (var response = _dlnaManager.GetIcon(request.Filename))
- {
- using (var ms = _memoryStreamProvider.CreateNew())
- {
- response.Stream.CopyTo(ms);
-
- ms.Position = 0;
- var bytes = ms.ToArray();
- return ResultFactory.GetResult(bytes, "image/" + response.Format.ToString().ToLower());
- }
- }
- }
-
- public object Subscribe(ProcessContentDirectoryEventRequest request)
- {
- return ProcessEventRequest(_contentDirectory);
- }
-
- public object Subscribe(ProcessConnectionManagerEventRequest request)
- {
- return ProcessEventRequest(_connectionManager);
- }
-
- public object Subscribe(ProcessMediaReceiverRegistrarEventRequest request)
- {
- return ProcessEventRequest(_mediaReceiverRegistrar);
- }
-
- public object Unsubscribe(ProcessContentDirectoryEventRequest request)
- {
- return ProcessEventRequest(_contentDirectory);
- }
-
- public object Unsubscribe(ProcessConnectionManagerEventRequest request)
- {
- return ProcessEventRequest(_connectionManager);
- }
-
- public object Unsubscribe(ProcessMediaReceiverRegistrarEventRequest request)
- {
- return ProcessEventRequest(_mediaReceiverRegistrar);
- }
-
- private object ProcessEventRequest(IEventManager eventManager)
- {
- var subscriptionId = GetHeader("SID");
-
- if (string.Equals(Request.Verb, "SUBSCRIBE", StringComparison.OrdinalIgnoreCase))
- {
- var notificationType = GetHeader("NT");
-
- var callback = GetHeader("CALLBACK");
- var timeoutString = GetHeader("TIMEOUT");
-
- if (string.IsNullOrEmpty(notificationType))
- {
- return GetSubscriptionResponse(eventManager.RenewEventSubscription(subscriptionId, notificationType, timeoutString, callback));
- }
-
- return GetSubscriptionResponse(eventManager.CreateEventSubscription(notificationType, timeoutString, callback));
- }
-
- return GetSubscriptionResponse(eventManager.CancelEventSubscription(subscriptionId));
- }
-
- private object GetSubscriptionResponse(EventSubscriptionResponse response)
- {
- return ResultFactory.GetResult(response.Content, response.ContentType, response.Headers);
- }
- }
-}
diff --git a/MediaBrowser.Api/Dlna/DlnaService.cs b/MediaBrowser.Api/Dlna/DlnaService.cs
deleted file mode 100644
index 4dd71f4463..0000000000
--- a/MediaBrowser.Api/Dlna/DlnaService.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System.Linq;
-using MediaBrowser.Controller.Dlna;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Services;
-
-namespace MediaBrowser.Api.Dlna
-{
- [Route("/Dlna/ProfileInfos", "GET", Summary = "Gets a list of profiles")]
- public class GetProfileInfos : IReturn<DeviceProfileInfo[]>
- {
- }
-
- [Route("/Dlna/Profiles/{Id}", "DELETE", Summary = "Deletes a profile")]
- public class DeleteProfile : IReturnVoid
- {
- [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
- }
-
- [Route("/Dlna/Profiles/Default", "GET", Summary = "Gets the default profile")]
- public class GetDefaultProfile : IReturn<DeviceProfile>
- {
- }
-
- [Route("/Dlna/Profiles/{Id}", "GET", Summary = "Gets a single profile")]
- public class GetProfile : IReturn<DeviceProfile>
- {
- [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/Dlna/Profiles/{Id}", "POST", Summary = "Updates a profile")]
- public class UpdateProfile : DeviceProfile, IReturnVoid
- {
- }
-
- [Route("/Dlna/Profiles", "POST", Summary = "Creates a profile")]
- public class CreateProfile : DeviceProfile, IReturnVoid
- {
- }
-
- [Authenticated(Roles = "Admin")]
- public class DlnaService : BaseApiService
- {
- private readonly IDlnaManager _dlnaManager;
-
- public DlnaService(IDlnaManager dlnaManager)
- {
- _dlnaManager = dlnaManager;
- }
-
- public object Get(GetProfileInfos request)
- {
- var result = _dlnaManager.GetProfileInfos().ToArray();
-
- return ToOptimizedResult(result);
- }
-
- public object Get(GetProfile request)
- {
- var result = _dlnaManager.GetProfile(request.Id);
-
- return ToOptimizedResult(result);
- }
-
- public object Get(GetDefaultProfile request)
- {
- var result = _dlnaManager.GetDefaultProfile();
-
- return ToOptimizedResult(result);
- }
-
- public void Delete(DeleteProfile request)
- {
- _dlnaManager.DeleteProfile(request.Id);
- }
-
- public void Post(UpdateProfile request)
- {
- _dlnaManager.UpdateProfile(request);
- }
-
- public void Post(CreateProfile request)
- {
- _dlnaManager.CreateProfile(request);
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs
index 400169ac55..ea3920d38d 100644
--- a/MediaBrowser.Api/EnvironmentService.cs
+++ b/MediaBrowser.Api/EnvironmentService.cs
@@ -36,18 +36,6 @@ namespace MediaBrowser.Api
/// <value><c>true</c> if [include directories]; otherwise, <c>false</c>.</value>
[ApiMember(Name = "IncludeDirectories", Description = "An optional filter to include or exclude folders from the results. true/false", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
public bool IncludeDirectories { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether [include hidden].
- /// </summary>
- /// <value><c>true</c> if [include hidden]; otherwise, <c>false</c>.</value>
- [ApiMember(Name = "IncludeHidden", Description = "An optional filter to include or exclude hidden files and folders. true/false", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
- public bool IncludeHidden { get; set; }
-
- public GetDirectoryContents()
- {
- IncludeHidden = true;
- }
}
[Route("/Environment/ValidatePath", "POST", Summary = "Gets the contents of a given directory in the file system")]
@@ -189,18 +177,7 @@ namespace MediaBrowser.Api
{
var result = new DefaultDirectoryBrowserInfo();
- try
- {
- var qnap = "/share/CACHEDEV1_DATA";
- if (_fileSystem.DirectoryExists(qnap))
- {
- result.Path = qnap;
- }
- }
- catch
- {
-
- }
+ result.Path = _fileSystem.DefaultDirectory;
return ToOptimizedResult(result);
}
@@ -223,10 +200,10 @@ namespace MediaBrowser.Api
if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf(UncSeparator) == 1)
{
- return ToOptimizedSerializedResultUsingCache(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
+ return ToOptimizedResult(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
}
- return ToOptimizedSerializedResultUsingCache(GetFileSystemEntries(request).ToList());
+ return ToOptimizedResult(GetFileSystemEntries(request).ToList());
}
public object Get(GetNetworkShares request)
@@ -235,7 +212,7 @@ namespace MediaBrowser.Api
var shares = GetNetworkShares(path).OrderBy(i => i.Path).ToList();
- return ToOptimizedSerializedResultUsingCache(shares);
+ return ToOptimizedResult(shares);
}
/// <summary>
@@ -247,7 +224,7 @@ namespace MediaBrowser.Api
{
var result = GetDrives().ToList();
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -273,7 +250,7 @@ namespace MediaBrowser.Api
{
var result = _networkManager.GetNetworkDevices().ToList();
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -300,11 +277,6 @@ namespace MediaBrowser.Api
{
var entries = _fileSystem.GetFileSystemEntries(request.Path).OrderBy(i => i.FullName).Where(i =>
{
- if (!request.IncludeHidden && i.IsHidden)
- {
- return false;
- }
-
var isDirectory = i.IsDirectory;
if (!request.IncludeFiles && !isDirectory)
diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs
index 585e9c49bc..59e203b7f7 100644
--- a/MediaBrowser.Api/FilterService.cs
+++ b/MediaBrowser.Api/FilterService.cs
@@ -19,7 +19,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ParentId { get; set; }
@@ -49,7 +49,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ParentId { get; set; }
@@ -76,6 +76,7 @@ namespace MediaBrowser.Api
public bool? IsKids { get; set; }
public bool? IsNews { get; set; }
public bool? IsSeries { get; set; }
+ public bool? Recursive { get; set; }
}
[Authenticated]
@@ -93,7 +94,7 @@ namespace MediaBrowser.Api
public object Get(GetQueryFilters request)
{
var parentItem = string.IsNullOrEmpty(request.ParentId) ? null : _libraryManager.GetItemById(request.ParentId);
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase) ||
@@ -107,7 +108,6 @@ namespace MediaBrowser.Api
var genreQuery = new InternalItemsQuery(user)
{
- AncestorIds = parentItem == null ? new string[] { } : new string[] { parentItem.Id.ToString("N") },
IncludeItemTypes = request.GetIncludeItemTypes(),
DtoOptions = new Controller.Dto.DtoOptions
{
@@ -123,34 +123,44 @@ namespace MediaBrowser.Api
IsSeries = request.IsSeries
};
+ // Non recursive not yet supported for library folders
+ if ((request.Recursive ?? true) || parentItem is UserView || parentItem is ICollectionFolder)
+ {
+ genreQuery.AncestorIds = parentItem == null ? Array.Empty<Guid>() : new Guid[] { parentItem.Id };
+ }
+ else
+ {
+ genreQuery.Parent = parentItem;
+ }
+
if (string.Equals(request.IncludeItemTypes, "MusicAlbum", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.IncludeItemTypes, "MusicVideo", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.IncludeItemTypes, "MusicArtist", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.IncludeItemTypes, "Audio", StringComparison.OrdinalIgnoreCase))
{
- filters.Genres = _libraryManager.GetMusicGenres(genreQuery).Items.Select(i => new NameIdPair
+ filters.Genres = _libraryManager.GetMusicGenres(genreQuery).Items.Select(i => new NameGuidPair
{
Name = i.Item1.Name,
- Id = i.Item1.Id.ToString("N")
+ Id = i.Item1.Id
}).ToArray();
}
else if (string.Equals(request.IncludeItemTypes, "Game", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.IncludeItemTypes, "GameSystem", StringComparison.OrdinalIgnoreCase))
{
- filters.Genres = _libraryManager.GetGameGenres(genreQuery).Items.Select(i => new NameIdPair
+ filters.Genres = _libraryManager.GetGameGenres(genreQuery).Items.Select(i => new NameGuidPair
{
Name = i.Item1.Name,
- Id = i.Item1.Id.ToString("N")
+ Id = i.Item1.Id
}).ToArray();
}
else
{
- filters.Genres = _libraryManager.GetGenres(genreQuery).Items.Select(i => new NameIdPair
+ filters.Genres = _libraryManager.GetGenres(genreQuery).Items.Select(i => new NameGuidPair
{
Name = i.Item1.Name,
- Id = i.Item1.Id.ToString("N")
+ Id = i.Item1.Id
}).ToArray();
}
@@ -161,7 +171,7 @@ namespace MediaBrowser.Api
public object Get(GetQueryFiltersLegacy request)
{
var parentItem = string.IsNullOrEmpty(request.ParentId) ? null : _libraryManager.GetItemById(request.ParentId);
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase) ||
@@ -172,7 +182,7 @@ namespace MediaBrowser.Api
}
var item = string.IsNullOrEmpty(request.ParentId) ?
- user == null ? _libraryManager.RootFolder : user.RootFolder :
+ user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder() :
parentItem;
var result = ((Folder)item).GetItemList(GetItemsQuery(request, user));
diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs
index 6c48b732f6..3e4e205067 100644
--- a/MediaBrowser.Api/GamesService.cs
+++ b/MediaBrowser.Api/GamesService.cs
@@ -17,14 +17,6 @@ using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api
{
/// <summary>
- /// Class GetSimilarGames
- /// </summary>
- [Route("/Games/{Id}/Similar", "GET", Summary = "Finds games similar to a given game.")]
- public class GetSimilarGames : BaseGetSimilarItemsFromItem
- {
- }
-
- /// <summary>
/// Class GetGameSystemSummaries
/// </summary>
[Route("/Games/SystemSummaries", "GET", Summary = "Finds games similar to a given game.")]
@@ -35,7 +27,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -109,11 +101,9 @@ namespace MediaBrowser.Api
.Select(i => GetSummary(i, user))
.ToArray();
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
- private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
/// <summary>
/// Gets the summary.
/// </summary>
@@ -151,51 +141,5 @@ namespace MediaBrowser.Api
return summary;
}
-
- /// <summary>
- /// Gets the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>System.Object.</returns>
- public object Get(GetSimilarGames request)
- {
- var result = GetSimilarItemsResult(request);
-
- return ToOptimizedSerializedResultUsingCache(result);
- }
-
- private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
- {
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
-
- var item = string.IsNullOrEmpty(request.Id) ?
- (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
- _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
-
- var dtoOptions = GetDtoOptions(_authContext, request);
-
- var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
- {
- Limit = request.Limit,
- IncludeItemTypes = new[]
- {
- typeof(Game).Name
- },
- SimilarTo = item,
- DtoOptions = dtoOptions
-
- });
-
- var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
-
- var result = new QueryResult<BaseItemDto>
- {
- Items = returnList,
-
- TotalRecordCount = itemsResult.Count
- };
-
- return result;
- }
}
}
diff --git a/MediaBrowser.Api/Images/ImageRequest.cs b/MediaBrowser.Api/Images/ImageRequest.cs
index b61c81972c..d4c01fdb02 100644
--- a/MediaBrowser.Api/Images/ImageRequest.cs
+++ b/MediaBrowser.Api/Images/ImageRequest.cs
@@ -87,18 +87,14 @@ namespace MediaBrowser.Api.Images
/// Gets or sets the type of the image.
/// </summary>
/// <value>The type of the image.</value>
- [ApiMember(Name = "Type", Description = "Image Type", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- [ApiMember(Name = "Type", Description = "Image Type", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- [ApiMember(Name = "Type", Description = "Image Type", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
+ [ApiMember(Name = "Type", Description = "Image Type", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET,POST,DELETE")]
public ImageType Type { get; set; }
/// <summary>
/// Gets or sets the index.
/// </summary>
/// <value>The index.</value>
- [ApiMember(Name = "Index", Description = "Image Index", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
- [ApiMember(Name = "Index", Description = "Image Index", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "POST")]
- [ApiMember(Name = "Index", Description = "Image Index", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "DELETE")]
+ [ApiMember(Name = "Index", Description = "Image Index", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET,POST,DELETE")]
public int? Index { get; set; }
}
}
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 2b8ac1a667..c3b2e82e7c 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -50,8 +50,8 @@ namespace MediaBrowser.Api.Images
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path")]
+ public Guid Id { get; set; }
}
/// <summary>
@@ -65,7 +65,7 @@ namespace MediaBrowser.Api.Images
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
/// <summary>
@@ -86,7 +86,7 @@ namespace MediaBrowser.Api.Images
/// Gets or sets the new index.
/// </summary>
/// <value>The new index.</value>
- [ApiMember(Name = "NewIndex", Description = "The new image index", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [ApiMember(Name = "NewIndex", Description = "The new image index", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public int NewIndex { get; set; }
}
@@ -105,8 +105,8 @@ namespace MediaBrowser.Api.Images
[Route("/Persons/{Name}/Images/{Type}/{Index}", "GET")]
[Route("/Studios/{Name}/Images/{Type}", "GET")]
[Route("/Studios/{Name}/Images/{Type}/{Index}", "GET")]
- [Route("/Years/{Year}/Images/{Type}", "GET")]
- [Route("/Years/{Year}/Images/{Type}/{Index}", "GET")]
+ ////[Route("/Years/{Year}/Images/{Type}", "GET")]
+ ////[Route("/Years/{Year}/Images/{Type}/{Index}", "GET")]
[Route("/Artists/{Name}/Images/{Type}", "HEAD")]
[Route("/Artists/{Name}/Images/{Type}/{Index}", "HEAD")]
[Route("/Genres/{Name}/Images/{Type}", "HEAD")]
@@ -119,8 +119,8 @@ namespace MediaBrowser.Api.Images
[Route("/Persons/{Name}/Images/{Type}/{Index}", "HEAD")]
[Route("/Studios/{Name}/Images/{Type}", "HEAD")]
[Route("/Studios/{Name}/Images/{Type}/{Index}", "HEAD")]
- [Route("/Years/{Year}/Images/{Type}", "HEAD")]
- [Route("/Years/{Year}/Images/{Type}/{Index}", "HEAD")]
+ ////[Route("/Years/{Year}/Images/{Type}", "HEAD")]
+ ////[Route("/Years/{Year}/Images/{Type}/{Index}", "HEAD")]
public class GetItemByNameImage : ImageRequest
{
/// <summary>
@@ -145,7 +145,7 @@ namespace MediaBrowser.Api.Images
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -177,7 +177,7 @@ namespace MediaBrowser.Api.Images
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -265,7 +265,7 @@ namespace MediaBrowser.Api.Images
var result = GetItemImageInfos(item);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -373,11 +373,7 @@ namespace MediaBrowser.Api.Images
/// <returns>System.Object.</returns>
public object Get(GetItemImage request)
{
- var item = string.IsNullOrEmpty(request.Id) ?
- _libraryManager.RootFolder :
- _libraryManager.GetItemById(request.Id);
-
- return GetImage(request, item, false);
+ return GetImage(request, request.Id, null, false);
}
/// <summary>
@@ -387,11 +383,7 @@ namespace MediaBrowser.Api.Images
/// <returns>System.Object.</returns>
public object Head(GetItemImage request)
{
- var item = string.IsNullOrEmpty(request.Id) ?
- _libraryManager.RootFolder :
- _libraryManager.GetItemById(request.Id);
-
- return GetImage(request, item, true);
+ return GetImage(request, request.Id, null, true);
}
/// <summary>
@@ -403,14 +395,14 @@ namespace MediaBrowser.Api.Images
{
var item = _userManager.GetUserById(request.Id);
- return GetImage(request, item, false);
+ return GetImage(request, Guid.Empty, item, false);
}
public object Head(GetUserImage request)
{
var item = _userManager.GetUserById(request.Id);
- return GetImage(request, item, true);
+ return GetImage(request, Guid.Empty, item, true);
}
public object Get(GetItemByNameImage request)
@@ -419,7 +411,7 @@ namespace MediaBrowser.Api.Images
var item = GetItemByName(request.Name, type, _libraryManager, new DtoOptions(false));
- return GetImage(request, item, false);
+ return GetImage(request, item.Id, item, false);
}
public object Head(GetItemByNameImage request)
@@ -428,32 +420,30 @@ namespace MediaBrowser.Api.Images
var item = GetItemByName(request.Name, type, _libraryManager, new DtoOptions(false));
- return GetImage(request, item, true);
+ return GetImage(request, item.Id, item, true);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(PostUserImage request)
+ public Task Post(PostUserImage request)
{
var userId = GetPathValue(1);
- AssertCanUpdateUser(_authContext, _userManager, userId, true);
+ AssertCanUpdateUser(_authContext, _userManager, new Guid(userId), true);
request.Type = (ImageType)Enum.Parse(typeof(ImageType), GetPathValue(3), true);
var item = _userManager.GetUserById(userId);
- var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType);
-
- Task.WaitAll(task);
+ return PostImage(item, request.RequestStream, request.Type, Request.ContentType);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(PostItemImage request)
+ public Task Post(PostItemImage request)
{
var id = GetPathValue(1);
@@ -461,9 +451,7 @@ namespace MediaBrowser.Api.Images
var item = _libraryManager.GetItemById(id);
- var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType);
-
- Task.WaitAll(task);
+ return PostImage(item, request.RequestStream, request.Type, Request.ContentType);
}
/// <summary>
@@ -510,7 +498,7 @@ namespace MediaBrowser.Api.Images
/// <param name="currentIndex">Index of the current.</param>
/// <param name="newIndex">The new index.</param>
/// <returns>Task.</returns>
- private void UpdateItemIndex(IHasMetadata item, ImageType type, int currentIndex, int newIndex)
+ private void UpdateItemIndex(BaseItem item, ImageType type, int currentIndex, int newIndex)
{
item.SwapImages(type, currentIndex, newIndex);
}
@@ -523,7 +511,7 @@ namespace MediaBrowser.Api.Images
/// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
/// <returns>System.Object.</returns>
/// <exception cref="ResourceNotFoundException"></exception>
- public Task<object> GetImage(ImageRequest request, IHasMetadata item, bool isHeadRequest)
+ public Task<object> GetImage(ImageRequest request, Guid itemId, BaseItem item, bool isHeadRequest)
{
if (request.PercentPlayed.HasValue)
{
@@ -549,18 +537,42 @@ namespace MediaBrowser.Api.Images
}
}
+ if (item == null)
+ {
+ item = _libraryManager.GetItemById(itemId);
+
+ if (item == null)
+ {
+ throw new ResourceNotFoundException(string.Format("Item {0} not found.", itemId.ToString("N")));
+ }
+ }
+
var imageInfo = GetImageInfo(request, item);
if (imageInfo == null)
{
- throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", item.Name, request.Type));
+ 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));
}
- var supportedImageEnhancers = request.EnableImageEnhancers ? _imageProcessor.GetSupportedEnhancers(item, request.Type) : new List<IImageEnhancer>();
+ IImageEnhancer[] supportedImageEnhancers;
+
+ if (_imageProcessor.ImageEnhancers.Length > 0)
+ {
+ if (item == null)
+ {
+ item = _libraryManager.GetItemById(itemId);
+ }
+
+ supportedImageEnhancers = request.EnableImageEnhancers ? _imageProcessor.GetSupportedEnhancers(item, request.Type) : Array.Empty<IImageEnhancer>();
+ }
+ else
+ {
+ supportedImageEnhancers = Array.Empty<IImageEnhancer>();
+ }
var cropwhitespace = request.Type == ImageType.Logo ||
- request.Type == ImageType.Art
- || (request.Type == ImageType.Primary && item is LiveTvChannel);
+ request.Type == ImageType.Art;
if (request.CropWhitespace.HasValue)
{
@@ -583,6 +595,7 @@ namespace MediaBrowser.Api.Images
};
return GetImageResult(item,
+ itemId,
request,
imageInfo,
cropwhitespace,
@@ -593,12 +606,13 @@ namespace MediaBrowser.Api.Images
isHeadRequest);
}
- private async Task<object> GetImageResult(IHasMetadata item,
+ private async Task<object> GetImageResult(BaseItem item,
+ Guid itemId,
ImageRequest request,
ItemImageInfo image,
bool cropwhitespace,
ImageFormat[] supportedFormats,
- List<IImageEnhancer> enhancers,
+ IImageEnhancer[] enhancers,
TimeSpan? cacheDuration,
IDictionary<string, string> headers,
bool isHeadRequest)
@@ -611,8 +625,7 @@ namespace MediaBrowser.Api.Images
ImageIndex = request.Index ?? 0,
Image = image,
Item = item,
- ItemId = item.Id.ToString("N"),
- ItemType = item.GetType().Name,
+ ItemId = itemId,
MaxHeight = request.MaxHeight,
MaxWidth = request.MaxWidth,
Quality = request.Quality ?? 100,
@@ -660,21 +673,15 @@ namespace MediaBrowser.Api.Images
private ImageFormat[] GetClientSupportedFormats()
{
- //Logger.Debug("Request types: {0}", string.Join(",", Request.AcceptTypes ?? new string[] { }));
- var supportsWebP = (Request.AcceptTypes ?? new string[] { }).Contains("image/webp", StringComparer.OrdinalIgnoreCase);
+ //Logger.Debug("Request types: {0}", string.Join(",", Request.AcceptTypes ?? Array.Empty<string>()));
+ var supportedFormats = (Request.AcceptTypes ?? Array.Empty<string>()).Select(i => i.Split(';')[0]).ToArray();
+ var acceptParam = Request.QueryString["accept"];
- var userAgent = Request.UserAgent ?? string.Empty;
-
- if (!supportsWebP)
- {
- if (string.Equals(Request.QueryString["accept"], "webp", StringComparison.OrdinalIgnoreCase))
- {
- supportsWebP = true;
- }
- }
+ var supportsWebP = SupportsFormat(supportedFormats, acceptParam, "webp", false);
if (!supportsWebP)
{
+ var userAgent = Request.UserAgent ?? string.Empty;
if (userAgent.IndexOf("crosswalk", StringComparison.OrdinalIgnoreCase) != -1 &&
userAgent.IndexOf("android", StringComparison.OrdinalIgnoreCase) != -1)
{
@@ -682,16 +689,39 @@ namespace MediaBrowser.Api.Images
}
}
+ var formats = new List<ImageFormat>(4);
+
if (supportsWebP)
{
- // Not displaying properly on iOS
- if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) == -1)
- {
- return new[] { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
- }
+ formats.Add(ImageFormat.Webp);
+ }
+
+ formats.Add(ImageFormat.Jpg);
+ formats.Add(ImageFormat.Png);
+
+ if (SupportsFormat(supportedFormats, acceptParam, "gif", true))
+ {
+ formats.Add(ImageFormat.Gif);
+ }
+
+ return formats.ToArray();
+ }
+
+ private bool SupportsFormat(string[] requestAcceptTypes, string acceptParam, string format, bool acceptAll)
+ {
+ var mimeType = "image/" + format;
+
+ if (requestAcceptTypes.Contains(mimeType))
+ {
+ return true;
+ }
+
+ if (acceptAll && requestAcceptTypes.Contains("*/*"))
+ {
+ return true;
}
- return new[] { ImageFormat.Jpg, ImageFormat.Png };
+ return string.Equals(Request.QueryString["accept"], format, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
@@ -700,7 +730,7 @@ 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, IHasMetadata item)
+ private ItemImageInfo GetImageInfo(ImageRequest request, BaseItem item)
{
var index = request.Index ?? 0;
diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs
index 4782d76dfc..8d75ec10c7 100644
--- a/MediaBrowser.Api/Images/RemoteImageService.cs
+++ b/MediaBrowser.Api/Images/RemoteImageService.cs
@@ -73,13 +73,13 @@ namespace MediaBrowser.Api.Images
public class BaseDownloadRemoteImage : IReturnVoid
{
- [ApiMember(Name = "Type", Description = "The image type", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [ApiMember(Name = "Type", Description = "The image type", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public ImageType Type { get; set; }
- [ApiMember(Name = "ProviderName", Description = "The image provider", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [ApiMember(Name = "ProviderName", Description = "The image provider", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public string ProviderName { get; set; }
- [ApiMember(Name = "ImageUrl", Description = "The image url", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [ApiMember(Name = "ImageUrl", Description = "The image url", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public string ImageUrl { get; set; }
}
@@ -91,7 +91,7 @@ namespace MediaBrowser.Api.Images
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string Id { get; set; }
}
@@ -129,7 +129,7 @@ namespace MediaBrowser.Api.Images
var result = GetImageProviders(item);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
private List<ImageProviderInfo> GetImageProviders(BaseItem item)
@@ -188,13 +188,11 @@ namespace MediaBrowser.Api.Images
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(DownloadRemoteImage request)
+ public Task Post(DownloadRemoteImage request)
{
var item = _libraryManager.GetItemById(request.Id);
- var task = DownloadRemoteImage(item, request);
-
- Task.WaitAll(task);
+ return DownloadRemoteImage(item, request);
}
/// <summary>
@@ -215,12 +213,7 @@ namespace MediaBrowser.Api.Images
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Get(GetRemoteImage request)
- {
- return GetAsync(request).Result;
- }
-
- public async Task<object> GetAsync(GetRemoteImage request)
+ public async Task<object> Get(GetRemoteImage request)
{
var urlHash = request.ImageUrl.GetMD5();
var pointerCachePath = GetFullCachePath(urlHash.ToString());
diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs
index a454642a42..39a7904866 100644
--- a/MediaBrowser.Api/ItemLookupService.cs
+++ b/MediaBrowser.Api/ItemLookupService.cs
@@ -29,7 +29,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
[Route("/Items/RemoteSearch/Movie", "POST")]
@@ -44,9 +44,9 @@ namespace MediaBrowser.Api
{
}
- [Route("/Items/RemoteSearch/AdultVideo", "POST")]
+ [Route("/Items/RemoteSearch/MusicVideo", "POST")]
[Authenticated]
- public class GetAdultVideoRemoteSearchResults : RemoteSearchQuery<ItemLookupInfo>, IReturn<List<RemoteSearchResult>>
+ public class GetMusicVideoRemoteSearchResults : RemoteSearchQuery<MusicVideoInfo>, IReturn<List<RemoteSearchResult>>
{
}
@@ -186,6 +186,13 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
+ public async Task<object> Post(GetMusicVideoRemoteSearchResults request)
+ {
+ var result = await _providerManager.GetRemoteSearchResults<MusicVideo, MusicVideoInfo>(request, CancellationToken.None).ConfigureAwait(false);
+
+ return ToOptimizedResult(result);
+ }
+
public async Task<object> Post(GetPersonRemoteSearchResults request)
{
var result = await _providerManager.GetRemoteSearchResults<Person, PersonLookupInfo>(request, CancellationToken.None).ConfigureAwait(false);
@@ -212,7 +219,7 @@ namespace MediaBrowser.Api
return GetRemoteImage(request);
}
- public void Post(ApplySearchCriteria request)
+ public Task Post(ApplySearchCriteria request)
{
var item = _libraryManager.GetItemById(new Guid(request.Id));
@@ -232,17 +239,15 @@ namespace MediaBrowser.Api
//item.ProductionYear = request.ProductionYear;
//item.Name = request.Name;
- var task = _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem)
+ return _providerManager.RefreshFullItem(item, new MetadataRefreshOptions(_fileSystem)
{
MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
- ImageRefreshMode = ImageRefreshMode.FullRefresh,
+ ImageRefreshMode = MetadataRefreshMode.FullRefresh,
ReplaceAllMetadata = true,
ReplaceAllImages = request.ReplaceAllImages,
- SearchResult = request,
- ForceEnableInternetMetadata = true
+ SearchResult = request
}, CancellationToken.None);
- Task.WaitAll(task);
}
/// <summary>
diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs
index d26fb768a3..ab083c207d 100644
--- a/MediaBrowser.Api/ItemRefreshService.cs
+++ b/MediaBrowser.Api/ItemRefreshService.cs
@@ -17,7 +17,7 @@ namespace MediaBrowser.Api
public MetadataRefreshMode MetadataRefreshMode { get; set; }
[ApiMember(Name = "ImageRefreshMode", Description = "Specifies the image refresh mode", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
- public ImageRefreshMode ImageRefreshMode { get; set; }
+ public MetadataRefreshMode ImageRefreshMode { get; set; }
[ApiMember(Name = "ReplaceAllMetadata", Description = "Determines if metadata should be replaced. Only applicable if mode is FullRefresh", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
public bool ReplaceAllMetadata { get; set; }
@@ -73,9 +73,8 @@ namespace MediaBrowser.Api
ImageRefreshMode = request.ImageRefreshMode,
ReplaceAllImages = request.ReplaceAllImages,
ReplaceAllMetadata = request.ReplaceAllMetadata,
- ForceSave = request.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || request.ImageRefreshMode == ImageRefreshMode.FullRefresh || request.ReplaceAllImages || request.ReplaceAllMetadata,
- IsAutomated = false,
- ValidateChildren = request.Recursive
+ ForceSave = request.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || request.ImageRefreshMode == MetadataRefreshMode.FullRefresh || request.ReplaceAllImages || request.ReplaceAllMetadata,
+ IsAutomated = false
};
}
}
diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs
index a55741d7dc..22eb7ea099 100644
--- a/MediaBrowser.Api/ItemUpdateService.cs
+++ b/MediaBrowser.Api/ItemUpdateService.cs
@@ -15,6 +15,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Services;
+using MediaBrowser.Model.IO;
namespace MediaBrowser.Api
{
@@ -36,7 +37,7 @@ namespace MediaBrowser.Api
public class UpdateItemContentType : IReturnVoid
{
[ApiMember(Name = "ItemId", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string ItemId { get; set; }
+ public Guid ItemId { get; set; }
[ApiMember(Name = "ContentType", Description = "The content type of the item", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string ContentType { get; set; }
@@ -49,13 +50,15 @@ namespace MediaBrowser.Api
private readonly IProviderManager _providerManager;
private readonly ILocalizationManager _localizationManager;
private readonly IServerConfigurationManager _config;
+ private readonly IFileSystem _fileSystem;
- public ItemUpdateService(ILibraryManager libraryManager, IProviderManager providerManager, ILocalizationManager localizationManager, IServerConfigurationManager config)
+ public ItemUpdateService(IFileSystem fileSystem, ILibraryManager libraryManager, IProviderManager providerManager, ILocalizationManager localizationManager, IServerConfigurationManager config)
{
_libraryManager = libraryManager;
_providerManager = providerManager;
_localizationManager = localizationManager;
_config = config;
+ _fileSystem = fileSystem;
}
public object Get(GetMetadataEditorInfo request)
@@ -199,6 +202,9 @@ namespace MediaBrowser.Api
var newLockData = request.LockData ?? false;
var isLockedChanged = item.IsLocked != newLockData;
+ var series = item as Series;
+ var displayOrderChanged = series != null && !string.Equals(series.DisplayOrder ?? string.Empty, request.DisplayOrder ?? string.Empty, StringComparison.OrdinalIgnoreCase);
+
// Do this first so that metadata savers can pull the updates from the database.
if (request.People != null)
{
@@ -221,6 +227,17 @@ namespace MediaBrowser.Api
child.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
}
}
+
+ if (displayOrderChanged)
+ {
+ _providerManager.QueueRefresh(series.Id, new MetadataRefreshOptions(_fileSystem)
+ {
+ MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
+ ImageRefreshMode = MetadataRefreshMode.FullRefresh,
+ ReplaceAllMetadata = true
+
+ }, RefreshPriority.High);
+ }
}
private DateTime NormalizeDateTime(DateTime val)
@@ -238,7 +255,6 @@ namespace MediaBrowser.Api
item.CriticRating = request.CriticRating;
item.CommunityRating = request.CommunityRating;
- item.HomePageUrl = request.HomePageUrl;
item.IndexNumber = request.IndexNumber;
item.ParentIndexNumber = request.ParentIndexNumber;
item.Overview = request.Overview;
@@ -247,12 +263,9 @@ namespace MediaBrowser.Api
var episode = item as Episode;
if (episode != null)
{
- episode.DvdSeasonNumber = request.DvdSeasonNumber;
- episode.DvdEpisodeNumber = request.DvdEpisodeNumber;
episode.AirsAfterSeasonNumber = request.AirsAfterSeasonNumber;
episode.AirsBeforeEpisodeNumber = request.AirsBeforeEpisodeNumber;
episode.AirsBeforeSeasonNumber = request.AirsBeforeSeasonNumber;
- episode.AbsoluteEpisodeNumber = request.AbsoluteEpisodeNumber;
}
item.Tags = request.Tags;
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index a036a00a6e..cc8c1251fe 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -30,6 +30,8 @@ using MediaBrowser.Model.Services;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Progress;
using MediaBrowser.Model.Extensions;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Api.Library
{
@@ -50,7 +52,7 @@ namespace MediaBrowser.Api.Library
/// </summary>
[Route("/Items/{Id}/CriticReviews", "GET", Summary = "Gets critic reviews for an item")]
[Authenticated]
- public class GetCriticReviews : IReturn<QueryResult<ItemReview>>
+ public class GetCriticReviews : IReturn<QueryResult<BaseItemDto>>
{
/// <summary>
/// Gets or sets the id.
@@ -86,7 +88,7 @@ namespace MediaBrowser.Api.Library
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -111,7 +113,7 @@ namespace MediaBrowser.Api.Library
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -136,7 +138,7 @@ namespace MediaBrowser.Api.Library
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -167,7 +169,7 @@ namespace MediaBrowser.Api.Library
[Authenticated]
public class DeleteItems : IReturnVoid
{
- [ApiMember(Name = "Ids", Description = "Ids", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
+ [ApiMember(Name = "Ids", Description = "Ids", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
public string Ids { get; set; }
}
@@ -176,7 +178,7 @@ namespace MediaBrowser.Api.Library
public class GetItemCounts : IReturn<ItemCounts>
{
[ApiMember(Name = "UserId", Description = "Optional. Get counts from a specific user's library.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
[ApiMember(Name = "IsFavorite", Description = "Optional. Get counts of favorite items", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsFavorite { get; set; }
@@ -191,7 +193,7 @@ namespace MediaBrowser.Api.Library
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -201,21 +203,6 @@ namespace MediaBrowser.Api.Library
public string Id { get; set; }
}
- [Route("/Items/YearIndex", "GET", Summary = "Gets a year index based on an item query.")]
- [Authenticated]
- public class GetYearIndex : IReturn<List<ItemIndex>>
- {
- /// <summary>
- /// Gets or sets the user id.
- /// </summary>
- /// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
-
- [ApiMember(Name = "IncludeItemTypes", Description = "Optional. If specified, results will be filtered based on item type. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
- public string IncludeItemTypes { get; set; }
- }
-
/// <summary>
/// Class GetPhyscialPaths
/// </summary>
@@ -238,7 +225,7 @@ namespace MediaBrowser.Api.Library
[Authenticated]
public class PostUpdatedSeries : IReturnVoid
{
- [ApiMember(Name = "TvdbId", Description = "Tvdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "TvdbId", Description = "Tvdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "POST")]
public string TvdbId { get; set; }
}
@@ -247,12 +234,28 @@ namespace MediaBrowser.Api.Library
[Authenticated]
public class PostUpdatedMovies : IReturnVoid
{
- [ApiMember(Name = "TmdbId", Description = "Tmdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "TmdbId", Description = "Tmdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "POST")]
public string TmdbId { get; set; }
- [ApiMember(Name = "ImdbId", Description = "Imdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "ImdbId", Description = "Imdb Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "POST")]
public string ImdbId { get; set; }
}
+ public class MediaUpdateInfo
+ {
+ public string Path { get; set; }
+
+ // Created, Modified, Deleted
+ public string UpdateType { get; set; }
+ }
+
+ [Route("/Library/Media/Updated", "POST", Summary = "Reports that new movies have been added by an external source")]
+ [Authenticated]
+ public class PostUpdatedMedia : IReturnVoid
+ {
+ [ApiMember(Name = "Updates", Description = "A list of updated media paths", IsRequired = false, DataType = "string", ParameterType = "body", Verb = "POST")]
+ public List<MediaUpdateInfo> Updates { get; set; }
+ }
+
[Route("/Items/{Id}/Download", "GET", Summary = "Downloads item media")]
[Authenticated(Roles = "download")]
public class GetDownload
@@ -265,12 +268,49 @@ namespace MediaBrowser.Api.Library
public string Id { get; set; }
}
+ [Route("/Games/{Id}/Similar", "GET", Summary = "Finds games similar to a given game.")]
+ [Route("/Artists/{Id}/Similar", "GET", Summary = "Finds albums similar to a given album.")]
[Route("/Items/{Id}/Similar", "GET", Summary = "Gets similar items")]
+ [Route("/Albums/{Id}/Similar", "GET", Summary = "Finds albums similar to a given album.")]
+ [Route("/Shows/{Id}/Similar", "GET", Summary = "Finds tv shows similar to a given one.")]
+ [Route("/Movies/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given movie.")]
+ [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
[Authenticated]
public class GetSimilarItems : BaseGetSimilarItemsFromItem
{
}
+ [Route("/Libraries/AvailableOptions", "GET")]
+ [Authenticated(AllowBeforeStartupWizard = true)]
+ 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
/// </summary>
@@ -294,11 +334,12 @@ namespace MediaBrowser.Api.Library
private readonly ILibraryMonitor _libraryMonitor;
private readonly IFileSystem _fileSystem;
private readonly IServerConfigurationManager _config;
+ private readonly IProviderManager _providerManager;
/// <summary>
/// Initializes a new instance of the <see cref="LibraryService" /> class.
/// </summary>
- public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager,
+ public LibraryService(IProviderManager providerManager, IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager,
IDtoService dtoService, IUserDataManager userDataManager, IAuthorizationContext authContext, IActivityManager activityManager, ILocalizationManager localization, ILiveTvManager liveTv, ITVSeriesManager tvManager, ILibraryMonitor libraryMonitor, IFileSystem fileSystem, IServerConfigurationManager config)
{
_itemRepo = itemRepo;
@@ -314,63 +355,287 @@ namespace MediaBrowser.Api.Library
_libraryMonitor = libraryMonitor;
_fileSystem = fileSystem;
_config = config;
+ _providerManager = providerManager;
}
- public object Get(GetSimilarItems request)
+ private string[] GetRepresentativeItemTypes(string contentType)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ switch (contentType)
+ {
+ case CollectionType.BoxSets:
+ return new string[] { "BoxSet" };
+ case CollectionType.Playlists:
+ return new string[] { "Playlist" };
+ case CollectionType.Movies:
+ return new string[] { "Movie" };
+ case CollectionType.TvShows:
+ return new string[] { "Series", "Season", "Episode" };
+ case CollectionType.Books:
+ return new string[] { "Book" };
+ case CollectionType.Games:
+ return new string[] { "Game", "GameSystem" };
+ case CollectionType.Music:
+ return new string[] { "MusicAlbum", "MusicArtist", "Audio", "MusicVideo" };
+ case CollectionType.HomeVideos:
+ case CollectionType.Photos:
+ return new string[] { "Video", "Photo" };
+ case CollectionType.MusicVideos:
+ return new string[] { "MusicVideo" };
+ default:
+ return new string[] { "Series", "Season", "Episode", "Movie" };
+ }
+ }
- var item = string.IsNullOrEmpty(request.Id) ?
- (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
- _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
+ private bool IsSaverEnabledByDefault(string name, string[] itemTypes, bool isNewLibrary)
+ {
+ if (isNewLibrary)
+ {
+ return false;
+ }
- if (item is Game)
+ var metadataOptions = _config.Configuration.MetadataOptions
+ .Where(i => itemTypes.Contains(i.ItemType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
+ .ToArray();
+
+ if (metadataOptions.Length == 0)
{
- return new GamesService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _authContext)
- {
- Request = Request,
+ return true;
+ }
- }.Get(new GetSimilarGames
+ return metadataOptions.Any(i => !i.DisabledMetadataSavers.Contains(name, StringComparer.OrdinalIgnoreCase));
+ }
+
+ private bool IsMetadataFetcherEnabledByDefault(string name, string type, bool isNewLibrary)
+ {
+ if (isNewLibrary)
+ {
+ if (string.Equals(name, "TheMovieDb", StringComparison.OrdinalIgnoreCase))
{
- Fields = request.Fields,
- Id = request.Id,
- Limit = request.Limit,
- UserId = request.UserId,
- ImageTypeLimit = request.ImageTypeLimit
- });
+ if (string.Equals(type, "Series", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ if (string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ return true;
+ }
+ else if (string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ else if (string.Equals(name, "The Open Movie Database", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ else if (string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ else if (string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ var metadataOptions = _config.Configuration.MetadataOptions
+ .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
+ .ToArray();
+
+ if (metadataOptions.Length == 0)
+ {
+ return true;
}
- if (item is MusicAlbum)
+
+ return metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparer.OrdinalIgnoreCase));
+ }
+
+ private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary)
+ {
+ if (isNewLibrary)
{
- return new AlbumsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _authContext)
+ if (string.Equals(name, "TheMovieDb", StringComparison.OrdinalIgnoreCase))
{
- Request = Request,
-
- }.Get(new GetSimilarAlbums
+ if (string.Equals(type, "Series", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(type, "Episode", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ return true;
+ }
+ else if (string.Equals(name, "TheTVDB", StringComparison.OrdinalIgnoreCase))
{
- Fields = request.Fields,
- Id = request.Id,
- Limit = request.Limit,
- UserId = request.UserId,
- ExcludeArtistIds = request.ExcludeArtistIds,
- ImageTypeLimit = request.ImageTypeLimit
- });
+ return true;
+ }
+ else if (string.Equals(name, "The Open Movie Database", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ else if (string.Equals(name, "FanArt", StringComparison.OrdinalIgnoreCase))
+ {
+ if (string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ return true;
+ }
+ else if (string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ else if (string.Equals(name, "Emby Designs", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ else if (string.Equals(name, "Screen Grabber", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ else if (string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+
+ return false;
}
- if (item is MusicArtist)
+
+ var metadataOptions = _config.Configuration.MetadataOptions
+ .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
+ .ToArray();
+
+ if (metadataOptions.Length == 0)
{
- return new AlbumsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _authContext)
+ return true;
+ }
+
+ return metadataOptions.Any(i => !i.DisabledImageFetchers.Contains(name, StringComparer.OrdinalIgnoreCase));
+ }
+
+ public object Get(GetLibraryOptionsInfo request)
+ {
+ var result = new LibraryOptionsResult();
+
+ var types = GetRepresentativeItemTypes(request.LibraryContentType);
+ var isNewLibrary = request.IsNewLibrary;
+ var typesList = types.ToList();
+
+ var plugins = _providerManager.GetAllMetadataPlugins()
+ .Where(i => types.Contains(i.ItemType, StringComparer.OrdinalIgnoreCase))
+ .OrderBy(i => typesList.IndexOf(i.ItemType))
+ .ToList();
+
+ result.MetadataSavers = plugins
+ .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.MetadataSaver))
+ .Select(i => new LibraryOptionInfo
{
- Request = Request,
+ Name = i.Name,
+ DefaultEnabled = IsSaverEnabledByDefault(i.Name, types, isNewLibrary)
+ })
+ .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
+ .ToArray();
- }.Get(new GetSimilarArtists
+ result.MetadataReaders = plugins
+ .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.LocalMetadataProvider))
+ .Select(i => new LibraryOptionInfo
{
- Fields = request.Fields,
- Id = request.Id,
- Limit = request.Limit,
- UserId = request.UserId,
- ImageTypeLimit = request.ImageTypeLimit
+ Name = i.Name,
+ DefaultEnabled = true
+ })
+ .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
+ .ToArray();
+
+ result.SubtitleFetchers = plugins
+ .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.SubtitleFetcher))
+ .Select(i => new LibraryOptionInfo
+ {
+ Name = i.Name,
+ DefaultEnabled = true
+ })
+ .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
+ .ToArray();
+
+ var typeOptions = new List<LibraryTypeOptions>();
+
+ foreach (var type in types)
+ {
+ ImageOption[] defaultImageOptions = null;
+ TypeOptions.DefaultImageOptions.TryGetValue(type, out defaultImageOptions);
+
+ typeOptions.Add(new LibraryTypeOptions
+ {
+ Type = type,
+
+ MetadataFetchers = plugins
+ .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
+ .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.MetadataFetcher))
+ .Select(i => new LibraryOptionInfo
+ {
+ Name = i.Name,
+ DefaultEnabled = IsMetadataFetcherEnabledByDefault(i.Name, type, isNewLibrary)
+ })
+ .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
+ .ToArray(),
+
+ ImageFetchers = plugins
+ .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
+ .SelectMany(i => i.Plugins.Where(p => p.Type == MetadataPluginType.ImageFetcher))
+ .Select(i => new LibraryOptionInfo
+ {
+ Name = i.Name,
+ DefaultEnabled = IsImageFetcherEnabledByDefault(i.Name, type, isNewLibrary)
+ })
+ .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase)
+ .ToArray(),
+
+ SupportedImageTypes = plugins
+ .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase))
+ .SelectMany(i => i.SupportedImageTypes ?? Array.Empty<ImageType>())
+ .Distinct()
+ .ToArray(),
+
+ DefaultImageOptions = defaultImageOptions ?? Array.Empty<ImageOption>()
});
}
+ result.TypeOptions = typeOptions.ToArray();
+
+ return result;
+ }
+
+ public object Get(GetSimilarItems request)
+ {
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
+
+ var item = string.IsNullOrEmpty(request.Id) ?
+ (!request.UserId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() :
+ _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
+
var program = item as IHasProgramAttributes;
if (item is Movie || (program != null && program.IsMovie) || item is Trailer)
@@ -379,33 +644,70 @@ namespace MediaBrowser.Api.Library
{
Request = Request,
- }.Get(new GetSimilarMovies
- {
- Fields = request.Fields,
- Id = request.Id,
- Limit = request.Limit,
- UserId = request.UserId,
- ImageTypeLimit = request.ImageTypeLimit
- });
+ }.GetSimilarItemsResult(request);
}
- if (item is Series || (program != null && program.IsSeries))
+ if (program != null && program.IsSeries)
{
- return new TvShowsService(_userManager, _userDataManager, _libraryManager, _itemRepo, _dtoService, _tvManager, _authContext)
- {
- Request = Request,
+ return GetSimilarItemsResult(request, new[] { typeof(Series).Name });
+ }
- }.Get(new GetSimilarShows
- {
- Fields = request.Fields,
- Id = request.Id,
- Limit = request.Limit,
- UserId = request.UserId,
- ImageTypeLimit = request.ImageTypeLimit
- });
+ if (item is Episode || (item is IItemByName && !(item is MusicArtist)))
+ {
+ return new QueryResult<BaseItemDto>();
}
- return new QueryResult<BaseItemDto>();
+ return GetSimilarItemsResult(request, new[] { item.GetType().Name });
+ }
+
+ private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request, string[] includeItemTypes)
+ {
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
+
+ var item = string.IsNullOrEmpty(request.Id) ?
+ (!request.UserId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() :
+ _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
+
+ var dtoOptions = GetDtoOptions(_authContext, request);
+
+ var query = new InternalItemsQuery(user)
+ {
+ Limit = request.Limit,
+ IncludeItemTypes = includeItemTypes,
+ SimilarTo = item,
+ DtoOptions = dtoOptions,
+ EnableTotalRecordCount = false
+ };
+
+ // ExcludeArtistIds
+ if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
+ {
+ query.ExcludeArtistIds = BaseApiService.GetGuids(request.ExcludeArtistIds);
+ }
+
+ List<BaseItem> itemsResult;
+
+ if (item is MusicArtist)
+ {
+ query.IncludeItemTypes = Array.Empty<string>();
+
+ itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
+ }
+ else
+ {
+ itemsResult = _libraryManager.GetItemList(query);
+ }
+
+ var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
+
+ var result = new QueryResult<BaseItemDto>
+ {
+ Items = returnList,
+
+ TotalRecordCount = itemsResult.Count
+ };
+
+ return result;
}
public object Get(GetMediaFolders request)
@@ -428,7 +730,7 @@ namespace MediaBrowser.Api.Library
Items = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions)).ToArray()
};
- return ToOptimizedResult(result);
+ return result;
}
public void Post(PostUpdatedSeries request)
@@ -443,17 +745,21 @@ namespace MediaBrowser.Api.Library
}).Where(i => string.Equals(request.TvdbId, i.GetProviderId(MetadataProviders.Tvdb), StringComparison.OrdinalIgnoreCase)).ToArray();
- if (series.Length > 0)
+ foreach (var item in series)
{
- foreach (var item in series)
+ _libraryMonitor.ReportFileSystemChanged(item.Path);
+ }
+ }
+
+ public void Post(PostUpdatedMedia request)
+ {
+ if (request.Updates != null)
+ {
+ foreach (var item in request.Updates)
{
_libraryMonitor.ReportFileSystemChanged(item.Path);
}
}
- else
- {
- Task.Run(() => _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None));
- }
}
public void Post(PostUpdatedMovies request)
@@ -481,16 +787,9 @@ namespace MediaBrowser.Api.Library
movies = new List<BaseItem>();
}
- if (movies.Count > 0)
- {
- foreach (var item in movies)
- {
- _libraryMonitor.ReportFileSystemChanged(item.Path);
- }
- }
- else
+ foreach (var item in movies)
{
- Task.Run(() => _libraryManager.ValidateMediaLibrary(new SimpleProgress<double>(), CancellationToken.None));
+ _libraryMonitor.ReportFileSystemChanged(item.Path);
}
}
@@ -499,7 +798,7 @@ namespace MediaBrowser.Api.Library
var item = _libraryManager.GetItemById(request.Id);
var auth = _authContext.GetAuthorizationInfo(Request);
- var user = _userManager.GetUserById(auth.UserId);
+ var user = auth.User;
if (user != null)
{
@@ -561,15 +860,6 @@ namespace MediaBrowser.Api.Library
public Task<object> Get(GetFile request)
{
var item = _libraryManager.GetItemById(request.Id);
- var locationType = item.LocationType;
- if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
- {
- throw new ArgumentException("This command cannot be used for remote or virtual items.");
- }
- if (_fileSystem.DirectoryExists(item.Path))
- {
- throw new ArgumentException("This command cannot be used for directories.");
- }
return ResultFactory.GetStaticFileResult(Request, item.Path);
}
@@ -585,7 +875,7 @@ namespace MediaBrowser.Api.Library
.SelectMany(c => c.PhysicalLocations)
.ToList();
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -597,7 +887,7 @@ namespace MediaBrowser.Api.Library
{
var result = GetAncestors(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -611,7 +901,7 @@ namespace MediaBrowser.Api.Library
var baseItemDtos = new List<BaseItemDto>();
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var dtoOptions = GetDtoOptions(_authContext, request);
@@ -636,7 +926,7 @@ namespace MediaBrowser.Api.Library
{
if (item.GetParent() is AggregateFolder)
{
- return user.RootFolder.GetChildren(user, true).FirstOrDefault(i => i.PhysicalLocations.Contains(item.Path));
+ return _libraryManager.GetUserRootFolder().GetChildren(user, true).FirstOrDefault(i => i.PhysicalLocations.Contains(item.Path));
}
return item;
@@ -649,9 +939,7 @@ namespace MediaBrowser.Api.Library
/// <returns>System.Object.</returns>
public object Get(GetCriticReviews request)
{
- var result = GetCriticReviews(request);
-
- return ToOptimizedSerializedResultUsingCache(result);
+ return new QueryResult<BaseItemDto>();
}
/// <summary>
@@ -661,7 +949,7 @@ namespace MediaBrowser.Api.Library
/// <returns>System.Object.</returns>
public object Get(GetItemCounts request)
{
- var user = string.IsNullOrWhiteSpace(request.UserId) ? null : _userManager.GetUserById(request.UserId);
+ var user = request.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(request.UserId);
var counts = new ItemCounts
{
@@ -677,7 +965,7 @@ namespace MediaBrowser.Api.Library
BookCount = GetCount(typeof(Book), user, request)
};
- return ToOptimizedSerializedResultUsingCache(counts);
+ return ToOptimizedResult(counts);
}
private int GetCount(Type type, User user, GetItemCounts request)
@@ -724,14 +1012,14 @@ namespace MediaBrowser.Api.Library
public void Delete(DeleteItems request)
{
var ids = string.IsNullOrWhiteSpace(request.Ids)
- ? new string[] { }
+ ? Array.Empty<string>()
: request.Ids.Split(',');
- var tasks = ids.Select(i =>
+ foreach (var i in ids)
{
var item = _libraryManager.GetItemById(i);
var auth = _authContext.GetAuthorizationInfo(Request);
- var user = _userManager.GetUserById(auth.UserId);
+ var user = auth.User;
if (!item.CanDelete(user))
{
@@ -740,17 +1028,15 @@ namespace MediaBrowser.Api.Library
throw new SecurityException("Unauthorized access");
}
- return Task.FromResult(true);
+ continue;
}
- return item.Delete(new DeleteOptions
+ _libraryManager.DeleteItem(item, new DeleteOptions
{
DeleteFileLocation = true
- });
- }).ToArray(ids.Length);
-
- Task.WaitAll(tasks);
+ }, true);
+ }
}
/// <summary>
@@ -765,36 +1051,6 @@ namespace MediaBrowser.Api.Library
});
}
- /// <summary>
- /// Gets the critic reviews async.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>Task{ItemReviewsResult}.</returns>
- private QueryResult<ItemReview> GetCriticReviews(GetCriticReviews request)
- {
- var reviews = _itemRepo.GetCriticReviews(new Guid(request.Id));
-
- var reviewsArray = reviews.ToArray(reviews.Count);
-
- var result = new QueryResult<ItemReview>
- {
- TotalRecordCount = reviewsArray.Length
- };
-
- if (request.StartIndex.HasValue)
- {
- reviewsArray = reviewsArray.Skip(request.StartIndex.Value).ToArray();
- }
- if (request.Limit.HasValue)
- {
- reviewsArray = reviewsArray.Take(request.Limit.Value).ToArray();
- }
-
- result.Items = reviewsArray;
-
- return result;
- }
-
public object Get(GetThemeMedia request)
{
var themeSongs = GetThemeSongs(new GetThemeSongs
@@ -813,7 +1069,7 @@ namespace MediaBrowser.Api.Library
});
- return ToOptimizedSerializedResultUsingCache(new AllThemeMediaResult
+ return ToOptimizedResult(new AllThemeMediaResult
{
ThemeSongsResult = themeSongs,
ThemeVideosResult = themeVideos,
@@ -831,16 +1087,16 @@ namespace MediaBrowser.Api.Library
{
var result = GetThemeSongs(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
private ThemeMediaResult GetThemeSongs(GetThemeSongs request)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var item = string.IsNullOrEmpty(request.Id)
- ? (!string.IsNullOrWhiteSpace(request.UserId)
- ? user.RootFolder
+ ? (!request.UserId.Equals(Guid.Empty)
+ ? _libraryManager.GetUserRootFolder()
: (Folder)_libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id);
@@ -849,16 +1105,33 @@ namespace MediaBrowser.Api.Library
throw new ResourceNotFoundException("Item not found.");
}
- while (item.ThemeSongIds.Length == 0 && request.InheritFromParent && item.GetParent() != null)
+ BaseItem[] themeItems = Array.Empty<BaseItem>();
+
+ while (true)
{
- item = item.GetParent();
+ themeItems = item.GetThemeSongs().ToArray();
+
+ if (themeItems.Length > 0)
+ {
+ break;
+ }
+
+ if (!request.InheritFromParent)
+ {
+ break;
+ }
+
+ var parent = item.GetParent();
+ if (parent == null)
+ {
+ break;
+ }
+ item = parent;
}
var dtoOptions = GetDtoOptions(_authContext, request);
- var dtos = item.ThemeSongIds.Select(_libraryManager.GetItemById)
- .Where(i => i != null)
- .OrderBy(i => i.SortName)
+ var dtos = themeItems
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
var items = dtos.ToArray();
@@ -867,7 +1140,7 @@ namespace MediaBrowser.Api.Library
{
Items = items,
TotalRecordCount = items.Length,
- OwnerId = _dtoService.GetDtoId(item)
+ OwnerId = item.Id
};
}
@@ -880,16 +1153,16 @@ namespace MediaBrowser.Api.Library
{
var result = GetThemeVideos(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public ThemeMediaResult GetThemeVideos(GetThemeVideos request)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var item = string.IsNullOrEmpty(request.Id)
- ? (!string.IsNullOrWhiteSpace(request.UserId)
- ? user.RootFolder
+ ? (!request.UserId.Equals(Guid.Empty)
+ ? _libraryManager.GetUserRootFolder()
: (Folder)_libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id);
@@ -898,16 +1171,33 @@ namespace MediaBrowser.Api.Library
throw new ResourceNotFoundException("Item not found.");
}
- while (item.ThemeVideoIds.Length == 0 && request.InheritFromParent && item.GetParent() != null)
+ BaseItem[] themeItems = Array.Empty<BaseItem>();
+
+ while (true)
{
- item = item.GetParent();
+ themeItems = item.GetThemeVideos().ToArray();
+
+ if (themeItems.Length > 0)
+ {
+ break;
+ }
+
+ if (!request.InheritFromParent)
+ {
+ break;
+ }
+
+ var parent = item.GetParent();
+ if (parent == null)
+ {
+ break;
+ }
+ item = parent;
}
var dtoOptions = GetDtoOptions(_authContext, request);
- var dtos = item.ThemeVideoIds.Select(_libraryManager.GetItemById)
- .Where(i => i != null)
- .OrderBy(i => i.SortName)
+ var dtos = themeItems
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
var items = dtos.ToArray();
@@ -916,43 +1206,8 @@ namespace MediaBrowser.Api.Library
{
Items = items,
TotalRecordCount = items.Length,
- OwnerId = _dtoService.GetDtoId(item)
+ OwnerId = item.Id
};
}
-
- private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-
- public object Get(GetYearIndex request)
- {
- var includeTypes = string.IsNullOrWhiteSpace(request.IncludeItemTypes)
- ? new string[] { }
- : request.IncludeItemTypes.Split(',');
-
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
-
- var query = new InternalItemsQuery(user)
- {
- IncludeItemTypes = includeTypes,
- Recursive = true,
- DtoOptions = new DtoOptions(false)
- {
- EnableImages = false
- }
- };
-
- var items = _libraryManager.GetItemList(query);
-
- var lookup = items
- .ToLookup(i => i.ProductionYear ?? -1)
- .OrderBy(i => i.Key)
- .Select(i => new ItemIndex
- {
- ItemCount = i.Count(),
- Name = i.Key == -1 ? string.Empty : i.Key.ToString(_usCulture)
- })
- .ToList();
-
- return ToOptimizedSerializedResultUsingCache(lookup);
- }
}
}
diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs
index ae488f066c..bba89acec6 100644
--- a/MediaBrowser.Api/Library/LibraryStructureService.cs
+++ b/MediaBrowser.Api/Library/LibraryStructureService.cs
@@ -210,7 +210,7 @@ namespace MediaBrowser.Api.Library
{
var result = _libraryManager.GetVirtualFolders(true);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public void Post(UpdateLibraryOptions request)
@@ -224,7 +224,7 @@ namespace MediaBrowser.Api.Library
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(AddVirtualFolder request)
+ public Task Post(AddVirtualFolder request)
{
var libraryOptions = request.LibraryOptions ?? new LibraryOptions();
@@ -233,7 +233,7 @@ namespace MediaBrowser.Api.Library
libraryOptions.PathInfos = request.Paths.Select(i => new MediaPathInfo { Path = i }).ToArray();
}
- _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, libraryOptions, request.RefreshLibrary);
+ return _libraryManager.AddVirtualFolder(request.Name, request.CollectionType, libraryOptions, request.RefreshLibrary);
}
/// <summary>
@@ -264,27 +264,27 @@ namespace MediaBrowser.Api.Library
if (!string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase) && _fileSystem.DirectoryExists(newPath))
{
- throw new ArgumentException("There is already a media collection with the name " + newPath + ".");
+ throw new ArgumentException("Media library already exists at " + newPath + ".");
}
_libraryMonitor.Stop();
try
{
- // Only make a two-phase move when changing capitalization
+ // Changing capitalization. Handle windows case insensitivity
if (string.Equals(currentPath, newPath, StringComparison.OrdinalIgnoreCase))
{
- //Create an unique name
- var temporaryName = Guid.NewGuid().ToString();
- var temporaryPath = Path.Combine(rootFolderPath, temporaryName);
- _fileSystem.MoveDirectory(currentPath, temporaryPath);
- currentPath = temporaryPath;
+ var tempPath = Path.Combine(rootFolderPath, Guid.NewGuid().ToString("N"));
+ _fileSystem.MoveDirectory(currentPath, tempPath);
+ currentPath = tempPath;
}
_fileSystem.MoveDirectory(currentPath, newPath);
}
finally
{
+ CollectionFolder.OnCollectionFolderChange();
+
Task.Run(() =>
{
// No need to start if scanning the library because it will handle it
@@ -309,9 +309,9 @@ namespace MediaBrowser.Api.Library
/// Deletes the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Delete(RemoveVirtualFolder request)
+ public Task Delete(RemoveVirtualFolder request)
{
- _libraryManager.RemoveVirtualFolder(request.Name, request.RefreshLibrary);
+ return _libraryManager.RemoveVirtualFolder(request.Name, request.RefreshLibrary);
}
/// <summary>
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index fee52ea5ee..510c5f135b 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -17,12 +17,15 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Api.UserLibrary;
using MediaBrowser.Model.IO;
-
+using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.Cryptography;
+using System.Text;
+using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Api.LiveTv
{
@@ -37,13 +40,13 @@ namespace MediaBrowser.Api.LiveTv
[Route("/LiveTv/Channels", "GET", Summary = "Gets available live tv channels.")]
[Authenticated]
- public class GetChannels : IReturn<QueryResult<ChannelInfoDto>>, IHasDtoOptions
+ public class GetChannels : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
{
[ApiMember(Name = "Type", Description = "Optional filter by channel type.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public ChannelType? Type { get; set; }
[ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -122,7 +125,7 @@ namespace MediaBrowser.Api.LiveTv
if (string.IsNullOrEmpty(val))
{
- return new string[] { };
+ return Array.Empty<string>();
}
return val.Split(',');
@@ -136,7 +139,7 @@ namespace MediaBrowser.Api.LiveTv
[Route("/LiveTv/Channels/{Id}", "GET", Summary = "Gets a live tv channel")]
[Authenticated]
- public class GetChannel : IReturn<ChannelInfoDto>
+ public class GetChannel : IReturn<BaseItemDto>
{
/// <summary>
/// Gets or sets the id.
@@ -146,7 +149,7 @@ namespace MediaBrowser.Api.LiveTv
public string Id { get; set; }
[ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
[Route("/LiveTv/Recordings", "GET", Summary = "Gets live tv recordings")]
@@ -157,10 +160,7 @@ namespace MediaBrowser.Api.LiveTv
public string ChannelId { get; set; }
[ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
-
- [ApiMember(Name = "GroupId", Description = "Optional filter by recording group.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string GroupId { get; set; }
+ public Guid UserId { get; set; }
[ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int? StartIndex { get; set; }
@@ -274,6 +274,14 @@ namespace MediaBrowser.Api.LiveTv
public string UserId { get; set; }
}
+ [Route("/LiveTv/Recordings/Folders", "GET", Summary = "Gets recording folders")]
+ [Authenticated]
+ public class GetRecordingFolders : IReturn<BaseItemDto[]>
+ {
+ [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public Guid UserId { get; set; }
+ }
+
[Route("/LiveTv/Recordings/{Id}", "GET", Summary = "Gets a live tv recording")]
[Authenticated]
public class GetRecording : IReturn<BaseItemDto>
@@ -282,7 +290,7 @@ namespace MediaBrowser.Api.LiveTv
public string Id { get; set; }
[ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
[Route("/LiveTv/Tuners/{Id}/Reset", "POST", Summary = "Resets a tv tuner")]
@@ -332,13 +340,14 @@ namespace MediaBrowser.Api.LiveTv
public string ChannelIds { get; set; }
[ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
[ApiMember(Name = "MinStartDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public string MinStartDate { get; set; }
[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")]
public string MaxStartDate { get; set; }
@@ -397,7 +406,7 @@ namespace MediaBrowser.Api.LiveTv
public bool? EnableUserData { get; set; }
public string SeriesTimerId { get; set; }
- public string LibrarySeriesId { get; set; }
+ public Guid LibrarySeriesId { get; set; }
/// <summary>
/// Fields to return within the items, in addition to basic information
@@ -424,7 +433,7 @@ namespace MediaBrowser.Api.LiveTv
}
[ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
[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; }
@@ -481,7 +490,7 @@ namespace MediaBrowser.Api.LiveTv
public string Id { get; set; }
[ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
@@ -489,15 +498,15 @@ namespace MediaBrowser.Api.LiveTv
[Authenticated]
public class DeleteRecording : IReturnVoid
{
- [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
+ public Guid Id { get; set; }
}
[Route("/LiveTv/Timers/{Id}", "DELETE", Summary = "Cancels a live tv timer")]
[Authenticated]
public class CancelTimer : IReturnVoid
{
- [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; }
}
@@ -536,7 +545,7 @@ namespace MediaBrowser.Api.LiveTv
[Authenticated]
public class CancelSeriesTimer : IReturnVoid
{
- [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Id { get; set; }
}
@@ -566,14 +575,6 @@ namespace MediaBrowser.Api.LiveTv
{
}
- [Route("/LiveTv/Folder", "GET", Summary = "Gets the users live tv folder, along with configured images")]
- [Authenticated]
- public class GetLiveTvFolder : IReturn<BaseItemDto>
- {
- [ApiMember(Name = "UserId", Description = "Optional attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
- }
-
[Route("/LiveTv/TunerHosts", "POST", Summary = "Adds a tuner host")]
[Authenticated]
public class AddTunerHost : TunerHostInfo, IReturn<TunerHostInfo>
@@ -600,6 +601,7 @@ namespace MediaBrowser.Api.LiveTv
{
public bool ValidateLogin { get; set; }
public bool ValidateListings { get; set; }
+ public string Pw { get; set; }
}
[Route("/LiveTv/ListingProviders", "DELETE", Summary = "Deletes a listing provider")]
@@ -637,7 +639,7 @@ namespace MediaBrowser.Api.LiveTv
[Authenticated]
public class GetChannelMappingOptions
{
- [ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query")]
public string ProviderId { get; set; }
}
@@ -645,7 +647,7 @@ namespace MediaBrowser.Api.LiveTv
[Authenticated]
public class SetChannelMapping
{
- [ApiMember(Name = "Id", Description = "Provider id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [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; }
@@ -659,14 +661,6 @@ namespace MediaBrowser.Api.LiveTv
public string ProviderName { get; set; }
}
- [Route("/LiveTv/Registration", "GET")]
- [Authenticated]
- public class GetLiveTvRegistrationInfo : IReturn<MBRegistrationRecord>
- {
- [ApiMember(Name = "Feature", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string Feature { get; set; }
- }
-
[Route("/LiveTv/LiveStreamFiles/{Id}/stream.{Container}", "GET", Summary = "Gets a live tv channel")]
public class GetLiveStreamFile
{
@@ -706,8 +700,11 @@ namespace MediaBrowser.Api.LiveTv
private readonly IAuthorizationContext _authContext;
private readonly ISessionContext _sessionContext;
private readonly IEnvironmentInfo _environment;
+ private ICryptoProvider _cryptographyProvider;
+ private IStreamHelper _streamHelper;
+ private IMediaSourceManager _mediaSourceManager;
- public LiveTvService(ILiveTvManager liveTvManager, IUserManager userManager, IServerConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService, IFileSystem fileSystem, IAuthorizationContext authContext, ISessionContext sessionContext, IEnvironmentInfo environment)
+ public LiveTvService(ICryptoProvider crypto, IMediaSourceManager mediaSourceManager, IStreamHelper streamHelper, ILiveTvManager liveTvManager, IUserManager userManager, IServerConfigurationManager config, IHttpClient httpClient, ILibraryManager libraryManager, IDtoService dtoService, IFileSystem fileSystem, IAuthorizationContext authContext, ISessionContext sessionContext, IEnvironmentInfo environment)
{
_liveTvManager = liveTvManager;
_userManager = userManager;
@@ -719,6 +716,9 @@ namespace MediaBrowser.Api.LiveTv
_authContext = authContext;
_sessionContext = sessionContext;
_environment = environment;
+ _cryptographyProvider = crypto;
+ _streamHelper = streamHelper;
+ _mediaSourceManager = mediaSourceManager;
}
public object Get(GetTunerHostTypes request)
@@ -727,6 +727,22 @@ namespace MediaBrowser.Api.LiveTv
return ToOptimizedResult(list);
}
+ public object Get(GetRecordingFolders request)
+ {
+ var user = request.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(request.UserId);
+ var folders = _liveTvManager.GetRecordingFolders(user);
+
+ var returnArray = _dtoService.GetBaseItemDtos(folders.ToArray(), new DtoOptions(), user);
+
+ var result = new QueryResult<BaseItemDto>
+ {
+ Items = returnArray,
+ TotalRecordCount = returnArray.Length
+ };
+
+ return ToOptimizedResult(result);
+ }
+
public object Get(GetLiveRecordingFile request)
{
var path = _liveTvManager.GetEmbyTvActiveRecordingPath(request.Id);
@@ -740,7 +756,7 @@ namespace MediaBrowser.Api.LiveTv
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType(path);
- return new ProgressiveFileCopier(_fileSystem, path, outputHeaders, Logger, _environment)
+ return new ProgressiveFileCopier(_fileSystem, _streamHelper, path, outputHeaders, Logger, _environment)
{
AllowEndOfFile = false
};
@@ -754,12 +770,15 @@ namespace MediaBrowser.Api.LiveTv
public async Task<object> Get(GetLiveStreamFile request)
{
- var directStreamProvider = (await _liveTvManager.GetEmbyTvLiveStream(request.Id).ConfigureAwait(false)) as IDirectStreamProvider;
+ var liveStreamInfo = await _mediaSourceManager.GetDirectStreamProviderByUniqueId(request.Id, CancellationToken.None).ConfigureAwait(false);
+
+ var directStreamProvider = liveStreamInfo;
+
var outputHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
outputHeaders["Content-Type"] = Model.Net.MimeTypes.GetMimeType("file." + request.Container);
- return new ProgressiveFileCopier(directStreamProvider, outputHeaders, Logger, _environment)
+ return new ProgressiveFileCopier(directStreamProvider, _streamHelper, outputHeaders, Logger, _environment)
{
AllowEndOfFile = false
};
@@ -770,13 +789,6 @@ namespace MediaBrowser.Api.LiveTv
return ToOptimizedResult(new ListingsProviderInfo());
}
- public async Task<object> Get(GetLiveTvRegistrationInfo request)
- {
- var result = await _liveTvManager.GetRegistrationInfo(request.Feature).ConfigureAwait(false);
-
- return ToOptimizedResult(result);
- }
-
public async Task<object> Post(SetChannelMapping request)
{
return await _liveTvManager.SetChannelMapping(request.ProviderId, request.TunerChannelId, request.ProviderChannelId).ConfigureAwait(false);
@@ -828,12 +840,12 @@ namespace MediaBrowser.Api.LiveTv
}).ConfigureAwait(false);
- return ResultFactory.GetResult(response, "application/json");
+ return ResultFactory.GetResult(Request, response, "application/json");
}
private void AssertUserCanManageLiveTv()
{
- var user = _sessionContext.GetUser(Request).Result;
+ var user = _sessionContext.GetUser(Request);
if (user == null)
{
@@ -848,10 +860,26 @@ namespace MediaBrowser.Api.LiveTv
public async Task<object> Post(AddListingProvider request)
{
+ if (request.Pw != null)
+ {
+ request.Password = GetHashedString(request.Pw);
+ }
+
+ request.Pw = null;
+
var result = await _liveTvManager.SaveListingProvider(request, request.ValidateLogin, request.ValidateListings).ConfigureAwait(false);
return ToOptimizedResult(result);
}
+ /// <summary>
+ /// Gets the hashed string.
+ /// </summary>
+ private string GetHashedString(string str)
+ {
+ // legacy
+ return BitConverter.ToString(_cryptographyProvider.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty).ToLower();
+ }
+
public void Delete(DeleteListingProvider request)
{
_liveTvManager.DeleteListingsProvider(request.Id);
@@ -859,8 +887,6 @@ namespace MediaBrowser.Api.LiveTv
public async Task<object> Post(AddTunerHost request)
{
- request.EnableNewHdhrChannelIds = true;
-
var result = await _liveTvManager.SaveTunerHost(request).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@@ -888,14 +914,14 @@ namespace MediaBrowser.Api.LiveTv
{
var info = await _liveTvManager.GetLineups(request.Type, request.Id, request.Country, request.Location).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(info);
+ return ToOptimizedResult(info);
}
- public async Task<object> Get(GetLiveTvInfo request)
+ public object Get(GetLiveTvInfo request)
{
- var info = await _liveTvManager.GetLiveTvInfo(CancellationToken.None).ConfigureAwait(false);
+ var info = _liveTvManager.GetLiveTvInfo(CancellationToken.None);
- return ToOptimizedSerializedResultUsingCache(info);
+ return ToOptimizedResult(info);
}
public object Get(GetChannels request)
@@ -923,7 +949,7 @@ namespace MediaBrowser.Api.LiveTv
}, options, CancellationToken.None);
- var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
+ var user = request.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(request.UserId);
RemoveFields(options);
@@ -937,7 +963,7 @@ namespace MediaBrowser.Api.LiveTv
TotalRecordCount = channelResult.TotalRecordCount
};
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
private void RemoveFields(DtoOptions options)
@@ -955,27 +981,24 @@ namespace MediaBrowser.Api.LiveTv
{
var user = _userManager.GetUserById(request.UserId);
- var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
+ var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(request.Id);
var dtoOptions = GetDtoOptions(_authContext, request);
var result = _dtoService.GetBaseItemDto(item, dtoOptions, user);
- return ToOptimizedSerializedResultUsingCache(result);
- }
-
- public object Get(GetLiveTvFolder request)
- {
- return ToOptimizedResult(_liveTvManager.GetLiveTvFolder(request.UserId, CancellationToken.None));
+ return ToOptimizedResult(result);
}
public async Task<object> Get(GetPrograms request)
{
- var query = new ProgramQuery
+ var user = request.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(request.UserId);
+
+ var query = new InternalItemsQuery(user)
{
- ChannelIds = ApiEntryPoint.Split(request.ChannelIds, ',', true),
- UserId = request.UserId,
+ ChannelIds = ApiEntryPoint.Split(request.ChannelIds, ',', true).Select(i => new Guid(i)).ToArray(),
HasAired = request.HasAired,
+ IsAiring = request.IsAiring,
EnableTotalRecordCount = request.EnableTotalRecordCount
};
@@ -1009,9 +1032,9 @@ namespace MediaBrowser.Api.LiveTv
query.IsSports = request.IsSports;
query.SeriesTimerId = request.SeriesTimerId;
query.Genres = (request.Genres ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- query.GenreIds = (request.GenreIds ?? String.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ query.GenreIds = GetGuids(request.GenreIds);
- if (!string.IsNullOrWhiteSpace(request.LibrarySeriesId))
+ if (!request.LibrarySeriesId.Equals(Guid.Empty))
{
query.IsSeries = true;
@@ -1029,9 +1052,10 @@ namespace MediaBrowser.Api.LiveTv
public object Get(GetRecommendedPrograms request)
{
- var query = new RecommendedProgramQuery
+ var user = _userManager.GetUserById(request.UserId);
+
+ var query = new InternalItemsQuery(user)
{
- UserId = request.UserId,
IsAiring = request.IsAiring,
Limit = request.Limit,
HasAired = request.HasAired,
@@ -1043,7 +1067,7 @@ namespace MediaBrowser.Api.LiveTv
EnableTotalRecordCount = request.EnableTotalRecordCount
};
- query.GenreIds = (request.GenreIds ?? String.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ query.GenreIds = GetGuids(request.GenreIds);
var result = _liveTvManager.GetRecommendedPrograms(query, GetDtoOptions(_authContext, request), CancellationToken.None);
@@ -1055,16 +1079,14 @@ namespace MediaBrowser.Api.LiveTv
return Get(request);
}
- public async Task<object> Get(GetRecordings request)
+ public object Get(GetRecordings request)
{
var options = GetDtoOptions(_authContext, request);
- options.DeviceId = _authContext.GetAuthorizationInfo(Request).DeviceId;
- var result = await _liveTvManager.GetRecordings(new RecordingQuery
+ var result = _liveTvManager.GetRecordings(new RecordingQuery
{
ChannelId = request.ChannelId,
UserId = request.UserId,
- GroupId = request.GroupId,
StartIndex = request.StartIndex,
Limit = request.Limit,
Status = request.Status,
@@ -1076,53 +1098,39 @@ namespace MediaBrowser.Api.LiveTv
IsSeries = request.IsSeries,
IsKids = request.IsKids,
IsSports = request.IsSports,
- IsLibraryItem = request.IsLibraryItem
+ IsLibraryItem = request.IsLibraryItem,
+ Fields = request.GetItemFields(),
+ ImageTypeLimit = request.ImageTypeLimit,
+ EnableImages = request.EnableImages
- }, options, CancellationToken.None).ConfigureAwait(false);
+ }, options);
return ToOptimizedResult(result);
}
public object Get(GetRecordingSeries request)
{
- var options = GetDtoOptions(_authContext, request);
- options.DeviceId = _authContext.GetAuthorizationInfo(Request).DeviceId;
-
- var result = _liveTvManager.GetRecordingSeries(new RecordingQuery
- {
- ChannelId = request.ChannelId,
- UserId = request.UserId,
- GroupId = request.GroupId,
- StartIndex = request.StartIndex,
- Limit = request.Limit,
- Status = request.Status,
- SeriesTimerId = request.SeriesTimerId,
- IsInProgress = request.IsInProgress,
- EnableTotalRecordCount = request.EnableTotalRecordCount
-
- }, options, CancellationToken.None);
-
- return ToOptimizedResult(result);
+ return ToOptimizedResult(new QueryResult<BaseItemDto>());
}
- public async Task<object> Get(GetRecording request)
+ public object Get(GetRecording request)
{
var user = _userManager.GetUserById(request.UserId);
- var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
+ var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(request.Id);
var dtoOptions = GetDtoOptions(_authContext, request);
var result = _dtoService.GetBaseItemDto(item, dtoOptions, user);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public async Task<object> Get(GetTimer request)
{
var result = await _liveTvManager.GetTimer(request.Id, CancellationToken.None).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public async Task<object> Get(GetTimers request)
@@ -1136,34 +1144,31 @@ namespace MediaBrowser.Api.LiveTv
}, CancellationToken.None).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public void Delete(DeleteRecording request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.DeleteRecording(request.Id);
-
- Task.WaitAll(task);
+ _libraryManager.DeleteItem(_libraryManager.GetItemById(request.Id), new DeleteOptions
+ {
+ DeleteFileLocation = false
+ });
}
- public void Delete(CancelTimer request)
+ public Task Delete(CancelTimer request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.CancelTimer(request.Id);
-
- Task.WaitAll(task);
+ return _liveTvManager.CancelTimer(request.Id);
}
- public void Post(UpdateTimer request)
+ public Task Post(UpdateTimer request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.UpdateTimer(request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _liveTvManager.UpdateTimer(request, CancellationToken.None);
}
public async Task<object> Get(GetSeriesTimers request)
@@ -1175,32 +1180,28 @@ namespace MediaBrowser.Api.LiveTv
}, CancellationToken.None).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public async Task<object> Get(GetSeriesTimer request)
{
var result = await _liveTvManager.GetSeriesTimer(request.Id, CancellationToken.None).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
- public void Delete(CancelSeriesTimer request)
+ public Task Delete(CancelSeriesTimer request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.CancelSeriesTimer(request.Id);
-
- Task.WaitAll(task);
+ return _liveTvManager.CancelSeriesTimer(request.Id);
}
- public void Post(UpdateSeriesTimer request)
+ public Task Post(UpdateSeriesTimer request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.UpdateSeriesTimer(request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _liveTvManager.UpdateSeriesTimer(request, CancellationToken.None);
}
public async Task<object> Get(GetDefaultTimer request)
@@ -1209,61 +1210,47 @@ namespace MediaBrowser.Api.LiveTv
{
var result = await _liveTvManager.GetNewTimerDefaults(CancellationToken.None).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
else
{
var result = await _liveTvManager.GetNewTimerDefaults(request.ProgramId, CancellationToken.None).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
}
public async Task<object> Get(GetProgram request)
{
- var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
+ var user = request.UserId.Equals(Guid.Empty) ? null : _userManager.GetUserById(request.UserId);
var result = await _liveTvManager.GetProgram(request.Id, CancellationToken.None, user).ConfigureAwait(false);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
- public void Post(CreateSeriesTimer request)
+ public Task Post(CreateSeriesTimer request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.CreateSeriesTimer(request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _liveTvManager.CreateSeriesTimer(request, CancellationToken.None);
}
- public void Post(CreateTimer request)
+ public Task Post(CreateTimer request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.CreateTimer(request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _liveTvManager.CreateTimer(request, CancellationToken.None);
}
- public async Task<object> Get(GetRecordingGroups request)
+ public object Get(GetRecordingGroups request)
{
- var result = await _liveTvManager.GetRecordingGroups(new RecordingGroupQuery
- {
- UserId = request.UserId
-
- }, CancellationToken.None).ConfigureAwait(false);
-
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(new QueryResult<BaseItemDto>());
}
- public async Task<object> Get(GetRecordingGroup request)
+ public object Get(GetRecordingGroup request)
{
- var result = await _liveTvManager.GetRecordingGroups(new RecordingGroupQuery(), CancellationToken.None).ConfigureAwait(false);
-
- var group = result.Items.FirstOrDefault(i => string.Equals(i.Id, request.Id, StringComparison.OrdinalIgnoreCase));
-
- return ToOptimizedSerializedResultUsingCache(group);
+ throw new FileNotFoundException();
}
public object Get(GetGuideInfo request)
@@ -1271,13 +1258,11 @@ namespace MediaBrowser.Api.LiveTv
return ToOptimizedResult(_liveTvManager.GetGuideInfo());
}
- public void Post(ResetTuner request)
+ public Task Post(ResetTuner request)
{
AssertUserCanManageLiveTv();
- var task = _liveTvManager.ResetTuner(request.Id, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _liveTvManager.ResetTuner(request.Id, CancellationToken.None);
}
}
} \ No newline at end of file
diff --git a/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs b/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs
index 74293ccd90..0a6ccd4c5c 100644
--- a/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs
+++ b/MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.System;
+using MediaBrowser.Controller.IO;
namespace MediaBrowser.Api.LiveTv
{
@@ -20,28 +21,30 @@ namespace MediaBrowser.Api.LiveTv
const int StreamCopyToBufferSize = 81920;
- private long _bytesWritten = 0;
public long StartPosition { get; set; }
public bool AllowEndOfFile = true;
private readonly IDirectStreamProvider _directStreamProvider;
private readonly IEnvironmentInfo _environment;
+ private IStreamHelper _streamHelper;
- public ProgressiveFileCopier(IFileSystem fileSystem, string path, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment)
+ public ProgressiveFileCopier(IFileSystem fileSystem, IStreamHelper streamHelper, string path, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment)
{
_fileSystem = fileSystem;
_path = path;
_outputHeaders = outputHeaders;
_logger = logger;
_environment = environment;
+ _streamHelper = streamHelper;
}
- public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment)
+ public ProgressiveFileCopier(IDirectStreamProvider directStreamProvider, IStreamHelper streamHelper, Dictionary<string, string> outputHeaders, ILogger logger, IEnvironmentInfo environment)
{
_directStreamProvider = directStreamProvider;
_outputHeaders = outputHeaders;
_logger = logger;
_environment = environment;
+ _streamHelper = streamHelper;
}
public IDictionary<string, string> Headers
@@ -75,7 +78,7 @@ namespace MediaBrowser.Api.LiveTv
var eofCount = 0;
// use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
- var allowAsyncFileRead = _environment.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.Windows;
+ var allowAsyncFileRead = true;
using (var inputStream = GetInputStream(allowAsyncFileRead))
{
@@ -89,14 +92,7 @@ namespace MediaBrowser.Api.LiveTv
while (eofCount < emptyReadLimit)
{
int bytesRead;
- if (allowAsyncFileRead)
- {
- bytesRead = await CopyToInternalAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
- }
- else
- {
- bytesRead = await CopyToInternalAsyncWithSyncRead(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
- }
+ bytesRead = await _streamHelper.CopyToAsync(inputStream, outputStream, cancellationToken).ConfigureAwait(false);
//var position = fs.Position;
//_logger.Debug("Streamed {0} bytes to position {1} from file {2}", bytesRead, position, path);
@@ -113,49 +109,5 @@ namespace MediaBrowser.Api.LiveTv
}
}
}
-
- private async Task<int> CopyToInternalAsyncWithSyncRead(Stream source, Stream destination, CancellationToken cancellationToken)
- {
- var array = new byte[StreamCopyToBufferSize];
- int bytesRead;
- int totalBytesRead = 0;
-
- while ((bytesRead = source.Read(array, 0, array.Length)) != 0)
- {
- var bytesToWrite = bytesRead;
-
- if (bytesToWrite > 0)
- {
- await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
-
- _bytesWritten += bytesRead;
- totalBytesRead += bytesRead;
- }
- }
-
- return totalBytesRead;
- }
-
- private async Task<int> CopyToInternalAsync(Stream source, Stream destination, CancellationToken cancellationToken)
- {
- var array = new byte[StreamCopyToBufferSize];
- int bytesRead;
- int totalBytesRead = 0;
-
- while ((bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0)
- {
- var bytesToWrite = bytesRead;
-
- if (bytesToWrite > 0)
- {
- await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
-
- _bytesWritten += bytesRead;
- totalBytesRead += bytesRead;
- }
- }
-
- return totalBytesRead;
- }
}
}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 650306ea60..e4c9a0c351 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -1,136 +1,17 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{4FD51AC5-2C16-4308-A993-C3A84F3B4582}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>MediaBrowser.Api</RootNamespace>
- <AssemblyName>MediaBrowser.Api</AssemblyName>
- <FileAlignment>512</FileAlignment>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <PlatformTarget>AnyCPU</PlatformTarget>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>none</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- </PropertyGroup>
+<Project Sdk="Microsoft.NET.Sdk">
+
<ItemGroup>
- <Compile Include="..\SharedVersion.cs">
- <Link>Properties\SharedVersion.cs</Link>
- </Compile>
- <Compile Include="BrandingService.cs" />
- <Compile Include="ChannelService.cs" />
- <Compile Include="Devices\DeviceService.cs" />
- <Compile Include="Dlna\DlnaServerService.cs" />
- <Compile Include="Dlna\DlnaService.cs" />
- <Compile Include="FilterService.cs" />
- <Compile Include="IHasDtoOptions.cs" />
- <Compile Include="LiveTv\ProgressiveFileCopier.cs" />
- <Compile Include="PlaylistService.cs" />
- <Compile Include="Social\SharingService.cs" />
- <Compile Include="StartupWizardService.cs" />
- <Compile Include="Subtitles\SubtitleService.cs" />
- <Compile Include="Movies\CollectionService.cs" />
- <Compile Include="Music\AlbumsService.cs" />
- <Compile Include="BaseApiService.cs" />
- <Compile Include="ConfigurationService.cs" />
- <Compile Include="DisplayPreferencesService.cs" />
- <Compile Include="EnvironmentService.cs" />
- <Compile Include="GamesService.cs" />
- <Compile Include="IHasItemFields.cs" />
- <Compile Include="Images\ImageByNameService.cs" />
- <Compile Include="Images\ImageRequest.cs" />
- <Compile Include="Images\ImageService.cs" />
- <Compile Include="Music\InstantMixService.cs" />
- <Compile Include="ItemLookupService.cs" />
- <Compile Include="ItemRefreshService.cs" />
- <Compile Include="ItemUpdateService.cs" />
- <Compile Include="Library\LibraryService.cs" />
- <Compile Include="Library\LibraryStructureService.cs" />
- <Compile Include="LiveTv\LiveTvService.cs" />
- <Compile Include="LocalizationService.cs" />
- <Compile Include="Movies\MoviesService.cs" />
- <Compile Include="NewsService.cs" />
- <Compile Include="NotificationsService.cs" />
- <Compile Include="PackageService.cs" />
- <Compile Include="PluginService.cs" />
- <Compile Include="Images\RemoteImageService.cs" />
- <Compile Include="ScheduledTasks\ScheduledTaskService.cs" />
- <Compile Include="ScheduledTasks\ScheduledTasksWebSocketListener.cs" />
- <Compile Include="ApiEntryPoint.cs" />
- <Compile Include="SearchService.cs" />
- <Compile Include="Session\SessionsService.cs" />
- <Compile Include="SimilarItemsHelper.cs" />
- <Compile Include="SuggestionsService.cs" />
- <Compile Include="System\ActivityLogService.cs" />
- <Compile Include="System\ActivityLogWebSocketListener.cs" />
- <Compile Include="System\SystemService.cs" />
- <Compile Include="Movies\TrailersService.cs" />
- <Compile Include="TvShowsService.cs" />
- <Compile Include="UserLibrary\ArtistsService.cs" />
- <Compile Include="UserLibrary\BaseItemsByNameService.cs" />
- <Compile Include="UserLibrary\BaseItemsRequest.cs" />
- <Compile Include="UserLibrary\GameGenresService.cs" />
- <Compile Include="UserLibrary\GenresService.cs" />
- <Compile Include="UserLibrary\ItemsService.cs" />
- <Compile Include="UserLibrary\MusicGenresService.cs" />
- <Compile Include="UserLibrary\PersonsService.cs" />
- <Compile Include="UserLibrary\StudiosService.cs" />
- <Compile Include="UserLibrary\UserLibraryService.cs" />
- <Compile Include="UserLibrary\UserViewsService.cs" />
- <Compile Include="UserLibrary\YearsService.cs" />
- <Compile Include="UserService.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="VideosService.cs" />
- <Compile Include="Session\SessionInfoWebSocketListener.cs" />
- <Compile Include="System\SystemInfoWebSocketListener.cs" />
+ <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
+ <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
</ItemGroup>
+
<ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
- <Project>{9142EEFA-7570-41E1-BFCC-468BB571AF2F}</Project>
- <Name>MediaBrowser.Common</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj">
- <Project>{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}</Project>
- <Name>MediaBrowser.Controller</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
- <Project>{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}</Project>
- <Name>MediaBrowser.Model</Name>
- </ProjectReference>
+ <Compile Include="..\SharedVersion.cs"/>
</ItemGroup>
- <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+
<PropertyGroup>
- <PostBuildEvent>
- </PostBuildEvent>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
+ <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
+
+</Project>
diff --git a/MediaBrowser.Api/MediaBrowser.Api.nuget.targets b/MediaBrowser.Api/MediaBrowser.Api.nuget.targets
deleted file mode 100644
index e69ce0e64f..0000000000
--- a/MediaBrowser.Api/MediaBrowser.Api.nuget.targets
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Target Name="EmitMSBuildWarning" BeforeTargets="Build">
- <Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." />
- </Target>
-</Project> \ No newline at end of file
diff --git a/MediaBrowser.Api/Movies/CollectionService.cs b/MediaBrowser.Api/Movies/CollectionService.cs
index c63712f4cc..9adefdf755 100644
--- a/MediaBrowser.Api/Movies/CollectionService.cs
+++ b/MediaBrowser.Api/Movies/CollectionService.cs
@@ -3,8 +3,6 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Collections;
using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Movies
@@ -38,7 +36,7 @@ namespace MediaBrowser.Api.Movies
[Route("/Collections/{Id}/Items", "DELETE", Summary = "Removes items from a collection")]
public class RemoveFromCollection : IReturnVoid
{
- [ApiMember(Name = "Ids", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
+ [ApiMember(Name = "Ids", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
public string Ids { get; set; }
[ApiMember(Name = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
@@ -59,44 +57,40 @@ namespace MediaBrowser.Api.Movies
_authContext = authContext;
}
- public async Task<object> Post(CreateCollection request)
+ public object Post(CreateCollection request)
{
var userId = _authContext.GetAuthorizationInfo(Request).UserId;
var parentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId);
- var item = await _collectionManager.CreateCollection(new CollectionCreationOptions
+ var item = _collectionManager.CreateCollection(new CollectionCreationOptions
{
IsLocked = request.IsLocked,
Name = request.Name,
ParentId = parentId,
ItemIdList = SplitValue(request.Ids, ','),
- UserIds = new string[] { userId }
+ UserIds = new [] { userId }
- }).ConfigureAwait(false);
+ });
var dtoOptions = GetDtoOptions(_authContext, request);
var dto = _dtoService.GetBaseItemDto(item, dtoOptions);
- return ToOptimizedResult(new CollectionCreationResult
+ return new CollectionCreationResult
{
Id = dto.Id
- });
+ };
}
public void Post(AddToCollection request)
{
- var task = _collectionManager.AddToCollection(new Guid(request.Id), SplitValue(request.Ids, ','));
-
- Task.WaitAll(task);
+ _collectionManager.AddToCollection(new Guid(request.Id), SplitValue(request.Ids, ','));
}
public void Delete(RemoveFromCollection request)
{
- var task = _collectionManager.RemoveFromCollection(new Guid(request.Id), SplitValue(request.Ids, ','));
-
- Task.WaitAll(task);
+ _collectionManager.RemoveFromCollection(new Guid(request.Id), SplitValue(request.Ids, ','));
}
}
}
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index 254c93b33a..7112806011 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -19,22 +19,6 @@ using MediaBrowser.Model.Services;
namespace MediaBrowser.Api.Movies
{
- /// <summary>
- /// Class GetSimilarMovies
- /// </summary>
- [Route("/Movies/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given movie.")]
- public class GetSimilarMovies : BaseGetSimilarItemsFromItem
- {
- }
-
- /// <summary>
- /// Class GetSimilarTrailers
- /// </summary>
- [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
- public class GetSimilarTrailers : BaseGetSimilarItemsFromItem
- {
- }
-
[Route("/Movies/Recommendations", "GET", Summary = "Gets movie recommendations")]
public class GetMovieRecommendations : IReturn<RecommendationDto[]>, IHasDtoOptions
{
@@ -49,7 +33,7 @@ namespace MediaBrowser.Api.Movies
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Specify this to localize the search to a specific item or folder. Omit to use the root.
@@ -108,25 +92,6 @@ namespace MediaBrowser.Api.Movies
_authContext = authContext;
}
- /// <summary>
- /// Gets the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>System.Object.</returns>
- public object Get(GetSimilarMovies request)
- {
- var result = GetSimilarItemsResult(request);
-
- return ToOptimizedSerializedResultUsingCache(result);
- }
-
- public object Get(GetSimilarTrailers request)
- {
- var result = GetSimilarItemsResult(request);
-
- return ToOptimizedSerializedResultUsingCache(result);
- }
-
public object Get(GetMovieRecommendations request)
{
var user = _userManager.GetUserById(request.UserId);
@@ -138,12 +103,12 @@ namespace MediaBrowser.Api.Movies
return ToOptimizedResult(result);
}
- private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
+ public QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var item = string.IsNullOrEmpty(request.Id) ?
- (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
+ (!request.UserId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() :
_libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
var itemTypes = new List<string> { typeof(Movie).Name };
@@ -182,7 +147,7 @@ namespace MediaBrowser.Api.Movies
{
var categories = new List<RecommendationDto>();
- var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? (Guid?)null : new Guid(parentId);
+ var parentIdGuid = string.IsNullOrWhiteSpace(parentId) ? Guid.Empty : new Guid(parentId);
var query = new InternalItemsQuery(user)
{
@@ -193,7 +158,7 @@ namespace MediaBrowser.Api.Movies
//typeof(LiveTvProgram).Name
},
// IsMovie = true
- OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
+ OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 7,
ParentId = parentIdGuid,
Recursive = true,
@@ -214,10 +179,10 @@ namespace MediaBrowser.Api.Movies
{
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
- OrderBy = new[] { ItemSortBy.Random }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
+ OrderBy = new[] { ItemSortBy.Random }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 10,
IsFavoriteOrLiked = true,
- ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(recentlyPlayedMovies.Count),
+ ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id).ToArray(recentlyPlayedMovies.Count),
EnableGroupByMetadataKey = true,
ParentId = parentIdGuid,
Recursive = true,
@@ -316,7 +281,7 @@ namespace MediaBrowser.Api.Movies
yield return new RecommendationDto
{
BaselineItemName = name,
- CategoryId = name.GetMD5().ToString("N"),
+ CategoryId = name.GetMD5(),
RecommendationType = type,
Items = returnItems
};
@@ -356,7 +321,7 @@ namespace MediaBrowser.Api.Movies
yield return new RecommendationDto
{
BaselineItemName = name,
- CategoryId = name.GetMD5().ToString("N"),
+ CategoryId = name.GetMD5(),
RecommendationType = type,
Items = returnItems
};
@@ -393,7 +358,7 @@ namespace MediaBrowser.Api.Movies
yield return new RecommendationDto
{
BaselineItemName = item.Name,
- CategoryId = item.Id.ToString("N"),
+ CategoryId = item.Id,
RecommendationType = type,
Items = returnItems
};
@@ -405,7 +370,7 @@ namespace MediaBrowser.Api.Movies
{
var people = _libraryManager.GetPeople(new InternalPeopleQuery
{
- ExcludePersonTypes = new List<string>
+ ExcludePersonTypes = new []
{
PersonType.Director
},
diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs
index d7986fa501..538840f6c4 100644
--- a/MediaBrowser.Api/Music/AlbumsService.cs
+++ b/MediaBrowser.Api/Music/AlbumsService.cs
@@ -64,7 +64,7 @@ namespace MediaBrowser.Api.Music
request, new[] { typeof(MusicArtist) },
SimilarItemsHelper.GetSimiliarityScore);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -85,7 +85,7 @@ namespace MediaBrowser.Api.Music
request, new[] { typeof(MusicAlbum) },
GetAlbumSimilarityScore);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs
index 8a18298f1e..8435b1ac1c 100644
--- a/MediaBrowser.Api/Music/InstantMixService.cs
+++ b/MediaBrowser.Api/Music/InstantMixService.cs
@@ -29,13 +29,6 @@ namespace MediaBrowser.Api.Music
{
}
- [Route("/Artists/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given artist")]
- public class GetInstantMixFromArtist : BaseGetSimilarItems
- {
- [ApiMember(Name = "Name", Description = "The artist name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Name { get; set; }
- }
-
[Route("/MusicGenres/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a music genre")]
public class GetInstantMixFromMusicGenre : BaseGetSimilarItems
{
@@ -170,18 +163,6 @@ namespace MediaBrowser.Api.Music
return GetResult(items, user, request, dtoOptions);
}
- public object Get(GetInstantMixFromArtist request)
- {
- var user = _userManager.GetUserById(request.UserId);
- var artist = _libraryManager.GetArtist(request.Name, new DtoOptions(false));
-
- var dtoOptions = GetDtoOptions(_authContext, request);
-
- var items = _musicManager.GetInstantMixFromArtist(artist, user, dtoOptions);
-
- return GetResult(items, user, request, dtoOptions);
- }
-
private object GetResult(List<BaseItem> items, User user, BaseGetSimilarItems request, DtoOptions dtoOptions)
{
var list = items;
@@ -200,7 +181,7 @@ namespace MediaBrowser.Api.Music
result.Items = returnList;
- return ToOptimizedResult(result);
+ return result;
}
}
diff --git a/MediaBrowser.Api/NewsService.cs b/MediaBrowser.Api/NewsService.cs
index 542103799b..cbc77bfc9a 100644
--- a/MediaBrowser.Api/NewsService.cs
+++ b/MediaBrowser.Api/NewsService.cs
@@ -40,7 +40,7 @@ namespace MediaBrowser.Api
});
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
}
}
diff --git a/MediaBrowser.Api/NotificationsService.cs b/MediaBrowser.Api/NotificationsService.cs
deleted file mode 100644
index 4876351fc0..0000000000
--- a/MediaBrowser.Api/NotificationsService.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Controller.Notifications;
-using MediaBrowser.Model.Notifications;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Services;
-
-namespace MediaBrowser.Api
-{
- [Route("/Notifications/{UserId}", "GET", Summary = "Gets notifications")]
- public class GetNotifications : IReturn<NotificationResult>
- {
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
-
- [ApiMember(Name = "IsRead", Description = "An optional filter by IsRead", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
- public bool? IsRead { get; set; }
-
- [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
- public int? StartIndex { get; set; }
-
- [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; }
- }
-
- [Route("/Notifications/{UserId}/Summary", "GET", Summary = "Gets a notification summary for a user")]
- public class GetNotificationsSummary : IReturn<NotificationsSummary>
- {
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
- }
-
- [Route("/Notifications/Types", "GET", Summary = "Gets notification types")]
- public class GetNotificationTypes : IReturn<List<NotificationTypeInfo>>
- {
- }
-
- [Route("/Notifications/Services", "GET", Summary = "Gets notification types")]
- public class GetNotificationServices : IReturn<List<NotificationServiceInfo>>
- {
- }
-
- [Route("/Notifications/Admin", "POST", Summary = "Sends a notification to all admin users")]
- public class AddAdminNotification : IReturnVoid
- {
- [ApiMember(Name = "Name", Description = "The notification's name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Name { get; set; }
-
- [ApiMember(Name = "Description", Description = "The notification's description", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Description { get; set; }
-
- [ApiMember(Name = "ImageUrl", Description = "The notification's image url", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string ImageUrl { get; set; }
-
- [ApiMember(Name = "Url", Description = "The notification's info url", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string Url { get; set; }
-
- [ApiMember(Name = "Level", Description = "The notification level", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
- public NotificationLevel Level { get; set; }
- }
-
- [Route("/Notifications/{UserId}/Read", "POST", Summary = "Marks notifications as read")]
- public class MarkRead : IReturnVoid
- {
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string UserId { get; set; }
-
- [ApiMember(Name = "Ids", Description = "A list of notification ids, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
- public string Ids { get; set; }
- }
-
- [Route("/Notifications/{UserId}/Unread", "POST", Summary = "Marks notifications as unread")]
- public class MarkUnread : IReturnVoid
- {
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string UserId { get; set; }
-
- [ApiMember(Name = "Ids", Description = "A list of notification ids, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
- public string Ids { get; set; }
- }
-
- [Authenticated]
- public class NotificationsService : BaseApiService
- {
- private readonly INotificationsRepository _notificationsRepo;
- private readonly INotificationManager _notificationManager;
- private readonly IUserManager _userManager;
-
- public NotificationsService(INotificationsRepository notificationsRepo, INotificationManager notificationManager, IUserManager userManager)
- {
- _notificationsRepo = notificationsRepo;
- _notificationManager = notificationManager;
- _userManager = userManager;
- }
-
- public object Get(GetNotificationTypes request)
- {
- var result = _notificationManager.GetNotificationTypes();
-
- return ToOptimizedResult(result);
- }
-
- public object Get(GetNotificationServices request)
- {
- var result = _notificationManager.GetNotificationServices().ToList();
-
- return ToOptimizedResult(result);
- }
-
- public object Get(GetNotificationsSummary request)
- {
- var result = _notificationsRepo.GetNotificationsSummary(request.UserId);
-
- return ToOptimizedResult(result);
- }
-
- public void Post(AddAdminNotification request)
- {
- // This endpoint really just exists as post of a real with sickbeard
- var task = AddNotification(request);
-
- Task.WaitAll(task);
- }
-
- private async Task AddNotification(AddAdminNotification request)
- {
- var notification = new NotificationRequest
- {
- Date = DateTime.UtcNow,
- Description = request.Description,
- Level = request.Level,
- Name = request.Name,
- Url = request.Url,
- UserIds = _userManager.Users.Where(i => i.Policy.IsAdministrator).Select(i => i.Id.ToString("N")).ToList()
- };
-
- await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false);
- }
-
- public void Post(MarkRead request)
- {
- var task = MarkRead(request.Ids, request.UserId, true);
-
- Task.WaitAll(task);
- }
-
- public void Post(MarkUnread request)
- {
- var task = MarkRead(request.Ids, request.UserId, false);
-
- Task.WaitAll(task);
- }
-
- private Task MarkRead(string idList, string userId, bool read)
- {
- var ids = (idList ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
-
- if (ids.Length == 0)
- {
- return _notificationsRepo.MarkAllRead(userId, read, CancellationToken.None);
- }
-
- return _notificationsRepo.MarkRead(ids, userId, read, CancellationToken.None);
- }
-
- public object Get(GetNotifications request)
- {
- var result = _notificationsRepo.GetNotifications(new NotificationQuery
- {
- IsRead = request.IsRead,
- Limit = request.Limit,
- StartIndex = request.StartIndex,
- UserId = request.UserId
- });
-
- return ToOptimizedResult(result);
- }
- }
-}
diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs
index 79dda87028..366d1318bf 100644
--- a/MediaBrowser.Api/PackageService.cs
+++ b/MediaBrowser.Api/PackageService.cs
@@ -49,7 +49,7 @@ namespace MediaBrowser.Api
[ApiMember(Name = "PackageType", Description = "Optional package type filter (System/UserInstalled)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string PackageType { get; set; }
- [ApiMember(Name = "TargetSystems", Description = "Optional. Filter by target system type. Allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET", AllowMultiple = true)]
+ [ApiMember(Name = "TargetSystems", Description = "Optional. Filter by target system type. Allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string TargetSystems { get; set; }
[ApiMember(Name = "IsPremium", Description = "Optional. Filter by premium status", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
@@ -146,24 +146,24 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Get(GetPackageVersionUpdates request)
+ public async Task<object> Get(GetPackageVersionUpdates request)
{
PackageVersionInfo[] result = null;
if (string.Equals(request.PackageType, "UserInstalled", StringComparison.OrdinalIgnoreCase) || string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase))
{
- result = _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).Result.ToArray();
+ result = (await _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).ConfigureAwait(false)).ToArray();
}
else if (string.Equals(request.PackageType, "System", StringComparison.OrdinalIgnoreCase) ||
string.Equals(request.PackageType, "All", StringComparison.OrdinalIgnoreCase))
{
- var updateCheckResult = _appHost
- .CheckForApplicationUpdate(CancellationToken.None, new SimpleProgress<double>()).Result;
+ var updateCheckResult = await _appHost
+ .CheckForApplicationUpdate(CancellationToken.None, new SimpleProgress<double>()).ConfigureAwait(false);
if (updateCheckResult.IsUpdateAvailable)
{
- result = new PackageVersionInfo[] {updateCheckResult.Package};
+ result = new PackageVersionInfo[] { updateCheckResult.Package };
}
}
@@ -224,11 +224,11 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <exception cref="ResourceNotFoundException"></exception>
- public void Post(InstallPackage request)
+ public async Task Post(InstallPackage request)
{
var package = string.IsNullOrEmpty(request.Version) ?
- _installationManager.GetLatestCompatibleVersion(request.Name, request.AssemblyGuid, _appHost.ApplicationVersion, request.UpdateClass).Result :
- _installationManager.GetPackage(request.Name, request.AssemblyGuid, request.UpdateClass, Version.Parse(request.Version)).Result;
+ await _installationManager.GetLatestCompatibleVersion(request.Name, request.AssemblyGuid, _appHost.ApplicationVersion, request.UpdateClass).ConfigureAwait(false) :
+ await _installationManager.GetPackage(request.Name, request.AssemblyGuid, request.UpdateClass, Version.Parse(request.Version)).ConfigureAwait(false);
if (package == null)
{
@@ -244,7 +244,7 @@ namespace MediaBrowser.Api
/// <param name="request">The request.</param>
public void Delete(CancelPackageInstallation request)
{
- var info = _installationManager.CurrentInstallations.FirstOrDefault(i => string.Equals(i.Item1.Id, request.Id));
+ var info = _installationManager.CurrentInstallations.FirstOrDefault(i => i.Item1.Id.Equals(request.Id));
if (info != null)
{
diff --git a/MediaBrowser.Api/PlaylistService.cs b/MediaBrowser.Api/PlaylistService.cs
index 2266780217..471e3bb575 100644
--- a/MediaBrowser.Api/PlaylistService.cs
+++ b/MediaBrowser.Api/PlaylistService.cs
@@ -9,6 +9,7 @@ using MediaBrowser.Model.Querying;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.Extensions;
+using System;
namespace MediaBrowser.Api
{
@@ -21,10 +22,10 @@ namespace MediaBrowser.Api
[ApiMember(Name = "Ids", Description = "Item Ids to add to the playlist", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)]
public string Ids { get; set; }
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ public Guid UserId { get; set; }
- [ApiMember(Name = "MediaType", Description = "The playlist media type", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ [ApiMember(Name = "MediaType", Description = "The playlist media type", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
public string MediaType { get; set; }
}
@@ -42,7 +43,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
[Route("/Playlists/{Id}/Items/{ItemId}/Move/{NewIndex}", "POST", Summary = "Moves a playlist item")]
@@ -76,14 +77,14 @@ namespace MediaBrowser.Api
public class GetPlaylistItems : IReturn<QueryResult<BaseItemDto>>, IHasDtoOptions
{
[ApiMember(Name = "Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -139,9 +140,7 @@ namespace MediaBrowser.Api
public void Post(MoveItem request)
{
- var task = _playlistManager.MoveItem(request.Id, request.ItemId, request.NewIndex);
-
- Task.WaitAll(task);
+ _playlistManager.MoveItem(request.Id, request.ItemId, request.NewIndex);
}
public async Task<object> Post(CreatePlaylist request)
@@ -149,7 +148,7 @@ namespace MediaBrowser.Api
var result = await _playlistManager.CreatePlaylist(new PlaylistCreationRequest
{
Name = request.Name,
- ItemIdList = SplitValue(request.Ids, ','),
+ ItemIdList = GetGuids(request.Ids),
UserId = request.UserId,
MediaType = request.MediaType
@@ -160,22 +159,18 @@ namespace MediaBrowser.Api
public void Post(AddToPlaylist request)
{
- var task = _playlistManager.AddToPlaylist(request.Id, request.Ids.Split(','), request.UserId);
-
- Task.WaitAll(task);
+ _playlistManager.AddToPlaylist(request.Id, GetGuids(request.Ids), request.UserId);
}
public void Delete(RemoveFromPlaylist request)
{
- var task = _playlistManager.RemoveFromPlaylist(request.Id, request.EntryIds.Split(','));
-
- Task.WaitAll(task);
+ _playlistManager.RemoveFromPlaylist(request.Id, request.EntryIds.Split(','));
}
public object Get(GetPlaylistItems request)
{
var playlist = (Playlist)_libraryManager.GetItemById(request.Id);
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var items = playlist.GetManageableItems().ToArray();
diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs
index 1eea894312..1ee096a2e7 100644
--- a/MediaBrowser.Api/PluginService.cs
+++ b/MediaBrowser.Api/PluginService.cs
@@ -6,7 +6,6 @@ using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Plugins;
-using MediaBrowser.Model.Registration;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
@@ -15,6 +14,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
+using MediaBrowser.Common.Plugins;
namespace MediaBrowser.Api
{
@@ -103,9 +103,6 @@ namespace MediaBrowser.Api
{
[ApiMember(Name = "Name", Description = "Feature Name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Name { get; set; }
-
- [ApiMember(Name = "Mb2Equivalent", Description = "Optional. The equivalent feature name in MB2", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string Mb2Equivalent { get; set; }
}
[Route("/Registrations/{Name}", "GET", Summary = "Gets registration status for a feature", IsHidden = true)]
@@ -116,6 +113,14 @@ namespace MediaBrowser.Api
public string Name { get; set; }
}
+ public class RegistrationInfo
+ {
+ public string Name { get; set; }
+ public DateTime ExpirationDate { get; set; }
+ public bool IsTrial { get; set; }
+ public bool IsRegistered { get; set; }
+ }
+
[Route("/Appstore/Register", "POST", Summary = "Registers an appstore sale", IsHidden = true)]
[Authenticated]
public class RegisterAppstoreSale
@@ -168,7 +173,7 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public async Task<object> Get(GetRegistrationStatus request)
{
- var result = await _securityManager.GetRegistrationStatus(request.Name, request.Mb2Equivalent).ConfigureAwait(false);
+ var result = await _securityManager.GetRegistrationStatus(request.Name).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@@ -235,7 +240,7 @@ namespace MediaBrowser.Api
}
}
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -246,7 +251,7 @@ namespace MediaBrowser.Api
public object Get(GetPluginConfiguration request)
{
var guid = new Guid(request.Id);
- var plugin = _appHost.Plugins.First(p => p.Id == guid);
+ var plugin = _appHost.Plugins.First(p => p.Id == guid) as IHasPluginConfiguration;
return ToOptimizedResult(plugin.Configuration);
}
@@ -256,15 +261,15 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Get(GetPluginSecurityInfo request)
+ public async Task<object> Get(GetPluginSecurityInfo request)
{
var result = new PluginSecurityInfo
{
- IsMBSupporter = _securityManager.IsMBSupporter,
+ IsMBSupporter = await _securityManager.IsSupporter().ConfigureAwait(false),
SupporterKey = _securityManager.SupporterKey
};
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -272,37 +277,38 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
- public void Post(RegisterAppstoreSale request)
+ public Task Post(RegisterAppstoreSale request)
{
- var task = _securityManager.RegisterAppStoreSale(request.Parameters);
-
- Task.WaitAll(task);
+ return _securityManager.RegisterAppStoreSale(request.Parameters);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(UpdatePluginSecurityInfo request)
+ public Task Post(UpdatePluginSecurityInfo request)
{
- var info = request;
-
- _securityManager.SupporterKey = info.SupporterKey;
+ return _securityManager.UpdateSupporterKey(request.SupporterKey);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(UpdatePluginConfiguration request)
+ public async Task Post(UpdatePluginConfiguration request)
{
// We need to parse this manually because we told service stack not to with IRequiresRequestStream
// https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
var id = new Guid(GetPathValue(1));
- var plugin = _appHost.Plugins.First(p => p.Id == id);
+ var plugin = _appHost.Plugins.First(p => p.Id == id) as IHasPluginConfiguration;
+
+ if (plugin == null)
+ {
+ throw new FileNotFoundException();
+ }
- var configuration = _jsonSerializer.DeserializeFromStream(request.RequestStream, plugin.ConfigurationType) as BasePluginConfiguration;
+ var configuration = (await _jsonSerializer.DeserializeFromStreamAsync(request.RequestStream, plugin.ConfigurationType).ConfigureAwait(false)) as BasePluginConfiguration;
plugin.UpdateConfiguration(configuration);
}
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
index abe3e5407c..959bdcd550 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
@@ -207,7 +207,7 @@ namespace MediaBrowser.Api.ScheduledTasks
}
}
- TaskManager.Execute(task);
+ TaskManager.Execute(task, new TaskOptions());
}
/// <summary>
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
index 2d30625a98..ff57b4dd15 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
@@ -33,8 +33,8 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary>
/// Initializes a new instance of the <see cref="ScheduledTasksWebSocketListener" /> class.
/// </summary>
- public ScheduledTasksWebSocketListener(ILogger logger, ITaskManager taskManager, ITimerFactory timerFactory)
- : base(logger, timerFactory)
+ public ScheduledTasksWebSocketListener(ILogger logger, ITaskManager taskManager)
+ : base(logger)
{
TaskManager = taskManager;
@@ -72,14 +72,6 @@ namespace MediaBrowser.Api.ScheduledTasks
.Where(i => !i.IsHidden));
}
- protected override bool SendOnTimer
- {
- get
- {
- return false;
- }
- }
-
protected override void Dispose(bool dispose)
{
TaskManager.TaskExecuting -= TaskManager_TaskExecuting;
diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs
index 50033eee82..2e363136b3 100644
--- a/MediaBrowser.Api/SearchService.cs
+++ b/MediaBrowser.Api/SearchService.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Model.Search;
using System.Threading.Tasks;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Services;
+using System;
namespace MediaBrowser.Api
{
@@ -39,7 +40,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Supply a user id to search within a user's library or omit to search all.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Search characters used to find items
@@ -134,11 +135,11 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public async Task<object> Get(GetSearchHints request)
+ public object Get(GetSearchHints request)
{
- var result = await GetSearchHintsAsync(request).ConfigureAwait(false);
+ var result = GetSearchHintsAsync(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -146,9 +147,9 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>Task{IEnumerable{SearchHintResult}}.</returns>
- private async Task<SearchHintResult> GetSearchHintsAsync(GetSearchHints request)
+ private SearchHintResult GetSearchHintsAsync(GetSearchHints request)
{
- var result = await _searchEngine.GetSearchHints(new SearchQuery
+ var result = _searchEngine.GetSearchHints(new SearchQuery
{
Limit = request.Limit,
SearchTerm = request.SearchTerm,
@@ -170,7 +171,7 @@ namespace MediaBrowser.Api
IsSeries = request.IsSeries,
IsSports = request.IsSports
- }).ConfigureAwait(false);
+ });
return new SearchHintResult
{
@@ -194,7 +195,7 @@ namespace MediaBrowser.Api
Name = item.Name,
IndexNumber = item.IndexNumber,
ParentIndexNumber = item.ParentIndexNumber,
- ItemId = _dtoService.GetDtoId(item),
+ Id = item.Id,
Type = item.GetClientTypeName(),
MediaType = item.MediaType,
MatchedTerm = hintInfo.MatchedTerm,
@@ -204,6 +205,14 @@ namespace MediaBrowser.Api
EndDate = item.EndDate
};
+ // legacy
+ result.ItemId = result.Id;
+
+ if (item.IsFolder)
+ {
+ result.IsFolder = true;
+ }
+
var primaryImageTag = _imageProcessor.GetImageCacheTag(item, ImageType.Primary);
if (primaryImageTag != null)
@@ -221,7 +230,7 @@ namespace MediaBrowser.Api
result.StartDate = program.StartDate;
}
- var hasSeries = item as IHasSeries;
+ var hasSeries = item as IHasSeriesName;
if (hasSeries != null)
{
result.Series = hasSeries.SeriesName;
@@ -256,7 +265,7 @@ namespace MediaBrowser.Api
if (album != null)
{
result.Album = album.Name;
- result.AlbumId = album.Id.ToString("N");
+ result.AlbumId = album.Id;
}
else
{
@@ -264,7 +273,7 @@ namespace MediaBrowser.Api
}
}
- if (!string.IsNullOrWhiteSpace(item.ChannelId))
+ if (!item.ChannelId.Equals(Guid.Empty))
{
var channel = _libraryManager.GetItemById(item.ChannelId);
result.ChannelName = channel == null ? null : channel.Name;
diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs
index 65c69fc7de..ca2c381cf6 100644
--- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs
+++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs
@@ -14,7 +14,7 @@ namespace MediaBrowser.Api.Session
/// <summary>
/// Class SessionInfoWebSocketListener
/// </summary>
- class SessionInfoWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SessionInfoDto>, WebSocketListenerState>
+ class SessionInfoWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<SessionInfo>, WebSocketListenerState>
{
/// <summary>
/// Gets the name.
@@ -33,8 +33,8 @@ namespace MediaBrowser.Api.Session
/// <summary>
/// Initializes a new instance of the <see cref="SessionInfoWebSocketListener"/> class.
/// </summary>
- public SessionInfoWebSocketListener(ILogger logger, ISessionManager sessionManager, ITimerFactory timerFactory)
- : base(logger, timerFactory)
+ public SessionInfoWebSocketListener(ILogger logger, ISessionManager sessionManager)
+ : base(logger)
{
_sessionManager = sessionManager;
@@ -87,17 +87,9 @@ namespace MediaBrowser.Api.Session
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{SystemInfo}.</returns>
- protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken)
+ protected override Task<IEnumerable<SessionInfo>> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken)
{
- return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_sessionManager.GetSessionInfoDto));
- }
-
- protected override bool SendOnTimer
- {
- get
- {
- return false;
- }
+ return Task.FromResult(_sessionManager.Sessions);
}
protected override void Dispose(bool dispose)
diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs
index 35c29cd15b..1056b3c8bd 100644
--- a/MediaBrowser.Api/Session/SessionsService.cs
+++ b/MediaBrowser.Api/Session/SessionsService.cs
@@ -11,6 +11,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
using MediaBrowser.Controller;
+using MediaBrowser.Model.Dto;
namespace MediaBrowser.Api.Session
{
@@ -19,13 +20,15 @@ namespace MediaBrowser.Api.Session
/// </summary>
[Route("/Sessions", "GET", Summary = "Gets a list of sessions")]
[Authenticated]
- public class GetSessions : IReturn<SessionInfoDto[]>
+ public class GetSessions : IReturn<SessionInfo[]>
{
[ApiMember(Name = "ControllableByUserId", Description = "Optional. Filter by sessions that a given user is allowed to remote control.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string ControllableByUserId { get; set; }
+ public Guid ControllableByUserId { get; set; }
[ApiMember(Name = "DeviceId", Description = "Optional. Filter by device id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string DeviceId { get; set; }
+
+ public int? ActiveWithinSeconds { get; set; }
}
/// <summary>
@@ -189,7 +192,7 @@ namespace MediaBrowser.Api.Session
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string Id { get; set; }
[ApiMember(Name = "PlayableMediaTypes", Description = "A list of playable media types, comma delimited. Audio, Video, Book, Game, Photo.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
@@ -198,9 +201,6 @@ namespace MediaBrowser.Api.Session
[ApiMember(Name = "SupportedCommands", Description = "A list of supported remote control commands, comma delimited", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
public string SupportedCommands { get; set; }
- [ApiMember(Name = "MessageCallbackUrl", Description = "A url to post messages to, including remote control commands.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string MessageCallbackUrl { get; set; }
-
[ApiMember(Name = "SupportsMediaControl", Description = "Determines whether media can be played remotely.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool SupportsMediaControl { get; set; }
@@ -210,8 +210,6 @@ namespace MediaBrowser.Api.Session
[ApiMember(Name = "SupportsPersistentIdentifier", Description = "Determines whether the device supports a unique identifier.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool SupportsPersistentIdentifier { get; set; }
- public bool SupportsContentUploading { get; set; }
-
public PostCapabilities()
{
SupportsPersistentIdentifier = true;
@@ -226,7 +224,7 @@ namespace MediaBrowser.Api.Session
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string Id { get; set; }
}
@@ -242,11 +240,17 @@ namespace MediaBrowser.Api.Session
{
}
+ [Route("/Auth/Providers", "GET")]
+ [Authenticated(Roles = "Admin")]
+ public class GetAuthProviders : IReturn<NameIdPair[]>
+ {
+ }
+
[Route("/Auth/Keys/{Key}", "DELETE")]
[Authenticated(Roles = "Admin")]
public class RevokeKey
{
- [ApiMember(Name = "Key", Description = "Auth Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ [ApiMember(Name = "Key", Description = "Auth Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
public string Key { get; set; }
}
@@ -286,6 +290,11 @@ namespace MediaBrowser.Api.Session
_appHost = appHost;
}
+ public object Get(GetAuthProviders request)
+ {
+ return _userManager.GetAuthenticationProviders();
+ }
+
public void Delete(RevokeKey request)
{
_sessionManager.RevokeToken(request.Key);
@@ -297,14 +306,13 @@ namespace MediaBrowser.Api.Session
_authRepo.Create(new AuthenticationInfo
{
AppName = request.App,
- IsActive = true,
AccessToken = Guid.NewGuid().ToString("N"),
DateCreated = DateTime.UtcNow,
DeviceId = _appHost.SystemId,
DeviceName = _appHost.FriendlyName,
AppVersion = _appHost.ApplicationVersion.ToString()
- }, CancellationToken.None);
+ });
}
public void Post(ReportSessionEnded request)
@@ -318,11 +326,10 @@ namespace MediaBrowser.Api.Session
{
var result = _authRepo.Get(new AuthenticationInfoQuery
{
- IsActive = true,
HasUser = false
});
- return ToOptimizedResult(result);
+ return result;
}
/// <summary>
@@ -332,27 +339,33 @@ namespace MediaBrowser.Api.Session
/// <returns>System.Object.</returns>
public object Get(GetSessions request)
{
- var result = _sessionManager.Sessions.Where(i => i.IsActive);
+ var result = _sessionManager.Sessions;
if (!string.IsNullOrEmpty(request.DeviceId))
{
result = result.Where(i => string.Equals(i.DeviceId, request.DeviceId, StringComparison.OrdinalIgnoreCase));
}
- if (!string.IsNullOrWhiteSpace(request.ControllableByUserId))
+ if (!request.ControllableByUserId.Equals(Guid.Empty))
{
- result = result.Where(i => i.SupportsMediaControl);
+ result = result.Where(i => i.SupportsRemoteControl);
var user = _userManager.GetUserById(request.ControllableByUserId);
if (!user.Policy.EnableRemoteControlOfOtherUsers)
{
- result = result.Where(i => !i.UserId.HasValue || i.ContainsUser(request.ControllableByUserId));
+ result = result.Where(i => i.UserId.Equals(Guid.Empty) || i.ContainsUser(request.ControllableByUserId));
}
if (!user.Policy.EnableSharedDeviceControl)
{
- result = result.Where(i => i.UserId.HasValue);
+ result = result.Where(i => !i.UserId.Equals(Guid.Empty));
+ }
+
+ if (request.ActiveWithinSeconds.HasValue && request.ActiveWithinSeconds.Value > 0)
+ {
+ var minActiveDate = DateTime.UtcNow.AddSeconds(0 - request.ActiveWithinSeconds.Value);
+ result = result.Where(i => i.LastActivityDate >= minActiveDate);
}
result = result.Where(i =>
@@ -361,7 +374,7 @@ namespace MediaBrowser.Api.Session
if (!string.IsNullOrWhiteSpace(deviceId))
{
- if (!_deviceManager.CanAccessDevice(user.Id.ToString("N"), deviceId))
+ if (!_deviceManager.CanAccessDevice(user, deviceId))
{
return false;
}
@@ -371,21 +384,19 @@ namespace MediaBrowser.Api.Session
});
}
- return ToOptimizedResult(result.Select(_sessionManager.GetSessionInfoDto).ToArray());
+ return ToOptimizedResult(result.ToArray());
}
- public void Post(SendPlaystateCommand request)
+ public Task Post(SendPlaystateCommand request)
{
- var task = _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Result.Id, request.Id, request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendPlaystateCommand(GetSession(_sessionContext).Id, request.Id, request, CancellationToken.None);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(DisplayContent request)
+ public Task Post(DisplayContent request)
{
var command = new BrowseRequest
{
@@ -394,16 +405,14 @@ namespace MediaBrowser.Api.Session
ItemType = request.ItemType
};
- var task = _sessionManager.SendBrowseCommand(GetSession(_sessionContext).Result.Id, request.Id, command, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendBrowseCommand(GetSession(_sessionContext).Id, request.Id, command, CancellationToken.None);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SendSystemCommand request)
+ public Task Post(SendSystemCommand request)
{
GeneralCommandType commandType;
var name = request.Command;
@@ -413,24 +422,22 @@ namespace MediaBrowser.Api.Session
name = commandType.ToString();
}
- var currentSession = GetSession(_sessionContext).Result;
+ var currentSession = GetSession(_sessionContext);
var command = new GeneralCommand
{
Name = name,
- ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null
+ ControllingUserId = currentSession.UserId
};
- var task = _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(SendMessageCommand request)
+ public Task Post(SendMessageCommand request)
{
var command = new MessageCommand
{
@@ -439,63 +446,55 @@ namespace MediaBrowser.Api.Session
Text = request.Text
};
- var task = _sessionManager.SendMessageCommand(GetSession(_sessionContext).Result.Id, request.Id, command, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendMessageCommand(GetSession(_sessionContext).Id, request.Id, command, CancellationToken.None);
}
/// <summary>
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(Play request)
+ public Task Post(Play request)
{
- var task = _sessionManager.SendPlayCommand(GetSession(_sessionContext).Result.Id, request.Id, request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendPlayCommand(GetSession(_sessionContext).Id, request.Id, request, CancellationToken.None);
}
- public void Post(SendGeneralCommand request)
+ public Task Post(SendGeneralCommand request)
{
- var currentSession = GetSession(_sessionContext).Result;
+ var currentSession = GetSession(_sessionContext);
var command = new GeneralCommand
{
Name = request.Command,
- ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null
+ ControllingUserId = currentSession.UserId
};
- var task = _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, command, CancellationToken.None);
}
- public void Post(SendFullGeneralCommand request)
+ public Task Post(SendFullGeneralCommand request)
{
- var currentSession = GetSession(_sessionContext).Result;
+ var currentSession = GetSession(_sessionContext);
- request.ControllingUserId = currentSession.UserId.HasValue ? currentSession.UserId.Value.ToString("N") : null;
+ request.ControllingUserId = currentSession.UserId;
- var task = _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, request, CancellationToken.None);
-
- Task.WaitAll(task);
+ return _sessionManager.SendGeneralCommand(currentSession.Id, request.Id, request, CancellationToken.None);
}
public void Post(AddUserToSession request)
{
- _sessionManager.AddAdditionalUser(request.Id, request.UserId);
+ _sessionManager.AddAdditionalUser(request.Id, new Guid(request.UserId));
}
public void Delete(RemoveUserFromSession request)
{
- _sessionManager.RemoveAdditionalUser(request.Id, request.UserId);
+ _sessionManager.RemoveAdditionalUser(request.Id, new Guid(request.UserId));
}
public void Post(PostCapabilities request)
{
if (string.IsNullOrWhiteSpace(request.Id))
{
- request.Id = GetSession(_sessionContext).Result.Id;
+ request.Id = GetSession(_sessionContext).Id;
}
_sessionManager.ReportCapabilities(request.Id, new ClientCapabilities
{
@@ -505,12 +504,8 @@ namespace MediaBrowser.Api.Session
SupportsMediaControl = request.SupportsMediaControl,
- MessageCallbackUrl = request.MessageCallbackUrl,
-
SupportsSync = request.SupportsSync,
- SupportsContentUploading = request.SupportsContentUploading,
-
SupportsPersistentIdentifier = request.SupportsPersistentIdentifier
});
}
@@ -519,7 +514,7 @@ namespace MediaBrowser.Api.Session
{
if (string.IsNullOrWhiteSpace(request.Id))
{
- request.Id = GetSession(_sessionContext).Result.Id;
+ request.Id = GetSession(_sessionContext).Id;
}
_sessionManager.ReportCapabilities(request.Id, request);
}
diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs
index 0b5eaa4760..be9c1a4c58 100644
--- a/MediaBrowser.Api/SimilarItemsHelper.cs
+++ b/MediaBrowser.Api/SimilarItemsHelper.cs
@@ -49,7 +49,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// The maximum number of items to return
@@ -73,10 +73,10 @@ namespace MediaBrowser.Api
{
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)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? userManager.GetUserById(request.UserId) : null;
var item = string.IsNullOrEmpty(request.Id) ?
- (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
+ (!request.UserId.Equals(Guid.Empty) ? libraryManager.GetUserRootFolder() :
libraryManager.RootFolder) : libraryManager.GetItemById(request.Id);
var query = new InternalItemsQuery(user)
@@ -89,7 +89,7 @@ namespace MediaBrowser.Api
// ExcludeArtistIds
if (!string.IsNullOrEmpty(request.ExcludeArtistIds))
{
- query.ExcludeArtistIds = request.ExcludeArtistIds.Split('|');
+ query.ExcludeArtistIds = BaseApiService.GetGuids(request.ExcludeArtistIds);
}
var inputItems = libraryManager.GetItemList(query);
diff --git a/MediaBrowser.Api/Social/SharingService.cs b/MediaBrowser.Api/Social/SharingService.cs
deleted file mode 100644
index 4f10667b72..0000000000
--- a/MediaBrowser.Api/Social/SharingService.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Dlna;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Social;
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Services;
-
-namespace MediaBrowser.Api.Social
-{
- [Route("/Social/Shares/{Id}", "GET", Summary = "Gets a share")]
- [Authenticated]
- public class GetSocialShareInfo : IReturn<SocialShareInfo>
- {
- [ApiMember(Name = "Id", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/Social/Shares/Public/{Id}", "GET", Summary = "Gets a share")]
- public class GetPublicSocialShareInfo : IReturn<SocialShareInfo>
- {
- [ApiMember(Name = "Id", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/Social/Shares/Public/{Id}/Image", "GET", Summary = "Gets a share")]
- public class GetShareImage
- {
- [ApiMember(Name = "Id", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- [Route("/Social/Shares", "POST", Summary = "Creates a share")]
- [Authenticated]
- public class CreateShare : IReturn<SocialShareInfo>
- {
- [ApiMember(Name = "ItemId", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string ItemId { get; set; }
-
- [ApiMember(Name = "UserId", Description = "The user id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
- public string UserId { get; set; }
- }
-
- [Route("/Social/Shares/{Id}", "DELETE", Summary = "Deletes a share")]
- [Authenticated]
- public class DeleteShare : IReturnVoid
- {
- [ApiMember(Name = "Id", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
- }
-
- [Route("/Social/Shares/Public/{Id}/Item", "GET", Summary = "Gets a share")]
- public class GetSharedLibraryItem
- {
- [ApiMember(Name = "Id", Description = "The id of the item", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- public class SharingService : BaseApiService
- {
- private readonly ISharingManager _sharingManager;
- private readonly ILibraryManager _libraryManager;
- private readonly IDlnaManager _dlnaManager;
- private readonly IDtoService _dtoService;
- private readonly IHttpResultFactory _resultFactory;
-
- public SharingService(ISharingManager sharingManager, IDlnaManager dlnaManager, ILibraryManager libraryManager, IDtoService dtoService, IHttpResultFactory resultFactory)
- {
- _sharingManager = sharingManager;
- _dlnaManager = dlnaManager;
- _libraryManager = libraryManager;
- _dtoService = dtoService;
- _resultFactory = resultFactory;
- }
-
- public object Get(GetSocialShareInfo request)
- {
- var info = _sharingManager.GetShareInfo(request.Id);
-
- return ToOptimizedResult(info);
- }
-
- public object Get(GetSharedLibraryItem request)
- {
- var info = _sharingManager.GetShareInfo(request.Id);
-
- if (info.ExpirationDate <= DateTime.UtcNow)
- {
- throw new ResourceNotFoundException();
- }
-
- var item = _libraryManager.GetItemById(info.ItemId);
-
- var dto = _dtoService.GetBaseItemDto(item, new DtoOptions());
-
- return ToOptimizedResult(dto);
- }
-
- public object Get(GetPublicSocialShareInfo request)
- {
- var info = _sharingManager.GetShareInfo(request.Id);
-
- if (info.ExpirationDate <= DateTime.UtcNow)
- {
- throw new ResourceNotFoundException();
- }
-
- return ToOptimizedResult(info);
- }
-
- public async Task<object> Post(CreateShare request)
- {
- var info = await _sharingManager.CreateShare(request.ItemId, request.UserId).ConfigureAwait(false);
-
- return ToOptimizedResult(info);
- }
-
- public void Delete(DeleteShare request)
- {
- _sharingManager.DeleteShare(request.Id);
- }
-
- public async Task<object> Get(GetShareImage request)
- {
- var share = _sharingManager.GetShareInfo(request.Id);
-
- if (share == null)
- {
- throw new ResourceNotFoundException();
- }
- if (share.ExpirationDate <= DateTime.UtcNow)
- {
- throw new ResourceNotFoundException();
- }
-
- var item = _libraryManager.GetItemById(share.ItemId);
-
- var image = item.GetImageInfo(ImageType.Primary, 0);
-
- if (image != null)
- {
- if (image.IsLocalFile)
- {
- return await _resultFactory.GetStaticFileResult(Request, image.Path).ConfigureAwait(false);
- }
-
- try
- {
- // Don't fail the request over this
- var updatedImage = await _libraryManager.ConvertImageToLocal(item, image, 0).ConfigureAwait(false);
- return await _resultFactory.GetStaticFileResult(Request, updatedImage.Path).ConfigureAwait(false);
- }
- catch
- {
-
- }
- }
-
- // Grab a dlna icon if nothing else is available
- using (var response = _dlnaManager.GetIcon("logo240.jpg"))
- {
- using (var ms = new MemoryStream())
- {
- response.Stream.CopyTo(ms);
-
- ms.Position = 0;
- var bytes = ms.ToArray();
- return ResultFactory.GetResult(bytes, "image/" + response.Format.ToString().ToLower());
- }
- }
-
- }
- }
-}
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs
index c6345c17f4..61d9a90d6c 100644
--- a/MediaBrowser.Api/StartupWizardService.cs
+++ b/MediaBrowser.Api/StartupWizardService.cs
@@ -3,7 +3,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Connect;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Configuration;
using System;
using System.Linq;
using System.Threading.Tasks;
@@ -14,32 +13,34 @@ using System.Threading;
namespace MediaBrowser.Api
{
- [Route("/Startup/Complete", "POST", Summary = "Reports that the startup wizard has been completed")]
+ [Route("/Startup/Complete", "POST", Summary = "Reports that the startup wizard has been completed", IsHidden = true)]
public class ReportStartupWizardComplete : IReturnVoid
{
}
- [Route("/Startup/Info", "GET", Summary = "Gets initial server info")]
- public class GetStartupInfo : IReturn<StartupInfo>
+ [Route("/Startup/Configuration", "GET", Summary = "Gets initial server configuration", IsHidden = true)]
+ public class GetStartupConfiguration : IReturn<StartupConfiguration>
{
}
- [Route("/Startup/Configuration", "GET", Summary = "Gets initial server configuration")]
- public class GetStartupConfiguration : IReturn<StartupConfiguration>
+ [Route("/Startup/Configuration", "POST", Summary = "Updates initial server configuration", IsHidden = true)]
+ public class UpdateStartupConfiguration : StartupConfiguration, IReturnVoid
{
}
- [Route("/Startup/Configuration", "POST", Summary = "Updates initial server configuration")]
- public class UpdateStartupConfiguration : StartupConfiguration, IReturnVoid
+ [Route("/Startup/RemoteAccess", "POST", Summary = "Updates initial server configuration", IsHidden = true)]
+ public class UpdateRemoteAccessConfiguration : IReturnVoid
{
+ public bool EnableRemoteAccess { get; set; }
+ public bool EnableAutomaticPortMapping { get; set; }
}
- [Route("/Startup/User", "GET", Summary = "Gets initial user info")]
+ [Route("/Startup/User", "GET", Summary = "Gets initial user info", IsHidden = true)]
public class GetStartupUser : IReturn<StartupUser>
{
}
- [Route("/Startup/User", "POST", Summary = "Updates initial user info")]
+ [Route("/Startup/User", "POST", Summary = "Updates initial user info", IsHidden = true)]
public class UpdateStartupUser : StartupUser, IReturn<UpdateStartupUserResult>
{
}
@@ -67,7 +68,6 @@ namespace MediaBrowser.Api
public void Post(ReportStartupWizardComplete request)
{
_config.Configuration.IsStartupWizardCompleted = true;
- _config.Configuration.AutoRunWebApp = true;
_config.SetOptimalValues();
_config.SaveConfiguration();
@@ -101,14 +101,6 @@ namespace MediaBrowser.Api
}
}
- public object Get(GetStartupInfo request)
- {
- return new StartupInfo
- {
- HasMediaEncoder = !string.IsNullOrWhiteSpace(_mediaEncoder.EncoderPath)
- };
- }
-
public object Get(GetStartupConfiguration request)
{
var result = new StartupConfiguration
@@ -129,6 +121,13 @@ namespace MediaBrowser.Api
_config.SaveConfiguration();
}
+ public void Post(UpdateRemoteAccessConfiguration request)
+ {
+ _config.Configuration.EnableRemoteAccess = request.EnableRemoteAccess;
+ _config.Configuration.EnableUPnP = request.EnableAutomaticPortMapping;
+ _config.SaveConfiguration();
+ }
+
public object Get(GetStartupUser request)
{
var user = _userManager.Users.First();
@@ -152,11 +151,11 @@ namespace MediaBrowser.Api
if (!string.IsNullOrWhiteSpace(user.ConnectUserName) &&
string.IsNullOrWhiteSpace(request.ConnectUserName))
{
- await _connectManager.RemoveConnect(user.Id.ToString("N")).ConfigureAwait(false);
+ await _connectManager.RemoveConnect(user).ConfigureAwait(false);
}
else if (!string.Equals(user.ConnectUserName, request.ConnectUserName, StringComparison.OrdinalIgnoreCase))
{
- result.UserLinkResult = await _connectManager.LinkUser(user.Id.ToString("N"), request.ConnectUserName).ConfigureAwait(false);
+ result.UserLinkResult = await _connectManager.LinkUser(user, request.ConnectUserName).ConfigureAwait(false);
}
return result;
@@ -170,11 +169,6 @@ namespace MediaBrowser.Api
public string PreferredMetadataLanguage { get; set; }
}
- public class StartupInfo
- {
- public bool HasMediaEncoder { get; set; }
- }
-
public class StartupUser
{
public string Name { get; set; }
diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs
index 4d4b4cb273..c8b0a32e95 100644
--- a/MediaBrowser.Api/Subtitles/SubtitleService.cs
+++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs
@@ -29,7 +29,7 @@ namespace MediaBrowser.Api.Subtitles
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
[ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "DELETE")]
public int Index { get; set; }
@@ -40,7 +40,7 @@ namespace MediaBrowser.Api.Subtitles
public class SearchRemoteSubtitles : IReturn<RemoteSubtitleInfo[]>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
[ApiMember(Name = "Language", Description = "Language", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Language { get; set; }
@@ -48,20 +48,12 @@ namespace MediaBrowser.Api.Subtitles
public bool? IsPerfectMatch { get; set; }
}
- [Route("/Items/{Id}/RemoteSearch/Subtitles/Providers", "GET")]
- [Authenticated]
- public class GetSubtitleProviders : IReturn<SubtitleProviderInfo[]>
- {
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
[Route("/Items/{Id}/RemoteSearch/Subtitles/{SubtitleId}", "POST")]
[Authenticated]
public class DownloadRemoteSubtitles : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
[ApiMember(Name = "SubtitleId", Description = "SubtitleId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
public string SubtitleId { get; set; }
@@ -84,7 +76,7 @@ namespace MediaBrowser.Api.Subtitles
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
[ApiMember(Name = "MediaSourceId", Description = "MediaSourceId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string MediaSourceId { get; set; }
@@ -123,7 +115,7 @@ namespace MediaBrowser.Api.Subtitles
[ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
public int Index { get; set; }
- [ApiMember(Name = "SegmentLength", Description = "The subtitle srgment length", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
+ [ApiMember(Name = "SegmentLength", Description = "The subtitle srgment length", IsRequired = true, DataType = "int", ParameterType = "query", Verb = "GET")]
public int SegmentLength { get; set; }
}
@@ -195,7 +187,7 @@ namespace MediaBrowser.Api.Subtitles
builder.AppendLine("#EXT-X-ENDLIST");
- return ResultFactory.GetResult(builder.ToString(), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
+ return ResultFactory.GetResult(Request, builder.ToString(), MimeTypes.GetMimeType("playlist.m3u8"), new Dictionary<string, string>());
}
public async Task<object> Get(GetSubtitle request)
@@ -206,10 +198,11 @@ namespace MediaBrowser.Api.Subtitles
}
if (string.IsNullOrEmpty(request.Format))
{
- var item = (Video)_libraryManager.GetItemById(new Guid(request.Id));
+ var item = (Video)_libraryManager.GetItemById(request.Id);
+ var idString = request.Id.ToString("N");
var mediaSource = _mediaSourceManager.GetStaticMediaSources(item, false, null)
- .First(i => string.Equals(i.Id, request.MediaSourceId ?? request.Id));
+ .First(i => string.Equals(i.Id, request.MediaSourceId ?? idString));
var subtitleStream = mediaSource.MediaStreams
.First(i => i.Type == MediaStreamType.Subtitle && i.Index == request.Index);
@@ -227,22 +220,24 @@ namespace MediaBrowser.Api.Subtitles
text = text.Replace("WEBVTT", "WEBVTT\nX-TIMESTAMP-MAP=MPEGTS:900000,LOCAL:00:00:00.000");
- return ResultFactory.GetResult(text, MimeTypes.GetMimeType("file." + request.Format));
+ return ResultFactory.GetResult(Request, text, MimeTypes.GetMimeType("file." + request.Format));
}
}
}
- return ResultFactory.GetResult(await GetSubtitles(request).ConfigureAwait(false), MimeTypes.GetMimeType("file." + request.Format));
+ return ResultFactory.GetResult(Request, await GetSubtitles(request).ConfigureAwait(false), MimeTypes.GetMimeType("file." + request.Format));
}
private Task<Stream> GetSubtitles(GetSubtitle request)
{
- return _subtitleEncoder.GetSubtitles(request.Id,
+ var item = _libraryManager.GetItemById(request.Id);
+
+ return _subtitleEncoder.GetSubtitles(item,
request.MediaSourceId,
request.Index,
request.Format,
request.StartPositionTicks,
- request.EndPositionTicks,
+ request.EndPositionTicks ?? 0,
request.CopyTimestamps,
CancellationToken.None);
}
@@ -251,30 +246,20 @@ namespace MediaBrowser.Api.Subtitles
{
var video = (Video)_libraryManager.GetItemById(request.Id);
- var response = await _subtitleManager.SearchSubtitles(video, request.Language, request.IsPerfectMatch, CancellationToken.None).ConfigureAwait(false);
-
- return ToOptimizedResult(response);
- }
-
- public void Delete(DeleteSubtitle request)
- {
- var task = _subtitleManager.DeleteSubtitles(request.Id, request.Index);
-
- Task.WaitAll(task);
+ return await _subtitleManager.SearchSubtitles(video, request.Language, request.IsPerfectMatch, CancellationToken.None).ConfigureAwait(false);
}
- public object Get(GetSubtitleProviders request)
+ public Task Delete(DeleteSubtitle request)
{
- var result = _subtitleManager.GetProviders(request.Id);
-
- return ToOptimizedResult(result);
+ var item = _libraryManager.GetItemById(request.Id);
+ return _subtitleManager.DeleteSubtitles(item, request.Index);
}
public async Task<object> Get(GetRemoteSubtitles request)
{
var result = await _subtitleManager.GetRemoteSubtitles(request.Id, CancellationToken.None).ConfigureAwait(false);
- return ResultFactory.GetResult(result.Stream, MimeTypes.GetMimeType("file." + result.Format));
+ return ResultFactory.GetResult(Request, result.Stream, MimeTypes.GetMimeType("file." + result.Format));
}
public void Post(DownloadRemoteSubtitles request)
diff --git a/MediaBrowser.Api/SuggestionsService.cs b/MediaBrowser.Api/SuggestionsService.cs
index 3b918d8a2f..07053c5542 100644
--- a/MediaBrowser.Api/SuggestionsService.cs
+++ b/MediaBrowser.Api/SuggestionsService.cs
@@ -14,11 +14,11 @@ using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api
{
[Route("/Users/{UserId}/Suggestions", "GET", Summary = "Gets items based on a query.")]
- public class GetSuggestedItems : IReturn<QueryResult<BaseItem>>
+ public class GetSuggestedItems : IReturn<QueryResult<BaseItemDto>>
{
public string MediaType { get; set; }
public string Type { get; set; }
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
public bool EnableTotalRecordCount { get; set; }
public int? StartIndex { get; set; }
public int? Limit { get; set; }
@@ -51,14 +51,12 @@ namespace MediaBrowser.Api
public object Get(GetSuggestedItems request)
{
- var result = GetResultItems(request);
-
- return ToOptimizedResult(result);
+ return GetResultItems(request);
}
private QueryResult<BaseItemDto> GetResultItems(GetSuggestedItems request)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var dtoOptions = GetDtoOptions(_authContext, request);
var result = GetItems(request, user, dtoOptions);
@@ -81,7 +79,7 @@ namespace MediaBrowser.Api
{
return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
- OrderBy = new[] { ItemSortBy.Random }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
+ OrderBy = new[] { ItemSortBy.Random }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
MediaTypes = request.GetMediaTypes(),
IncludeItemTypes = request.GetIncludeItemTypes(),
IsVirtualItem = false,
diff --git a/MediaBrowser.Api/System/ActivityLogService.cs b/MediaBrowser.Api/System/ActivityLogService.cs
index e3a18a9335..d55c57ffaa 100644
--- a/MediaBrowser.Api/System/ActivityLogService.cs
+++ b/MediaBrowser.Api/System/ActivityLogService.cs
@@ -24,8 +24,10 @@ namespace MediaBrowser.Api.System
[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; }
- [ApiMember(Name = "MinDate", Description = "Optional. The minimum date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ [ApiMember(Name = "MinDate", Description = "Optional. The minimum date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string MinDate { get; set; }
+
+ public bool? HasUserId { get; set; }
}
[Authenticated(Roles = "Admin")]
@@ -44,7 +46,7 @@ namespace MediaBrowser.Api.System
(DateTime?)null :
DateTime.Parse(request.MinDate, null, DateTimeStyles.RoundtripKind).ToUniversalTime();
- var result = _activityManager.GetActivityLogEntries(minDate, request.StartIndex, request.Limit);
+ var result = _activityManager.GetActivityLogEntries(minDate, request.HasUserId, request.StartIndex, request.Limit);
return ToOptimizedResult(result);
}
diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
index f9cac7389d..6991244c6c 100644
--- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
+++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
@@ -4,7 +4,6 @@ using MediaBrowser.Model.Logging;
using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Threading;
using System.Threading;
namespace MediaBrowser.Api.System
@@ -28,7 +27,7 @@ namespace MediaBrowser.Api.System
/// </summary>
private readonly IActivityManager _activityManager;
- public ActivityLogWebSocketListener(ILogger logger, ITimerFactory timerFactory, IActivityManager activityManager) : base(logger, timerFactory)
+ public ActivityLogWebSocketListener(ILogger logger, IActivityManager activityManager) : base(logger)
{
_activityManager = activityManager;
_activityManager.EntryCreated += _activityManager_EntryCreated;
@@ -48,14 +47,7 @@ namespace MediaBrowser.Api.System
{
return Task.FromResult(new List<ActivityLogEntry>());
}
-
- protected override bool SendOnTimer
- {
- get
- {
- return false;
- }
- }
+
protected override void Dispose(bool dispose)
{
diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
deleted file mode 100644
index 63847f2b52..0000000000
--- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Net;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.System;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Threading;
-using System.Threading;
-
-namespace MediaBrowser.Api.System
-{
- /// <summary>
- /// Class SystemInfoWebSocketListener
- /// </summary>
- public class SystemInfoWebSocketListener : BasePeriodicWebSocketListener<SystemInfo, WebSocketListenerState>
- {
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- protected override string Name
- {
- get { return "SystemInfo"; }
- }
-
- /// <summary>
- /// The _kernel
- /// </summary>
- private readonly IServerApplicationHost _appHost;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SystemInfoWebSocketListener" /> class.
- /// </summary>
- public SystemInfoWebSocketListener(ILogger logger, IServerApplicationHost appHost, ITimerFactory timerFactory)
- : base(logger, timerFactory)
- {
- _appHost = appHost;
- }
-
- /// <summary>
- /// Gets the data to send.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <returns>Task{SystemInfo}.</returns>
- protected override Task<SystemInfo> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken)
- {
- return _appHost.GetSystemInfo(cancellationToken);
- }
- }
-}
diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index c0bbf70ead..d2880f735a 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -35,6 +35,7 @@ namespace MediaBrowser.Api.System
}
[Route("/System/Ping", "POST")]
+ [Route("/System/Ping", "GET")]
public class PingSystem : IReturnVoid
{
@@ -79,6 +80,13 @@ namespace MediaBrowser.Api.System
public string Name { get; set; }
}
+ [Route("/System/WakeOnLanInfo", "GET", Summary = "Gets wake on lan information")]
+ [Authenticated]
+ public class GetWakeOnLanInfo : IReturn<WakeOnLanInfo[]>
+ {
+
+ }
+
/// <summary>
/// Class SystemInfoService
/// </summary>
@@ -116,6 +124,13 @@ namespace MediaBrowser.Api.System
return _appHost.Name;
}
+ public object Get(GetWakeOnLanInfo request)
+ {
+ var result = _appHost.GetWakeOnLanInfo();
+
+ return ToOptimizedResult(result);
+ }
+
public object Get(GetServerLogs request)
{
IEnumerable<FileSystemMetadata> files;
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index fd81a9a3e6..6cbb4062dc 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -28,7 +28,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -88,7 +88,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
@@ -131,11 +131,6 @@ namespace MediaBrowser.Api
public bool? EnableUserData { get; set; }
}
- [Route("/Shows/{Id}/Similar", "GET", Summary = "Finds tv shows similar to a given one.")]
- public class GetSimilarShows : BaseGetSimilarItemsFromItem
- {
- }
-
[Route("/Shows/{Id}/Episodes", "GET", Summary = "Gets episodes for a tv season")]
public class GetEpisodes : IReturn<QueryResult<BaseItemDto>>, IHasItemFields, IHasDtoOptions
{
@@ -144,7 +139,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Fields to return within the items, in addition to basic information
@@ -212,7 +207,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Fields to return within the items, in addition to basic information
@@ -288,66 +283,20 @@ namespace MediaBrowser.Api
_authContext = authContext;
}
- /// <summary>
- /// Gets the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>System.Object.</returns>
- public object Get(GetSimilarShows request)
- {
- var result = GetSimilarItemsResult(request);
-
- return ToOptimizedSerializedResultUsingCache(result);
- }
-
- private QueryResult<BaseItemDto> GetSimilarItemsResult(BaseGetSimilarItemsFromItem request)
- {
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
-
- var item = string.IsNullOrEmpty(request.Id) ?
- (!string.IsNullOrWhiteSpace(request.UserId) ? user.RootFolder :
- _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id);
-
- var dtoOptions = GetDtoOptions(_authContext, request);
-
- var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
- {
- Limit = request.Limit,
- IncludeItemTypes = new[]
- {
- typeof(Series).Name
- },
- SimilarTo = item,
- DtoOptions = dtoOptions
-
- });
-
- var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
-
- var result = new QueryResult<BaseItemDto>
- {
- Items = returnList,
-
- TotalRecordCount = itemsResult.Count
- };
-
- return result;
- }
-
public object Get(GetUpcomingEpisodes request)
{
var user = _userManager.GetUserById(request.UserId);
var minPremiereDate = DateTime.Now.Date.ToUniversalTime().AddDays(-1);
- var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId);
+ var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? Guid.Empty : new Guid(request.ParentId);
var options = GetDtoOptions(_authContext, request);
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Episode).Name },
- OrderBy = new[] { ItemSortBy.PremiereDate, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
+ OrderBy = new[] { ItemSortBy.PremiereDate, ItemSortBy.SortName }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
MinPremiereDate = minPremiereDate,
StartIndex = request.StartIndex,
Limit = request.Limit,
@@ -365,7 +314,7 @@ namespace MediaBrowser.Api
Items = returnItems
};
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -391,7 +340,7 @@ namespace MediaBrowser.Api
var returnItems = _dtoService.GetBaseItemDtos(result.Items, options, user);
- return ToOptimizedSerializedResultUsingCache(new QueryResult<BaseItemDto>
+ return ToOptimizedResult(new QueryResult<BaseItemDto>
{
TotalRecordCount = result.TotalRecordCount,
Items = returnItems
diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
index 4018759d99..cd3c80463b 100644
--- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
@@ -40,7 +40,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -56,9 +56,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetArtist request)
{
- var result = GetItem(request);
-
- return ToOptimizedResult(result);
+ return GetItem(request);
}
/// <summary>
@@ -71,8 +69,8 @@ namespace MediaBrowser.Api.UserLibrary
var dtoOptions = GetDtoOptions(AuthorizationContext, request);
var item = GetArtist(request.Name, LibraryManager, dtoOptions);
-
- if (!string.IsNullOrWhiteSpace(request.UserId))
+
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -94,9 +92,7 @@ namespace MediaBrowser.Api.UserLibrary
//request.IncludeItemTypes = "Audio,MusicVideo";
}
- var result = GetResultSlim(request);
-
- return ToOptimizedResult(result);
+ return GetResultSlim(request);
}
/// <summary>
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index ed0c4069b3..fe8b446a1f 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -56,10 +56,10 @@ namespace MediaBrowser.Api.UserLibrary
{
BaseItem parentItem;
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
- parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.GetUserRootFolder() : LibraryManager.GetItemById(request.ParentId);
}
else
{
@@ -73,18 +73,12 @@ namespace MediaBrowser.Api.UserLibrary
{
var parent = GetParentItem(request);
- var collectionFolder = parent as ICollectionFolder;
+ var collectionFolder = parent as IHasCollectionType;
if (collectionFolder != null)
{
return collectionFolder.CollectionType;
}
- var view = parent as UserView;
- if (view != null)
- {
- return view.ViewType;
- }
-
return null;
}
@@ -95,10 +89,10 @@ namespace MediaBrowser.Api.UserLibrary
User user = null;
BaseItem parentItem;
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
user = UserManager.GetUserById(request.UserId);
- parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.GetUserRootFolder() : LibraryManager.GetItemById(request.ParentId);
}
else
{
@@ -123,25 +117,27 @@ namespace MediaBrowser.Api.UserLibrary
Tags = request.GetTags(),
OfficialRatings = request.GetOfficialRatings(),
Genres = request.GetGenres(),
- GenreIds = request.GetGenreIds(),
- StudioIds = request.GetStudioIds(),
+ GenreIds = GetGuids(request.GenreIds),
+ StudioIds = GetGuids(request.StudioIds),
Person = request.Person,
- PersonIds = request.GetPersonIds(),
+ PersonIds = GetGuids(request.PersonIds),
PersonTypes = request.GetPersonTypes(),
Years = request.GetYears(),
MinCommunityRating = request.MinCommunityRating,
- DtoOptions = dtoOptions
+ DtoOptions = dtoOptions,
+ SearchTerm = request.SearchTerm,
+ EnableTotalRecordCount = request.EnableTotalRecordCount
};
if (!string.IsNullOrWhiteSpace(request.ParentId))
{
if (parentItem is Folder)
{
- query.AncestorIds = new[] { request.ParentId };
+ query.AncestorIds = new[] { new Guid(request.ParentId) };
}
else
{
- query.ItemIds = new[] { request.ParentId };
+ query.ItemIds = new[] { new Guid(request.ParentId) };
}
}
@@ -158,7 +154,7 @@ namespace MediaBrowser.Api.UserLibrary
{
return null;
}
- }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray();
+ }).Where(i => i != null).Select(i => i.Id).ToArray();
}
foreach (var filter in request.GetFilters())
@@ -197,10 +193,9 @@ namespace MediaBrowser.Api.UserLibrary
var result = GetItems(request, query);
- var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions);
var dtos = result.Items.Select(i =>
{
- var dto = DtoService.GetItemByNameDto(i.Item1, dtoOptions, null, syncProgess, user);
+ var dto = DtoService.GetItemByNameDto(i.Item1, dtoOptions, null, user);
if (!string.IsNullOrWhiteSpace(request.IncludeItemTypes))
{
@@ -247,10 +242,10 @@ namespace MediaBrowser.Api.UserLibrary
User user = null;
BaseItem parentItem;
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
user = UserManager.GetUserById(request.UserId);
- parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId);
+ parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.GetUserRootFolder() : LibraryManager.GetItemById(request.ParentId);
}
else
{
@@ -277,7 +272,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var folder = (Folder)parentItem;
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
items = request.Recursive ?
folder.GetRecursiveChildren(user, query).ToList() :
@@ -297,9 +292,7 @@ namespace MediaBrowser.Api.UserLibrary
var extractedItems = GetAllItems(request, items);
- var filteredItems = FilterItems(request, extractedItems, user);
-
- filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy());
+ var filteredItems = LibraryManager.Sort(extractedItems, user, request.GetOrderBy());
var ibnItemsArray = filteredItems.ToList();
@@ -326,8 +319,7 @@ namespace MediaBrowser.Api.UserLibrary
var tuples = ibnItems.Select(i => new Tuple<BaseItem, List<BaseItem>>(i, new List<BaseItem>()));
- var syncProgess = DtoService.GetSyncedItemProgress(dtoOptions);
- var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, syncProgess, user));
+ var dtos = tuples.Select(i => DtoService.GetItemByNameDto(i.Item1, dtoOptions, i.Item2, user));
result.Items = dtos.Where(i => i != null).ToArray();
@@ -338,125 +330,6 @@ namespace MediaBrowser.Api.UserLibrary
/// Filters the items.
/// </summary>
/// <param name="request">The request.</param>
- /// <param name="items">The items.</param>
- /// <param name="user">The user.</param>
- /// <returns>IEnumerable{`0}.</returns>
- private IEnumerable<BaseItem> FilterItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
- {
- if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater))
- {
- items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.SortName, StringComparison.CurrentCultureIgnoreCase) < 1);
- }
- if (!string.IsNullOrEmpty(request.NameStartsWith))
- {
- items = items.Where(i => string.Compare(request.NameStartsWith, i.SortName.Substring(0, 1), StringComparison.CurrentCultureIgnoreCase) == 0);
- }
-
- if (!string.IsNullOrEmpty(request.NameLessThan))
- {
- items = items.Where(i => string.Compare(request.NameLessThan, i.SortName, StringComparison.CurrentCultureIgnoreCase) == 1);
- }
-
- var imageTypes = request.GetImageTypes();
- if (imageTypes.Length > 0)
- {
- items = items.Where(item => imageTypes.Any(item.HasImage));
- }
-
- var filters = request.GetFilters();
-
- if (filters.Contains(ItemFilter.Dislikes))
- {
- items = items.Where(i =>
- {
- var userdata = UserDataRepository.GetUserData(user, i);
-
- return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value;
- });
- }
-
- if (filters.Contains(ItemFilter.Likes))
- {
- items = items.Where(i =>
- {
- var userdata = UserDataRepository.GetUserData(user, i);
-
- return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value;
- });
- }
-
- if (filters.Contains(ItemFilter.IsFavoriteOrLikes))
- {
- items = items.Where(i =>
- {
- var userdata = UserDataRepository.GetUserData(user, i);
-
- var likes = userdata.Likes ?? false;
- var favorite = userdata.IsFavorite;
-
- return likes || favorite;
- });
- }
-
- if (filters.Contains(ItemFilter.IsFavorite))
- {
- items = items.Where(i =>
- {
- var userdata = UserDataRepository.GetUserData(user, i);
-
- return userdata != null && userdata.IsFavorite;
- });
- }
-
- // Avoid implicitly captured closure
- var currentRequest = request;
- return items.Where(i => ApplyAdditionalFilters(currentRequest, i, user, false));
- }
-
- private bool ApplyAdditionalFilters(BaseItemsRequest request, BaseItem i, User user, bool isPreFiltered)
- {
- if (!isPreFiltered)
- {
- // Apply tag filter
- var tags = request.GetTags();
- if (tags.Length > 0)
- {
- if (!tags.Any(v => i.Tags.Contains(v, StringComparer.OrdinalIgnoreCase)))
- {
- return false;
- }
- }
-
- // Apply official rating filter
- var officialRatings = request.GetOfficialRatings();
- if (officialRatings.Length > 0 && !officialRatings.Contains(i.OfficialRating ?? string.Empty))
- {
- return false;
- }
-
- // Apply genre filter
- var genres = request.GetGenres();
- if (genres.Length > 0 && !genres.Any(v => i.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
- {
- return false;
- }
-
- // Apply year filter
- var years = request.GetYears();
- if (years.Length > 0 && !(i.ProductionYear.HasValue && years.Contains(i.ProductionYear.Value)))
- {
- return false;
- }
- }
-
- return true;
- }
-
-
- /// <summary>
- /// Filters the items.
- /// </summary>
- /// <param name="request">The request.</param>
/// <param name="f">The f.</param>
/// <param name="excludeItemTypes">The exclude item types.</param>
/// <param name="includeItemTypes">The include item types.</param>
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
index 88d080db58..11c12c718f 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
@@ -58,6 +58,8 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "IsHD", Description = "Optional filter by items that are HD or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsHD { get; set; }
+ public bool? Is4K { get; set; }
+
[ApiMember(Name = "LocationTypes", Description = "Optional. If specified, results will be filtered based on LocationType. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string LocationTypes { get; set; }
@@ -103,9 +105,7 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "HasTvdbId", Description = "Optional filter by items that have a tvdb id or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? HasTvdbId { get; set; }
- [ApiMember(Name = "IsInBoxSet", Description = "Optional filter by items that are in boxsets, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
- public bool? IsInBoxSet { get; set; }
-
+ [ApiMember(Name = "ExcludeItemIds", Description = "Optional. If specified, results will be filtered by exxcluding item ids. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string ExcludeItemIds { get; set; }
public bool EnableTotalRecordCount { get; set; }
@@ -131,6 +131,8 @@ namespace MediaBrowser.Api.UserLibrary
[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")]
public bool Recursive { get; set; }
+ public string SearchTerm { get; set; }
+
/// <summary>
/// Gets or sets the sort order.
/// </summary>
@@ -277,6 +279,10 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "ArtistIds", Description = "Optional. If specified, results will be filtered based on artist. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string ArtistIds { get; set; }
+ public string AlbumArtistIds { get; set; }
+
+ public string ContributingArtistIds { get; set; }
+
[ApiMember(Name = "Albums", Description = "Optional. If specified, results will be filtered based on album. This allows multiple, pipe delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Albums { get; set; }
@@ -300,8 +306,8 @@ namespace MediaBrowser.Api.UserLibrary
/// Gets or sets the user id.
/// </summary>
/// <value>The user id.</value>
- [ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ [ApiMember(Name = "UserId", Description = "User Id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the min offical rating.
@@ -321,6 +327,12 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "CollapseBoxSetItems", Description = "Whether or not to hide items behind their boxsets.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
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>
/// Gets or sets the video formats.
/// </summary>
@@ -369,11 +381,6 @@ namespace MediaBrowser.Api.UserLibrary
return (IncludeItemTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
- public string[] GetExcludeItemIds()
- {
- return (ExcludeItemIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
-
public string[] GetExcludeItemTypes()
{
return (ExcludeItemTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
@@ -389,36 +396,11 @@ namespace MediaBrowser.Api.UserLibrary
return (Studios ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
}
- public string[] GetArtistIds()
- {
- return (ArtistIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
- }
-
- public string[] GetStudioIds()
- {
- return (StudioIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
- }
-
- public string[] GetGenreIds()
- {
- return (GenreIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
- }
-
public string[] GetPersonTypes()
{
return (PersonTypes ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
- public string[] GetPersonIds()
- {
- return (PersonIds ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
-
- public string[] GetItemIds()
- {
- return (Ids ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- }
-
public VideoType[] GetVideoTypes()
{
var val = VideoTypes;
@@ -467,18 +449,18 @@ namespace MediaBrowser.Api.UserLibrary
/// Gets the order by.
/// </summary>
/// <returns>IEnumerable{ItemSortBy}.</returns>
- public Tuple<string, SortOrder>[] GetOrderBy()
+ public ValueTuple<string, SortOrder>[] GetOrderBy()
{
return GetOrderBy(SortBy, SortOrder);
}
- public static Tuple<string, SortOrder>[] GetOrderBy(string sortBy, string requestedSortOrder)
+ public static ValueTuple<string, SortOrder>[] GetOrderBy(string sortBy, string requestedSortOrder)
{
var val = sortBy;
if (string.IsNullOrEmpty(val))
{
- return new Tuple<string, Model.Entities.SortOrder>[] { };
+ return Array.Empty<ValueTuple<string, Model.Entities.SortOrder>>();
}
var vals = val.Split(',');
@@ -489,7 +471,7 @@ namespace MediaBrowser.Api.UserLibrary
var sortOrders = requestedSortOrder.Split(',');
- var result = new Tuple<string, Model.Entities.SortOrder>[vals.Length];
+ var result = new ValueTuple<string, Model.Entities.SortOrder>[vals.Length];
for (var i = 0; i < vals.Length; i++)
{
@@ -498,7 +480,7 @@ namespace MediaBrowser.Api.UserLibrary
var sortOrderValue = sortOrders.Length > sortOrderIndex ? sortOrders[sortOrderIndex] : null;
var sortOrder = string.Equals(sortOrderValue, "Descending", StringComparison.OrdinalIgnoreCase) ? MediaBrowser.Model.Entities.SortOrder.Descending : MediaBrowser.Model.Entities.SortOrder.Ascending;
- result[i] = new Tuple<string, Model.Entities.SortOrder>(vals[i], sortOrder);
+ result[i] = new ValueTuple<string, Model.Entities.SortOrder>(vals[i], sortOrder);
}
return result;
diff --git a/MediaBrowser.Api/UserLibrary/GameGenresService.cs b/MediaBrowser.Api/UserLibrary/GameGenresService.cs
index 0b2ca4daf9..476e881b97 100644
--- a/MediaBrowser.Api/UserLibrary/GameGenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GameGenresService.cs
@@ -31,7 +31,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
[Authenticated]
@@ -46,7 +46,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetItem(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -60,7 +60,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = GetGameGenre(request.Name, LibraryManager, dtoOptions);
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -79,7 +79,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetResultSlim(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
diff --git a/MediaBrowser.Api/UserLibrary/GenresService.cs b/MediaBrowser.Api/UserLibrary/GenresService.cs
index d913f52d96..0bb7d7865a 100644
--- a/MediaBrowser.Api/UserLibrary/GenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/GenresService.cs
@@ -38,7 +38,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -56,7 +56,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetItem(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -70,7 +70,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = GetGenre(request.Name, LibraryManager, dtoOptions);
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -89,7 +89,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetResultSlim(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index 1e531ba664..aa17e85f34 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -88,25 +88,25 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId);
+ var parentIdGuid = string.IsNullOrWhiteSpace(request.ParentId) ? Guid.Empty : new Guid(request.ParentId);
var options = GetDtoOptions(_authContext, request);
- var ancestorIds = new List<string>();
+ var ancestorIds = new List<Guid>();
var excludeFolderIds = user.Configuration.LatestItemsExcludes;
- if (!parentIdGuid.HasValue && excludeFolderIds.Length > 0)
+ if (parentIdGuid.Equals(Guid.Empty) && excludeFolderIds.Length > 0)
{
- ancestorIds = user.RootFolder.GetChildren(user, true)
+ ancestorIds = _libraryManager.GetUserRootFolder().GetChildren(user, true)
.Where(i => i is Folder)
.Where(i => !excludeFolderIds.Contains(i.Id.ToString("N")))
- .Select(i => i.Id.ToString("N"))
+ .Select(i => i.Id)
.ToList();
}
var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
- OrderBy = new[] { ItemSortBy.DatePlayed }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
+ OrderBy = new[] { ItemSortBy.DatePlayed }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
IsResumable = true,
StartIndex = request.StartIndex,
Limit = request.Limit,
@@ -119,7 +119,8 @@ namespace MediaBrowser.Api.UserLibrary
EnableTotalRecordCount = request.EnableTotalRecordCount,
AncestorIds = ancestorIds.ToArray(),
IncludeItemTypes = request.GetIncludeItemTypes(),
- ExcludeItemTypes = request.GetExcludeItemTypes()
+ ExcludeItemTypes = request.GetExcludeItemTypes(),
+ SearchTerm = request.SearchTerm
});
var returnItems = _dtoService.GetBaseItemDtos(itemsResult.Items, options, user);
@@ -130,7 +131,7 @@ namespace MediaBrowser.Api.UserLibrary
Items = returnItems
};
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -147,7 +148,7 @@ namespace MediaBrowser.Api.UserLibrary
var result = GetItems(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -156,7 +157,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="request">The request.</param>
private QueryResult<BaseItemDto> GetItems(GetItems request)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var dtoOptions = GetDtoOptions(_authContext, request);
@@ -191,26 +192,23 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
private QueryResult<BaseItem> GetQueryResult(GetItems request, DtoOptions dtoOptions, User user)
{
- var item = string.IsNullOrEmpty(request.ParentId) ?
- null :
- _libraryManager.GetItemById(request.ParentId);
-
if (string.Equals(request.IncludeItemTypes, "Playlist", StringComparison.OrdinalIgnoreCase))
{
- if (item == null || user != null)
- {
- item = _libraryManager.RootFolder.Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, "PlaylistsFolder", StringComparison.OrdinalIgnoreCase));
- }
+ request.ParentId = null;
}
else if (string.Equals(request.IncludeItemTypes, "BoxSet", StringComparison.OrdinalIgnoreCase))
{
- item = user == null ? _libraryManager.RootFolder : user.RootFolder;
+ request.ParentId = null;
}
+ var item = string.IsNullOrEmpty(request.ParentId) ?
+ null :
+ _libraryManager.GetItemById(request.ParentId);
+
if (item == null)
{
item = string.IsNullOrEmpty(request.ParentId) ?
- user == null ? _libraryManager.RootFolder : user.RootFolder :
+ user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder() :
_libraryManager.GetItemById(request.ParentId);
}
@@ -222,6 +220,15 @@ namespace MediaBrowser.Api.UserLibrary
folder = user == null ? _libraryManager.RootFolder : _libraryManager.GetUserRootFolder();
}
+ var hasCollectionType = folder as IHasCollectionType;
+ var isPlaylistQuery = (hasCollectionType != null && string.Equals(hasCollectionType.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase));
+
+ if (isPlaylistQuery)
+ {
+ request.Recursive = true;
+ request.IncludeItemTypes = "Playlist";
+ }
+
if (request.Recursive || !string.IsNullOrEmpty(request.Ids) || user == null)
{
return folder.GetItems(GetItemsQuery(request, dtoOptions, user));
@@ -266,8 +273,10 @@ namespace MediaBrowser.Api.UserLibrary
HasImdbId = request.HasImdbId,
IsPlaceHolder = request.IsPlaceHolder,
IsLocked = request.IsLocked,
- IsInBoxSet = request.IsInBoxSet,
- IsHD = request.IsHD,
+ MinWidth = request.MinWidth,
+ MinHeight = request.MinHeight,
+ MaxWidth = request.MaxWidth,
+ MaxHeight = request.MaxHeight,
Is3D = request.Is3D,
HasTvdbId = request.HasTvdbId,
HasTmdbId = request.HasTmdbId,
@@ -279,33 +288,37 @@ namespace MediaBrowser.Api.UserLibrary
HasThemeSong = request.HasThemeSong,
HasThemeVideo = request.HasThemeVideo,
HasTrailer = request.HasTrailer,
+ IsHD = request.IsHD,
+ Is4K = request.Is4K,
Tags = request.GetTags(),
OfficialRatings = request.GetOfficialRatings(),
Genres = request.GetGenres(),
- ArtistIds = request.GetArtistIds(),
- GenreIds = request.GetGenreIds(),
- StudioIds = request.GetStudioIds(),
+ ArtistIds = GetGuids(request.ArtistIds),
+ AlbumArtistIds = GetGuids(request.AlbumArtistIds),
+ ContributingArtistIds = GetGuids(request.ContributingArtistIds),
+ GenreIds = GetGuids(request.GenreIds),
+ StudioIds = GetGuids(request.StudioIds),
Person = request.Person,
- PersonIds = request.GetPersonIds(),
+ PersonIds = GetGuids(request.PersonIds),
PersonTypes = request.GetPersonTypes(),
Years = request.GetYears(),
ImageTypes = request.GetImageTypes(),
VideoTypes = request.GetVideoTypes(),
AdjacentTo = request.AdjacentTo,
- ItemIds = request.GetItemIds(),
+ ItemIds = GetGuids(request.Ids),
MinPlayers = request.MinPlayers,
MaxPlayers = request.MaxPlayers,
MinCommunityRating = request.MinCommunityRating,
MinCriticRating = request.MinCriticRating,
- ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? (Guid?)null : new Guid(request.ParentId),
+ ParentId = string.IsNullOrWhiteSpace(request.ParentId) ? Guid.Empty : new Guid(request.ParentId),
ParentIndexNumber = request.ParentIndexNumber,
- AiredDuringSeason = request.AiredDuringSeason,
EnableTotalRecordCount = request.EnableTotalRecordCount,
- ExcludeItemIds = request.GetExcludeItemIds(),
- DtoOptions = dtoOptions
+ ExcludeItemIds = GetGuids(request.ExcludeItemIds),
+ DtoOptions = dtoOptions,
+ SearchTerm = request.SearchTerm
};
- if (!string.IsNullOrWhiteSpace(request.Ids))
+ if (!string.IsNullOrWhiteSpace(request.Ids) || !string.IsNullOrWhiteSpace(request.SearchTerm))
{
query.CollapseBoxSetItems = false;
}
@@ -416,18 +429,18 @@ namespace MediaBrowser.Api.UserLibrary
{
return null;
}
- }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray();
+ }).Where(i => i != null).Select(i => i.Id).ToArray();
}
// ExcludeArtistIds
if (!string.IsNullOrWhiteSpace(request.ExcludeArtistIds))
{
- query.ExcludeArtistIds = request.ExcludeArtistIds.Split('|');
+ query.ExcludeArtistIds = GetGuids(request.ExcludeArtistIds);
}
if (!string.IsNullOrWhiteSpace(request.AlbumIds))
{
- query.AlbumIds = request.AlbumIds.Split('|');
+ query.AlbumIds = GetGuids(request.AlbumIds);
}
// Albums
@@ -441,7 +454,7 @@ namespace MediaBrowser.Api.UserLibrary
Name = i,
Limit = 1
- }).Select(albumId => albumId.ToString("N"));
+ }).Select(albumId => albumId);
}).ToArray();
}
@@ -459,7 +472,7 @@ namespace MediaBrowser.Api.UserLibrary
{
return null;
}
- }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray();
+ }).Where(i => i != null).Select(i => i.Id).ToArray();
}
// Apply default sorting if none requested
@@ -468,10 +481,10 @@ namespace MediaBrowser.Api.UserLibrary
// Albums by artist
if (query.ArtistIds.Length > 0 && query.IncludeItemTypes.Length == 1 && string.Equals(query.IncludeItemTypes[0], "MusicAlbum", StringComparison.OrdinalIgnoreCase))
{
- query.OrderBy = new Tuple<string, SortOrder>[]
+ query.OrderBy = new []
{
- new Tuple<string, SortOrder>(ItemSortBy.ProductionYear, SortOrder.Descending),
- new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending)
+ new ValueTuple<string, SortOrder>(ItemSortBy.ProductionYear, SortOrder.Descending),
+ new ValueTuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending)
};
}
}
diff --git a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
index 36dc773d4d..d4f1b3fa8d 100644
--- a/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
+++ b/MediaBrowser.Api/UserLibrary/MusicGenresService.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
[Authenticated]
@@ -47,7 +47,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetItem(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -61,7 +61,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = GetMusicGenre(request.Name, LibraryManager, dtoOptions);
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -80,7 +80,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetResultSlim(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
diff --git a/MediaBrowser.Api/UserLibrary/PersonsService.cs b/MediaBrowser.Api/UserLibrary/PersonsService.cs
index 9417447d84..d2c9ef33aa 100644
--- a/MediaBrowser.Api/UserLibrary/PersonsService.cs
+++ b/MediaBrowser.Api/UserLibrary/PersonsService.cs
@@ -7,6 +7,8 @@ using MediaBrowser.Model.Dto;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Services;
+using System;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Api.UserLibrary
{
@@ -36,7 +38,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -54,7 +56,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetItem(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -67,8 +69,8 @@ namespace MediaBrowser.Api.UserLibrary
var dtoOptions = GetDtoOptions(AuthorizationContext, request);
var item = GetPerson(request.Name, LibraryManager, dtoOptions);
-
- if (!string.IsNullOrWhiteSpace(request.UserId))
+
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -85,9 +87,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>System.Object.</returns>
public object Get(GetPersons request)
{
- var result = GetResult(request);
-
- return ToOptimizedSerializedResultUsingCache(result);
+ return GetResultSlim(request);
}
/// <summary>
@@ -98,48 +98,22 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
{
- var inputPersonTypes = ((GetPersons)request).PersonTypes;
- var personTypes = string.IsNullOrEmpty(inputPersonTypes) ? new string[] { } : inputPersonTypes.Split(',');
-
- // Either get all people, or all people filtered by a specific person type
- var allPeople = GetAllPeople(items, personTypes);
-
- return allPeople
- .Select(i => i.Name)
- .DistinctNames()
-
- .Select(name =>
- {
- try
- {
- return LibraryManager.GetPerson(name);
- }
- catch
- {
- return null;
- // Already logged at lower levels
- }
- }
-
- ).Where(i => i != null);
+ throw new NotImplementedException();
}
- /// <summary>
- /// Gets all people.
- /// </summary>
- /// <param name="itemsList">The items list.</param>
- /// <param name="personTypes">The person types.</param>
- /// <returns>IEnumerable{PersonInfo}.</returns>
- private IEnumerable<PersonInfo> GetAllPeople(IList<BaseItem> itemsList, string[] personTypes)
+ protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
{
- var allIds = itemsList.Select(i => i.Id).ToArray();
-
- var allPeople = LibraryManager.GetPeople(new InternalPeopleQuery
+ var items = LibraryManager.GetPeopleItems(new InternalPeopleQuery
{
- PersonTypes = personTypes
+ PersonTypes = query.PersonTypes,
+ NameContains = query.NameContains ?? query.SearchTerm
});
- return allPeople.Where(i => allIds.Contains(i.ItemId)).OrderBy(p => p.SortOrder ?? int.MaxValue).ThenBy(p => p.Type);
+ return new QueryResult<Tuple<BaseItem, ItemCounts>>
+ {
+ TotalRecordCount = items.Count,
+ Items = items.Take(query.Limit ?? int.MaxValue).Select(i => new Tuple<BaseItem, ItemCounts>(i, new ItemCounts())).ToArray()
+ };
}
public PersonsService(IUserManager userManager, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepository, IDtoService dtoService, IAuthorizationContext authorizationContext) : base(userManager, libraryManager, userDataRepository, itemRepository, dtoService, authorizationContext)
diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs
index f10cccbb13..4a3204f71f 100644
--- a/MediaBrowser.Api/UserLibrary/StudiosService.cs
+++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs
@@ -38,7 +38,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -56,7 +56,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetItem(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -70,7 +70,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = GetStudio(request.Name, LibraryManager, dtoOptions);
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -89,7 +89,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetResultSlim(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
protected override QueryResult<Tuple<BaseItem, ItemCounts>> GetItems(GetItemsByName request, InternalItemsQuery query)
@@ -105,10 +105,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
protected override IEnumerable<BaseItem> GetAllItems(GetItemsByName request, IList<BaseItem> items)
{
- return items
- .SelectMany(i => i.Studios)
- .DistinctNames()
- .Select(name => LibraryManager.GetStudio(name));
+ throw new NotImplementedException();
}
public StudiosService(IUserManager userManager, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepository, IDtoService dtoService, IAuthorizationContext authorizationContext) : base(userManager, libraryManager, userDataRepository, itemRepository, dtoService, authorizationContext)
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 1bbc740c01..30df0ad23c 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -29,7 +29,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -50,7 +50,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -64,7 +64,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the item id.
@@ -85,14 +85,14 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -106,14 +106,14 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -127,14 +127,14 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -148,14 +148,14 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UpdateUserItemRating" /> is likes.
@@ -176,7 +176,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -197,7 +197,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -215,13 +215,13 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
[ApiMember(Name = "Limit", Description = "Limit", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
public int Limit { get; set; }
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string ParentId { get; set; }
+ public Guid ParentId { get; set; }
[ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, SortName, Studios, Taglines", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Fields { get; set; }
@@ -291,7 +291,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetAsync(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public object Get(GetLatestMedia request)
@@ -344,43 +344,15 @@ namespace MediaBrowser.Api.UserLibrary
var user = _userManager.GetUserById(request.UserId);
var item = string.IsNullOrEmpty(request.Id) ?
- user.RootFolder :
+ _libraryManager.GetUserRootFolder() :
_libraryManager.GetItemById(request.Id);
- var series = item as Series;
-
- // Get them from the child tree
- if (series != null)
- {
- var dtoOptions = GetDtoOptions(_authContext, request);
-
- // Avoid implicitly captured closure
- var currentUser = user;
-
- var dtos = series
- .GetEpisodes(user, dtoOptions)
- .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0)
- .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, currentUser));
-
- return dtos.ToArray();
- }
-
- var movie = item as IHasSpecialFeatures;
-
- // Get them from the db
- if (movie != null)
- {
- var dtoOptions = GetDtoOptions(_authContext, request);
-
- var dtos = movie.SpecialFeatureIds
- .Select(_libraryManager.GetItemById)
- .OrderBy(i => i.SortName)
- .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
+ var dtoOptions = GetDtoOptions(_authContext, request);
- return dtos.ToArray();
- }
+ var dtos = item.GetDisplayExtras()
+ .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
- return new BaseItemDto[] { };
+ return dtos.ToArray();
}
/// <summary>
@@ -392,28 +364,15 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
-
- List<Guid> trailerIds = null;
-
- var hasTrailers = item as IHasTrailers;
- if (hasTrailers != null)
- {
- trailerIds = hasTrailers.GetTrailerIds();
- }
- else
- {
- trailerIds = new List<Guid>();
- }
+ var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(request.Id);
var dtoOptions = GetDtoOptions(_authContext, request);
- var dtos = trailerIds
- .Select(_libraryManager.GetItemById)
+ var dtos = item.GetExtras(new[] { ExtraType.Trailer })
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
.ToArray();
- return ToOptimizedSerializedResultUsingCache(dtos);
+ return ToOptimizedResult(dtos);
}
/// <summary>
@@ -425,7 +384,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
+ var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(request.Id);
await RefreshItemOnDemandIfNeeded(item).ConfigureAwait(false);
@@ -433,7 +392,7 @@ namespace MediaBrowser.Api.UserLibrary
var result = _dtoService.GetBaseItemDto(item, dtoOptions, user);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
private async Task RefreshItemOnDemandIfNeeded(BaseItem item)
@@ -448,7 +407,7 @@ namespace MediaBrowser.Api.UserLibrary
var options = new MetadataRefreshOptions(_fileSystem)
{
MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
- ImageRefreshMode = ImageRefreshMode.FullRefresh,
+ ImageRefreshMode = MetadataRefreshMode.FullRefresh,
ForceSave = performFullRefresh
};
@@ -466,13 +425,13 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var item = user.RootFolder;
+ var item = _libraryManager.GetUserRootFolder();
var dtoOptions = GetDtoOptions(_authContext, request);
var result = _dtoService.GetBaseItemDto(item, dtoOptions, user);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -484,7 +443,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id);
+ var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(request.Id);
var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
@@ -498,7 +457,7 @@ namespace MediaBrowser.Api.UserLibrary
TotalRecordCount = dtos.Length
};
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -507,7 +466,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="request">The request.</param>
public object Post(MarkFavoriteItem request)
{
- var dto = MarkFavorite(request.UserId, request.Id, true);
+ var dto = MarkFavorite(request.UserId, request.Id, true);
return ToOptimizedResult(dto);
}
@@ -529,11 +488,11 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="isFavorite">if set to <c>true</c> [is favorite].</param>
- private UserItemDataDto MarkFavorite(string userId, string itemId, bool isFavorite)
+ private UserItemDataDto MarkFavorite(Guid userId, Guid itemId, bool isFavorite)
{
var user = _userManager.GetUserById(userId);
- var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId);
+ var item = itemId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(itemId);
// Get the user data for this item
var data = _userDataRepository.GetUserData(user, item);
@@ -541,7 +500,7 @@ namespace MediaBrowser.Api.UserLibrary
// Set favorite status
data.IsFavorite = isFavorite;
- _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None);
+ _userDataRepository.SaveUserData(user, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None);
return _userDataRepository.GetUserDataDto(item, user);
}
@@ -563,7 +522,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="request">The request.</param>
public object Post(UpdateUserItemRating request)
{
- var dto = UpdateUserItemRating(request.UserId, request.Id, request.Likes);
+ var dto = UpdateUserItemRating(request.UserId, request.Id, request.Likes);
return ToOptimizedResult(dto);
}
@@ -574,18 +533,18 @@ namespace MediaBrowser.Api.UserLibrary
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="likes">if set to <c>true</c> [likes].</param>
- private UserItemDataDto UpdateUserItemRating(string userId, string itemId, bool? likes)
+ private UserItemDataDto UpdateUserItemRating(Guid userId, Guid itemId, bool? likes)
{
var user = _userManager.GetUserById(userId);
- var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId);
+ var item = itemId.Equals(Guid.Empty) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(itemId);
// Get the user data for this item
var data = _userDataRepository.GetUserData(user, item);
data.Likes = likes;
- _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None);
+ _userDataRepository.SaveUserData(user, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None);
return _userDataRepository.GetUserDataDto(item, user);
}
diff --git a/MediaBrowser.Api/UserLibrary/UserViewsService.cs b/MediaBrowser.Api/UserLibrary/UserViewsService.cs
index 096157e47f..5e9270e0bf 100644
--- a/MediaBrowser.Api/UserLibrary/UserViewsService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserViewsService.cs
@@ -24,10 +24,11 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
- [ApiMember(Name = "IncludeExternalContent", Description = "Whether or not to include external views such as channels or live tv", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ [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; }
}
@@ -40,7 +41,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
public class UserViewsService : BaseApiService
@@ -49,16 +50,18 @@ namespace MediaBrowser.Api.UserLibrary
private readonly IUserViewManager _userViewManager;
private readonly IDtoService _dtoService;
private readonly IAuthorizationContext _authContext;
+ private readonly ILibraryManager _libraryManager;
- public UserViewsService(IUserManager userManager, IUserViewManager userViewManager, IDtoService dtoService, IAuthorizationContext authContext)
+ public UserViewsService(IUserManager userManager, IUserViewManager userViewManager, IDtoService dtoService, IAuthorizationContext authContext, ILibraryManager libraryManager)
{
_userManager = userManager;
_userViewManager = userViewManager;
_dtoService = dtoService;
_authContext = authContext;
+ _libraryManager = libraryManager;
}
- public async Task<object> Get(GetUserViews request)
+ public object Get(GetUserViews request)
{
var query = new UserViewQuery
{
@@ -69,6 +72,7 @@ namespace MediaBrowser.Api.UserLibrary
{
query.IncludeExternalContent = request.IncludeExternalContent.Value;
}
+ query.IncludeHidden = request.IncludeHidden;
if (!string.IsNullOrWhiteSpace(request.PresetViews))
{
@@ -78,18 +82,16 @@ namespace MediaBrowser.Api.UserLibrary
var app = _authContext.GetAuthorizationInfo(Request).Client ?? string.Empty;
if (app.IndexOf("emby rt", StringComparison.OrdinalIgnoreCase) != -1)
{
- query.PresetViews = new[] { CollectionType.Music, CollectionType.Movies, CollectionType.TvShows };
+ query.PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows };
}
- //query.PresetViews = new[] { CollectionType.Music, CollectionType.Movies, CollectionType.TvShows };
- var folders = await _userViewManager.GetUserViews(query, CancellationToken.None).ConfigureAwait(false);
+ var folders = _userViewManager.GetUserViews(query);
var dtoOptions = GetDtoOptions(_authContext, request);
var fields = dtoOptions.Fields.ToList();
fields.Add(ItemFields.PrimaryImageAspectRatio);
fields.Add(ItemFields.DisplayPreferencesId);
- fields.Remove(ItemFields.SyncInfo);
fields.Remove(ItemFields.BasicSyncInfo);
dtoOptions.Fields = fields.ToArray(fields.Count);
@@ -111,7 +113,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var list = user.RootFolder
+ var list = _libraryManager.GetUserRootFolder()
.GetChildren(user, true)
.OfType<Folder>()
.Where(UserView.IsEligibleForGrouping)
diff --git a/MediaBrowser.Api/UserLibrary/YearsService.cs b/MediaBrowser.Api/UserLibrary/YearsService.cs
index db622a9b34..30ac88e00f 100644
--- a/MediaBrowser.Api/UserLibrary/YearsService.cs
+++ b/MediaBrowser.Api/UserLibrary/YearsService.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Model.Dto;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Services;
+using System;
namespace MediaBrowser.Api.UserLibrary
{
@@ -36,7 +37,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The user id.</value>
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
}
/// <summary>
@@ -54,7 +55,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetItem(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
@@ -68,7 +69,7 @@ namespace MediaBrowser.Api.UserLibrary
var dtoOptions = GetDtoOptions(AuthorizationContext, request);
- if (!string.IsNullOrWhiteSpace(request.UserId))
+ if (!request.UserId.Equals(Guid.Empty))
{
var user = UserManager.GetUserById(request.UserId);
@@ -87,7 +88,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var result = GetResult(request);
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
/// <summary>
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 66d6a024eb..29f3070a59 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -14,6 +14,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Model.Services;
+using MediaBrowser.Controller.Authentication;
namespace MediaBrowser.Api
{
@@ -51,22 +52,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
- }
-
- /// <summary>
- /// Class GetUser
- /// </summary>
- [Route("/Users/{Id}/Offline", "GET", Summary = "Gets an offline user record by Id")]
- [Authenticated]
- public class GetOfflineUser : IReturn<UserDto>
- {
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- [ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -81,7 +67,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -95,7 +81,7 @@ namespace MediaBrowser.Api
/// </summary>
/// <value>The id.</value>
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
[ApiMember(Name = "Pw", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string Pw { get; set; }
@@ -130,9 +116,6 @@ namespace MediaBrowser.Api
[ApiMember(Name = "Pw", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
public string Pw { get; set; }
-
- [ApiMember(Name = "PasswordMd5", IsRequired = true, DataType = "string", ParameterType = "body", Verb = "POST")]
- public string PasswordMd5 { get; set; }
}
/// <summary>
@@ -146,7 +129,7 @@ namespace MediaBrowser.Api
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- public string Id { get; set; }
+ public Guid Id { get; set; }
/// <summary>
/// Gets or sets the password.
@@ -156,12 +139,6 @@ namespace MediaBrowser.Api
public string CurrentPw { get; set; }
- /// <summary>
- /// Gets or sets the new password.
- /// </summary>
- /// <value>The new password.</value>
- public string NewPassword { get; set; }
-
public string NewPw { get; set; }
/// <summary>
@@ -182,7 +159,7 @@ namespace MediaBrowser.Api
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
- public string Id { get; set; }
+ public Guid Id { get; set; }
/// <summary>
/// Gets or sets the new password.
@@ -216,7 +193,7 @@ namespace MediaBrowser.Api
public class UpdateUserPolicy : UserPolicy, IReturnVoid
{
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -227,7 +204,7 @@ namespace MediaBrowser.Api
public class UpdateUserConfiguration : UserConfiguration, IReturnVoid
{
[ApiMember(Name = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public string Id { get; set; }
+ public Guid Id { get; set; }
}
/// <summary>
@@ -296,7 +273,7 @@ namespace MediaBrowser.Api
IsHidden = false,
IsDisabled = false
- }, true);
+ }, true, true);
}
/// <summary>
@@ -306,10 +283,10 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetUsers request)
{
- return Get(request, false);
+ return Get(request, false, false);
}
- private object Get(GetUsers request, bool filterByDevice)
+ private object Get(GetUsers request, bool filterByDevice, bool filterByNetwork)
{
var users = _userManager.Users;
@@ -334,7 +311,15 @@ namespace MediaBrowser.Api
if (!string.IsNullOrWhiteSpace(deviceId))
{
- users = users.Where(i => _deviceManager.CanAccessDevice(i.Id.ToString("N"), deviceId));
+ users = users.Where(i => _deviceManager.CanAccessDevice(i, deviceId));
+ }
+ }
+
+ if (filterByNetwork)
+ {
+ if (!_networkManager.IsInLocalNetwork(Request.RemoteIp))
+ {
+ users = users.Where(i => i.Policy.EnableRemoteAccess);
}
}
@@ -365,32 +350,16 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
- public object Get(GetOfflineUser request)
- {
- var user = _userManager.GetUserById(request.Id);
-
- if (user == null)
- {
- throw new ResourceNotFoundException("User not found");
- }
-
- var result = _userManager.GetOfflineUserDto(user);
-
- return ToOptimizedResult(result);
- }
-
/// <summary>
/// Deletes the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Delete(DeleteUser request)
+ public Task Delete(DeleteUser request)
{
- var task = DeleteAsync(request);
-
- Task.WaitAll(task);
+ return DeleteAsync(request);
}
- public async Task DeleteAsync(DeleteUser request)
+ public Task DeleteAsync(DeleteUser request)
{
var user = _userManager.GetUserById(request.Id);
@@ -399,9 +368,9 @@ namespace MediaBrowser.Api
throw new ResourceNotFoundException("User not found");
}
- _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), null);
+ _sessionMananger.RevokeUserTokens(user.Id, null);
- await _userManager.DeleteUser(user).ConfigureAwait(false);
+ return _userManager.DeleteUser(user);
}
/// <summary>
@@ -437,7 +406,6 @@ namespace MediaBrowser.Api
DeviceName = auth.Device,
Password = request.Pw,
PasswordSha1 = request.Password,
- PasswordMd5 = request.PasswordMd5,
RemoteEndPoint = Request.RemoteIp,
Username = request.Username
@@ -450,10 +418,9 @@ namespace MediaBrowser.Api
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(UpdateUserPassword request)
+ public Task Post(UpdateUserPassword request)
{
- var task = PostAsync(request);
- Task.WaitAll(task);
+ return PostAsync(request);
}
public async Task PostAsync(UpdateUserPassword request)
@@ -469,22 +436,22 @@ namespace MediaBrowser.Api
if (request.ResetPassword)
{
- _userManager.ResetPassword(user);
+ await _userManager.ResetPassword(user).ConfigureAwait(false);
}
else
{
- var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPw, request.CurrentPassword, null, Request.RemoteIp, false).ConfigureAwait(false);
+ var success = await _userManager.AuthenticateUser(user.Name, request.CurrentPw, request.CurrentPassword, Request.RemoteIp, false).ConfigureAwait(false);
if (success == null)
{
throw new ArgumentException("Invalid user or password entered.");
}
- _userManager.ChangePassword(user, request.NewPw, request.NewPassword);
+ await _userManager.ChangePassword(user, request.NewPw).ConfigureAwait(false);
var currentToken = _authContext.GetAuthorizationInfo(Request).Token;
- _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), currentToken);
+ _sessionMananger.RevokeUserTokens(user.Id, currentToken);
}
}
@@ -513,11 +480,11 @@ namespace MediaBrowser.Api
/// Posts the specified request.
/// </summary>
/// <param name="request">The request.</param>
- public void Post(UpdateUser request)
+ public async Task Post(UpdateUser request)
{
var id = GetPathValue(1);
- AssertCanUpdateUser(_authContext, _userManager, id, false);
+ AssertCanUpdateUser(_authContext, _userManager, new Guid(id), false);
var dtoUser = request;
@@ -526,15 +493,14 @@ namespace MediaBrowser.Api
if (string.Equals(user.Name, dtoUser.Name, StringComparison.Ordinal))
{
_userManager.UpdateUser(user);
+ _userManager.UpdateConfiguration(user, dtoUser.Configuration);
}
else
{
- var task = _userManager.RenameUser(user, dtoUser.Name);
+ await _userManager.RenameUser(user, dtoUser.Name).ConfigureAwait(false);
- Task.WaitAll(task);
+ _userManager.UpdateConfiguration(dtoUser.Id, dtoUser.Configuration);
}
-
- _userManager.UpdateConfiguration(dtoUser.Id, dtoUser.Configuration);
}
/// <summary>
@@ -542,11 +508,11 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Post(CreateUserByName request)
+ public async Task<object> Post(CreateUserByName request)
{
var dtoUser = request;
- var newUser = _userManager.CreateUser(dtoUser.Name).Result;
+ var newUser = await _userManager.CreateUser(dtoUser.Name).ConfigureAwait(false);
var result = _userManager.GetUserDto(newUser, Request.RemoteIp);
@@ -558,16 +524,20 @@ namespace MediaBrowser.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Post(ForgotPassword request)
+ public async Task<object> Post(ForgotPassword request)
{
var isLocal = Request.IsLocal || _networkManager.IsInLocalNetwork(Request.RemoteIp);
- return _userManager.StartForgotPasswordProcess(request.EnteredUsername, isLocal);
+ var result = await _userManager.StartForgotPasswordProcess(request.EnteredUsername, isLocal).ConfigureAwait(false);
+
+ return result;
}
- public object Post(ForgotPasswordPin request)
+ public async Task<object> Post(ForgotPasswordPin request)
{
- return _userManager.RedeemPasswordResetPin(request.Pin);
+ var result = await _userManager.RedeemPasswordResetPin(request.Pin).ConfigureAwait(false);
+
+ return result;
}
public void Post(UpdateUserConfiguration request)
@@ -606,7 +576,7 @@ namespace MediaBrowser.Api
}
var currentToken = _authContext.GetAuthorizationInfo(Request).Token;
- _sessionMananger.RevokeUserTokens(user.Id.ToString("N"), currentToken);
+ _sessionMananger.RevokeUserTokens(user.Id, currentToken);
}
_userManager.UpdateUserPolicy(request.Id, request);
diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs
index 3f4bb46f45..40d2e066c5 100644
--- a/MediaBrowser.Api/VideosService.cs
+++ b/MediaBrowser.Api/VideosService.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Api
public class GetAdditionalParts : IReturn<QueryResult<BaseItemDto>>
{
[ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public string UserId { get; set; }
+ public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id.
@@ -76,11 +76,11 @@ namespace MediaBrowser.Api
/// <returns>System.Object.</returns>
public object Get(GetAdditionalParts request)
{
- var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
+ var user = !request.UserId.Equals(Guid.Empty) ? _userManager.GetUserById(request.UserId) : null;
var item = string.IsNullOrEmpty(request.Id)
- ? (!string.IsNullOrWhiteSpace(request.UserId)
- ? user.RootFolder
+ ? (!request.UserId.Equals(Guid.Empty)
+ ? _libraryManager.GetUserRootFolder()
: _libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id);
@@ -105,7 +105,7 @@ namespace MediaBrowser.Api
TotalRecordCount = items.Length
};
- return ToOptimizedSerializedResultUsingCache(result);
+ return ToOptimizedResult(result);
}
public void Delete(DeleteAlternateSources request)
@@ -115,12 +115,12 @@ namespace MediaBrowser.Api
foreach (var link in video.GetLinkedAlternateVersions())
{
link.SetPrimaryVersionId(null);
- link.LinkedAlternateVersions = Video.EmptyLinkedChildArray;
+ link.LinkedAlternateVersions = Array.Empty<LinkedChild>();
link.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
}
- video.LinkedAlternateVersions = Video.EmptyLinkedChildArray;
+ video.LinkedAlternateVersions = Array.Empty<LinkedChild>();
video.SetPrimaryVersionId(null);
video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
}
@@ -140,11 +140,6 @@ namespace MediaBrowser.Api
var videosWithVersions = items.Where(i => i.MediaSourceCount > 1)
.ToList();
- if (videosWithVersions.Count > 1)
- {
- throw new ArgumentException("Videos with sub-versions cannot be merged.");
- }
-
var primaryVersion = videosWithVersions.FirstOrDefault();
if (primaryVersion == null)
@@ -185,10 +180,23 @@ namespace MediaBrowser.Api
Path = item.Path,
ItemId = item.Id
});
+
+ foreach (var linkedItem in item.LinkedAlternateVersions)
+ {
+ if (!list.Any(i => string.Equals(i.Path, linkedItem.Path, StringComparison.OrdinalIgnoreCase)))
+ {
+ list.Add(linkedItem);
+ }
+ }
+
+ if (item.LinkedAlternateVersions.Length > 0)
+ {
+ item.LinkedAlternateVersions = Array.Empty<LinkedChild>();
+ item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
+ }
}
primaryVersion.LinkedAlternateVersions = list.ToArray();
-
primaryVersion.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
}
}