unified the two sorting api's
This commit is contained in:
parent
913cb3c564
commit
31d079f1ba
|
@ -1,5 +1,4 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
|
@ -81,12 +80,6 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// <value>The index by.</value>
|
||||
public string IndexBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The dynamic, localized sort function name
|
||||
/// </summary>
|
||||
/// <value>The dynamic sort by.</value>
|
||||
public string DynamicSortBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What to sort the results by
|
||||
/// </summary>
|
||||
|
@ -254,7 +247,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
return ((Folder)item).GetRecursiveChildren(user);
|
||||
}
|
||||
|
||||
return ((Folder)item).GetChildren(user, request.IndexBy, request.DynamicSortBy, GetSortOrder(request));
|
||||
return ((Folder)item).GetChildren(user, request.IndexBy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -266,58 +259,9 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> ApplySortOrder(GetItems request, IEnumerable<BaseItem> items, User user)
|
||||
{
|
||||
var isFirst = true;
|
||||
var descending = (GetSortOrder(request) ?? SortOrder.Ascending) == SortOrder.Descending;
|
||||
var orderBy = GetOrderBy(request).ToArray();
|
||||
|
||||
IOrderedEnumerable<BaseItem> orderedItems = null;
|
||||
|
||||
foreach (var orderBy in GetOrderBy(request).Select(o => GetComparer(o, user)))
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
orderedItems = descending ? items.OrderByDescending(i => i, orderBy) : items.OrderBy(i => i, orderBy);
|
||||
}
|
||||
else
|
||||
{
|
||||
orderedItems = descending ? orderedItems.ThenByDescending(i => i, orderBy) : orderedItems.ThenBy(i => i, orderBy);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
return orderedItems ?? items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the comparer.
|
||||
/// </summary>
|
||||
/// <param name="sortBy">The sort by.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IComparer{BaseItem}.</returns>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
private IComparer<BaseItem> GetComparer(ItemSortBy sortBy, User user)
|
||||
{
|
||||
switch (sortBy)
|
||||
{
|
||||
case ItemSortBy.Album:
|
||||
return new AlbumComparer();
|
||||
case ItemSortBy.AlbumArtist:
|
||||
return new AlbumArtistComparer();
|
||||
case ItemSortBy.Artist:
|
||||
return new ArtistComparer();
|
||||
case ItemSortBy.Random:
|
||||
return new RandomComparer();
|
||||
case ItemSortBy.DateCreated:
|
||||
return new DateCreatedComparer();
|
||||
case ItemSortBy.SortName:
|
||||
return new SortNameComparer();
|
||||
case ItemSortBy.PremiereDate:
|
||||
return new PremiereDateComparer();
|
||||
case ItemSortBy.DatePlayed:
|
||||
return new DatePlayedComparer { User = user };
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
return orderBy.Length == 0 ? items : _libraryManager.Sort(items, user, orderBy, GetSortOrder(request) ?? SortOrder.Ascending);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -575,16 +519,16 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>IEnumerable{ItemSortBy}.</returns>
|
||||
private IEnumerable<ItemSortBy> GetOrderBy(GetItems request)
|
||||
private IEnumerable<string> GetOrderBy(GetItems request)
|
||||
{
|
||||
var val = request.SortBy;
|
||||
|
||||
if (string.IsNullOrEmpty(val))
|
||||
{
|
||||
return new ItemSortBy[] { };
|
||||
return new string[] { };
|
||||
}
|
||||
|
||||
return val.Split(',').Select(v => (ItemSortBy)Enum.Parse(typeof(ItemSortBy), v, true));
|
||||
return val.Split(',');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -621,201 +565,4 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
return x.DateCreated.CompareTo(y.DateCreated);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class RandomComparer
|
||||
/// </summary>
|
||||
public class RandomComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return Guid.NewGuid().CompareTo(Guid.NewGuid());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class SortNameComparer
|
||||
/// </summary>
|
||||
public class SortNameComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(x.SortName, y.SortName, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class AlbumArtistComparer
|
||||
/// </summary>
|
||||
public class AlbumArtistComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetValue(BaseItem x)
|
||||
{
|
||||
var audio = x as Audio;
|
||||
|
||||
return audio == null ? string.Empty : audio.AlbumArtist;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class AlbumComparer
|
||||
/// </summary>
|
||||
public class AlbumComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetValue(BaseItem x)
|
||||
{
|
||||
var audio = x as Audio;
|
||||
|
||||
return audio == null ? string.Empty : audio.Album;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class ArtistComparer
|
||||
/// </summary>
|
||||
public class ArtistComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetValue(BaseItem x)
|
||||
{
|
||||
var audio = x as Audio;
|
||||
|
||||
return audio == null ? string.Empty : audio.Artist;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class PremiereDateComparer
|
||||
/// </summary>
|
||||
public class PremiereDateComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetDate(x).CompareTo(GetDate(y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
private DateTime GetDate(BaseItem x)
|
||||
{
|
||||
if (x.PremiereDate.HasValue)
|
||||
{
|
||||
return x.PremiereDate.Value;
|
||||
}
|
||||
|
||||
if (x.ProductionYear.HasValue)
|
||||
{
|
||||
return new DateTime(x.ProductionYear.Value, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
}
|
||||
return DateTime.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class DatePlayedComparer
|
||||
/// </summary>
|
||||
public class DatePlayedComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user.
|
||||
/// </summary>
|
||||
/// <value>The user.</value>
|
||||
public User User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetDate(x).CompareTo(GetDate(y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
private DateTime GetDate(BaseItem x)
|
||||
{
|
||||
var userdata = x.GetUserData(User, false);
|
||||
|
||||
if (userdata != null && userdata.LastPlayedDate.HasValue)
|
||||
{
|
||||
return userdata.LastPlayedDate.Value;
|
||||
}
|
||||
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ using System.Linq;
|
|||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SortOrder = MediaBrowser.Controller.Sorting.SortOrder;
|
||||
|
||||
namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
|
@ -177,63 +176,6 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
}
|
||||
|
||||
#region Sorting
|
||||
|
||||
/// <summary>
|
||||
/// The _sort by options
|
||||
/// </summary>
|
||||
private Dictionary<string, IComparer<BaseItem>> _sortByOptions;
|
||||
/// <summary>
|
||||
/// Dictionary of sort options - consists of a display value (localized) and an IComparer of BaseItem
|
||||
/// </summary>
|
||||
/// <value>The sort by options.</value>
|
||||
[IgnoreDataMember]
|
||||
public Dictionary<string, IComparer<BaseItem>> SortByOptions
|
||||
{
|
||||
get { return _sortByOptions ?? (_sortByOptions = GetSortByOptions()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the valid set of sort by options for this folder type.
|
||||
/// Override or extend to modify.
|
||||
/// </summary>
|
||||
/// <returns>Dictionary{System.StringIComparer{BaseItem}}.</returns>
|
||||
protected virtual Dictionary<string, IComparer<BaseItem>> GetSortByOptions()
|
||||
{
|
||||
return new Dictionary<string, IComparer<BaseItem>> {
|
||||
{LocalizedStrings.Instance.GetString("NameDispPref"), new BaseItemComparer(SortOrder.Name, Logger)},
|
||||
{LocalizedStrings.Instance.GetString("DateDispPref"), new BaseItemComparer(SortOrder.Date, Logger)},
|
||||
{LocalizedStrings.Instance.GetString("RatingDispPref"), new BaseItemComparer(SortOrder.Rating, Logger)},
|
||||
{LocalizedStrings.Instance.GetString("RuntimeDispPref"), new BaseItemComparer(SortOrder.Runtime, Logger)},
|
||||
{LocalizedStrings.Instance.GetString("YearDispPref"), new BaseItemComparer(SortOrder.Year, Logger)}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a sorting comparer by name
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>IComparer{BaseItem}.</returns>
|
||||
private IComparer<BaseItem> GetSortingFunction(string name)
|
||||
{
|
||||
IComparer<BaseItem> sorting;
|
||||
SortByOptions.TryGetValue(name ?? "", out sorting);
|
||||
return sorting ?? new BaseItemComparer(SortOrder.Name, Logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of sort by choices for this folder (localized).
|
||||
/// </summary>
|
||||
/// <value>The sort by option strings.</value>
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<string> SortByOptionStrings
|
||||
{
|
||||
get { return SortByOptions.Keys; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexing
|
||||
|
||||
/// <summary>
|
||||
|
@ -877,11 +819,9 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="indexBy">The index by.</param>
|
||||
/// <param name="sortBy">The sort by.</param>
|
||||
/// <param name="sortOrder">The sort order.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public virtual IEnumerable<BaseItem> GetChildren(User user, string indexBy = null, string sortBy = null, Model.Entities.SortOrder? sortOrder = null)
|
||||
public virtual IEnumerable<BaseItem> GetChildren(User user, string indexBy = null)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
|
@ -889,7 +829,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
}
|
||||
|
||||
//the true root should return our users root folder children
|
||||
if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, indexBy, sortBy, sortOrder);
|
||||
if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, indexBy);
|
||||
|
||||
IEnumerable<BaseItem> result = null;
|
||||
|
||||
|
@ -904,14 +844,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
result = ActualChildren.Where(c => c.IsVisible(user));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return sortOrder.HasValue && sortOrder.Value == Model.Entities.SortOrder.Descending
|
||||
? result.OrderByDescending(i => i, GetSortingFunction(sortBy))
|
||||
: result.OrderBy(i => i, GetSortingFunction(sortBy));
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -373,11 +373,6 @@ namespace MediaBrowser.Controller.Library
|
|||
{
|
||||
dto.IndexOptions = folder.IndexByOptionStrings.ToArray();
|
||||
}
|
||||
|
||||
if (fields.Contains(ItemFields.SortOptions))
|
||||
{
|
||||
dto.SortOptions = folder.SortByOptionStrings.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
// Add audio info
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
@ -158,7 +159,19 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <param name="pluginFolders">The plugin folders.</param>
|
||||
/// <param name="resolvers">The resolvers.</param>
|
||||
/// <param name="introProviders">The intro providers.</param>
|
||||
/// <param name="itemComparers">The item comparers.</param>
|
||||
void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders,
|
||||
IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders);
|
||||
IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders, IEnumerable<IBaseItemComparer> itemComparers);
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the specified items.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <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);
|
||||
}
|
||||
}
|
|
@ -185,8 +185,8 @@
|
|||
<Compile Include="Providers\FolderProviderFromXml.cs" />
|
||||
<Compile Include="Providers\ImageFromMediaLocationProvider.cs" />
|
||||
<Compile Include="Providers\MediaInfo\FFProbeVideoInfoProvider.cs" />
|
||||
<Compile Include="Sorting\BaseItemComparer.cs" />
|
||||
<Compile Include="Sorting\SortOrder.cs" />
|
||||
<Compile Include="Sorting\IBaseItemComparer.cs" />
|
||||
<Compile Include="Sorting\IUserBaseItemComparer.cs" />
|
||||
<Compile Include="Updates\IInstallationManager.cs" />
|
||||
<Compile Include="Weather\IWeatherProvider.cs" />
|
||||
<Compile Include="Providers\BaseItemXmlParser.cs" />
|
||||
|
|
|
@ -1,248 +0,0 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Sorting {
|
||||
/// <summary>
|
||||
/// Class BaseItemComparer
|
||||
/// </summary>
|
||||
public class BaseItemComparer : IComparer<BaseItem> {
|
||||
/// <summary>
|
||||
/// The _order
|
||||
/// </summary>
|
||||
private readonly SortOrder _order;
|
||||
/// <summary>
|
||||
/// The _property name
|
||||
/// </summary>
|
||||
private readonly string _propertyName;
|
||||
/// <summary>
|
||||
/// The _compare culture
|
||||
/// </summary>
|
||||
private readonly StringComparison _compareCulture = StringComparison.CurrentCultureIgnoreCase;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logger.
|
||||
/// </summary>
|
||||
/// <value>The logger.</value>
|
||||
private ILogger Logger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseItemComparer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="order">The order.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public BaseItemComparer(SortOrder order, ILogger logger) {
|
||||
_order = order;
|
||||
Logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseItemComparer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="order">The order.</param>
|
||||
/// <param name="compare">The compare.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public BaseItemComparer(SortOrder order, StringComparison compare, ILogger logger)
|
||||
{
|
||||
_order = order;
|
||||
_compareCulture = compare;
|
||||
Logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseItemComparer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public BaseItemComparer(string property, ILogger logger)
|
||||
{
|
||||
_order = SortOrder.Custom;
|
||||
_propertyName = property;
|
||||
Logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BaseItemComparer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="property">The property.</param>
|
||||
/// <param name="compare">The compare.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public BaseItemComparer(string property, StringComparison compare, ILogger logger)
|
||||
{
|
||||
_order = SortOrder.Custom;
|
||||
_propertyName = property;
|
||||
_compareCulture = compare;
|
||||
Logger = logger;
|
||||
}
|
||||
|
||||
#region IComparer<BaseItem> Members
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y) {
|
||||
int compare = 0;
|
||||
|
||||
switch (_order) {
|
||||
|
||||
case SortOrder.Date:
|
||||
compare = -x.DateCreated.CompareTo(y.DateCreated);
|
||||
break;
|
||||
|
||||
case SortOrder.Year:
|
||||
|
||||
var xProductionYear = x.ProductionYear ?? 0;
|
||||
var yProductionYear = y.ProductionYear ?? 0;
|
||||
|
||||
|
||||
compare = yProductionYear.CompareTo(xProductionYear);
|
||||
break;
|
||||
|
||||
case SortOrder.Rating:
|
||||
|
||||
var xRating = x.CommunityRating ?? 0;
|
||||
var yRating = y.CommunityRating ?? 0;
|
||||
|
||||
compare = yRating.CompareTo(xRating);
|
||||
break;
|
||||
|
||||
case SortOrder.Runtime:
|
||||
var xRuntime = x.RunTimeTicks ?? 0;
|
||||
var yRuntime = y.RunTimeTicks ?? 0;
|
||||
|
||||
compare = xRuntime.CompareTo(yRuntime);
|
||||
break;
|
||||
|
||||
case SortOrder.Custom:
|
||||
|
||||
Logger.Debug("Sorting on custom field " + _propertyName);
|
||||
var yProp = y.GetType().GetProperty(_propertyName);
|
||||
var xProp = x.GetType().GetProperty(_propertyName);
|
||||
if (yProp == null || xProp == null) break;
|
||||
var yVal = yProp.GetValue(y, null);
|
||||
var xVal = xProp.GetValue(x,null);
|
||||
if (yVal == null && xVal == null) break;
|
||||
if (yVal == null) return 1;
|
||||
if (xVal == null) return -1;
|
||||
compare = String.Compare(xVal.ToString(), yVal.ToString(),_compareCulture);
|
||||
break;
|
||||
|
||||
default:
|
||||
compare = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (compare == 0) {
|
||||
|
||||
var name1 = x.SortName ?? x.Name ?? "";
|
||||
var name2 = y.SortName ?? y.Name ?? "";
|
||||
|
||||
//if (Config.Instance.EnableAlphanumericSorting)
|
||||
compare = AlphaNumericCompare(name1, name2,_compareCulture);
|
||||
//else
|
||||
// compare = String.Compare(name1,name2,_compareCulture);
|
||||
}
|
||||
|
||||
return compare;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Alphas the numeric compare.
|
||||
/// </summary>
|
||||
/// <param name="s1">The s1.</param>
|
||||
/// <param name="s2">The s2.</param>
|
||||
/// <param name="compareCulture">The compare culture.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
private int AlphaNumericCompare(string s1, string s2, StringComparison compareCulture) {
|
||||
// http://dotnetperls.com/Content/Alphanumeric-Sorting.aspx
|
||||
|
||||
int len1 = s1.Length;
|
||||
int len2 = s2.Length;
|
||||
int marker1 = 0;
|
||||
int marker2 = 0;
|
||||
|
||||
// Walk through two the strings with two markers.
|
||||
while (marker1 < len1 && marker2 < len2) {
|
||||
char ch1 = s1[marker1];
|
||||
char ch2 = s2[marker2];
|
||||
|
||||
// Some buffers we can build up characters in for each chunk.
|
||||
var space1 = new char[len1];
|
||||
var loc1 = 0;
|
||||
var space2 = new char[len2];
|
||||
var loc2 = 0;
|
||||
|
||||
// Walk through all following characters that are digits or
|
||||
// characters in BOTH strings starting at the appropriate marker.
|
||||
// Collect char arrays.
|
||||
do {
|
||||
space1[loc1++] = ch1;
|
||||
marker1++;
|
||||
|
||||
if (marker1 < len1) {
|
||||
ch1 = s1[marker1];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
|
||||
|
||||
do {
|
||||
space2[loc2++] = ch2;
|
||||
marker2++;
|
||||
|
||||
if (marker2 < len2) {
|
||||
ch2 = s2[marker2];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
|
||||
|
||||
// If we have collected numbers, compare them numerically.
|
||||
// Otherwise, if we have strings, compare them alphabetically.
|
||||
var str1 = new string(space1);
|
||||
var str2 = new string(space2);
|
||||
|
||||
var result = 0;
|
||||
|
||||
//biggest int - 2147483647
|
||||
if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]) /*&& str1.Length < 10 && str2.Length < 10*/) //this assumed the entire string was a number...
|
||||
{
|
||||
int thisNumericChunk;
|
||||
var isValid = false;
|
||||
|
||||
if (int.TryParse(str1.Substring(0, str1.Length > 9 ? 10 : str1.Length), out thisNumericChunk))
|
||||
{
|
||||
int thatNumericChunk;
|
||||
|
||||
if (int.TryParse(str2.Substring(0, str2.Length > 9 ? 10 : str2.Length), out thatNumericChunk))
|
||||
{
|
||||
isValid = true;
|
||||
result = thisNumericChunk.CompareTo(thatNumericChunk);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isValid)
|
||||
{
|
||||
Logger.Error("Error comparing numeric strings: " + str1 + "/" + str2);
|
||||
result = String.Compare(str1, str2, compareCulture);
|
||||
}
|
||||
|
||||
} else {
|
||||
result = String.Compare(str1,str2,compareCulture);
|
||||
}
|
||||
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return len1 - len2;
|
||||
}
|
||||
}
|
||||
}
|
17
MediaBrowser.Controller/Sorting/IBaseItemComparer.cs
Normal file
17
MediaBrowser.Controller/Sorting/IBaseItemComparer.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface IBaseItemComparer
|
||||
/// </summary>
|
||||
public interface IBaseItemComparer : IComparer<BaseItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
16
MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs
Normal file
16
MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
|
||||
namespace MediaBrowser.Controller.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a BaseItem comparer that requires a User to perform it's comparison
|
||||
/// </summary>
|
||||
public interface IUserBaseItemComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user.
|
||||
/// </summary>
|
||||
/// <value>The user.</value>
|
||||
User User { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
|
||||
namespace MediaBrowser.Controller.Sorting {
|
||||
/// <summary>
|
||||
/// Enum SortOrder
|
||||
/// </summary>
|
||||
public enum SortOrder {
|
||||
|
||||
/// <summary>
|
||||
/// Sort by name
|
||||
/// </summary>
|
||||
Name,
|
||||
/// <summary>
|
||||
/// Sort by date added to the library
|
||||
/// </summary>
|
||||
Date,
|
||||
/// <summary>
|
||||
/// Sort by community rating
|
||||
/// </summary>
|
||||
Rating,
|
||||
/// <summary>
|
||||
/// Sort by runtime
|
||||
/// </summary>
|
||||
Runtime,
|
||||
/// <summary>
|
||||
/// Sort by year
|
||||
/// </summary>
|
||||
Year,
|
||||
/// <summary>
|
||||
/// Custom sort order added by plugins
|
||||
/// </summary>
|
||||
Custom
|
||||
}
|
||||
}
|
|
@ -315,13 +315,6 @@ namespace MediaBrowser.Model.Dto
|
|||
[ProtoMember(52)]
|
||||
public List<DayOfWeek> AirDays { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sort options.
|
||||
/// </summary>
|
||||
/// <value>The sort options.</value>
|
||||
[ProtoMember(53)]
|
||||
public string[] SortOptions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index options.
|
||||
/// </summary>
|
||||
|
|
|
@ -86,11 +86,6 @@ namespace MediaBrowser.Model.Dto
|
|||
/// </summary>
|
||||
SortName,
|
||||
|
||||
/// <summary>
|
||||
/// The fields that the server supports sorting on
|
||||
/// </summary>
|
||||
SortOptions,
|
||||
|
||||
/// <summary>
|
||||
/// The studios of the item
|
||||
/// </summary>
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace MediaBrowser.Model.Dto
|
|||
/// What to sort the results by
|
||||
/// </summary>
|
||||
/// <value>The sort by.</value>
|
||||
public ItemSortBy[] SortBy { get; set; }
|
||||
public string[] SortBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The sort order to return results with
|
||||
|
@ -116,12 +116,6 @@ namespace MediaBrowser.Model.Dto
|
|||
/// <value>The index by.</value>
|
||||
public string IndexBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The dynamic, localized sort function name
|
||||
/// </summary>
|
||||
/// <value>The dynamic sort by.</value>
|
||||
public string DynamicSortBy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image types.
|
||||
/// </summary>
|
||||
|
|
|
@ -2,41 +2,53 @@
|
|||
namespace MediaBrowser.Model.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum ItemSortBy
|
||||
/// These represent sort orders that are known by the core
|
||||
/// </summary>
|
||||
public enum ItemSortBy
|
||||
public static class ItemSortBy
|
||||
{
|
||||
/// <summary>
|
||||
/// The album
|
||||
/// </summary>
|
||||
Album,
|
||||
public const string Album = "Album";
|
||||
/// <summary>
|
||||
/// The album artist
|
||||
/// </summary>
|
||||
AlbumArtist,
|
||||
public const string AlbumArtist = "AlbumArtist";
|
||||
/// <summary>
|
||||
/// The artist
|
||||
/// </summary>
|
||||
Artist,
|
||||
public const string Artist = "Artist";
|
||||
/// <summary>
|
||||
/// The date created
|
||||
/// </summary>
|
||||
DateCreated,
|
||||
public const string DateCreated = "DateCreated";
|
||||
/// <summary>
|
||||
/// The date played
|
||||
/// </summary>
|
||||
DatePlayed,
|
||||
public const string DatePlayed = "DatePlayed";
|
||||
/// <summary>
|
||||
/// The premiere date
|
||||
/// </summary>
|
||||
PremiereDate,
|
||||
public const string PremiereDate = "PremiereDate";
|
||||
/// <summary>
|
||||
/// The sort name
|
||||
/// </summary>
|
||||
SortName,
|
||||
public const string SortName = "SortName";
|
||||
/// <summary>
|
||||
/// The random
|
||||
/// </summary>
|
||||
Random
|
||||
public const string Random = "Random";
|
||||
/// <summary>
|
||||
/// The runtime
|
||||
/// </summary>
|
||||
public const string Runtime = "Runtime";
|
||||
/// <summary>
|
||||
/// The community rating
|
||||
/// </summary>
|
||||
public const string CommunityRating = "CommunityRating";
|
||||
/// <summary>
|
||||
/// The production year
|
||||
/// </summary>
|
||||
public const string ProductionYear = "ProductionYear";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using MediaBrowser.Controller.IO;
|
|||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Controller.ScheduledTasks;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations.Library.Resolvers;
|
||||
|
@ -22,6 +23,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SortOrder = MediaBrowser.Model.Entities.SortOrder;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Library
|
||||
{
|
||||
|
@ -54,6 +56,12 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <value>The entity resolvers enumerable.</value>
|
||||
private IEnumerable<IItemResolver> EntityResolvers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the comparers.
|
||||
/// </summary>
|
||||
/// <value>The comparers.</value>
|
||||
private IEnumerable<IBaseItemComparer> Comparers { get; set; }
|
||||
|
||||
#region LibraryChanged Event
|
||||
/// <summary>
|
||||
/// Fires whenever any validation routine adds or removes items. The added and removed items are properties of the args.
|
||||
|
@ -124,12 +132,14 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
/// <param name="pluginFolders">The plugin folders.</param>
|
||||
/// <param name="resolvers">The resolvers.</param>
|
||||
/// <param name="introProviders">The intro providers.</param>
|
||||
public void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders, IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders)
|
||||
/// <param name="itemComparers">The item comparers.</param>
|
||||
public void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders, IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders, IEnumerable<IBaseItemComparer> itemComparers)
|
||||
{
|
||||
EntityResolutionIgnoreRules = rules;
|
||||
PluginFolderCreators = pluginFolders;
|
||||
EntityResolvers = resolvers.OrderBy(i => i.Priority).ToArray();
|
||||
IntroProviders = introProviders;
|
||||
Comparers = itemComparers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -702,5 +712,62 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
{
|
||||
return IntroProviders.SelectMany(i => i.GetIntros(item, user));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sorts the specified sort by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="sortBy">The sort by.</param>
|
||||
/// <param name="sortOrder">The sort order.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<string> sortBy, SortOrder sortOrder)
|
||||
{
|
||||
var isFirst = true;
|
||||
|
||||
IOrderedEnumerable<BaseItem> orderedItems = null;
|
||||
|
||||
foreach (var orderBy in sortBy.Select(o => GetComparer(o, user)).Where(c => c != null))
|
||||
{
|
||||
if (isFirst)
|
||||
{
|
||||
orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, orderBy) : items.OrderBy(i => i, orderBy);
|
||||
}
|
||||
else
|
||||
{
|
||||
orderedItems = sortOrder == SortOrder.Descending ? orderedItems.ThenByDescending(i => i, orderBy) : orderedItems.ThenBy(i => i, orderBy);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
return orderedItems ?? items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the comparer.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IBaseItemComparer.</returns>
|
||||
private IBaseItemComparer GetComparer(string name, User user)
|
||||
{
|
||||
var comparer = Comparers.FirstOrDefault(c => string.Equals(name, c.Name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (comparer != null)
|
||||
{
|
||||
// If it requires a user, create a new one, and assign the user
|
||||
if (comparer is IUserBaseItemComparer)
|
||||
{
|
||||
var userComparer = (IUserBaseItemComparer)Activator.CreateInstance(comparer.GetType());
|
||||
|
||||
userComparer.User = user;
|
||||
|
||||
return userComparer;
|
||||
}
|
||||
}
|
||||
|
||||
return comparer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,6 +139,17 @@
|
|||
<Compile Include="ServerApplicationPaths.cs" />
|
||||
<Compile Include="ServerManager\ServerManager.cs" />
|
||||
<Compile Include="ServerManager\WebSocketConnection.cs" />
|
||||
<Compile Include="Sorting\AlbumArtistComparer.cs" />
|
||||
<Compile Include="Sorting\AlbumComparer.cs" />
|
||||
<Compile Include="Sorting\ArtistComparer.cs" />
|
||||
<Compile Include="Sorting\CommunityRatingComparer.cs" />
|
||||
<Compile Include="Sorting\DateCreatedComparer.cs" />
|
||||
<Compile Include="Sorting\DatePlayedComparer.cs" />
|
||||
<Compile Include="Sorting\PremiereDateComparer.cs" />
|
||||
<Compile Include="Sorting\ProductionYearComparer.cs" />
|
||||
<Compile Include="Sorting\RandomComparer.cs" />
|
||||
<Compile Include="Sorting\RuntimeComparer.cs" />
|
||||
<Compile Include="Sorting\SortNameComparer.cs" />
|
||||
<Compile Include="Sqlite\SQLiteDisplayPreferencesRepository.cs" />
|
||||
<Compile Include="Sqlite\SQLiteExtensions.cs" />
|
||||
<Compile Include="Sqlite\SQLiteItemRepository.cs" />
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class AlbumArtistComparer
|
||||
/// </summary>
|
||||
public class AlbumArtistComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetValue(BaseItem x)
|
||||
{
|
||||
var audio = x as Audio;
|
||||
|
||||
return audio == null ? string.Empty : audio.AlbumArtist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.AlbumArtist; }
|
||||
}
|
||||
}
|
||||
}
|
46
MediaBrowser.Server.Implementations/Sorting/AlbumComparer.cs
Normal file
46
MediaBrowser.Server.Implementations/Sorting/AlbumComparer.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class AlbumComparer
|
||||
/// </summary>
|
||||
public class AlbumComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetValue(BaseItem x)
|
||||
{
|
||||
var audio = x as Audio;
|
||||
|
||||
return audio == null ? string.Empty : audio.Album;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.Album; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class ArtistComparer
|
||||
/// </summary>
|
||||
public class ArtistComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private string GetValue(BaseItem x)
|
||||
{
|
||||
var audio = x as Audio;
|
||||
|
||||
return audio == null ? string.Empty : audio.Artist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.Artist; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
public class CommunityRatingComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return (x.CommunityRating ?? 0).CompareTo(y.CommunityRating ?? 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.CommunityRating; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class DateCreatedComparer
|
||||
/// </summary>
|
||||
public class DateCreatedComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return DateTime.Compare(x.DateCreated, y.DateCreated);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.DateCreated; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class DatePlayedComparer
|
||||
/// </summary>
|
||||
public class DatePlayedComparer : IUserBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the user.
|
||||
/// </summary>
|
||||
/// <value>The user.</value>
|
||||
public User User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetDate(x).CompareTo(GetDate(y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
private DateTime GetDate(BaseItem x)
|
||||
{
|
||||
var userdata = x.GetUserData(User, false);
|
||||
|
||||
if (userdata != null && userdata.LastPlayedDate.HasValue)
|
||||
{
|
||||
return userdata.LastPlayedDate.Value;
|
||||
}
|
||||
|
||||
return DateTime.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.DatePlayed; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class PremiereDateComparer
|
||||
/// </summary>
|
||||
public class PremiereDateComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetDate(x).CompareTo(GetDate(y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
private DateTime GetDate(BaseItem x)
|
||||
{
|
||||
if (x.PremiereDate.HasValue)
|
||||
{
|
||||
return x.PremiereDate.Value;
|
||||
}
|
||||
|
||||
if (x.ProductionYear.HasValue)
|
||||
{
|
||||
return new DateTime(x.ProductionYear.Value, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
}
|
||||
return DateTime.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.PremiereDate; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class ProductionYearComparer
|
||||
/// </summary>
|
||||
public class ProductionYearComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return GetValue(x).CompareTo(GetValue(y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns>DateTime.</returns>
|
||||
private int GetValue(BaseItem x)
|
||||
{
|
||||
if (x.ProductionYear.HasValue)
|
||||
{
|
||||
return x.ProductionYear.Value;
|
||||
}
|
||||
|
||||
if (x.PremiereDate.HasValue)
|
||||
{
|
||||
return x.PremiereDate.Value.Year;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.ProductionYear; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class RandomComparer
|
||||
/// </summary>
|
||||
public class RandomComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return Guid.NewGuid().CompareTo(Guid.NewGuid());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.Random; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class RuntimeComparer
|
||||
/// </summary>
|
||||
public class RuntimeComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return (x.RunTimeTicks ?? 0).CompareTo(y.RunTimeTicks ?? 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.Runtime; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using System;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Model.Dto;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sorting
|
||||
{
|
||||
/// <summary>
|
||||
/// Class SortNameComparer
|
||||
/// </summary>
|
||||
public class SortNameComparer : IBaseItemComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares the specified x.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public int Compare(BaseItem x, BaseItem y)
|
||||
{
|
||||
return string.Compare(x.SortName, y.SortName, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return ItemSortBy.SortName; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ using MediaBrowser.Controller.Persistence;
|
|||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Controller.Resolvers;
|
||||
using MediaBrowser.Controller.Sorting;
|
||||
using MediaBrowser.Controller.Updates;
|
||||
using MediaBrowser.Controller.Weather;
|
||||
using MediaBrowser.IsoMounter;
|
||||
|
@ -242,7 +243,7 @@ namespace MediaBrowser.ServerApplication
|
|||
ServerManager.AddWebSocketListeners(GetExports<IWebSocketListener>(false));
|
||||
ServerManager.Start();
|
||||
|
||||
LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IItemResolver>(), GetExports<IIntroProvider>());
|
||||
LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IItemResolver>(), GetExports<IIntroProvider>(), GetExports<IBaseItemComparer>());
|
||||
|
||||
ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().OrderBy(e => e.Priority).ToArray());
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Movies;
|
|||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Localization;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
@ -78,7 +79,8 @@ namespace MediaBrowser.ServerApplication
|
|||
Cursor = Cursors.Wait;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
IEnumerable<BaseItem> children = CurrentUser.Name == "Physical" ? _libraryManager.RootFolder.Children.OrderBy(i => i.SortName) : _libraryManager.RootFolder.GetChildren(CurrentUser, sortBy: LocalizedStrings.Instance.GetString("NameDispPref"));
|
||||
IEnumerable<BaseItem> children = CurrentUser.Name == "Physical" ? _libraryManager.RootFolder.Children : _libraryManager.RootFolder.GetChildren(CurrentUser);
|
||||
children = OrderByName(children, CurrentUser);
|
||||
|
||||
foreach (Folder folder in children)
|
||||
{
|
||||
|
@ -86,9 +88,12 @@ namespace MediaBrowser.ServerApplication
|
|||
var currentFolder = folder;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
var prefs = ddlProfile.SelectedItem != null ? currentFolder.GetDisplayPrefs(ddlProfile.SelectedItem as User, false) ?? new DisplayPreferences {SortBy = LocalizedStrings.Instance.GetString("NameDispPref")} : new DisplayPreferences {SortBy = LocalizedStrings.Instance.GetString("NameDispPref")};
|
||||
var prefs = ddlProfile.SelectedItem != null ? currentFolder.GetDisplayPrefs(ddlProfile.SelectedItem as User, false) ?? new DisplayPreferences {SortBy = ItemSortBy.SortName} : new DisplayPreferences {SortBy = ItemSortBy.SortName};
|
||||
var node = new TreeViewItem { Tag = currentFolder };
|
||||
AddChildren(node, currentFolder.GetChildren(CurrentUser, prefs.IndexBy, prefs.SortBy ?? LocalizedStrings.Instance.GetString("NameDispPref")), CurrentUser);
|
||||
|
||||
var subChildren = currentFolder.GetChildren(CurrentUser, prefs.IndexBy);
|
||||
subChildren = OrderByName(subChildren, CurrentUser);
|
||||
AddChildren(node, subChildren, CurrentUser);
|
||||
node.Header = currentFolder.Name + " (" +
|
||||
node.Items.Count + ")";
|
||||
tvwLibrary.Items.Add(node);
|
||||
|
@ -100,6 +105,28 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Orders the name of the by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> OrderByName(IEnumerable<BaseItem> items, User user)
|
||||
{
|
||||
return OrderBy(items, user, ItemSortBy.SortName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Orders the name of the by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> OrderBy(IEnumerable<BaseItem> items, User user, string order)
|
||||
{
|
||||
return _libraryManager.Sort(items, user, new[] { order }, SortOrder.Ascending);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the children.
|
||||
/// </summary>
|
||||
|
@ -115,7 +142,7 @@ namespace MediaBrowser.ServerApplication
|
|||
if (subFolder != null)
|
||||
{
|
||||
var prefs = subFolder.GetDisplayPrefs(user, false) ?? new DisplayPreferences {SortBy = LocalizedStrings.Instance.GetString("NameDispPref")};
|
||||
AddChildren(node, subFolder.GetChildren(user, sortBy: prefs.SortBy), user);
|
||||
AddChildren(node, OrderBy(subFolder.GetChildren(user), user, prefs.SortBy), user);
|
||||
node.Header = item.Name + " (" + node.Items.Count + ")";
|
||||
}
|
||||
else
|
||||
|
@ -152,14 +179,29 @@ namespace MediaBrowser.ServerApplication
|
|||
{
|
||||
lblIndexBy.Visibility = ddlIndexBy.Visibility = ddlSortBy.Visibility = lblSortBy.Visibility = Visibility.Visible;
|
||||
ddlIndexBy.ItemsSource = folder.IndexByOptionStrings;
|
||||
ddlSortBy.ItemsSource = folder.SortByOptionStrings;
|
||||
|
||||
ddlSortBy.ItemsSource = new []
|
||||
{
|
||||
ItemSortBy.SortName,
|
||||
ItemSortBy.Album,
|
||||
ItemSortBy.AlbumArtist,
|
||||
ItemSortBy.Artist,
|
||||
ItemSortBy.CommunityRating,
|
||||
ItemSortBy.DateCreated,
|
||||
ItemSortBy.DatePlayed,
|
||||
ItemSortBy.PremiereDate,
|
||||
ItemSortBy.ProductionYear,
|
||||
ItemSortBy.Random,
|
||||
ItemSortBy.Runtime
|
||||
};
|
||||
|
||||
var prefs = folder.GetDisplayPrefs(ddlProfile.SelectedItem as User, false);
|
||||
ddlIndexBy.SelectedItem = prefs != null
|
||||
? prefs.IndexBy ?? LocalizedStrings.Instance.GetString("NoneDispPref")
|
||||
: LocalizedStrings.Instance.GetString("NoneDispPref");
|
||||
ddlSortBy.SelectedItem = prefs != null
|
||||
? prefs.SortBy ?? LocalizedStrings.Instance.GetString("NameDispPref")
|
||||
: LocalizedStrings.Instance.GetString("NameDispPref");
|
||||
? prefs.SortBy ?? ItemSortBy.SortName
|
||||
: ItemSortBy.SortName;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -311,7 +353,7 @@ namespace MediaBrowser.ServerApplication
|
|||
var folder = treeItem != null
|
||||
? treeItem.Tag as Folder
|
||||
: null;
|
||||
var prefs = folder != null ? folder.GetDisplayPrefs(CurrentUser, true) : new DisplayPreferences {SortBy = LocalizedStrings.Instance.GetString("NameDispPref")};
|
||||
var prefs = folder != null ? folder.GetDisplayPrefs(CurrentUser, true) : new DisplayPreferences {SortBy = ItemSortBy.SortName};
|
||||
if (folder != null && prefs.IndexBy != ddlIndexBy.SelectedItem as string)
|
||||
{
|
||||
//grab UI context so we can update within the below task
|
||||
|
@ -326,7 +368,7 @@ namespace MediaBrowser.ServerApplication
|
|||
//re-build the current item's children as an index
|
||||
prefs.IndexBy = ddlIndexBy.SelectedItem as string;
|
||||
treeItem.Items.Clear();
|
||||
AddChildren(treeItem,folder.GetChildren(CurrentUser, prefs.IndexBy, prefs.SortBy), CurrentUser);
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, prefs.IndexBy), CurrentUser, prefs.SortBy), CurrentUser);
|
||||
treeItem.Header = folder.Name + "(" +
|
||||
treeItem.Items.Count + ")";
|
||||
Cursor = Cursors.Arrow;
|
||||
|
@ -367,7 +409,7 @@ namespace MediaBrowser.ServerApplication
|
|||
//re-sort
|
||||
prefs.SortBy = ddlSortBy.SelectedItem as string;
|
||||
treeItem.Items.Clear();
|
||||
AddChildren(treeItem,folder.GetChildren(CurrentUser,prefs.IndexBy, prefs.SortBy ?? LocalizedStrings.Instance.GetString("NameDispPref")), CurrentUser);
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, prefs.IndexBy), CurrentUser, prefs.SortBy ?? ItemSortBy.SortName), CurrentUser);
|
||||
treeItem.Header = folder.Name + "(" +
|
||||
treeItem.Items.Count + ")";
|
||||
Cursor = Cursors.Arrow;
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
</ManifestKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>true</GenerateManifests>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignManifests>false</SignManifests>
|
||||
|
@ -112,6 +112,9 @@
|
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Hardcodet.Wpf.TaskbarNotification">
|
||||
<HintPath>..\packages\Hardcodet.Wpf.TaskbarNotification.1.0.4.0\lib\net40\Hardcodet.Wpf.TaskbarNotification.dll</HintPath>
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user