diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 9547cc0a4e..3c6ea62f47 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -202,6 +202,9 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "MinCriticRating", Description = "Optional filter by minimum critic rating.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public double? MinCriticRating { get; set; } + + [ApiMember(Name = "AiredDuringSeason", Description = "Gets all episodes that aired during a season, including specials.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? AiredDuringSeason { get; set; } } /// @@ -1000,6 +1003,25 @@ namespace MediaBrowser.Api.UserLibrary }); } + if (request.AiredDuringSeason.HasValue) + { + var val = request.AiredDuringSeason.Value; + + items = items.Where(i => + { + var episode = i as Episode; + + if (episode != null) + { + var seasonNumber = episode.SpecialSeasonNumber ?? episode.ParentIndexNumber; + + return seasonNumber.HasValue && seasonNumber.Value == val; + } + + return false; + }); + } + return items; } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index dbed0b4892..f92e7e3e05 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -796,7 +796,7 @@ namespace MediaBrowser.Controller.Entities foreach (var tuple in list) { - if (tasks.Count > 7) + if (tasks.Count > 10) { await Task.WhenAll(tasks).ConfigureAwait(false); } @@ -873,7 +873,8 @@ namespace MediaBrowser.Controller.Entities progress.Report((90 * percent) + 10); } } - })); + + }, cancellationToken)); } cancellationToken.ThrowIfCancellationRequested(); diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 95d346733d..5100916ffa 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -32,6 +32,12 @@ namespace MediaBrowser.Controller.Entities.TV } } + /// + /// Gets the season in which it aired. + /// + /// The aired season. + public int? SpecialSeasonNumber { get; set; } + /// /// We want to group into series not show individually in an index /// diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 1d50a59331..bfa7517561 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -30,6 +30,12 @@ namespace MediaBrowser.Model.Dto /// The date created. public DateTime? DateCreated { get; set; } + /// + /// Gets or sets the special season number. + /// + /// The special season number. + public int? SpecialSeasonNumber { get; set; } + /// /// Gets or sets the name of the sort. /// diff --git a/MediaBrowser.Model/LiveTv/ChannelGuide.cs b/MediaBrowser.Model/LiveTv/ChannelGuide.cs new file mode 100644 index 0000000000..d2bebac182 --- /dev/null +++ b/MediaBrowser.Model/LiveTv/ChannelGuide.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Model.LiveTv +{ + public class ChannelGuide + { + /// + /// Gets or sets the name of the service. + /// + /// The name of the service. + public string ServiceName { get; set; } + + /// + /// ChannelId for the EPG. + /// + public string ChannelId { get; set; } + + /// + /// List of all the programs for a specific channel + /// + public List Programs { get; set; } + } +} diff --git a/MediaBrowser.Model/LiveTv/ProgramInfo.cs b/MediaBrowser.Model/LiveTv/ProgramInfo.cs new file mode 100644 index 0000000000..6bf0e383fa --- /dev/null +++ b/MediaBrowser.Model/LiveTv/ProgramInfo.cs @@ -0,0 +1,37 @@ +using System; + +namespace MediaBrowser.Model.LiveTv +{ + public class ProgramInfo + { + /// + /// Id of the program. + /// + public string Id { get; set; } + + /// + /// Name of the program + /// + public string Name { get; set; } + + /// + /// Description of the progam. + /// + public string Description { get; set; } + + /// + /// The start date of the program, in UTC. + /// + public DateTime StartDate { get; set; } + + /// + /// The end date of the program, in UTC. + /// + public DateTime EndDate { get; set; } + + /// + /// Genre of the program. + /// + public string Genre { get; set; } + } +} \ No newline at end of file diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs new file mode 100644 index 0000000000..e7a91f4d55 --- /dev/null +++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs @@ -0,0 +1,14 @@ +namespace MediaBrowser.Model.LiveTv +{ + /// + /// Class RecordingQuery. + /// + public class RecordingQuery + { + /// + /// Gets or sets a value indicating whether this instance has recorded. + /// + /// null if [has recorded] contains no value, true if [has recorded]; otherwise, false. + public bool? HasRecorded { get; set; } + } +} diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs index 13720ea2bb..14c946ba18 100644 --- a/MediaBrowser.Model/Querying/ItemQuery.cs +++ b/MediaBrowser.Model/Querying/ItemQuery.cs @@ -265,6 +265,8 @@ namespace MediaBrowser.Model.Querying public double? MinCommunityRating { get; set; } public double? MinCriticRating { get; set; } + public int? AiredDuringSeason { get; set; } + /// /// Initializes a new instance of the class. /// diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs index 5413bd848b..6d7a607565 100644 --- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs +++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs @@ -75,6 +75,11 @@ namespace MediaBrowser.Providers.Savers { builder.Append("" + SecurityElement.Escape(episode.IndexNumberEnd.Value.ToString(_usCulture)) + ""); } + + if (episode.SpecialSeasonNumber.HasValue) + { + builder.Append("" + SecurityElement.Escape(episode.SpecialSeasonNumber.Value.ToString(_usCulture)) + ""); + } if (episode.ParentIndexNumber.HasValue) { @@ -99,7 +104,8 @@ namespace MediaBrowser.Providers.Savers "SeasonNumber", "EpisodeNumber", "EpisodeName", - "EpisodeNumberEnd" + "EpisodeNumberEnd", + "SpecialSeasonNumber" }); // Set last refreshed so that the provider doesn't trigger after the file save diff --git a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs index d3abf397f2..5188e0824b 100644 --- a/MediaBrowser.Providers/TV/EpisodeXmlParser.cs +++ b/MediaBrowser.Providers/TV/EpisodeXmlParser.cs @@ -139,6 +139,22 @@ namespace MediaBrowser.Providers.TV break; } + case "SpecialSeasonNumber": + { + var number = reader.ReadElementContentAsString(); + + if (!string.IsNullOrWhiteSpace(number)) + { + int num; + + if (int.TryParse(number, out num)) + { + item.SpecialSeasonNumber = num; + } + } + break; + } + case "EpisodeName": { var name = reader.ReadElementContentAsString(); diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs index c47640ad96..ab824ac578 100644 --- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs @@ -113,7 +113,7 @@ namespace MediaBrowser.Providers.TV { get { - return "1"; + return "3"; } } @@ -404,6 +404,40 @@ namespace MediaBrowser.Providers.TV break; } + case "airsafter_season": + { + var val = reader.ReadElementContentAsString(); + + if (!string.IsNullOrWhiteSpace(val)) + { + int rval; + + // int.TryParse is local aware, so it can be probamatic, force us culture + if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval)) + { + item.SpecialSeasonNumber = rval; + } + } + break; + } + + case "airsbefore_season": + { + var val = reader.ReadElementContentAsString(); + + if (!string.IsNullOrWhiteSpace(val)) + { + int rval; + + // int.TryParse is local aware, so it can be probamatic, force us culture + if (int.TryParse(val, NumberStyles.Integer, _usCulture, out rval)) + { + item.SpecialSeasonNumber = rval; + } + } + break; + } + case "EpisodeName": { if (!item.LockedFields.Contains(MetadataFields.Name)) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 31b0c1a6a5..62c4c2e6fa 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1029,6 +1029,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (episode != null) { dto.IndexNumberEnd = episode.IndexNumberEnd; + dto.SpecialSeasonNumber = episode.SpecialSeasonNumber; } // Add SeriesInfo