aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs36
-rw-r--r--MediaBrowser.Api/TvShowsService.cs25
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs55
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs36
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvManager.cs16
-rw-r--r--MediaBrowser.Controller/LiveTv/RecordingInfo.cs20
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs6
-rw-r--r--MediaBrowser.Model/LiveTv/RecordingInfoDto.cs30
-rw-r--r--MediaBrowser.Model/LiveTv/TimerInfoDto.cs6
-rw-r--r--MediaBrowser.Providers/TV/SeriesPostScanTask.cs1
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs6
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs26
12 files changed, 231 insertions, 32 deletions
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 4cd75afca..0e40db58c 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -1,12 +1,12 @@
-using System.Threading;
-using System.Threading.Tasks;
-using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Querying;
using ServiceStack.ServiceHost;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
namespace MediaBrowser.Api.LiveTv
{
@@ -58,6 +58,22 @@ namespace MediaBrowser.Api.LiveTv
public string ChannelId { get; set; }
}
+ [Route("/LiveTv/Recordings/{Id}", "GET")]
+ [Api(Description = "Gets a live tv recording")]
+ public class GetRecording : IReturn<RecordingInfoDto>
+ {
+ [ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Id { get; set; }
+ }
+
+ [Route("/LiveTv/Timers/{Id}", "GET")]
+ [Api(Description = "Gets a live tv timer")]
+ public class GetTimer : IReturn<TimerInfoDto>
+ {
+ [ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Id { get; set; }
+ }
+
[Route("/LiveTv/Timers", "GET")]
[Api(Description = "Gets live tv timers")]
public class GetTimers : IReturn<QueryResult<TimerInfoDto>>
@@ -182,6 +198,20 @@ namespace MediaBrowser.Api.LiveTv
return ToOptimizedResult(result);
}
+ public object Get(GetRecording request)
+ {
+ var result = _liveTvManager.GetRecording(request.Id, CancellationToken.None).Result;
+
+ return ToOptimizedResult(result);
+ }
+
+ public object Get(GetTimer request)
+ {
+ var result = _liveTvManager.GetTimer(request.Id, CancellationToken.None).Result;
+
+ return ToOptimizedResult(result);
+ }
+
public object Get(GetTimers request)
{
var result = _liveTvManager.GetTimers(new TimerQuery
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index 9191bfc0c..68ebd60c5 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Dto;
+using MediaBrowser.Api.UserLibrary;
+using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
@@ -89,6 +90,9 @@ namespace MediaBrowser.Api
[ApiMember(Name = "IsVirtualUnaired", Description = "Optional filter by items that are virtual unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsVirtualUnaired { get; set; }
+
+ [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string AdjacentTo { get; set; }
}
[Route("/Shows/{Id}/Seasons", "GET")]
@@ -120,6 +124,9 @@ namespace MediaBrowser.Api
[ApiMember(Name = "IsVirtualUnaired", Description = "Optional filter by items that are virtual unaired episodes or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool? IsVirtualUnaired { get; set; }
+
+ [ApiMember(Name = "AdjacentTo", Description = "Optional. Return items that are siblings of a supplied item.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string AdjacentTo { get; set; }
}
/// <summary>
@@ -394,6 +401,13 @@ namespace MediaBrowser.Api
seasons = _libraryManager.Sort(seasons, user, new[] { sortOrder }, SortOrder.Ascending)
.Cast<Season>();
+ // This must be the last filter
+ if (!string.IsNullOrEmpty(request.AdjacentTo))
+ {
+ seasons = ItemsService.FilterForAdjacency(seasons, request.AdjacentTo)
+ .Cast<Season>();
+ }
+
var returnItems = seasons.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToArray();
@@ -447,7 +461,7 @@ namespace MediaBrowser.Api
if (!string.IsNullOrEmpty(request.SeasonId))
{
- var season = _libraryManager.GetItemById(request.Id) as Season;
+ var season = _libraryManager.GetItemById(new Guid(request.SeasonId)) as Season;
if (season.IndexNumber.HasValue)
{
@@ -496,6 +510,13 @@ namespace MediaBrowser.Api
episodes = _libraryManager.Sort(episodes, user, new[] { sortOrder }, SortOrder.Ascending)
.Cast<Episode>();
+ // This must be the last filter
+ if (!string.IsNullOrEmpty(request.AdjacentTo))
+ {
+ episodes = ItemsService.FilterForAdjacency(episodes, request.AdjacentTo)
+ .Cast<Episode>();
+ }
+
var returnItems = episodes.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToArray();
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index 0e40ef395..3a7ea5ddd 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -310,6 +310,12 @@ namespace MediaBrowser.Api.UserLibrary
items = ApplySortOrder(request, items, user, _libraryManager);
+ // This must be the last filter
+ if (!string.IsNullOrEmpty(request.AdjacentTo))
+ {
+ items = FilterForAdjacency(items, request.AdjacentTo);
+ }
+
var itemsArray = items.ToList();
var pagedItems = ApplyPaging(request, itemsArray);
@@ -666,30 +672,6 @@ namespace MediaBrowser.Api.UserLibrary
});
}
- if (!string.IsNullOrEmpty(request.AdjacentTo))
- {
- var item = _dtoService.GetItemByDtoId(request.AdjacentTo);
-
- var allSiblings = item.Parent.GetChildren(user, true).OrderBy(i => i.SortName).ToList();
-
- var index = allSiblings.IndexOf(item);
-
- var previousId = Guid.Empty;
- var nextId = Guid.Empty;
-
- if (index > 0)
- {
- previousId = allSiblings[index - 1].Id;
- }
-
- if (index < allSiblings.Count - 1)
- {
- nextId = allSiblings[index + 1].Id;
- }
-
- items = items.Where(i => i.Id == previousId || i.Id == nextId);
- }
-
// Min index number
if (request.MinIndexNumber.HasValue)
{
@@ -1144,6 +1126,31 @@ namespace MediaBrowser.Api.UserLibrary
return false;
}
+ internal static IEnumerable<BaseItem> FilterForAdjacency(IEnumerable<BaseItem> items, string adjacentToId)
+ {
+ var list = items.ToList();
+
+ var adjacentToIdGuid = new Guid(adjacentToId);
+ var adjacentToItem = list.FirstOrDefault(i => i.Id == adjacentToIdGuid);
+
+ var index = list.IndexOf(adjacentToItem);
+
+ var previousId = Guid.Empty;
+ var nextId = Guid.Empty;
+
+ if (index > 0)
+ {
+ previousId = list[index - 1].Id;
+ }
+
+ if (index < list.Count - 1)
+ {
+ nextId = list[index + 1].Id;
+ }
+
+ return list.Where(i => i.Id == previousId || i.Id == nextId);
+ }
+
/// <summary>
/// Determines whether the specified item has image.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index 40b999b02..e9f250d2a 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -235,6 +235,42 @@ namespace MediaBrowser.Controller.Entities.TV
get { return LocationType == Model.Entities.LocationType.Virtual && IsUnaired; }
}
+ [IgnoreDataMember]
+ public Guid? SeasonId
+ {
+ get
+ {
+ // First see if the parent is a Season
+ var season = Parent as Season;
+
+ if (season != null)
+ {
+ return season.Id;
+ }
+
+ var seasonNumber = ParentIndexNumber;
+
+ // Parent is a Series
+ if (seasonNumber.HasValue)
+ {
+ var series = Parent as Series;
+
+ if (series != null)
+ {
+ season = series.Children.OfType<Season>()
+ .FirstOrDefault(i => i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber.Value);
+
+ if (season != null)
+ {
+ return season.Id;
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
public override IEnumerable<string> GetDeletePaths()
{
return new[] { Path };
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
index d5b9cea27..4e73fc109 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvManager.cs
@@ -52,6 +52,22 @@ namespace MediaBrowser.Controller.LiveTv
QueryResult<ChannelInfoDto> GetChannels(ChannelQuery query);
/// <summary>
+ /// Gets the recording.
+ /// </summary>
+ /// <param name="id">The identifier.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task{RecordingInfoDto}.</returns>
+ Task<RecordingInfoDto> GetRecording(string id, CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Gets the timer.
+ /// </summary>
+ /// <param name="id">The identifier.</param>
+ /// <param name="cancellationToken">The cancellation token.</param>
+ /// <returns>Task{TimerInfoDto}.</returns>
+ Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken);
+
+ /// <summary>
/// Gets the recordings.
/// </summary>
/// <param name="query">The query.</param>
diff --git a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
index 65e977d75..2c8e8cb46 100644
--- a/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
+++ b/MediaBrowser.Controller/LiveTv/RecordingInfo.cs
@@ -20,7 +20,13 @@ namespace MediaBrowser.Controller.LiveTv
/// ChannelName of the recording.
/// </summary>
public string ChannelName { get; set; }
-
+
+ /// <summary>
+ /// Gets or sets the type of the channel.
+ /// </summary>
+ /// <value>The type of the channel.</value>
+ public ChannelType ChannelType { get; set; }
+
/// <summary>
/// Name of the recording.
/// </summary>
@@ -76,6 +82,18 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The episode title.</value>
public string EpisodeTitle { get; set; }
+ /// <summary>
+ /// Gets or sets the official rating.
+ /// </summary>
+ /// <value>The official rating.</value>
+ public string OfficialRating { get; set; }
+
+ /// <summary>
+ /// Gets or sets the community rating.
+ /// </summary>
+ /// <value>The community rating.</value>
+ public float? CommunityRating { get; set; }
+
public RecordingInfo()
{
Genres = new List<string>();
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index bfa751756..20f60586c 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -313,6 +313,12 @@ namespace MediaBrowser.Model.Dto
public string SeriesId { get; set; }
/// <summary>
+ /// Gets or sets the season identifier.
+ /// </summary>
+ /// <value>The season identifier.</value>
+ public string SeasonId { get; set; }
+
+ /// <summary>
/// Gets or sets the special feature count.
/// </summary>
/// <value>The special feature count.</value>
diff --git a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
index 9ad6233a6..86e82b562 100644
--- a/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
@@ -81,6 +81,36 @@ namespace MediaBrowser.Model.LiveTv
/// <value>The episode title.</value>
public string EpisodeTitle { get; set; }
+ /// <summary>
+ /// Gets or sets the duration ms.
+ /// </summary>
+ /// <value>The duration ms.</value>
+ public int DurationMs { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type of the media.
+ /// </summary>
+ /// <value>The type of the media.</value>
+ public string MediaType { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type of the channel.
+ /// </summary>
+ /// <value>The type of the channel.</value>
+ public ChannelType ChannelType { get; set; }
+
+ /// <summary>
+ /// Gets or sets the official rating.
+ /// </summary>
+ /// <value>The official rating.</value>
+ public string OfficialRating { get; set; }
+
+ /// <summary>
+ /// Gets or sets the community rating.
+ /// </summary>
+ /// <value>The community rating.</value>
+ public float? CommunityRating { get; set; }
+
public RecordingInfoDto()
{
Genres = new List<string>();
diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs
index 59a320bfd..9ebc2314d 100644
--- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs
+++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs
@@ -74,5 +74,11 @@ namespace MediaBrowser.Model.LiveTv
/// </summary>
/// <value>The post padding seconds.</value>
public int PostPaddingSeconds { get; set; }
+
+ /// <summary>
+ /// Gets or sets the duration ms.
+ /// </summary>
+ /// <value>The duration ms.</value>
+ public int DurationMs { get; set; }
}
}
diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
index 055a6c101..56b06f490 100644
--- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
+++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index f6291cf36..f298c2d4d 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -1029,6 +1029,12 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.IndexNumberEnd = episode.IndexNumberEnd;
dto.SpecialSeasonNumber = episode.AirsAfterSeasonNumber ?? episode.AirsBeforeSeasonNumber;
+
+ var seasonId = episode.SeasonId;
+ if (seasonId.HasValue)
+ {
+ dto.SeasonId = seasonId.Value.ToString("N");
+ }
}
// Add SeriesInfo
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 704d1ea59..4fd1f0e43 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -391,9 +391,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv
Path = info.Path,
Genres = info.Genres,
IsRepeat = info.IsRepeat,
- EpisodeTitle = info.EpisodeTitle
+ EpisodeTitle = info.EpisodeTitle,
+ ChannelType = info.ChannelType,
+ MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video,
+ CommunityRating = info.CommunityRating,
+ OfficialRating = info.OfficialRating
};
+ var duration = info.EndDate - info.StartDate;
+ dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds);
+
if (!string.IsNullOrEmpty(info.ProgramId))
{
dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N");
@@ -510,6 +517,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
PostPaddingSeconds = info.PostPaddingSeconds
};
+ var duration = info.EndDate - info.StartDate;
+ dto.DurationMs = Convert.ToInt32(duration.TotalMilliseconds);
+
if (!string.IsNullOrEmpty(info.ProgramId))
{
dto.ProgramId = GetInternalProgramIdId(service.Name, info.ProgramId).ToString("N");
@@ -563,5 +573,19 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CancelTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
}
+
+ public async Task<RecordingInfoDto> GetRecording(string id, CancellationToken cancellationToken)
+ {
+ var results = await GetRecordings(new RecordingQuery(), cancellationToken).ConfigureAwait(false);
+
+ return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture));
+ }
+
+ public async Task<TimerInfoDto> GetTimer(string id, CancellationToken cancellationToken)
+ {
+ var results = await GetTimers(new TimerQuery(), cancellationToken).ConfigureAwait(false);
+
+ return results.Items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.CurrentCulture));
+ }
}
}