diff options
| author | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-20 20:33:05 -0500 |
|---|---|---|
| committer | LukePulverenti <luke.pulverenti@gmail.com> | 2013-02-20 20:33:05 -0500 |
| commit | 767cdc1f6f6a63ce997fc9476911e2c361f9d402 (patch) | |
| tree | 49add55976f895441167c66cfa95e5c7688d18ce /MediaBrowser.Controller/Sorting | |
| parent | 845554722efaed872948a9e0f7202e3ef52f1b6e (diff) | |
Pushing missing changes
Diffstat (limited to 'MediaBrowser.Controller/Sorting')
| -rw-r--r-- | MediaBrowser.Controller/Sorting/BaseItemComparer.cs | 231 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Sorting/SortOrder.cs | 33 |
2 files changed, 264 insertions, 0 deletions
diff --git a/MediaBrowser.Controller/Sorting/BaseItemComparer.cs b/MediaBrowser.Controller/Sorting/BaseItemComparer.cs new file mode 100644 index 000000000..6e49f396f --- /dev/null +++ b/MediaBrowser.Controller/Sorting/BaseItemComparer.cs @@ -0,0 +1,231 @@ +using MediaBrowser.Common.Logging; +using MediaBrowser.Controller.Entities; +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> + /// Initializes a new instance of the <see cref="BaseItemComparer" /> class. + /// </summary> + /// <param name="order">The order.</param> + public BaseItemComparer(SortOrder order) { + _order = order; + } + + /// <summary> + /// Initializes a new instance of the <see cref="BaseItemComparer" /> class. + /// </summary> + /// <param name="order">The order.</param> + /// <param name="compare">The compare.</param> + public BaseItemComparer(SortOrder order, StringComparison compare) { + _order = order; + _compareCulture = compare; + } + + /// <summary> + /// Initializes a new instance of the <see cref="BaseItemComparer" /> class. + /// </summary> + /// <param name="property">The property.</param> + public BaseItemComparer(string property) { + _order = SortOrder.Custom; + _propertyName = property; + } + + /// <summary> + /// Initializes a new instance of the <see cref="BaseItemComparer" /> class. + /// </summary> + /// <param name="property">The property.</param> + /// <param name="compare">The compare.</param> + public BaseItemComparer(string property, StringComparison compare) { + _order = SortOrder.Custom; + _propertyName = property; + _compareCulture = compare; + } + + #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.LogDebugInfo("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> + public static 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.LogError("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; + } + } +} diff --git a/MediaBrowser.Controller/Sorting/SortOrder.cs b/MediaBrowser.Controller/Sorting/SortOrder.cs new file mode 100644 index 000000000..3152ac67e --- /dev/null +++ b/MediaBrowser.Controller/Sorting/SortOrder.cs @@ -0,0 +1,33 @@ + +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 + } +} |
