aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Sync/MediaSync.cs')
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MediaSync.cs174
1 files changed, 174 insertions, 0 deletions
diff --git a/MediaBrowser.Server.Implementations/Sync/MediaSync.cs b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
new file mode 100644
index 000000000..efdfbb086
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sync/MediaSync.cs
@@ -0,0 +1,174 @@
+using MediaBrowser.Common.Progress;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Sync;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+ public class MediaSync
+ {
+ private readonly ISyncManager _syncManager;
+ private readonly IServerApplicationHost _appHost;
+ private readonly ILogger _logger;
+
+ public MediaSync(ILogger logger, ISyncManager syncManager, IServerApplicationHost appHost)
+ {
+ _logger = logger;
+ _syncManager = syncManager;
+ _appHost = appHost;
+ }
+
+ public async Task Sync(IServerSyncProvider provider,
+ SyncTarget target,
+ IProgress<double> progress,
+ CancellationToken cancellationToken)
+ {
+ var serverId = _appHost.SystemId;
+
+ await SyncData(provider, serverId, target, cancellationToken).ConfigureAwait(false);
+ progress.Report(2);
+
+ // Do the data sync twice so the server knows what was removed from the device
+ await SyncData(provider, serverId, target, cancellationToken).ConfigureAwait(false);
+ progress.Report(3);
+
+ var innerProgress = new ActionableProgress<double>();
+ innerProgress.RegisterAction(pct =>
+ {
+ var totalProgress = pct * .97;
+ totalProgress += 1;
+ progress.Report(totalProgress);
+ });
+ await GetNewMedia(provider, target, serverId, innerProgress, cancellationToken);
+ progress.Report(100);
+ }
+
+ private async Task SyncData(IServerSyncProvider provider,
+ string serverId,
+ SyncTarget target,
+ CancellationToken cancellationToken)
+ {
+ var localIds = await provider.GetServerItemIds(serverId, target, cancellationToken).ConfigureAwait(false);
+
+ var result = await _syncManager.SyncData(new SyncDataRequest
+ {
+ TargetId = target.Id,
+ LocalItemIds = localIds
+
+ }).ConfigureAwait(false);
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ foreach (var itemIdToRemove in result.ItemIdsToRemove)
+ {
+ try
+ {
+ await RemoveItem(provider, serverId, itemIdToRemove, target, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error deleting item from sync target. Id: {0}", ex, itemIdToRemove);
+ }
+ }
+ }
+
+ private async Task GetNewMedia(IServerSyncProvider provider,
+ SyncTarget target,
+ string serverId,
+ IProgress<double> progress,
+ CancellationToken cancellationToken)
+ {
+ var jobItems = _syncManager.GetReadySyncItems(target.Id);
+
+ var numComplete = 0;
+ double startingPercent = 0;
+ double percentPerItem = 1;
+ if (jobItems.Count > 0)
+ {
+ percentPerItem /= jobItems.Count;
+ }
+
+ foreach (var jobItem in jobItems)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ var currentPercent = startingPercent;
+ var innerProgress = new ActionableProgress<double>();
+ innerProgress.RegisterAction(pct =>
+ {
+ var totalProgress = pct * percentPerItem;
+ totalProgress += currentPercent;
+ progress.Report(totalProgress);
+ });
+
+ await GetItem(provider, target, serverId, jobItem, innerProgress, cancellationToken).ConfigureAwait(false);
+
+ numComplete++;
+ startingPercent = numComplete;
+ startingPercent /= jobItems.Count;
+ startingPercent *= 100;
+ progress.Report(startingPercent);
+ }
+ }
+
+ private async Task GetItem(IServerSyncProvider provider,
+ SyncTarget target,
+ string serverId,
+ SyncedItem jobItem,
+ IProgress<double> progress,
+ CancellationToken cancellationToken)
+ {
+ var libraryItem = jobItem.Item;
+ var internalSyncJobItem = _syncManager.GetJobItem(jobItem.SyncJobItemId);
+
+ var fileTransferProgress = new ActionableProgress<double>();
+ fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));
+
+ await _syncManager.ReportSyncJobItemTransferBeginning(internalSyncJobItem.Id);
+
+ var transferSuccess = false;
+ Exception transferException = null;
+
+ try
+ {
+ //await provider.TransferItemFile(serverId, libraryItem.Id, internalSyncJobItem.OutputPath, target, cancellationToken)
+ // .ConfigureAwait(false);
+
+ progress.Report(92);
+
+ transferSuccess = true;
+
+ progress.Report(99);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error transferring sync job file", ex);
+ transferException = ex;
+ }
+
+ if (transferSuccess)
+ {
+ await _syncManager.ReportSyncJobItemTransferred(jobItem.SyncJobItemId).ConfigureAwait(false);
+ }
+ else
+ {
+ await _syncManager.ReportSyncJobItemTransferFailed(jobItem.SyncJobItemId).ConfigureAwait(false);
+
+ throw transferException;
+ }
+ }
+
+ private Task RemoveItem(IServerSyncProvider provider,
+ string serverId,
+ string itemId,
+ SyncTarget target,
+ CancellationToken cancellationToken)
+ {
+ return provider.DeleteItem(serverId, itemId, target, cancellationToken);
+ }
+ }
+}