diff options
| author | Eric Reed <ebr@mediabrowser3.com> | 2013-03-11 11:03:41 -0400 |
|---|---|---|
| committer | Eric Reed <ebr@mediabrowser3.com> | 2013-03-11 11:03:41 -0400 |
| commit | 6470c62c5048dd22caff3a2f4cb296e7e0e5937a (patch) | |
| tree | a566b28ca659291da99bdded88b4b366cc2572e1 /MediaBrowser.Server.Implementations | |
| parent | 889bd32e9e798fe816f4ae1d0051e755c30eac5e (diff) | |
| parent | 39020714f75b1bd1fe41355d4e9dadc9620ed8a1 (diff) | |
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
Diffstat (limited to 'MediaBrowser.Server.Implementations')
17 files changed, 750 insertions, 8 deletions
diff --git a/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs b/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs index cdb6adbe7..0445cd863 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.Extensions; +using System.Net; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; @@ -257,7 +258,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer var stream = await factoryFn().ConfigureAwait(false); - return new StreamWriter(stream); + var httpListenerResponse = (HttpListenerResponse) Response.OriginalResponse; + httpListenerResponse.SendChunked = false; + + if (IsRangeRequest) + { + return new RangeRequestWriter(Request.Headers, httpListenerResponse, stream); + } + + httpListenerResponse.ContentLength64 = stream.Length; + return new StreamWriter(stream, Logger); } string content; diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs new file mode 100644 index 000000000..e5c4c9796 --- /dev/null +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -0,0 +1,177 @@ +using ServiceStack.Service; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.HttpServer +{ + public class RangeRequestWriter : IStreamWriter + { + /// <summary> + /// Gets or sets the source stream. + /// </summary> + /// <value>The source stream.</value> + public Stream SourceStream { get; set; } + public HttpListenerResponse Response { get; set; } + public NameValueCollection RequestHeaders { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="StreamWriter" /> class. + /// </summary> + /// <param name="requestHeaders">The request headers.</param> + /// <param name="response">The response.</param> + /// <param name="source">The source.</param> + public RangeRequestWriter(NameValueCollection requestHeaders, HttpListenerResponse response, Stream source) + { + RequestHeaders = requestHeaders; + Response = response; + SourceStream = source; + } + + /// <summary> + /// The _requested ranges + /// </summary> + private List<KeyValuePair<long, long?>> _requestedRanges; + /// <summary> + /// Gets the requested ranges. + /// </summary> + /// <value>The requested ranges.</value> + protected IEnumerable<KeyValuePair<long, long?>> RequestedRanges + { + get + { + if (_requestedRanges == null) + { + _requestedRanges = new List<KeyValuePair<long, long?>>(); + + // Example: bytes=0-,32-63 + var ranges = RequestHeaders["Range"].Split('=')[1].Split(','); + + foreach (var range in ranges) + { + var vals = range.Split('-'); + + long start = 0; + long? end = null; + + if (!string.IsNullOrEmpty(vals[0])) + { + start = long.Parse(vals[0]); + } + if (!string.IsNullOrEmpty(vals[1])) + { + end = long.Parse(vals[1]); + } + + _requestedRanges.Add(new KeyValuePair<long, long?>(start, end)); + } + } + + return _requestedRanges; + } + } + + /// <summary> + /// Writes to. + /// </summary> + /// <param name="responseStream">The response stream.</param> + public void WriteTo(Stream responseStream) + { + Response.Headers["Accept-Ranges"] = "bytes"; + Response.StatusCode = 206; + + var task = WriteToAsync(responseStream); + + Task.WaitAll(task); + } + + /// <summary> + /// Writes to async. + /// </summary> + /// <param name="responseStream">The response stream.</param> + /// <returns>Task.</returns> + private async Task WriteToAsync(Stream responseStream) + { + using (var source = SourceStream) + { + var requestedRange = RequestedRanges.First(); + + var totalLength = SourceStream.Length; + + // If the requested range is "0-", we can optimize by just doing a stream copy + if (!requestedRange.Value.HasValue) + { + await ServeCompleteRangeRequest(source, requestedRange, responseStream, totalLength).ConfigureAwait(false); + } + + // This will have to buffer a portion of the content into memory + await ServePartialRangeRequest(source, requestedRange.Key, requestedRange.Value.Value, responseStream, totalLength).ConfigureAwait(false); + } + } + + /// <summary> + /// Handles a range request of "bytes=0-" + /// This will serve the complete content and add the content-range header + /// </summary> + /// <param name="sourceStream">The source stream.</param> + /// <param name="requestedRange">The requested range.</param> + /// <param name="responseStream">The response stream.</param> + /// <param name="totalContentLength">Total length of the content.</param> + /// <returns>Task.</returns> + private Task ServeCompleteRangeRequest(Stream sourceStream, KeyValuePair<long, long?> requestedRange, Stream responseStream, long totalContentLength) + { + var rangeStart = requestedRange.Key; + var rangeEnd = totalContentLength - 1; + var rangeLength = 1 + rangeEnd - rangeStart; + + // Content-Length is the length of what we're serving, not the original content + Response.ContentLength64 = rangeLength; + Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength); + + if (rangeStart > 0) + { + sourceStream.Position = rangeStart; + } + + return sourceStream.CopyToAsync(responseStream); + } + + /// <summary> + /// Serves a partial range request + /// </summary> + /// <param name="sourceStream">The source stream.</param> + /// <param name="rangeStart">The range start.</param> + /// <param name="rangeEnd">The range end.</param> + /// <param name="responseStream">The response stream.</param> + /// <param name="totalContentLength">Total length of the content.</param> + /// <returns>Task.</returns> + private async Task ServePartialRangeRequest(Stream sourceStream, long rangeStart, long rangeEnd, Stream responseStream, long totalContentLength) + { + var rangeLength = 1 + rangeEnd - rangeStart; + + // Content-Length is the length of what we're serving, not the original content + Response.ContentLength64 = rangeLength; + Response.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", rangeStart, rangeEnd, totalContentLength); + + sourceStream.Position = rangeStart; + + // Fast track to just copy the stream to the end + if (rangeEnd == totalContentLength - 1) + { + await sourceStream.CopyToAsync(responseStream).ConfigureAwait(false); + } + else + { + // Read the bytes we need + var buffer = new byte[Convert.ToInt32(rangeLength)]; + await sourceStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); + + await responseStream.WriteAsync(buffer, 0, Convert.ToInt32(rangeLength)).ConfigureAwait(false); + } + } + } +} diff --git a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs index ab178b6ea..6f5d6e25f 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs @@ -1,4 +1,6 @@ -using ServiceStack.Service; +using MediaBrowser.Model.Logging; +using ServiceStack.Service; +using System; using System.IO; using System.Threading.Tasks; @@ -9,6 +11,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// </summary> public class StreamWriter : IStreamWriter { + private ILogger Logger { get; set; } + /// <summary> /// Gets or sets the source stream. /// </summary> @@ -19,9 +23,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// Initializes a new instance of the <see cref="StreamWriter" /> class. /// </summary> /// <param name="source">The source.</param> - public StreamWriter(Stream source) + /// <param name="logger">The logger.</param> + public StreamWriter(Stream source, ILogger logger) { SourceStream = source; + Logger = logger; } /// <summary> @@ -42,9 +48,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// <returns>Task.</returns> private async Task WriteToAsync(Stream responseStream) { - using (var src = SourceStream) + try { - await src.CopyToAsync(responseStream).ConfigureAwait(false); + using (var src = SourceStream) + { + await src.CopyToAsync(responseStream).ConfigureAwait(false); + } + } + catch (Exception ex) + { + Logger.ErrorException("Error streaming media", ex); + + throw; } } } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 78ada1431..6cd46a310 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -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; + } } } diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 0b9f7c7e1..2bb75a18d 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -109,6 +109,7 @@ <Compile Include="HttpServer\HttpResultFactory.cs" /> <Compile Include="HttpServer\HttpServer.cs" /> <Compile Include="HttpServer\NativeWebSocket.cs" /> + <Compile Include="HttpServer\RangeRequestWriter.cs" /> <Compile Include="HttpServer\ServerFactory.cs" /> <Compile Include="HttpServer\StreamWriter.cs" /> <Compile Include="HttpServer\SwaggerService.cs" /> @@ -139,6 +140,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" /> diff --git a/MediaBrowser.Server.Implementations/Sorting/AlbumArtistComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AlbumArtistComparer.cs new file mode 100644 index 000000000..2493c0fc6 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/AlbumArtistComparer.cs @@ -0,0 +1,46 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/AlbumComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AlbumComparer.cs new file mode 100644 index 000000000..f455d5c2b --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/AlbumComparer.cs @@ -0,0 +1,46 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs b/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs new file mode 100644 index 000000000..c34f096a2 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs @@ -0,0 +1,46 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/CommunityRatingComparer.cs b/MediaBrowser.Server.Implementations/Sorting/CommunityRatingComparer.cs new file mode 100644 index 000000000..bdd18a648 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/CommunityRatingComparer.cs @@ -0,0 +1,29 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; + +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/DateCreatedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DateCreatedComparer.cs new file mode 100644 index 000000000..9862f0a8a --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/DateCreatedComparer.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs new file mode 100644 index 000000000..db7e455c7 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs @@ -0,0 +1,56 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs b/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs new file mode 100644 index 000000000..fcbc58987 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs @@ -0,0 +1,52 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/ProductionYearComparer.cs b/MediaBrowser.Server.Implementations/Sorting/ProductionYearComparer.cs new file mode 100644 index 000000000..16d531334 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/ProductionYearComparer.cs @@ -0,0 +1,52 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; + +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/RandomComparer.cs b/MediaBrowser.Server.Implementations/Sorting/RandomComparer.cs new file mode 100644 index 000000000..b1677331a --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/RandomComparer.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/RuntimeComparer.cs b/MediaBrowser.Server.Implementations/Sorting/RuntimeComparer.cs new file mode 100644 index 000000000..793cb265e --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/RuntimeComparer.cs @@ -0,0 +1,32 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; + +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs b/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs new file mode 100644 index 000000000..873753a2b --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; +using System; + +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; } + } + } +} diff --git a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs index c6869c12d..8315b2000 100644 --- a/MediaBrowser.Server.Implementations/Udp/UdpServer.cs +++ b/MediaBrowser.Server.Implementations/Udp/UdpServer.cs @@ -127,7 +127,10 @@ namespace MediaBrowser.Server.Implementations.Udp /// </summary> public void Stop() { - _udpClient.Close(); + if (_udpClient != null) + { + _udpClient.Close(); + } } /// <summary> |
