diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-11-20 12:10:02 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-11-20 12:10:02 -0500 |
| commit | 977d9c7f3b92154642046f06c8ac2c4dfb31d35e (patch) | |
| tree | 0fcf19b28507415a7e2ed904ab530ce393aab320 | |
| parent | 7dd75e079a7c2c82e00bb84bed0c7308ba738e3c (diff) | |
improve episode sorting with embedded specials
5 files changed, 182 insertions, 1 deletions
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs index d39d98fa3..3d68a4ec7 100644 --- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs +++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using MediaBrowser.Model.LiveTv; using System.Collections.Generic; using System.Threading; @@ -25,6 +26,24 @@ namespace MediaBrowser.Controller.LiveTv Task<IEnumerable<ChannelInfo>> GetChannelsAsync(CancellationToken cancellationToken); /// <summary> + /// Cancels the recording asynchronous. + /// </summary> + /// <param name="recordingId">The recording identifier.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task CancelRecordingAsync(string recordingId, CancellationToken cancellationToken); + + /// <summary> + /// Schedules the recording asynchronous. + /// </summary> + /// <param name="channelId">The channel identifier.</param> + /// <param name="startTime">The start time.</param> + /// <param name="duration">The duration.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task ScheduleRecordingAsync(string channelId, DateTime startTime, TimeSpan duration, CancellationToken cancellationToken); + + /// <summary> /// Gets the channel image asynchronous. /// </summary> /// <param name="channelId">The channel identifier.</param> diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs index 12dfa9626..57e09d724 100644 --- a/MediaBrowser.Model/Querying/ItemSortBy.cs +++ b/MediaBrowser.Model/Querying/ItemSortBy.cs @@ -6,6 +6,7 @@ namespace MediaBrowser.Model.Querying /// </summary> public static class ItemSortBy { + public const string AiredEpisodeOrder = "AiredEpisodeOrder"; /// <summary> /// The album /// </summary> diff --git a/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs b/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs index fc8f55ae1..592c5dcac 100644 --- a/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs +++ b/MediaBrowser.Providers/TV/EpisodeIndexNumberProvider.cs @@ -27,6 +27,22 @@ namespace MediaBrowser.Providers.TV { } + protected override bool RefreshOnVersionChange + { + get + { + return true; + } + } + + protected override string ProviderVersion + { + get + { + return "2"; + } + } + /// <summary> /// Supportses the specified item. /// </summary> @@ -51,6 +67,16 @@ namespace MediaBrowser.Providers.TV episode.IndexNumber = TVUtils.GetEpisodeNumberFromFile(item.Path, item.Parent is Season); episode.IndexNumberEnd = TVUtils.GetEndingEpisodeNumberFromFile(item.Path); + if (!episode.ParentIndexNumber.HasValue) + { + var season = episode.Parent as Season; + + if (season != null) + { + episode.ParentIndexNumber = season.IndexNumber; + } + } + SetLastRefreshed(item, DateTime.UtcNow); return TrueTaskResult; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index ac451e1eb..282991cc1 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -188,6 +188,7 @@ </Compile> <Compile Include="Session\SessionWebSocketListener.cs" /> <Compile Include="Session\WebSocketController.cs" /> + <Compile Include="Sorting\AiredEpisodeOrderComparer.cs" /> <Compile Include="Sorting\AirTimeComparer.cs" /> <Compile Include="Sorting\AlbumArtistComparer.cs" /> <Compile Include="Sorting\AlbumComparer.cs" /> diff --git a/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs new file mode 100644 index 000000000..cec9743ba --- /dev/null +++ b/MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs @@ -0,0 +1,134 @@ +using System; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Sorting; +using MediaBrowser.Model.Querying; + +namespace MediaBrowser.Server.Implementations.Sorting +{ + class AiredEpisodeOrderComparer : 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) + { + var val = DateTime.Compare(x.PremiereDate ?? DateTime.MinValue, y.PremiereDate ?? DateTime.MinValue); + + if (val != 0) + { + return val; + } + + var episode1 = x as Episode; + var episode2 = y as Episode; + + if (episode1 == null) + { + if (episode2 == null) + { + return 0; + } + + return 1; + } + + if (episode2 == null) + { + return -1; + } + + return Compare(episode1, episode2); + } + + private int Compare(Episode x, Episode y) + { + var isXSpecial = (x.ParentIndexNumber ?? -1) == 0; + var isYSpecial = (y.ParentIndexNumber ?? -1) == 0; + + if (isXSpecial && isYSpecial) + { + return CompareSpecials(x, y); + } + + if (!isXSpecial && !isYSpecial) + { + return CompareEpisodes(x, y); + } + + if (!isXSpecial && isYSpecial) + { + return CompareEpisodeToSpecial(x, y); + } + + return CompareEpisodeToSpecial(x, y) * -1; + } + + private int CompareEpisodeToSpecial(Episode x, Episode y) + { + var xSeason = x.ParentIndexNumber ?? -1; + var ySeason = y.AirsAfterSeasonNumber ?? y.AirsBeforeSeasonNumber ?? -1; + + if (xSeason != ySeason) + { + return xSeason.CompareTo(ySeason); + } + + // Now we know they have the same season + + // Compare episode number + + // Add 1 to to non-specials to account for AirsBeforeEpisodeNumber + var xEpisode = (x.IndexNumber ?? 0) * 1000 + 1; + var yEpisode = (y.AirsBeforeEpisodeNumber ?? 0) * 1000; + + return xEpisode.CompareTo(yEpisode); + } + + private int CompareSpecials(Episode x, Episode y) + { + return GetSpecialCompareValue(x).CompareTo(GetSpecialCompareValue(y)); + } + + private int GetSpecialCompareValue(Episode item) + { + // First sort by season number + // Since there are three sort orders, pad with 9 digits (3 for each, figure 1000 episode buffer should be enough) + var val = (item.AirsBeforeSeasonNumber ?? item.AirsAfterSeasonNumber ?? 0) * 1000000000; + + // Second sort order is if it airs after the season + if (item.AirsAfterSeasonNumber.HasValue) + { + val += 1000000; + } + + // Third level is the episode number + val += (item.AirsBeforeEpisodeNumber ?? 0) * 1000; + + // Finally, if that's still the same, last resort is the special number itself + val += item.IndexNumber ?? 0; + + return val; + } + + private int CompareEpisodes(Episode x, Episode y) + { + var xValue = ((x.ParentIndexNumber ?? -1) * 1000) + (x.IndexNumber ?? -1); + var yValue = ((y.ParentIndexNumber ?? -1) * 1000) + (y.IndexNumber ?? -1); + + return xValue.CompareTo(yValue); + } + + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + public string Name + { + get { return ItemSortBy.AiredEpisodeOrder; } + } + } +} |
