live tv fix

This commit is contained in:
Luke Pulverenti
2015-03-31 14:50:08 -04:00
parent a025f4eefa
commit 5965afecde
20 changed files with 207 additions and 66 deletions

View File

@@ -67,12 +67,12 @@ namespace MediaBrowser.Server.Implementations.Sync
SyncTarget target,
CancellationToken cancellationToken)
{
var localIds = await dataProvider.GetServerItemIds(target, serverId).ConfigureAwait(false);
var jobItemIds = await dataProvider.GetSyncJobItemIds(target, serverId).ConfigureAwait(false);
var result = await _syncManager.SyncData(new SyncDataRequest
{
TargetId = target.Id,
LocalItemIds = localIds
SyncJobItemIds = jobItemIds
}).ConfigureAwait(false);
@@ -285,11 +285,11 @@ namespace MediaBrowser.Server.Implementations.Sync
private async Task RemoveItem(IServerSyncProvider provider,
ISyncDataProvider dataProvider,
string serverId,
string itemId,
string syncJobItemId,
SyncTarget target,
CancellationToken cancellationToken)
{
var localItems = await dataProvider.GetCachedItems(target, serverId, itemId);
var localItems = await dataProvider.GetCachedItemsBySyncJobItemId(target, serverId, syncJobItemId);
foreach (var localItem in localItems)
{
@@ -350,7 +350,8 @@ namespace MediaBrowser.Server.Implementations.Sync
ItemId = libraryItem.Id,
ServerId = serverId,
LocalPath = localPath,
Id = GetLocalId(syncedItem.SyncJobItemId, libraryItem.Id)
Id = GetLocalId(syncedItem.SyncJobItemId, libraryItem.Id),
SyncJobItemId = syncedItem.SyncJobItemId
};
}

View File

@@ -3,6 +3,7 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
@@ -42,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly ILogger _logger;
private readonly IUserManager _userManager;
private readonly Func<IDtoService> _dtoService;
private readonly IApplicationHost _appHost;
private readonly IServerApplicationHost _appHost;
private readonly ITVSeriesManager _tvSeriesManager;
private readonly Func<IMediaEncoder> _mediaEncoder;
private readonly IFileSystem _fileSystem;
@@ -60,7 +61,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json)
public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json)
{
_libraryManager = libraryManager;
_repo = repo;
@@ -94,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target)
{
return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost.SystemId, _logger, _json, _fileSystem, _config.CommonApplicationPaths));
return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost, _logger, _json, _fileSystem, _config.CommonApplicationPaths));
}
public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
@@ -737,10 +738,15 @@ namespace MediaBrowser.Server.Implementations.Sync
public async Task<SyncDataResponse> SyncData(SyncDataRequest request)
{
if (request.SyncJobItemIds != null)
{
return await SyncDataUsingSyncJobItemIds(request).ConfigureAwait(false);
}
var jobItemResult = GetJobItems(new SyncJobItemQuery
{
TargetId = request.TargetId,
Statuses = new SyncJobItemStatus[] { SyncJobItemStatus.Synced }
Statuses = new[] { SyncJobItemStatus.Synced }
});
var response = new SyncDataResponse();
@@ -816,6 +822,87 @@ namespace MediaBrowser.Server.Implementations.Sync
return response;
}
private async Task<SyncDataResponse> SyncDataUsingSyncJobItemIds(SyncDataRequest request)
{
var jobItemResult = GetJobItems(new SyncJobItemQuery
{
TargetId = request.TargetId,
Statuses = new[] { SyncJobItemStatus.Synced }
});
var response = new SyncDataResponse();
foreach (var jobItem in jobItemResult.Items)
{
if (request.SyncJobItemIds.Contains(jobItem.Id, StringComparer.OrdinalIgnoreCase))
{
var job = _repo.GetJob(jobItem.JobId);
var user = _userManager.GetUserById(job.UserId);
if (jobItem.IsMarkedForRemoval)
{
// Tell the device to remove it since it has been marked for removal
response.ItemIdsToRemove.Add(jobItem.Id);
}
else if (user == null)
{
// Tell the device to remove it since the user is gone now
response.ItemIdsToRemove.Add(jobItem.Id);
}
else if (job.UnwatchedOnly)
{
var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);
if (IsLibraryItemAvailable(libraryItem))
{
if (libraryItem.IsPlayed(user) && libraryItem is Video)
{
// Tell the device to remove it since it has been played
response.ItemIdsToRemove.Add(jobItem.Id);
}
}
else
{
// Tell the device to remove it since it's no longer available
response.ItemIdsToRemove.Add(jobItem.Id);
}
}
}
else
{
// Content is no longer on the device
jobItem.Status = SyncJobItemStatus.RemovedFromDevice;
await UpdateSyncJobItemInternal(jobItem).ConfigureAwait(false);
}
}
// Now check each item that's on the device
foreach (var syncJobItemId in request.SyncJobItemIds)
{
// See if it's already marked for removal
if (response.ItemIdsToRemove.Contains(syncJobItemId, StringComparer.OrdinalIgnoreCase))
{
continue;
}
// If there isn't a sync job for this item, mark it for removal
if (!jobItemResult.Items.Any(i => string.Equals(syncJobItemId, i.Id, StringComparison.OrdinalIgnoreCase)))
{
response.ItemIdsToRemove.Add(syncJobItemId);
}
}
response.ItemIdsToRemove = response.ItemIdsToRemove.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
var itemsOnDevice = request.LocalItemIds
.Except(response.ItemIdsToRemove)
.ToList();
SetUserAccess(request, response, itemsOnDevice);
return response;
}
private void SetUserAccess(SyncDataRequest request, SyncDataResponse response, List<string> itemIds)
{
var users = request.OfflineUserIds

View File

@@ -1,6 +1,7 @@
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
@@ -26,11 +27,11 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IJsonSerializer _json;
private readonly IFileSystem _fileSystem;
private readonly IApplicationPaths _appPaths;
private readonly string _serverId;
private readonly IServerApplicationHost _appHost;
private readonly SemaphoreSlim _cacheFileLock = new SemaphoreSlim(1, 1);
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, string serverId, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
{
_logger = logger;
_json = json;
@@ -38,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_target = target;
_fileSystem = fileSystem;
_appPaths = appPaths;
_serverId = serverId;
_appHost = appHost;
}
private string GetCachePath()
@@ -50,13 +51,21 @@ namespace MediaBrowser.Server.Implementations.Sync
{
var parts = new List<string>
{
_serverId,
_appHost.FriendlyName,
"data.json"
};
parts = parts.Select(i => GetValidFilename(_provider, i)).ToList();
return _provider.GetFullPath(parts, _target);
}
private string GetValidFilename(IServerSyncProvider provider, string filename)
{
// We can always add this method to the sync provider if it's really needed
return _fileSystem.GetValidFilename(filename);
}
private async Task CacheData(Stream stream)
{
var cachePath = GetCachePath();
@@ -167,6 +176,11 @@ namespace MediaBrowser.Server.Implementations.Sync
return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.ItemId).ToList());
}
public Task<List<string>> GetSyncJobItemIds(SyncTarget target, string serverId)
{
return GetData(items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase)).Select(i => i.SyncJobItemId).Where(i => !string.IsNullOrWhiteSpace(i)).ToList());
}
public Task AddOrUpdate(SyncTarget target, LocalItem item)
{
return UpdateData(items =>
@@ -239,5 +253,13 @@ namespace MediaBrowser.Server.Implementations.Sync
return items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.ItemId, itemId, StringComparison.OrdinalIgnoreCase))
.ToList();
}
public async Task<List<LocalItem>> GetCachedItemsBySyncJobItemId(SyncTarget target, string serverId, string syncJobItemId)
{
var items = await GetCachedData().ConfigureAwait(false);
return items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.SyncJobItemId, syncJobItemId, StringComparison.OrdinalIgnoreCase))
.ToList();
}
}
}