Ejemplo n.º 1
0
        public async Task Sync(IServerSyncProvider provider,
                               ISyncDataProvider dataProvider,
                               SyncTarget target,
                               IProgress <double> progress,
                               CancellationToken cancellationToken)
        {
            var serverId   = _appHost.SystemId;
            var serverName = _appHost.FriendlyName;

            await SyncData(provider, dataProvider, 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, dataProvider, target, serverId, serverName, innerProgress, cancellationToken);

            // Do the data sync twice so the server knows what was removed from the device
            await SyncData(provider, dataProvider, serverId, target, cancellationToken).ConfigureAwait(false);

            progress.Report(100);
        }
Ejemplo n.º 2
0
        private async Task SyncData(IServerSyncProvider provider,
                                    ISyncDataProvider dataProvider,
                                    string serverId,
                                    SyncTarget target,
                                    CancellationToken cancellationToken)
        {
            var localIds = await dataProvider.GetServerItemIds(target, serverId).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, dataProvider, serverId, itemIdToRemove, target, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error deleting item from device. Id: {0}", ex, itemIdToRemove);
                }
            }
        }
Ejemplo n.º 3
0
        public async Task Sync(IServerSyncProvider provider,
            ISyncDataProvider dataProvider,
            SyncTarget target,
            IProgress<double> progress,
            CancellationToken cancellationToken)
        {
            var serverId = _appHost.SystemId;
            var serverName = _appHost.FriendlyName;

            await SyncData(provider, dataProvider, 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, dataProvider, target, serverId, serverName, innerProgress, cancellationToken);

            // Do the data sync twice so the server knows what was removed from the device
            await SyncData(provider, dataProvider, serverId, target, cancellationToken).ConfigureAwait(false);
            
            progress.Report(100);
        }
Ejemplo n.º 4
0
        private async Task RemoveItem(IServerSyncProvider provider,
                                      ISyncDataProvider dataProvider,
                                      string serverId,
                                      string syncJobItemId,
                                      SyncTarget target,
                                      CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetItemsBySyncJobItemId(target, serverId, syncJobItemId);

            foreach (var localItem in localItems)
            {
                var files = localItem.AdditionalFiles.ToList();

                foreach (var file in files)
                {
                    _logger.Debug("Removing {0} from {1}.", file, target.Name);
                    await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
                }

                _logger.Debug("Removing {0} from {1}.", localItem.FileId, target.Name);
                await provider.DeleteFile(localItem.FileId, target, cancellationToken).ConfigureAwait(false);

                await dataProvider.Delete(target, localItem.Id).ConfigureAwait(false);
            }
        }
Ejemplo n.º 5
0
        private async Task RemoveItem(IServerSyncProvider provider,
                                      ISyncDataProvider dataProvider,
                                      string serverId,
                                      string syncJobItemId,
                                      SyncTarget target,
                                      CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetItemsBySyncJobItemId(target, serverId, syncJobItemId);

            foreach (var localItem in localItems)
            {
                var files = localItem.AdditionalFiles.ToList();

                // TODO: Remove this. Have to check it for now since this is a new property
                if (!string.IsNullOrWhiteSpace(localItem.FileId))
                {
                    files.Insert(0, localItem.FileId);
                }

                foreach (var file in files)
                {
                    _logger.Debug("Removing {0} from {1}.", file, target.Name);
                    await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
                }

                await dataProvider.Delete(target, localItem.Id).ConfigureAwait(false);
            }
        }
Ejemplo n.º 6
0
        private async Task GetNewMedia(IServerSyncProvider provider,
                                       ISyncDataProvider dataProvider,
                                       SyncTarget target,
                                       string serverId,
                                       string serverName,
                                       IProgress <double> progress,
                                       CancellationToken cancellationToken)
        {
            var jobItems = await _syncManager.GetReadySyncItems(target.Id).ConfigureAwait(false);

            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);
                });

                try
                {
                    await GetItem(provider, dataProvider, target, serverId, serverName, jobItem, innerProgress, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error syncing item", ex);
                }

                numComplete++;
                startingPercent  = numComplete;
                startingPercent /= jobItems.Count;
                startingPercent *= 100;
                progress.Report(startingPercent);
            }
        }
Ejemplo n.º 7
0
        private async Task SyncData(IServerSyncProvider provider,
                                    ISyncDataProvider dataProvider,
                                    string serverId,
                                    SyncTarget target,
                                    CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetLocalItems(target, serverId).ConfigureAwait(false);

            var remoteFiles = await provider.GetFiles(new FileQuery(), target, cancellationToken).ConfigureAwait(false);

            var remoteIds = remoteFiles.Items.Select(i => i.Id).ToList();

            var jobItemIds = new List <string>();

            foreach (var localItem in localItems)
            {
                // TODO: Remove this after a while
                if (string.IsNullOrWhiteSpace(localItem.FileId))
                {
                    jobItemIds.Add(localItem.SyncJobItemId);
                }
                else if (remoteIds.Contains(localItem.FileId, StringComparer.OrdinalIgnoreCase))
                {
                    jobItemIds.Add(localItem.SyncJobItemId);
                }
            }

            var result = await _syncManager.SyncData(new SyncDataRequest
            {
                TargetId       = target.Id,
                SyncJobItemIds = jobItemIds
            }).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();

            foreach (var itemIdToRemove in result.ItemIdsToRemove)
            {
                try
                {
                    await RemoveItem(provider, dataProvider, serverId, itemIdToRemove, target, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error deleting item from device. Id: {0}", ex, itemIdToRemove);
                }
            }
        }
Ejemplo n.º 8
0
        private async Task SyncData(IServerSyncProvider provider,
            ISyncDataProvider dataProvider,
            string serverId,
            SyncTarget target,
            CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetLocalItems(target, serverId).ConfigureAwait(false);
            var remoteFiles = await provider.GetFiles(new FileQuery(), target, cancellationToken).ConfigureAwait(false);
            var remoteIds = remoteFiles.Items.Select(i => i.Id).ToList();

            var jobItemIds = new List<string>();

            foreach (var localItem in localItems)
            {
                // TODO: Remove this after a while
                if (string.IsNullOrWhiteSpace(localItem.FileId))
                {
                    jobItemIds.Add(localItem.SyncJobItemId);
                }
                else if (remoteIds.Contains(localItem.FileId, StringComparer.OrdinalIgnoreCase))
                {
                    jobItemIds.Add(localItem.SyncJobItemId);
                }
            }

            var result = await _syncManager.SyncData(new SyncDataRequest
            {
                TargetId = target.Id,
                SyncJobItemIds = jobItemIds

            }).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();

            foreach (var itemIdToRemove in result.ItemIdsToRemove)
            {
                try
                {
                    await RemoveItem(provider, dataProvider, serverId, itemIdToRemove, target, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error deleting item from device. Id: {0}", ex, itemIdToRemove);
                }
            }
        }
Ejemplo n.º 9
0
        private async Task RemoveItem(IServerSyncProvider provider,
                                      ISyncDataProvider dataProvider,
                                      string serverId,
                                      string itemId,
                                      SyncTarget target,
                                      CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetCachedItems(target, serverId, itemId);

            foreach (var localItem in localItems)
            {
                var files = await GetFiles(provider, localItem, target, cancellationToken);

                foreach (var file in files)
                {
                    await provider.DeleteFile(file.Path, target, cancellationToken).ConfigureAwait(false);
                }

                await dataProvider.Delete(target, localItem.Id).ConfigureAwait(false);
            }
        }
Ejemplo n.º 10
0
        private async Task SendSubtitles(LocalItem localItem, MediaSourceInfo mediaSource, IServerSyncProvider provider, ISyncDataProvider dataProvider, SyncTarget target, SyncOptions options, CancellationToken cancellationToken)
        {
            var failedSubtitles = new List <MediaStream>();
            var requiresSave    = false;

            foreach (var mediaStream in mediaSource.MediaStreams
                     .Where(i => i.Type == MediaStreamType.Subtitle && i.IsExternal)
                     .ToList())
            {
                try
                {
                    var remotePath     = GetRemoteSubtitlePath(localItem, mediaStream, provider, target);
                    var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, options, new Progress <double>(), cancellationToken).ConfigureAwait(false);

                    // This is the path that will be used when talking to the provider
                    mediaStream.ExternalId = sendFileResult.Id;

                    // Keep track of all additional files for cleanup later.
                    localItem.AdditionalFiles.Add(sendFileResult.Id);

                    // This is the public path clients will use
                    mediaStream.Path = sendFileResult.Path;
                    requiresSave     = true;
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error sending subtitle stream", ex);
                    failedSubtitles.Add(mediaStream);
                }
            }

            if (failedSubtitles.Count > 0)
            {
                mediaSource.MediaStreams = mediaSource.MediaStreams.Except(failedSubtitles).ToList();
                requiresSave             = true;
            }

            if (requiresSave)
            {
                await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);
            }
        }
Ejemplo n.º 11
0
        private async Task GetItem(IServerSyncProvider provider,
                                   ISyncDataProvider dataProvider,
                                   SyncTarget target,
                                   string serverId,
                                   string serverName,
                                   SyncedItem jobItem,
                                   IProgress <double> progress,
                                   CancellationToken cancellationToken)
        {
            var libraryItem         = jobItem.Item;
            var internalSyncJobItem = _syncManager.GetJobItem(jobItem.SyncJobItemId);
            var internalSyncJob     = _syncManager.GetJob(jobItem.SyncJobId);

            var localItem = CreateLocalItem(provider, jobItem, internalSyncJob, target, libraryItem, serverId, serverName, jobItem.OriginalFileName);

            await _syncManager.ReportSyncJobItemTransferBeginning(internalSyncJobItem.Id);

            var       transferSuccess   = false;
            Exception transferException = null;

            var options = _config.GetSyncOptions();

            try
            {
                var fileTransferProgress = new ActionableProgress <double>();
                fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));

                var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath.Split(PathSeparatorChar), target, options, fileTransferProgress, cancellationToken).ConfigureAwait(false);

                if (localItem.Item.MediaSources != null)
                {
                    var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
                    if (mediaSource != null)
                    {
                        mediaSource.Path                = sendFileResult.Path;
                        mediaSource.Protocol            = sendFileResult.Protocol;
                        mediaSource.RequiredHttpHeaders = sendFileResult.RequiredHttpHeaders;
                        mediaSource.SupportsTranscoding = false;
                    }
                }

                localItem.FileId = sendFileResult.Id;

                // Create db record
                await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);

                if (localItem.Item.MediaSources != null)
                {
                    var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
                    if (mediaSource != null)
                    {
                        await SendSubtitles(localItem, mediaSource, provider, dataProvider, target, options, 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;
            }
        }
Ejemplo n.º 12
0
        private async Task RemoveItem(IServerSyncProvider provider,
            ISyncDataProvider dataProvider,
            string serverId,
            string syncJobItemId,
            SyncTarget target,
            CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetItemsBySyncJobItemId(target, serverId, syncJobItemId);

            foreach (var localItem in localItems)
            {
                var files = localItem.AdditionalFiles.ToList();

                foreach (var file in files)
                {
                    _logger.Debug("Removing {0} from {1}.", file, target.Name);
                    await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
                }

                await dataProvider.Delete(target, localItem.Id).ConfigureAwait(false);
            }
        }
Ejemplo n.º 13
0
        private async Task SendSubtitles(LocalItem localItem, MediaSourceInfo mediaSource, IServerSyncProvider provider, ISyncDataProvider dataProvider, SyncTarget target, SyncOptions options, CancellationToken cancellationToken)
        {
            var failedSubtitles = new List<MediaStream>();
            var requiresSave = false;

            foreach (var mediaStream in mediaSource.MediaStreams
                .Where(i => i.Type == MediaStreamType.Subtitle && i.IsExternal)
                .ToList())
            {
                try
                {
                    var remotePath = GetRemoteSubtitlePath(localItem, mediaStream, provider, target);
                    var sendFileResult = await SendFile(provider, mediaStream.Path, remotePath, target, options, new Progress<double>(), cancellationToken).ConfigureAwait(false);

                    // This is the path that will be used when talking to the provider
                    mediaStream.ExternalId = sendFileResult.Id;

                    // Keep track of all additional files for cleanup later.
                    localItem.AdditionalFiles.Add(sendFileResult.Id);

                    // This is the public path clients will use
                    mediaStream.Path = sendFileResult.Path;
                    requiresSave = true;
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error sending subtitle stream", ex);
                    failedSubtitles.Add(mediaStream);
                }
            }

            if (failedSubtitles.Count > 0)
            {
                mediaSource.MediaStreams = mediaSource.MediaStreams.Except(failedSubtitles).ToList();
                requiresSave = true;
            }

            if (requiresSave)
            {
                await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);
            }
        }
Ejemplo n.º 14
0
        private async Task GetItem(IServerSyncProvider provider,
            ISyncDataProvider dataProvider,
            SyncTarget target,
            string serverId,
            string serverName,
            SyncedItem jobItem,
            IProgress<double> progress,
            CancellationToken cancellationToken)
        {
            var libraryItem = jobItem.Item;
            var internalSyncJobItem = _syncManager.GetJobItem(jobItem.SyncJobItemId);
            var internalSyncJob = _syncManager.GetJob(jobItem.SyncJobId);

            var localItem = CreateLocalItem(provider, jobItem, internalSyncJob, target, libraryItem, serverId, serverName, jobItem.OriginalFileName);

            await _syncManager.ReportSyncJobItemTransferBeginning(internalSyncJobItem.Id);

            var transferSuccess = false;
            Exception transferException = null;

            var options = _config.GetSyncOptions();

            try
            {
                var fileTransferProgress = new ActionableProgress<double>();
                fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));

                var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem.LocalPath.Split(PathSeparatorChar), target, options, fileTransferProgress, cancellationToken).ConfigureAwait(false);

                if (localItem.Item.MediaSources != null)
                {
                    var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
                    if (mediaSource != null)
                    {
                        mediaSource.Path = sendFileResult.Path;
                        mediaSource.Protocol = sendFileResult.Protocol;
                        mediaSource.RequiredHttpHeaders = sendFileResult.RequiredHttpHeaders;
                        mediaSource.SupportsTranscoding = false;
                    }
                }

                localItem.FileId = sendFileResult.Id;

                // Create db record
                await dataProvider.AddOrUpdate(target, localItem).ConfigureAwait(false);

                if (localItem.Item.MediaSources != null)
                {
                    var mediaSource = localItem.Item.MediaSources.FirstOrDefault();
                    if (mediaSource != null)
                    {
                        await SendSubtitles(localItem, mediaSource, provider, dataProvider, target, options, 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;
            }
        }
Ejemplo n.º 15
0
        private async Task GetNewMedia(IServerSyncProvider provider,
            ISyncDataProvider dataProvider,
            SyncTarget target,
            string serverId,
            string serverName,
            IProgress<double> progress,
            CancellationToken cancellationToken)
        {
            var jobItems = await _syncManager.GetReadySyncItems(target.Id).ConfigureAwait(false);

            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);
                });

                try
                {
                    await GetItem(provider, dataProvider, target, serverId, serverName, jobItem, innerProgress, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    _logger.ErrorException("Error syncing item", ex);
                }

                numComplete++;
                startingPercent = numComplete;
                startingPercent /= jobItems.Count;
                startingPercent *= 100;
                progress.Report(startingPercent);
            }
        }
Ejemplo n.º 16
0
        private async Task RemoveItem(IServerSyncProvider provider,
            ISyncDataProvider dataProvider,
            string serverId,
            string syncJobItemId,
            SyncTarget target,
            CancellationToken cancellationToken)
        {
            var localItems = await dataProvider.GetItemsBySyncJobItemId(target, serverId, syncJobItemId);

            foreach (var localItem in localItems)
            {
                var files = localItem.AdditionalFiles.ToList();

                // TODO: Remove this. Have to check it for now since this is a new property
                if (!string.IsNullOrWhiteSpace(localItem.FileId))
                {
                    files.Insert(0, localItem.FileId);
                }

                foreach (var file in files)
                {
                    _logger.Debug("Removing {0} from {1}.", file, target.Name);
                    await provider.DeleteFile(file, target, cancellationToken).ConfigureAwait(false);
                }

                await dataProvider.Delete(target, localItem.Id).ConfigureAwait(false);
            }
        }