aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2017-09-04 15:34:53 -0400
committerGitHub <noreply@github.com>2017-09-04 15:34:53 -0400
commit637795aaf5e203d3a5a98cf9caa742663d0ee14e (patch)
tree732342d058b10e49a73fe6863bc722bde56806d0
parent9cf5cd1e5b504619875be6c5b9e4d76a990686e7 (diff)
parent3b318a3add352a72b6b0430300fddbf61edac216 (diff)
Merge pull request #2864 from MediaBrowser/dev
Dev
-rw-r--r--Emby.Dlna/ContentDirectory/ControlHandler.cs18
-rw-r--r--Emby.Server.Implementations/Channels/ChannelManager.cs13
-rw-r--r--Emby.Server.Implementations/Data/SqliteItemRepository.cs18
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs3
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthService.cs31
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs9
-rw-r--r--Emby.Server.Implementations/HttpServer/Security/SessionContext.cs12
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs34
-rw-r--r--Emby.Server.Implementations/Library/MusicManager.cs3
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs3
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs3
-rw-r--r--Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs3
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs34
-rw-r--r--Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs7
-rw-r--r--Emby.Server.Implementations/ServerManager/WebSocketConnection.cs2
-rw-r--r--Emby.Server.Implementations/TV/TVSeriesManager.cs12
-rw-r--r--Emby.Server.Implementations/TextEncoding/TextEncoding.cs61
-rw-r--r--Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs2
-rw-r--r--MediaBrowser.Api/ChannelService.cs15
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs4
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs6
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs6
-rw-r--r--MediaBrowser.Api/Reports/ReportsService.cs3
-rw-r--r--MediaBrowser.Api/SuggestionsService.cs4
-rw-r--r--MediaBrowser.Api/System/SystemService.cs13
-rw-r--r--MediaBrowser.Api/TvShowsService.cs3
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs2
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs35
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs3
-rw-r--r--MediaBrowser.Controller/Channels/Channel.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs7
-rw-r--r--MediaBrowser.Controller/Entities/InternalItemsQuery.cs9
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs12
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs18
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs4
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj2
-rw-r--r--MediaBrowser.Controller/Net/AuthenticatedAttribute.cs7
-rw-r--r--MediaBrowser.Controller/Net/IAuthService.cs6
-rw-r--r--MediaBrowser.Controller/Net/IAuthorizationContext.cs5
-rw-r--r--MediaBrowser.Controller/Net/IServiceRequest.cs14
-rw-r--r--MediaBrowser.Controller/Net/ISessionContext.cs5
-rw-r--r--MediaBrowser.Controller/Net/LoggedAttribute.cs4
-rw-r--r--MediaBrowser.Controller/Net/ServiceRequest.cs42
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs8
-rw-r--r--MediaBrowser.Model/Channels/ChannelItemQuery.cs9
-rw-r--r--MediaBrowser.Model/LiveTv/ProgramQuery.cs14
-rw-r--r--MediaBrowser.Model/Text/ITextEncoding.cs4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
-rw-r--r--SharedVersion.cs2
-rw-r--r--SocketHttpListener/Net/HttpResponseStream.Managed.cs56
51 files changed, 326 insertions, 273 deletions
diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs
index 205f4e890..47d199e6e 100644
--- a/Emby.Dlna/ContentDirectory/ControlHandler.cs
+++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs
@@ -458,8 +458,7 @@ namespace Emby.Dlna.ContentDirectory
{
Limit = limit,
StartIndex = startIndex,
- SortBy = sortOrders.ToArray(sortOrders.Count),
- SortOrder = sort.SortOrder,
+ OrderBy = sortOrders.Select(i => new Tuple<string, SortOrder>(i, sort.SortOrder)).ToArray(),
User = user,
Recursive = true,
IsMissing = false,
@@ -828,7 +827,7 @@ namespace Emby.Dlna.ContentDirectory
query.Parent = parent;
query.SetUser(user);
- query.OrderBy = new List<Tuple<string, SortOrder>>
+ query.OrderBy = new Tuple<string, SortOrder>[]
{
new Tuple<string, SortOrder> (ItemSortBy.DatePlayed, SortOrder.Descending),
new Tuple<string, SortOrder> (ItemSortBy.SortName, SortOrder.Ascending)
@@ -1077,7 +1076,7 @@ namespace Emby.Dlna.ContentDirectory
private QueryResult<ServerItem> GetMusicLatest(BaseItem parent, User user, InternalItemsQuery query)
{
- query.SortBy = new string[] { };
+ query.OrderBy = new Tuple<string, SortOrder>[] { };
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
{
@@ -1094,7 +1093,7 @@ namespace Emby.Dlna.ContentDirectory
private QueryResult<ServerItem> GetNextUp(BaseItem parent, User user, InternalItemsQuery query)
{
- query.SortBy = new string[] { };
+ query.OrderBy = new Tuple<string, SortOrder>[] { };
var result = _tvSeriesManager.GetNextUp(new NextUpQuery
{
@@ -1109,7 +1108,7 @@ namespace Emby.Dlna.ContentDirectory
private QueryResult<ServerItem> GetTvLatest(BaseItem parent, User user, InternalItemsQuery query)
{
- query.SortBy = new string[] { };
+ query.OrderBy = new Tuple<string, SortOrder>[] { };
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
{
@@ -1126,7 +1125,7 @@ namespace Emby.Dlna.ContentDirectory
private QueryResult<ServerItem> GetMovieLatest(BaseItem parent, User user, InternalItemsQuery query)
{
- query.SortBy = new string[] { };
+ query.OrderBy = new Tuple<string, SortOrder>[] { };
var items = _userViewManager.GetLatestItems(new LatestItemsQuery
{
@@ -1236,8 +1235,7 @@ namespace Emby.Dlna.ContentDirectory
sortOrders.Add(ItemSortBy.SortName);
}
- query.SortBy = sortOrders.ToArray(sortOrders.Count);
- query.SortOrder = sort.SortOrder;
+ query.OrderBy = sortOrders.Select(i => new Tuple<string, SortOrder>(i, sort.SortOrder)).ToArray();
}
private QueryResult<ServerItem> GetItemsFromPerson(Person person, User user, int? startIndex, int? limit)
@@ -1246,7 +1244,7 @@ namespace Emby.Dlna.ContentDirectory
{
PersonIds = new[] { person.Id.ToString("N") },
IncludeItemTypes = new[] { typeof(Movie).Name, typeof(Series).Name, typeof(Trailer).Name },
- SortBy = new[] { ItemSortBy.SortName },
+ OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
Limit = limit,
StartIndex = startIndex,
DtoOptions = GetDtoOptions()
diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs
index 1a90c85ee..e842005a5 100644
--- a/Emby.Server.Implementations/Channels/ChannelManager.cs
+++ b/Emby.Server.Implementations/Channels/ChannelManager.cs
@@ -466,7 +466,7 @@ namespace Emby.Server.Implementations.Channels
return _libraryManager.GetItemIds(new InternalItemsQuery
{
IncludeItemTypes = new[] { typeof(Channel).Name },
- SortBy = new[] { ItemSortBy.SortName }
+ OrderBy = new Tuple<string, SortOrder>[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) }
}).Select(i => GetChannelFeatures(i.ToString("N"))).ToArray();
}
@@ -932,14 +932,15 @@ namespace Emby.Server.Implementations.Channels
ChannelItemSortField? sortField = null;
ChannelItemSortField parsedField;
- if (query.SortBy.Length == 1 &&
- Enum.TryParse(query.SortBy[0], true, out parsedField))
+ var sortDescending = false;
+
+ if (query.OrderBy.Length == 1 &&
+ Enum.TryParse(query.OrderBy[0].Item1, true, out parsedField))
{
sortField = parsedField;
+ sortDescending = query.OrderBy[0].Item2 == SortOrder.Descending;
}
- var sortDescending = query.SortOrder.HasValue && query.SortOrder.Value == SortOrder.Descending;
-
var itemsResult = await GetChannelItems(channelProvider,
user,
query.FolderId,
@@ -1166,7 +1167,7 @@ namespace Emby.Server.Implementations.Channels
{
items = ApplyFilters(items, query.Filters, user);
- items = _libraryManager.Sort(items, user, query.SortBy, query.SortOrder ?? SortOrder.Ascending);
+ items = _libraryManager.Sort(items, user, query.OrderBy);
var all = items.ToList();
var totalCount = totalCountFromProvider ?? all.Count;
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 74e009bd9..165d17a57 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -2135,8 +2135,7 @@ namespace Emby.Server.Implementations.Data
//return true;
}
- var sortingFields = query.SortBy.ToList();
- sortingFields.AddRange(query.OrderBy.Select(i => i.Item1));
+ var sortingFields = query.OrderBy.Select(i => i.Item1).ToList();
if (sortingFields.Contains(ItemSortBy.IsFavoriteOrLiked, StringComparer.OrdinalIgnoreCase))
{
@@ -2975,16 +2974,7 @@ namespace Emby.Server.Implementations.Data
private string GetOrderByText(InternalItemsQuery query)
{
var orderBy = query.OrderBy.ToList();
- var enableOrderInversion = true;
-
- if (orderBy.Count == 0)
- {
- orderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder)));
- }
- else
- {
- enableOrderInversion = false;
- }
+ var enableOrderInversion = false;
if (query.SimilarTo != null)
{
@@ -2993,12 +2983,10 @@ namespace Emby.Server.Implementations.Data
orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
orderBy.Add(new Tuple<string, SortOrder>("SimilarityScore", SortOrder.Descending));
//orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
- query.SortOrder = SortOrder.Descending;
- enableOrderInversion = false;
}
}
- query.OrderBy = orderBy;
+ query.OrderBy = orderBy.ToArray();
if (orderBy.Count == 0)
{
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index 8cb7b5dbf..aa679e1b9 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -160,6 +160,9 @@ namespace Emby.Server.Implementations.HttpServer
if (string.IsNullOrWhiteSpace(RangeHeader) || (RangeStart <= 0 && RangeEnd >= TotalContentLength - 1))
{
Logger.Info("Transmit file {0}", Path);
+
+ //var count = FileShare == FileShareMode.ReadWrite ? TotalContentLength : 0;
+
await response.TransmitFile(Path, 0, 0, FileShare, cancellationToken).ConfigureAwait(false);
return;
}
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
index 500bdc61e..fadab4482 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
using System;
using System.Linq;
+using MediaBrowser.Model.Services;
namespace Emby.Server.Implementations.HttpServer.Security
{
@@ -37,19 +38,19 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// </summary>
public string HtmlRedirect { get; set; }
- public void Authenticate(IServiceRequest request,
+ public void Authenticate(IRequest request,
IAuthenticationAttributes authAttribtues)
{
ValidateUser(request, authAttribtues);
}
- private void ValidateUser(IServiceRequest request,
+ private void ValidateUser(IRequest request,
IAuthenticationAttributes authAttribtues)
{
// This code is executed before the service
var auth = AuthorizationContext.GetAuthorizationInfo(request);
- if (!IsExemptFromAuthenticationToken(auth, authAttribtues))
+ if (!IsExemptFromAuthenticationToken(auth, authAttribtues, request))
{
var valid = IsValidConnectKey(auth.Token);
@@ -75,7 +76,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
var info = GetTokenInfo(request);
- if (!IsExemptFromRoles(auth, authAttribtues, info))
+ if (!IsExemptFromRoles(auth, authAttribtues, request, info))
{
var roles = authAttribtues.GetRoles();
@@ -95,7 +96,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
}
}
- private void ValidateUserAccess(User user, IServiceRequest request,
+ private void ValidateUserAccess(User user, IRequest request,
IAuthenticationAttributes authAttribtues,
AuthorizationInfo auth)
{
@@ -111,7 +112,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
!authAttribtues.EscapeParentalControl &&
!user.IsParentalScheduleAllowed())
{
- request.AddResponseHeader("X-Application-Error-Code", "ParentalControl");
+ request.Response.AddHeader("X-Application-Error-Code", "ParentalControl");
throw new SecurityException("This user account is not allowed access at this time.")
{
@@ -131,23 +132,33 @@ namespace Emby.Server.Implementations.HttpServer.Security
}
}
- private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues)
+ private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request)
{
if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard)
{
return true;
}
+ if (authAttribtues.AllowLocal && request.IsLocal)
+ {
+ return true;
+ }
+
return false;
}
- private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, AuthenticationInfo tokenInfo)
+ private bool IsExemptFromRoles(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues, IRequest request, AuthenticationInfo tokenInfo)
{
if (!_config.Configuration.IsStartupWizardCompleted && authAttribtues.AllowBeforeStartupWizard)
{
return true;
}
+ if (authAttribtues.AllowLocal && request.IsLocal)
+ {
+ return true;
+ }
+
if (string.IsNullOrWhiteSpace(auth.Token))
{
return true;
@@ -195,7 +206,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
}
}
- private AuthenticationInfo GetTokenInfo(IServiceRequest request)
+ private AuthenticationInfo GetTokenInfo(IRequest request)
{
object info;
request.Items.TryGetValue("OriginalAuthenticationInfo", out info);
@@ -212,7 +223,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return ConnectManager.IsAuthorizationTokenValid(token);
}
- private void ValidateSecurityToken(IServiceRequest request, string token)
+ private void ValidateSecurityToken(IRequest request, string token)
{
if (string.IsNullOrWhiteSpace(token))
{
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index f40277778..c9d5ed007 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -21,11 +21,10 @@ namespace Emby.Server.Implementations.HttpServer.Security
public AuthorizationInfo GetAuthorizationInfo(object requestContext)
{
- var req = new ServiceRequest((IRequest)requestContext);
- return GetAuthorizationInfo(req);
+ return GetAuthorizationInfo((IRequest)requestContext);
}
- public AuthorizationInfo GetAuthorizationInfo(IServiceRequest requestContext)
+ public AuthorizationInfo GetAuthorizationInfo(IRequest requestContext)
{
object cached;
if (requestContext.Items.TryGetValue("AuthorizationInfo", out cached))
@@ -41,7 +40,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// </summary>
/// <param name="httpReq">The HTTP req.</param>
/// <returns>Dictionary{System.StringSystem.String}.</returns>
- private AuthorizationInfo GetAuthorization(IServiceRequest httpReq)
+ private AuthorizationInfo GetAuthorization(IRequest httpReq)
{
var auth = GetAuthorizationDictionary(httpReq);
@@ -135,7 +134,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
/// </summary>
/// <param name="httpReq">The HTTP req.</param>
/// <returns>Dictionary{System.StringSystem.String}.</returns>
- private Dictionary<string, string> GetAuthorizationDictionary(IServiceRequest httpReq)
+ private Dictionary<string, string> GetAuthorizationDictionary(IRequest httpReq)
{
var auth = httpReq.Headers["X-Emby-Authorization"];
diff --git a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
index 33dd4e2d7..dd5d64bf6 100644
--- a/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/SessionContext.cs
@@ -21,7 +21,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
_sessionManager = sessionManager;
}
- public Task<SessionInfo> GetSession(IServiceRequest requestContext)
+ public Task<SessionInfo> GetSession(IRequest requestContext)
{
var authorization = _authContext.GetAuthorizationInfo(requestContext);
@@ -38,7 +38,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
return _sessionManager.LogSessionActivity(authorization.Client, authorization.Version, authorization.DeviceId, authorization.Device, requestContext.RemoteIp, user);
}
- private AuthenticationInfo GetTokenInfo(IServiceRequest request)
+ private AuthenticationInfo GetTokenInfo(IRequest request)
{
object info;
request.Items.TryGetValue("OriginalAuthenticationInfo", out info);
@@ -47,11 +47,10 @@ namespace Emby.Server.Implementations.HttpServer.Security
public Task<SessionInfo> GetSession(object requestContext)
{
- var req = new ServiceRequest((IRequest)requestContext);
- return GetSession(req);
+ return GetSession((IRequest)requestContext);
}
- public async Task<User> GetUser(IServiceRequest requestContext)
+ public async Task<User> GetUser(IRequest requestContext)
{
var session = await GetSession(requestContext).ConfigureAwait(false);
@@ -60,8 +59,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
public Task<User> GetUser(object requestContext)
{
- var req = new ServiceRequest((IRequest)requestContext);
- return GetUser(req);
+ return GetUser((IRequest)requestContext);
}
}
}
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 57e42985d..8c5ecf782 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -846,8 +846,7 @@ namespace Emby.Server.Implementations.Library
{
Path = path,
IsFolder = isFolder,
- SortBy = new[] { ItemSortBy.DateCreated },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { ItemSortBy.DateCreated }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 1,
DtoOptions = new DtoOptions(true)
};
@@ -1777,6 +1776,37 @@ namespace Emby.Server.Implementations.Library
return orderedItems ?? items;
}
+ public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<Tuple<string, SortOrder>> orderByList)
+ {
+ var isFirst = true;
+
+ IOrderedEnumerable<BaseItem> orderedItems = null;
+
+ foreach (var orderBy in orderByList)
+ {
+ var comparer = GetComparer(orderBy.Item1, user);
+ if (comparer == null)
+ {
+ continue;
+ }
+
+ var sortOrder = orderBy.Item2;
+
+ if (isFirst)
+ {
+ orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, comparer) : items.OrderBy(i => i, comparer);
+ }
+ else
+ {
+ orderedItems = sortOrder == SortOrder.Descending ? orderedItems.ThenByDescending(i => i, comparer) : orderedItems.ThenBy(i => i, comparer);
+ }
+
+ isFirst = false;
+ }
+
+ return orderedItems ?? items;
+ }
+
/// <summary>
/// Gets the comparer.
/// </summary>
diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs
index 7f77170ad..1cbf4235a 100644
--- a/Emby.Server.Implementations/Library/MusicManager.cs
+++ b/Emby.Server.Implementations/Library/MusicManager.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Controller.Dto;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.Library
@@ -88,7 +89,7 @@ namespace Emby.Server.Implementations.Library
Limit = 200,
- SortBy = new[] { ItemSortBy.Random },
+ OrderBy = new [] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
DtoOptions = dtoOptions
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index d4c4f2794..b1ed034ca 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -10,6 +10,7 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Extensions;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Library
@@ -169,7 +170,7 @@ namespace Emby.Server.Implementations.Library
Limit = query.Limit,
IncludeItemsByName = string.IsNullOrWhiteSpace(query.ParentId),
ParentId = string.IsNullOrWhiteSpace(query.ParentId) ? (Guid?)null : new Guid(query.ParentId),
- SortBy = new[] { ItemSortBy.SortName },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) },
Recursive = true,
IsKids = query.IsKids,
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index b02c114bb..8c9377291 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -319,8 +319,7 @@ namespace Emby.Server.Implementations.Library
var query = new InternalItemsQuery(user)
{
IncludeItemTypes = includeItemTypes,
- SortOrder = SortOrder.Descending,
- SortBy = new[] { ItemSortBy.DateCreated },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null,
ExcludeItemTypes = excludeItemTypes,
IsVirtualItem = false,
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index f1694efb4..885e3b0ee 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1687,8 +1687,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
var episodesToDelete = (librarySeries.GetItemList(new InternalItemsQuery
{
- SortBy = new[] { ItemSortBy.DateCreated },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
IsVirtualItem = false,
IsFolder = false,
Recursive = true,
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 185935e88..089af2a01 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -187,7 +187,6 @@ namespace Emby.Server.Implementations.LiveTv
IsSports = query.IsSports,
IsSeries = query.IsSeries,
IncludeItemTypes = new[] { typeof(LiveTvChannel).Name },
- SortOrder = query.SortOrder ?? SortOrder.Ascending,
TopParentIds = new[] { topFolder.Id.ToString("N") },
IsFavorite = query.IsFavorite,
IsLiked = query.IsLiked,
@@ -196,18 +195,22 @@ namespace Emby.Server.Implementations.LiveTv
DtoOptions = dtoOptions
};
- internalQuery.OrderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder ?? SortOrder.Ascending)));
+ var orderBy = internalQuery.OrderBy.ToList();
+
+ orderBy.AddRange(query.SortBy.Select(i => new Tuple<string, SortOrder>(i, query.SortOrder ?? SortOrder.Ascending)));
if (query.EnableFavoriteSorting)
{
- internalQuery.OrderBy.Insert(0, new Tuple<string, SortOrder>(ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending));
+ orderBy.Insert(0, new Tuple<string, SortOrder>(ItemSortBy.IsFavoriteOrLiked, SortOrder.Descending));
}
if (!internalQuery.OrderBy.Any(i => string.Equals(i.Item1, ItemSortBy.SortName, StringComparison.OrdinalIgnoreCase)))
{
- internalQuery.OrderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending));
+ orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending));
}
+ internalQuery.OrderBy = orderBy.ToArray();
+
return _libraryManager.GetItemsResult(internalQuery);
}
@@ -918,10 +921,10 @@ namespace Emby.Server.Implementations.LiveTv
var topFolder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false);
- if (query.SortBy.Length == 0)
+ if (query.OrderBy.Length == 0)
{
// Unless something else was specified, order by start date to take advantage of a specialized index
- query.SortBy = new[] { ItemSortBy.StartDate };
+ query.OrderBy = new Tuple<string, SortOrder>[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) };
}
RemoveFields(options);
@@ -942,8 +945,7 @@ namespace Emby.Server.Implementations.LiveTv
Genres = query.Genres,
StartIndex = query.StartIndex,
Limit = query.Limit,
- SortBy = query.SortBy,
- SortOrder = query.SortOrder ?? SortOrder.Ascending,
+ OrderBy = query.OrderBy,
EnableTotalRecordCount = query.EnableTotalRecordCount,
TopParentIds = new[] { topFolder.Id.ToString("N") },
Name = query.Name,
@@ -1012,7 +1014,7 @@ namespace Emby.Server.Implementations.LiveTv
IsSports = query.IsSports,
IsKids = query.IsKids,
EnableTotalRecordCount = query.EnableTotalRecordCount,
- SortBy = new[] { ItemSortBy.StartDate },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) },
TopParentIds = new[] { topFolder.Id.ToString("N") },
DtoOptions = options
};
@@ -1644,8 +1646,7 @@ namespace Emby.Server.Implementations.LiveTv
IsVirtualItem = false,
Limit = query.Limit,
StartIndex = query.StartIndex,
- SortBy = new[] { ItemSortBy.DateCreated },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
EnableTotalRecordCount = query.EnableTotalRecordCount,
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
@@ -1692,8 +1693,7 @@ namespace Emby.Server.Implementations.LiveTv
Recursive = true,
AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(folders.Count),
Limit = query.Limit,
- SortBy = new[] { ItemSortBy.DateCreated },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
EnableTotalRecordCount = query.EnableTotalRecordCount,
IncludeItemTypes = includeItemTypes.ToArray(includeItemTypes.Count),
ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
@@ -1927,11 +1927,11 @@ namespace Emby.Server.Implementations.LiveTv
var info = recording;
- dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId)
+ dto.SeriesTimerId = string.IsNullOrEmpty(info.SeriesTimerId) || service == null
? null
: _tvDtoService.GetInternalSeriesTimerId(service.Name, info.SeriesTimerId).ToString("N");
- dto.TimerId = string.IsNullOrEmpty(info.TimerId)
+ dto.TimerId = string.IsNullOrEmpty(info.TimerId) || service == null
? null
: _tvDtoService.GetInternalTimerId(service.Name, info.TimerId).ToString("N");
@@ -2037,7 +2037,7 @@ namespace Emby.Server.Implementations.LiveTv
var internalResult = await GetInternalRecordings(query, options, cancellationToken).ConfigureAwait(false);
- var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user);
+ var returnArray = _dtoService.GetBaseItemDtos(internalResult.Items, options, user);
return new QueryResult<BaseItemDto>
{
@@ -2377,7 +2377,7 @@ namespace Emby.Server.Implementations.LiveTv
MaxStartDate = now,
MinEndDate = now,
Limit = channelIds.Length,
- SortBy = new[] { "StartDate" },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.StartDate, SortOrder.Ascending) },
TopParentIds = new[] { GetInternalLiveTvFolder(CancellationToken.None).Result.Id.ToString("N") },
DtoOptions = options
diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
index c2e860339..525df0350 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Configuration;
+using System;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
@@ -86,7 +87,7 @@ namespace Emby.Server.Implementations.Playlists
{
Genres = new[] { item.Name },
IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name },
- SortBy = new[] { ItemSortBy.Random },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
Limit = 4,
Recursive = true,
ImageTypes = new[] { ImageType.Primary },
@@ -118,7 +119,7 @@ namespace Emby.Server.Implementations.Playlists
{
Genres = new[] { item.Name },
IncludeItemTypes = new[] { typeof(Series).Name, typeof(Movie).Name },
- SortBy = new[] { ItemSortBy.Random },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
Limit = 4,
Recursive = true,
ImageTypes = new[] { ImageType.Primary },
diff --git a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs
index 4d5192fea..076f50d93 100644
--- a/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs
+++ b/Emby.Server.Implementations/ServerManager/WebSocketConnection.cs
@@ -136,7 +136,7 @@ namespace Emby.Server.Implementations.ServerManager
return;
}
- var charset = _textEncoding.GetDetectedEncodingName(bytes, null, false);
+ var charset = _textEncoding.GetDetectedEncodingName(bytes, bytes.Length, null, false);
if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase))
{
diff --git a/Emby.Server.Implementations/TV/TVSeriesManager.cs b/Emby.Server.Implementations/TV/TVSeriesManager.cs
index 018e452be..0b81f7e93 100644
--- a/Emby.Server.Implementations/TV/TVSeriesManager.cs
+++ b/Emby.Server.Implementations/TV/TVSeriesManager.cs
@@ -64,8 +64,7 @@ namespace Emby.Server.Implementations.TV
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { ItemSortBy.DatePlayed },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DatePlayed, SortOrder.Descending) },
SeriesPresentationUniqueKey = presentationUniqueKey,
Limit = limit,
ParentId = parentIdGuid,
@@ -122,8 +121,7 @@ namespace Emby.Server.Implementations.TV
var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { ItemSortBy.DatePlayed },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DatePlayed, SortOrder.Descending) },
SeriesPresentationUniqueKey = presentationUniqueKey,
Limit = limit,
DtoOptions = new MediaBrowser.Controller.Dto.DtoOptions
@@ -200,8 +198,7 @@ namespace Emby.Server.Implementations.TV
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { ItemSortBy.SortName },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Descending) },
IsPlayed = true,
Limit = 1,
ParentIndexNumberNotEquals = 0,
@@ -223,8 +220,7 @@ namespace Emby.Server.Implementations.TV
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { ItemSortBy.SortName },
- SortOrder = SortOrder.Ascending,
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) },
Limit = 1,
IsPlayed = false,
IsVirtualItem = false,
diff --git a/Emby.Server.Implementations/TextEncoding/TextEncoding.cs b/Emby.Server.Implementations/TextEncoding/TextEncoding.cs
index 1496d6f0f..9eb9be7ea 100644
--- a/Emby.Server.Implementations/TextEncoding/TextEncoding.cs
+++ b/Emby.Server.Implementations/TextEncoding/TextEncoding.cs
@@ -27,18 +27,33 @@ namespace Emby.Server.Implementations.TextEncoding
return Encoding.ASCII;
}
- private Encoding GetInitialEncoding(byte[] buffer)
+ private Encoding GetInitialEncoding(byte[] buffer, int count)
{
- if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
- return Encoding.UTF8;
- if (buffer[0] == 0xfe && buffer[1] == 0xff)
- return Encoding.Unicode;
- if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
- return Encoding.UTF32;
- if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
- return Encoding.UTF7;
+ if (count >= 3)
+ {
+ if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
+ return Encoding.UTF8;
+ }
+
+ if (count >= 2)
+ {
+ if (buffer[0] == 0xfe && buffer[1] == 0xff)
+ return Encoding.Unicode;
+ }
+
+ if (count >= 4)
+ {
+ if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
+ return Encoding.UTF32;
+ }
- var result = new TextEncodingDetect().DetectEncoding(buffer, buffer.Length);
+ if (count >= 3)
+ {
+ if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
+ return Encoding.UTF7;
+ }
+
+ var result = new TextEncodingDetect().DetectEncoding(buffer, count);
switch (result)
{
@@ -64,9 +79,11 @@ namespace Emby.Server.Implementations.TextEncoding
}
private bool _langDetectInitialized;
- public string GetDetectedEncodingName(byte[] bytes, string language, bool enableLanguageDetection)
+ public string GetDetectedEncodingName(byte[] bytes, int count, string language, bool enableLanguageDetection)
{
- var encoding = GetInitialEncoding(bytes);
+ var index = 0;
+
+ var encoding = GetInitialEncoding(bytes, count);
if (encoding != null && encoding.Equals(Encoding.UTF8))
{
@@ -81,7 +98,7 @@ namespace Emby.Server.Implementations.TextEncoding
LanguageDetector.Initialize(_json);
}
- language = DetectLanguage(bytes);
+ language = DetectLanguage(bytes, index, count);
if (!string.IsNullOrWhiteSpace(language))
{
@@ -89,7 +106,7 @@ namespace Emby.Server.Implementations.TextEncoding
}
}
- var charset = DetectCharset(bytes, language);
+ var charset = DetectCharset(bytes, index, count, language);
if (!string.IsNullOrWhiteSpace(charset))
{
@@ -112,11 +129,11 @@ namespace Emby.Server.Implementations.TextEncoding
return null;
}
- private string DetectLanguage(byte[] bytes)
+ private string DetectLanguage(byte[] bytes, int index, int count)
{
try
{
- return LanguageDetector.DetectLanguage(Encoding.UTF8.GetString(bytes));
+ return LanguageDetector.DetectLanguage(Encoding.UTF8.GetString(bytes, index, count));
}
catch (NLangDetectException ex)
{
@@ -124,7 +141,7 @@ namespace Emby.Server.Implementations.TextEncoding
try
{
- return LanguageDetector.DetectLanguage(Encoding.ASCII.GetString(bytes));
+ return LanguageDetector.DetectLanguage(Encoding.ASCII.GetString(bytes, index, count));
}
catch (NLangDetectException ex)
{
@@ -132,7 +149,7 @@ namespace Emby.Server.Implementations.TextEncoding
try
{
- return LanguageDetector.DetectLanguage(Encoding.Unicode.GetString(bytes));
+ return LanguageDetector.DetectLanguage(Encoding.Unicode.GetString(bytes, index, count));
}
catch (NLangDetectException ex)
{
@@ -163,9 +180,9 @@ namespace Emby.Server.Implementations.TextEncoding
}
}
- public Encoding GetDetectedEncoding(byte[] bytes, string language, bool enableLanguageDetection)
+ public Encoding GetDetectedEncoding(byte[] bytes, int size, string language, bool enableLanguageDetection)
{
- var charset = GetDetectedEncodingName(bytes, language, enableLanguageDetection);
+ var charset = GetDetectedEncodingName(bytes, size, language, enableLanguageDetection);
return GetEncodingFromCharset(charset);
}
@@ -225,10 +242,10 @@ namespace Emby.Server.Implementations.TextEncoding
}
}
- private string DetectCharset(byte[] bytes, string language)
+ private string DetectCharset(byte[] bytes, int index, int count, string language)
{
var detector = new CharsetDetector();
- detector.Feed(bytes, 0, bytes.Length);
+ detector.Feed(bytes, index, count);
detector.DataEnd();
var charset = detector.Charset;
diff --git a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs
index 98e0c4080..fa1d5b74e 100644
--- a/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs
+++ b/Emby.Server.Implementations/UserViews/CollectionFolderImageProvider.cs
@@ -145,7 +145,7 @@ namespace Emby.Server.Implementations.UserViews
Recursive = recursive,
IncludeItemTypes = new[] { typeof(BoxSet).Name },
Limit = 20,
- SortBy = new[] { ItemSortBy.Random },
+ OrderBy = new [] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
DtoOptions = new DtoOptions(false)
});
diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs
index 35ac2b482..d64bf7ec7 100644
--- a/MediaBrowser.Api/ChannelService.cs
+++ b/MediaBrowser.Api/ChannelService.cs
@@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Api.UserLibrary;
using MediaBrowser.Model.Services;
namespace MediaBrowser.Api
@@ -90,7 +91,7 @@ namespace MediaBrowser.Api
public int? Limit { get; set; }
[ApiMember(Name = "SortOrder", Description = "Sort Order - Ascending,Descending", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public SortOrder? SortOrder { get; set; }
+ public string SortOrder { get; set; }
[ApiMember(Name = "Filters", Description = "Optional. Specify additional filters to apply. This allows multiple, comma delimeted. Options: IsFolder, IsNotFolder, IsUnplayed, IsPlayed, IsFavorite, IsResumable, Likes, Dislikes", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Filters { get; set; }
@@ -116,6 +117,15 @@ namespace MediaBrowser.Api
return val.Split(',').Select(v => (ItemFilter)Enum.Parse(typeof(ItemFilter), v, true));
}
+
+ /// <summary>
+ /// Gets the order by.
+ /// </summary>
+ /// <returns>IEnumerable{ItemSortBy}.</returns>
+ public Tuple<string, SortOrder>[] GetOrderBy()
+ {
+ return BaseItemsRequest.GetOrderBy(SortBy, SortOrder);
+ }
}
[Route("/Channels/Items/Latest", "GET", Summary = "Gets channel items")]
@@ -228,8 +238,7 @@ namespace MediaBrowser.Api
UserId = request.UserId,
ChannelId = request.Id,
FolderId = request.FolderId,
- SortOrder = request.SortOrder,
- SortBy = (request.SortBy ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(),
+ OrderBy = request.GetOrderBy(),
Filters = request.GetFilters().ToArray(),
Fields = request.GetItemFields()
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 309c7195b..69d4a4ab4 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -639,9 +639,7 @@ namespace MediaBrowser.Api.Images
IsHeadRequest = isHeadRequest,
Path = imageResult.Item1,
- // Sometimes imagemagick keeps a hold on the file briefly even after it's done writing to it.
- // I'd rather do this than add a delay after saving the file
- FileShare = FileShareMode.ReadWrite
+ FileShare = FileShareMode.Read
}).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 81b0894ac..36bcee913 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -15,6 +15,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Api.UserLibrary;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller.Configuration;
@@ -373,7 +374,7 @@ namespace MediaBrowser.Api.LiveTv
public string SortBy { get; set; }
[ApiMember(Name = "SortOrder", Description = "Sort Order - Ascending,Descending", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public SortOrder? SortOrder { get; set; }
+ public string SortOrder { get; set; }
[ApiMember(Name = "Genres", Description = "The genres to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
public string Genres { get; set; }
@@ -994,8 +995,7 @@ namespace MediaBrowser.Api.LiveTv
query.StartIndex = request.StartIndex;
query.Limit = request.Limit;
- query.SortBy = (request.SortBy ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- query.SortOrder = request.SortOrder;
+ query.OrderBy = BaseItemsRequest.GetOrderBy(request.SortBy, request.SortOrder);
query.IsNews = request.IsNews;
query.IsMovie = request.IsMovie;
query.IsSeries = request.IsSeries;
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index 9157e6d89..254c93b33 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -193,8 +193,7 @@ namespace MediaBrowser.Api.Movies
//typeof(LiveTvProgram).Name
},
// IsMovie = true
- SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 7,
ParentId = parentIdGuid,
Recursive = true,
@@ -215,8 +214,7 @@ namespace MediaBrowser.Api.Movies
{
IncludeItemTypes = itemTypes.ToArray(itemTypes.Count),
IsMovie = true,
- SortBy = new[] { ItemSortBy.Random },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { ItemSortBy.Random }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 10,
IsFavoriteOrLiked = true,
ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray(recentlyPlayedMovies.Count),
diff --git a/MediaBrowser.Api/Reports/ReportsService.cs b/MediaBrowser.Api/Reports/ReportsService.cs
index 76d282990..a100b91e6 100644
--- a/MediaBrowser.Api/Reports/ReportsService.cs
+++ b/MediaBrowser.Api/Reports/ReportsService.cs
@@ -176,8 +176,7 @@ namespace MediaBrowser.Api.Reports
IncludeItemTypes = request.GetIncludeItemTypes(),
ExcludeItemTypes = request.GetExcludeItemTypes(),
Recursive = request.Recursive,
- SortBy = request.GetOrderBy(),
- SortOrder = request.SortOrder ?? SortOrder.Ascending,
+ OrderBy = request.GetOrderBy(),
IsFavorite = request.IsFavorite,
Limit = request.Limit,
diff --git a/MediaBrowser.Api/SuggestionsService.cs b/MediaBrowser.Api/SuggestionsService.cs
index 616e22519..3b918d8a2 100644
--- a/MediaBrowser.Api/SuggestionsService.cs
+++ b/MediaBrowser.Api/SuggestionsService.cs
@@ -5,8 +5,10 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Services;
using System;
+using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Api
@@ -79,7 +81,7 @@ namespace MediaBrowser.Api
{
return _libraryManager.GetItemsResult(new InternalItemsQuery(user)
{
- SortBy = new string[] { ItemSortBy.Random },
+ OrderBy = new[] { ItemSortBy.Random }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
MediaTypes = request.GetMediaTypes(),
IncludeItemTypes = request.GetIncludeItemTypes(),
IsVirtualItem = false,
diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index edb9f063d..37613c1c8 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -43,7 +43,7 @@ namespace MediaBrowser.Api.System
/// Class RestartApplication
/// </summary>
[Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")]
- [Authenticated(Roles = "Admin")]
+ [Authenticated(Roles = "Admin", AllowLocal = true)]
public class RestartApplication
{
}
@@ -52,10 +52,9 @@ namespace MediaBrowser.Api.System
/// This is currently not authenticated because the uninstaller needs to be able to shutdown the server.
/// </summary>
[Route("/System/Shutdown", "POST", Summary = "Shuts down the application")]
+ [Authenticated(Roles = "Admin", AllowLocal = true)]
public class ShutdownApplication
{
- // TODO: This is not currently authenticated due to uninstaller
- // Improve later
}
[Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")]
@@ -126,7 +125,7 @@ namespace MediaBrowser.Api.System
}
catch (IOException)
{
- files = new FileSystemMetadata[]{};
+ files = new FileSystemMetadata[] { };
}
var result = files.Select(i => new LogFile
@@ -149,6 +148,12 @@ namespace MediaBrowser.Api.System
var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
.First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase));
+ // For older files, assume fully static
+ if (file.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-1))
+ {
+ return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShareMode.Read);
+ }
+
return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShareMode.ReadWrite);
}
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index 3d0116665..fd81a9a3e 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -347,8 +347,7 @@ namespace MediaBrowser.Api
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
{
IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { "PremiereDate", "AirTime", "SortName" },
- SortOrder = SortOrder.Ascending,
+ OrderBy = new[] { ItemSortBy.PremiereDate, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
MinPremiereDate = minPremiereDate,
StartIndex = request.StartIndex,
Limit = request.Limit,
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index fca842289..ed0c4069b 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -299,7 +299,7 @@ namespace MediaBrowser.Api.UserLibrary
var filteredItems = FilterItems(request, extractedItems, user);
- filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy(), request.SortOrder ?? SortOrder.Ascending);
+ filteredItems = LibraryManager.Sort(filteredItems, user, request.GetOrderBy());
var ibnItemsArray = filteredItems.ToList();
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
index 66aa35de9..88d080db5 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
@@ -136,7 +136,7 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <value>The sort order.</value>
[ApiMember(Name = "SortOrder", Description = "Sort Order - Ascending,Descending", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public SortOrder? SortOrder { get; set; }
+ public string SortOrder { get; set; }
/// <summary>
/// Specify this to localize the search to a specific item or folder. Omit to use the root.
@@ -467,16 +467,41 @@ namespace MediaBrowser.Api.UserLibrary
/// Gets the order by.
/// </summary>
/// <returns>IEnumerable{ItemSortBy}.</returns>
- public string[] GetOrderBy()
+ public Tuple<string, SortOrder>[] GetOrderBy()
{
- var val = SortBy;
+ return GetOrderBy(SortBy, SortOrder);
+ }
+
+ public static Tuple<string, SortOrder>[] GetOrderBy(string sortBy, string requestedSortOrder)
+ {
+ var val = sortBy;
if (string.IsNullOrEmpty(val))
{
- return new string[] { };
+ return new Tuple<string, Model.Entities.SortOrder>[] { };
+ }
+
+ var vals = val.Split(',');
+ if (string.IsNullOrWhiteSpace(requestedSortOrder))
+ {
+ requestedSortOrder = "Ascending";
+ }
+
+ var sortOrders = requestedSortOrder.Split(',');
+
+ var result = new Tuple<string, Model.Entities.SortOrder>[vals.Length];
+
+ for (var i = 0; i < vals.Length; i++)
+ {
+ var sortOrderIndex = sortOrders.Length > i ? i : 0;
+
+ 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);
}
- return val.Split(',');
+ return result;
}
}
}
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index 2f946e35a..fb48f65e4 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -198,8 +198,7 @@ namespace MediaBrowser.Api.UserLibrary
IncludeItemTypes = request.GetIncludeItemTypes(),
ExcludeItemTypes = request.GetExcludeItemTypes(),
Recursive = request.Recursive,
- SortBy = request.GetOrderBy(),
- SortOrder = request.SortOrder ?? SortOrder.Ascending,
+ OrderBy = request.GetOrderBy(),
IsFavorite = request.IsFavorite,
Limit = request.Limit,
diff --git a/MediaBrowser.Controller/Channels/Channel.cs b/MediaBrowser.Controller/Channels/Channel.cs
index c6e750a0c..54faa1443 100644
--- a/MediaBrowser.Controller/Channels/Channel.cs
+++ b/MediaBrowser.Controller/Channels/Channel.cs
@@ -58,8 +58,7 @@ namespace MediaBrowser.Controller.Channels
Limit = query.Limit,
StartIndex = query.StartIndex,
UserId = query.User.Id.ToString("N"),
- SortBy = query.SortBy,
- SortOrder = query.SortOrder
+ OrderBy = query.OrderBy
}, new SimpleProgress<double>(), CancellationToken.None).Result;
}
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 8a87f3c6a..2e741a8c4 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -952,7 +952,7 @@ namespace MediaBrowser.Controller.Entities
{
var result = LibraryManager.GetItemsResult(query);
- if (query.SortBy.Length == 0)
+ if (query.OrderBy.Length == 0)
{
var ids = query.ItemIds.ToList();
@@ -973,7 +973,7 @@ namespace MediaBrowser.Controller.Entities
{
var result = LibraryManager.GetItemList(query);
- if (query.SortBy.Length == 0)
+ if (query.OrderBy.Length == 0)
{
var ids = query.ItemIds.ToList();
@@ -1000,8 +1000,7 @@ namespace MediaBrowser.Controller.Entities
Limit = query.Limit,
StartIndex = query.StartIndex,
UserId = query.User.Id.ToString("N"),
- SortBy = query.SortBy,
- SortOrder = query.SortOrder
+ OrderBy = query.OrderBy
}, new SimpleProgress<double>(), CancellationToken.None).Result;
}
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index 04833d049..03dc18b7a 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -16,10 +16,6 @@ namespace MediaBrowser.Controller.Entities
public int? Limit { get; set; }
- public string[] SortBy { get; set; }
-
- public SortOrder SortOrder { get; set; }
-
public User User { get; set; }
public BaseItem SimilarTo { get; set; }
@@ -165,7 +161,7 @@ namespace MediaBrowser.Controller.Entities
public Dictionary<string, string> ExcludeProviderIds { get; set; }
public bool EnableGroupByMetadataKey { get; set; }
- public List<Tuple<string, SortOrder>> OrderBy { get; set; }
+ public Tuple<string, SortOrder>[] OrderBy { get; set; }
public DateTime? MinDateCreated { get; set; }
public DateTime? MinDateLastSaved { get; set; }
@@ -190,7 +186,6 @@ namespace MediaBrowser.Controller.Entities
BlockUnratedItems = new UnratedItem[] { };
Tags = new string[] { };
OfficialRatings = new string[] { };
- SortBy = new string[] { };
MediaTypes = new string[] { };
IncludeItemTypes = new string[] { };
ExcludeItemTypes = new string[] { };
@@ -213,7 +208,7 @@ namespace MediaBrowser.Controller.Entities
TrailerTypes = new TrailerType[] { };
SourceTypes = new SourceType[] { };
SeriesStatuses = new SeriesStatus[] { };
- OrderBy = new List<Tuple<string, SortOrder>>();
+ OrderBy = new Tuple<string, SortOrder>[] { };
}
public InternalItemsQuery(User user)
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 6514d31d2..60d2624fa 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -252,7 +252,7 @@ namespace MediaBrowser.Controller.Entities.TV
query.AncestorWithPresentationUniqueKey = null;
query.SeriesPresentationUniqueKey = seriesKey;
query.IncludeItemTypes = new[] { typeof(Season).Name };
- query.SortBy = new[] {ItemSortBy.SortName};
+ query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
if (!config.DisplayMissingEpisodes)
{
@@ -275,9 +275,9 @@ namespace MediaBrowser.Controller.Entities.TV
query.AncestorWithPresentationUniqueKey = null;
query.SeriesPresentationUniqueKey = seriesKey;
- if (query.SortBy.Length == 0)
+ if (query.OrderBy.Length == 0)
{
- query.SortBy = new[] { ItemSortBy.SortName };
+ query.OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray();
}
if (query.IncludeItemTypes.Length == 0)
{
@@ -301,7 +301,7 @@ namespace MediaBrowser.Controller.Entities.TV
AncestorWithPresentationUniqueKey = null,
SeriesPresentationUniqueKey = seriesKey,
IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
- SortBy = new[] { ItemSortBy.SortName },
+ OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
};
var config = user.Configuration;
@@ -410,7 +410,7 @@ namespace MediaBrowser.Controller.Entities.TV
AncestorWithPresentationUniqueKey = queryFromSeries ? null : seriesKey,
SeriesPresentationUniqueKey = queryFromSeries ? seriesKey : null,
IncludeItemTypes = new[] { typeof(Episode).Name },
- SortBy = new[] { ItemSortBy.SortName },
+ OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
};
if (user != null)
@@ -453,7 +453,7 @@ namespace MediaBrowser.Controller.Entities.TV
return episodes.Where(episode =>
{
- var episodeItem = (Episode) episode;
+ var episodeItem = (Episode)episode;
var currentSeasonNumber = supportSpecialsInSeason ? episodeItem.AiredSeasonNumber : episode.ParentIndexNumber;
if (currentSeasonNumber.HasValue && seasonNumber.HasValue && currentSeasonNumber.Value == seasonNumber.Value)
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index acfa239d3..3ab82a103 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -397,7 +397,7 @@ namespace MediaBrowser.Controller.Entities
}, query.DtoOptions).Select(i => i.Item1 ?? i.Item2.FirstOrDefault()).Where(i => i != null);
- query.SortBy = new string[] { };
+ query.OrderBy = new Tuple<string, SortOrder>[] { };
return PostFilterAndSort(items, parent, null, query, false, true);
}
@@ -507,8 +507,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMovieLatest(Folder parent, User user, InternalItemsQuery query)
{
- query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
- query.SortOrder = SortOrder.Descending;
+ query.OrderBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
query.Recursive = true;
query.Parent = parent;
@@ -521,8 +520,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
{
- query.SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName };
- query.SortOrder = SortOrder.Descending;
+ query.OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
query.IsResumable = true;
query.Recursive = true;
query.Parent = parent;
@@ -633,8 +631,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
{
- query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
- query.SortOrder = SortOrder.Descending;
+ query.OrderBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
query.Recursive = true;
query.Parent = parent;
@@ -663,8 +660,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvResume(Folder parent, User user, InternalItemsQuery query)
{
- query.SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName };
- query.SortOrder = SortOrder.Descending;
+ query.OrderBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray();
query.IsResumable = true;
query.Recursive = true;
query.Parent = parent;
@@ -1104,9 +1100,9 @@ namespace MediaBrowser.Controller.Entities
{
items = items.DistinctBy(i => i.GetPresentationUniqueKey(), StringComparer.OrdinalIgnoreCase);
- if (query.SortBy.Length > 0)
+ if (query.OrderBy.Length > 0)
{
- items = libraryManager.Sort(items, query.User, query.SortBy, query.SortOrder);
+ items = libraryManager.Sort(items, query.User, query.OrderBy);
}
var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 265d4d786..05845102b 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -181,8 +181,8 @@ namespace MediaBrowser.Controller.Library
/// <param name="sortBy">The sort by.</param>
/// <param name="sortOrder">The sort order.</param>
/// <returns>IEnumerable{BaseItem}.</returns>
- IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<string> sortBy,
- SortOrder sortOrder);
+ IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<string> sortBy, SortOrder sortOrder);
+ IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<Tuple<string, SortOrder>> orderBy);
/// <summary>
/// Gets the user root folder.
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 26766f51a..5ef763b62 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -183,14 +183,12 @@
<Compile Include="Net\IHttpResultFactory.cs" />
<Compile Include="Net\IHttpServer.cs" />
<Compile Include="Net\IServerManager.cs" />
- <Compile Include="Net\IServiceRequest.cs" />
<Compile Include="Net\ISessionContext.cs" />
<Compile Include="Net\IWebSocket.cs" />
<Compile Include="Net\IWebSocketConnection.cs" />
<Compile Include="Net\IWebSocketListener.cs" />
<Compile Include="Net\LoggedAttribute.cs" />
<Compile Include="Net\SecurityException.cs" />
- <Compile Include="Net\ServiceRequest.cs" />
<Compile Include="Net\StaticResultOptions.cs" />
<Compile Include="Net\WebSocketConnectEventArgs.cs" />
<Compile Include="Net\WebSocketMessageInfo.cs" />
diff --git a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
index 6ded3761f..ecbfaecea 100644
--- a/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
+++ b/MediaBrowser.Controller/Net/AuthenticatedAttribute.cs
@@ -25,6 +25,8 @@ namespace MediaBrowser.Controller.Net
/// <value><c>true</c> if [allow before startup wizard]; otherwise, <c>false</c>.</value>
public bool AllowBeforeStartupWizard { get; set; }
+ public bool AllowLocal { get; set; }
+
/// <summary>
/// The request filter is executed before the service.
/// </summary>
@@ -33,9 +35,7 @@ namespace MediaBrowser.Controller.Net
/// <param name="requestDto">The request DTO</param>
public void RequestFilter(IRequest request, IResponse response, object requestDto)
{
- var serviceRequest = new ServiceRequest(request);
-
- AuthService.Authenticate(serviceRequest, this);
+ AuthService.Authenticate(request, this);
}
/// <summary>
@@ -59,6 +59,7 @@ namespace MediaBrowser.Controller.Net
{
bool EscapeParentalControl { get; }
bool AllowBeforeStartupWizard { get; }
+ bool AllowLocal { get; }
string[] GetRoles();
}
diff --git a/MediaBrowser.Controller/Net/IAuthService.cs b/MediaBrowser.Controller/Net/IAuthService.cs
index dc298c8d9..361320250 100644
--- a/MediaBrowser.Controller/Net/IAuthService.cs
+++ b/MediaBrowser.Controller/Net/IAuthService.cs
@@ -1,9 +1,9 @@
-
+using MediaBrowser.Model.Services;
+
namespace MediaBrowser.Controller.Net
{
public interface IAuthService
{
- void Authenticate(IServiceRequest request,
- IAuthenticationAttributes authAttribtues);
+ void Authenticate(IRequest request, IAuthenticationAttributes authAttribtues);
}
}
diff --git a/MediaBrowser.Controller/Net/IAuthorizationContext.cs b/MediaBrowser.Controller/Net/IAuthorizationContext.cs
index bdaed6046..5a9d0aa30 100644
--- a/MediaBrowser.Controller/Net/IAuthorizationContext.cs
+++ b/MediaBrowser.Controller/Net/IAuthorizationContext.cs
@@ -1,4 +1,5 @@
-
+using MediaBrowser.Model.Services;
+
namespace MediaBrowser.Controller.Net
{
public interface IAuthorizationContext
@@ -15,6 +16,6 @@ namespace MediaBrowser.Controller.Net
/// </summary>
/// <param name="requestContext">The request context.</param>
/// <returns>AuthorizationInfo.</returns>
- AuthorizationInfo GetAuthorizationInfo(IServiceRequest requestContext);
+ AuthorizationInfo GetAuthorizationInfo(IRequest requestContext);
}
}
diff --git a/MediaBrowser.Controller/Net/IServiceRequest.cs b/MediaBrowser.Controller/Net/IServiceRequest.cs
deleted file mode 100644
index ebc7e8d65..000000000
--- a/MediaBrowser.Controller/Net/IServiceRequest.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Collections.Generic;
-using MediaBrowser.Model.Services;
-
-namespace MediaBrowser.Controller.Net
-{
- public interface IServiceRequest
- {
- string RemoteIp { get; }
- QueryParamCollection Headers { get; }
- QueryParamCollection QueryString { get; }
- IDictionary<string,object> Items { get; }
- void AddResponseHeader(string name, string value);
- }
-}
diff --git a/MediaBrowser.Controller/Net/ISessionContext.cs b/MediaBrowser.Controller/Net/ISessionContext.cs
index 167e17867..213a66dac 100644
--- a/MediaBrowser.Controller/Net/ISessionContext.cs
+++ b/MediaBrowser.Controller/Net/ISessionContext.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Session;
using System.Threading.Tasks;
+using MediaBrowser.Model.Services;
namespace MediaBrowser.Controller.Net
{
@@ -9,7 +10,7 @@ namespace MediaBrowser.Controller.Net
Task<SessionInfo> GetSession(object requestContext);
Task<User> GetUser(object requestContext);
- Task<SessionInfo> GetSession(IServiceRequest requestContext);
- Task<User> GetUser(IServiceRequest requestContext);
+ Task<SessionInfo> GetSession(IRequest requestContext);
+ Task<User> GetUser(IRequest requestContext);
}
}
diff --git a/MediaBrowser.Controller/Net/LoggedAttribute.cs b/MediaBrowser.Controller/Net/LoggedAttribute.cs
index 6a2a5e2e3..eb57392e2 100644
--- a/MediaBrowser.Controller/Net/LoggedAttribute.cs
+++ b/MediaBrowser.Controller/Net/LoggedAttribute.cs
@@ -30,10 +30,8 @@ namespace MediaBrowser.Controller.Net
/// <param name="requestDto">The request DTO</param>
public void Filter(IRequest request, IResponse response, object requestDto)
{
- var serviceRequest = new ServiceRequest(request);
-
//This code is executed before the service
- var auth = AuthorizationContext.GetAuthorizationInfo(serviceRequest);
+ var auth = AuthorizationContext.GetAuthorizationInfo(request);
if (auth != null)
{
diff --git a/MediaBrowser.Controller/Net/ServiceRequest.cs b/MediaBrowser.Controller/Net/ServiceRequest.cs
deleted file mode 100644
index 1f72d0eb2..000000000
--- a/MediaBrowser.Controller/Net/ServiceRequest.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using MediaBrowser.Model.Services;
-
-namespace MediaBrowser.Controller.Net
-{
- public class ServiceRequest : IServiceRequest
- {
- private readonly IRequest _request;
-
- public ServiceRequest(IRequest request)
- {
- _request = request;
- }
-
- public string RemoteIp
- {
- get { return _request.RemoteIp; }
- }
-
- public QueryParamCollection Headers
- {
- get { return _request.Headers; }
- }
-
- public QueryParamCollection QueryString
- {
- get { return _request.QueryString; }
- }
-
- public IDictionary<string, object> Items
- {
- get { return _request.Items; }
- }
-
- public void AddResponseHeader(string name, string value)
- {
- _request.Response.AddHeader(name, value);
- }
- }
-}
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index e36e6ad5d..ee96a8c3b 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -149,8 +149,7 @@ namespace MediaBrowser.Controller.Playlists
Recursive = true,
IncludeItemTypes = new[] { typeof(Audio).Name },
GenreIds = new[] { musicGenre.Id.ToString("N") },
- SortBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName },
- SortOrder = SortOrder.Ascending,
+ OrderBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
});
}
@@ -163,8 +162,7 @@ namespace MediaBrowser.Controller.Playlists
Recursive = true,
IncludeItemTypes = new[] { typeof(Audio).Name },
ArtistIds = new[] { musicArtist.Id.ToString("N") },
- SortBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName },
- SortOrder = SortOrder.Ascending,
+ OrderBy = new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
DtoOptions = options
});
}
@@ -176,7 +174,7 @@ namespace MediaBrowser.Controller.Playlists
{
Recursive = true,
IsFolder = false,
- SortBy = new[] { ItemSortBy.SortName },
+ OrderBy = new[] { ItemSortBy.SortName }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),
MediaTypes = new[] { mediaType },
EnableTotalRecordCount = false,
DtoOptions = options
diff --git a/MediaBrowser.Model/Channels/ChannelItemQuery.cs b/MediaBrowser.Model/Channels/ChannelItemQuery.cs
index 4aacc1619..909d35b38 100644
--- a/MediaBrowser.Model/Channels/ChannelItemQuery.cs
+++ b/MediaBrowser.Model/Channels/ChannelItemQuery.cs
@@ -1,4 +1,6 @@
-using MediaBrowser.Model.Entities;
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Model.Channels
@@ -35,16 +37,15 @@ namespace MediaBrowser.Model.Channels
/// <value>The limit.</value>
public int? Limit { get; set; }
- public SortOrder? SortOrder { get; set; }
- public string[] SortBy { get; set; }
public ItemFilter[] Filters { get; set; }
public ItemFields[] Fields { get; set; }
+ public Tuple<string, SortOrder>[] OrderBy { get; set; }
public ChannelItemQuery()
{
Filters = new ItemFilter[] { };
- SortBy = new string[] { };
Fields = new ItemFields[] { };
+ OrderBy = new Tuple<string, SortOrder>[] { };
}
}
diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
index 1fd995760..c0959635f 100644
--- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs
+++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Model.LiveTv
public ProgramQuery()
{
ChannelIds = new string[] { };
- SortBy = new string[] { };
+ OrderBy = new Tuple<string, SortOrder>[] { };
Genres = new string[] { };
EnableTotalRecordCount = true;
EnableUserData = true;
@@ -104,17 +104,7 @@ namespace MediaBrowser.Model.LiveTv
/// </summary>
public int? Limit { get; set; }
- /// <summary>
- /// What to sort the results by
- /// </summary>
- /// <value>The sort by.</value>
- public string[] SortBy { get; set; }
-
- /// <summary>
- /// The sort order to return results with
- /// </summary>
- /// <value>The sort order.</value>
- public SortOrder? SortOrder { get; set; }
+ public Tuple<string, SortOrder>[] OrderBy { get; set; }
/// <summary>
/// Limit results to items containing specific genres
diff --git a/MediaBrowser.Model/Text/ITextEncoding.cs b/MediaBrowser.Model/Text/ITextEncoding.cs
index 96dca0c04..619d90a2b 100644
--- a/MediaBrowser.Model/Text/ITextEncoding.cs
+++ b/MediaBrowser.Model/Text/ITextEncoding.cs
@@ -7,8 +7,8 @@ namespace MediaBrowser.Model.Text
{
Encoding GetASCIIEncoding();
- string GetDetectedEncodingName(byte[] bytes, string language, bool enableLanguageDetection);
- Encoding GetDetectedEncoding(byte[] bytes, string language, bool enableLanguageDetection);
+ string GetDetectedEncodingName(byte[] bytes, int size, string language, bool enableLanguageDetection);
+ Encoding GetDetectedEncoding(byte[] bytes, int size, string language, bool enableLanguageDetection);
Encoding GetEncodingFromCharset(string charset);
}
}
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 87c8a70ae..a3cb05bf7 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.747</version>
+ <version>3.0.748</version>
<title>Emby.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 20c043007..6c2f2d399 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.747</version>
+ <version>3.0.748</version>
<title>Emby.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.747" />
+ <dependency id="MediaBrowser.Common" version="3.0.748" />
</dependencies>
</metadata>
<files>
diff --git a/SharedVersion.cs b/SharedVersion.cs
index 00bdebb12..fe1bfdeb6 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,3 +1,3 @@
using System.Reflection;
-[assembly: AssemblyVersion("3.2.30.6")]
+[assembly: AssemblyVersion("3.2.30.7")]
diff --git a/SocketHttpListener/Net/HttpResponseStream.Managed.cs b/SocketHttpListener/Net/HttpResponseStream.Managed.cs
index d5ef0b320..7e175f8d6 100644
--- a/SocketHttpListener/Net/HttpResponseStream.Managed.cs
+++ b/SocketHttpListener/Net/HttpResponseStream.Managed.cs
@@ -289,9 +289,65 @@ namespace SocketHttpListener.Net
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
{
+ //if (_supportsDirectSocketAccess && offset == 0 && count == 0 && !_response.SendChunked && _response.ContentLength64 > 8192)
+ //{
+ // if (EnableSendFileWithSocket)
+ // {
+ // return TransmitFileOverSocket(path, offset, count, fileShareMode, cancellationToken);
+ // }
+ //}
+
return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
}
+ private readonly byte[] _emptyBuffer = new byte[] { };
+ private Task TransmitFileOverSocket(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
+ {
+ var ms = GetHeaders(false);
+
+ byte[] preBuffer;
+ if (ms != null)
+ {
+ using (var msCopy = new MemoryStream())
+ {
+ ms.CopyTo(msCopy);
+ preBuffer = msCopy.ToArray();
+ }
+ }
+ else
+ {
+ return TransmitFileManaged(path, offset, count, fileShareMode, cancellationToken);
+ }
+
+ //_logger.Info("Socket sending file {0} {1}", path, response.ContentLength64);
+
+ var taskCompletion = new TaskCompletionSource<bool>();
+
+ Action<IAsyncResult> callback = callbackResult =>
+ {
+ try
+ {
+ _socket.EndSendFile(callbackResult);
+ taskCompletion.TrySetResult(true);
+ }
+ catch (Exception ex)
+ {
+ taskCompletion.TrySetException(ex);
+ }
+ };
+
+ var result = _socket.BeginSendFile(path, preBuffer, _emptyBuffer, TransmitFileOptions.UseDefaultWorkerThread, new AsyncCallback(callback), null);
+
+ if (result.CompletedSynchronously)
+ {
+ callback(result);
+ }
+
+ cancellationToken.Register(() => taskCompletion.TrySetCanceled());
+
+ return taskCompletion.Task;
+ }
+
const int StreamCopyToBufferSize = 81920;
private async Task TransmitFileManaged(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
{