support sync for live tv recordings

pull/702/head
Luke Pulverenti 9 years ago
parent d4b61da59d
commit 933fca78e6

@ -1,4 +1,5 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dto;
@ -460,6 +461,9 @@ namespace MediaBrowser.Api.LiveTv
public async Task<object> Get(GetRecordings request)
{
var options = new DtoOptions();
options.DeviceId = AuthorizationContext.GetAuthorizationInfo(Request).DeviceId;
var result = await _liveTvManager.GetRecordings(new RecordingQuery
{
ChannelId = request.ChannelId,
@ -471,7 +475,7 @@ namespace MediaBrowser.Api.LiveTv
SeriesTimerId = request.SeriesTimerId,
IsInProgress = request.IsInProgress
}, CancellationToken.None).ConfigureAwait(false);
}, options, CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
}
@ -480,7 +484,10 @@ namespace MediaBrowser.Api.LiveTv
{
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
var result = await _liveTvManager.GetRecording(request.Id, CancellationToken.None, user).ConfigureAwait(false);
var options = new DtoOptions();
options.DeviceId = AuthorizationContext.GetAuthorizationInfo(Request).DeviceId;
var result = await _liveTvManager.GetRecording(request.Id, options, CancellationToken.None, user).ConfigureAwait(false);
return ToOptimizedSerializedResultUsingCache(result);
}

@ -35,6 +35,14 @@ namespace MediaBrowser.Controller.Dto
/// <returns>Task{BaseItemDto}.</returns>
BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null);
/// <summary>
/// Fills the synchronize information.
/// </summary>
/// <param name="dtos">The dtos.</param>
/// <param name="options">The options.</param>
/// <param name="user">The user.</param>
void FillSyncInfo(IEnumerable<IHasSyncInfo> dtos, DtoOptions options, User user);
/// <summary>
/// Gets the base item dto.
/// </summary>

@ -50,6 +50,16 @@ namespace MediaBrowser.Controller.Entities
{
var user = query.User;
if (query.IncludeItemTypes != null &&
query.IncludeItemTypes.Length == 1 &&
string.Equals(query.IncludeItemTypes[0], "Playlist", StringComparison.OrdinalIgnoreCase))
{
if (!string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
{
return await FindPlaylists(queryParent, user, query).ConfigureAwait(false);
}
}
switch (viewType)
{
case CollectionType.Channels:
@ -240,6 +250,16 @@ namespace MediaBrowser.Controller.Entities
}
}
private async Task<QueryResult<BaseItem>> FindPlaylists(Folder parent, User user, InternalItemsQuery query)
{
var collectionFolders = user.RootFolder.GetChildren(user, true).Select(i => i.Id).ToList();
var list = _playlistManager.GetPlaylists(user.Id.ToString("N"))
.Where(i => i.GetChildren(user, true).Any(media => _libraryManager.GetCollectionFolders(media).Select(c => c.Id).Any(collectionFolders.Contains)));
return GetResult(list, parent, query);
}
private int GetSpecialItemsLimit()
{
return 50;

@ -1,4 +1,5 @@
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.LiveTv;
@ -74,10 +75,11 @@ namespace MediaBrowser.Controller.LiveTv
/// Gets the recording.
/// </summary>
/// <param name="id">The identifier.</param>
/// <param name="user">The user.</param>
/// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="user">The user.</param>
/// <returns>Task{RecordingInfoDto}.</returns>
Task<RecordingInfoDto> GetRecording(string id, CancellationToken cancellationToken, User user = null);
Task<RecordingInfoDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null);
/// <summary>
/// Gets the channel.
@ -103,14 +105,15 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{TimerInfoDto}.</returns>
Task<SeriesTimerInfoDto> GetSeriesTimer(string id, CancellationToken cancellationToken);
/// <summary>
/// Gets the recordings.
/// </summary>
/// <param name="query">The query.</param>
/// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>QueryResult{RecordingInfoDto}.</returns>
Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken);
Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken);
/// <summary>
/// Gets the timers.

@ -464,6 +464,9 @@
<Compile Include="..\MediaBrowser.Model\Dto\IHasServerId.cs">
<Link>Dto\IHasServerId.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dto\IHasSyncInfo.cs">
<Link>Dto\IHasSyncInfo.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dto\IItemDto.cs">
<Link>Dto\IItemDto.cs</Link>
</Compile>

@ -429,6 +429,9 @@
<Compile Include="..\MediaBrowser.Model\Dto\IHasServerId.cs">
<Link>Dto\IHasServerId.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dto\IHasSyncInfo.cs">
<Link>Dto\IHasSyncInfo.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Dto\IItemDto.cs">
<Link>Dto\IItemDto.cs</Link>
</Compile>

@ -3,6 +3,7 @@ using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Sync;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -16,7 +17,7 @@ namespace MediaBrowser.Model.Dto
/// This holds information about a BaseItem in a format that is convenient for the client.
/// </summary>
[DebuggerDisplay("Name = {Name}, ID = {Id}, Type = {Type}")]
public class BaseItemDto : IHasProviderIds, IHasPropertyChangedEvent, IItemDto, IHasServerId
public class BaseItemDto : IHasProviderIds, IHasPropertyChangedEvent, IItemDto, IHasServerId, IHasSyncInfo
{
/// <summary>
/// Gets or sets the name.
@ -87,6 +88,11 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value><c>null</c> if [is synced] contains no value, <c>true</c> if [is synced]; otherwise, <c>false</c>.</value>
public bool? IsSynced { get; set; }
/// <summary>
/// Gets or sets the synchronize status.
/// </summary>
/// <value>The synchronize status.</value>
public SyncJobItemStatus? SyncStatus { get; set; }
/// <summary>
/// Gets or sets the DVD season number.

@ -0,0 +1,13 @@
using MediaBrowser.Model.Sync;
namespace MediaBrowser.Model.Dto
{
public interface IHasSyncInfo
{
string Id { get; }
bool? SupportsSync { get; set; }
bool? HasSyncJob { get; set; }
bool? IsSynced { get; set; }
SyncJobItemStatus? SyncStatus { get; set; }
}
}

@ -2,6 +2,7 @@
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Sync;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -11,7 +12,7 @@ using System.Runtime.Serialization;
namespace MediaBrowser.Model.LiveTv
{
[DebuggerDisplay("Name = {Name}, ChannelName = {ChannelName}")]
public class RecordingInfoDto : IHasPropertyChangedEvent, IItemDto, IHasServerId
public class RecordingInfoDto : IHasPropertyChangedEvent, IItemDto, IHasServerId, IHasSyncInfo
{
/// <summary>
/// Id of the recording.
@ -35,6 +36,27 @@ namespace MediaBrowser.Model.LiveTv
/// </summary>
/// <value>The original primary image aspect ratio.</value>
public double? OriginalPrimaryImageAspectRatio { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [supports synchronize].
/// </summary>
/// <value><c>null</c> if [supports synchronize] contains no value, <c>true</c> if [supports synchronize]; otherwise, <c>false</c>.</value>
public bool? SupportsSync { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance has synchronize job.
/// </summary>
/// <value><c>null</c> if [has synchronize job] contains no value, <c>true</c> if [has synchronize job]; otherwise, <c>false</c>.</value>
public bool? HasSyncJob { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is synced.
/// </summary>
/// <value><c>null</c> if [is synced] contains no value, <c>true</c> if [is synced]; otherwise, <c>false</c>.</value>
public bool? IsSynced { get; set; }
/// <summary>
/// Gets or sets the synchronize status.
/// </summary>
/// <value>The synchronize status.</value>
public SyncJobItemStatus? SyncStatus { get; set; }
/// <summary>
/// Gets or sets the series timer identifier.

@ -138,6 +138,7 @@
<Compile Include="Dlna\SubtitleStreamInfo.cs" />
<Compile Include="Drawing\ImageOrientation.cs" />
<Compile Include="Dto\IHasServerId.cs" />
<Compile Include="Dto\IHasSyncInfo.cs" />
<Compile Include="Dto\MetadataEditorInfo.cs" />
<Compile Include="Dto\NameIdPair.cs" />
<Compile Include="Dto\NameValuePair.cs" />

@ -188,7 +188,22 @@ namespace MediaBrowser.Server.Implementations.Dto
return new Tuple<IEnumerable<string>, IEnumerable<string>>(result1.Items, result2.Items);
}
private void FillSyncInfo(BaseItemDto dto, BaseItem item, DtoOptions options, User user)
public void FillSyncInfo(IEnumerable<IHasSyncInfo> dtos, DtoOptions options, User user)
{
if (options.Fields.Contains(ItemFields.SyncInfo))
{
var tuple = GetItemIdsWithSyncJobs(options);
foreach (var dto in dtos)
{
var item = _libraryManager.GetItemById(dto.Id);
FillSyncInfo(dto, item, tuple.Item1, tuple.Item2, options, user);
}
}
}
private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user)
{
if (options.Fields.Contains(ItemFields.SyncInfo))
{
@ -202,10 +217,20 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.HasSyncJob = tuple.Item1.Contains(dto.Id, StringComparer.OrdinalIgnoreCase);
dto.IsSynced = tuple.Item2.Contains(dto.Id, StringComparer.OrdinalIgnoreCase);
if (dto.IsSynced.Value)
{
dto.SyncStatus = SyncJobItemStatus.Synced;
}
else if (dto.HasSyncJob.Value)
{
dto.SyncStatus = SyncJobItemStatus.Queued;
}
}
}
private void FillSyncInfo(BaseItemDto dto, BaseItem item, IEnumerable<string> itemIdsWithPendingSyncJobs, IEnumerable<string> syncedItemIds, DtoOptions options, User user)
private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, IEnumerable<string> itemIdsWithPendingSyncJobs, IEnumerable<string> syncedItemIds, DtoOptions options, User user)
{
if (options.Fields.Contains(ItemFields.SyncInfo))
{
@ -217,6 +242,16 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.HasSyncJob = itemIdsWithPendingSyncJobs.Contains(dto.Id, StringComparer.OrdinalIgnoreCase);
dto.IsSynced = syncedItemIds.Contains(dto.Id, StringComparer.OrdinalIgnoreCase);
if (dto.IsSynced.Value)
{
dto.SyncStatus = SyncJobItemStatus.Synced;
}
else if (dto.HasSyncJob.Value)
{
dto.SyncStatus = SyncJobItemStatus.Queued;
}
}
}

@ -8,12 +8,12 @@ using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Querying;
namespace MediaBrowser.Server.Implementations.LiveTv
{

@ -1148,7 +1148,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
RefreshIfNeeded(programs.Take(500));
// Load these now which will prefetch metadata
await GetRecordings(new RecordingQuery(), cancellationToken).ConfigureAwait(false);
var dtoOptions = new DtoOptions();
dtoOptions.Fields.Remove(ItemFields.SyncInfo);
await GetRecordings(new RecordingQuery(), dtoOptions, cancellationToken).ConfigureAwait(false);
progress.Report(100);
}
@ -1322,7 +1324,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
};
}
public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, CancellationToken cancellationToken)
public async Task<QueryResult<RecordingInfoDto>> GetRecordings(RecordingQuery query, DtoOptions options, CancellationToken cancellationToken)
{
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
@ -1338,6 +1340,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
})
.ToArray();
if (user != null)
{
_dtoService.FillSyncInfo(returnArray, new DtoOptions(), user);
}
return new QueryResult<RecordingInfoDto>
{
Items = returnArray,
@ -1410,7 +1417,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task DeleteRecording(string recordingId)
{
var recording = await GetRecording(recordingId, CancellationToken.None).ConfigureAwait(false);
var dtoOptions = new DtoOptions();
dtoOptions.Fields.Remove(ItemFields.SyncInfo);
var recording = await GetRecording(recordingId, dtoOptions, CancellationToken.None).ConfigureAwait(false);
if (recording == null)
{
@ -1450,14 +1460,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false);
}
public async Task<RecordingInfoDto> GetRecording(string id, CancellationToken cancellationToken, User user = null)
public async Task<RecordingInfoDto> GetRecording(string id, DtoOptions options, CancellationToken cancellationToken, User user = null)
{
var results = await GetRecordings(new RecordingQuery
{
UserId = user == null ? null : user.Id.ToString("N"),
Id = id
}, cancellationToken).ConfigureAwait(false);
}, options, cancellationToken).ConfigureAwait(false);
return results.Items.FirstOrDefault();
}
@ -1737,11 +1747,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public async Task<QueryResult<RecordingGroupDto>> GetRecordingGroups(RecordingGroupQuery query, CancellationToken cancellationToken)
{
var dtoOptions = new DtoOptions();
dtoOptions.Fields.Remove(ItemFields.SyncInfo);
var recordingResult = await GetRecordings(new RecordingQuery
{
UserId = query.UserId
}, cancellationToken).ConfigureAwait(false);
}, dtoOptions, cancellationToken).ConfigureAwait(false);
var recordings = recordingResult.Items;

@ -94,7 +94,7 @@ namespace MediaBrowser.Server.Implementations.Photos
protected abstract Task<List<BaseItem>> GetItemsWithImages(IHasImages item);
private const string Version = "27";
private const string Version = "29";
protected string GetConfigurationCacheKey(List<BaseItem> items, string itemName)
{
var parts = Version + "_" + (itemName ?? string.Empty) + "_" +

Loading…
Cancel
Save