private async Task GetItemSubtitles(IApiClient apiClient,
                                            SyncedItem jobItem,
                                            LocalItem item,
                                            CancellationToken cancellationToken)
        {
            var hasDownloads = false;

            foreach (var file in jobItem.AdditionalFiles.Where(i => i.Type == ItemFileType.Subtitles))
            {
                using (var response = await apiClient.GetSyncJobItemAdditionalFile(jobItem.SyncJobItemId, file.Name, cancellationToken).ConfigureAwait(false))
                {
                    var subtitleStream = jobItem.Item.MediaSources.First().MediaStreams.First(i => i.Type == MediaStreamType.Subtitle && i.Index == file.Index);
                    var path           = await _localAssetManager.SaveSubtitles(response, subtitleStream.Codec, item, subtitleStream.Language, subtitleStream.IsForced).ConfigureAwait(false);

                    subtitleStream.Path = path;
                }

                hasDownloads = true;
            }

            // Save the changes to the item
            if (hasDownloads)
            {
                await _localAssetManager.AddOrUpdate(item).ConfigureAwait(false);
            }
        }
Exemple #2
0
        private SyncedItem GetJobItemInfo(SyncJobItem jobItem)
        {
            var job = _repo.GetJob(jobItem.JobId);

            var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);

            var syncedItem = new SyncedItem
            {
                SyncJobId     = jobItem.JobId,
                SyncJobItemId = jobItem.Id,
                ServerId      = _appHost.SystemId,
                UserId        = job.UserId
            };

            var dtoOptions = new DtoOptions();

            // Remove some bloat
            dtoOptions.Fields.Remove(ItemFields.MediaStreams);
            dtoOptions.Fields.Remove(ItemFields.IndexOptions);
            dtoOptions.Fields.Remove(ItemFields.MediaSourceCount);
            dtoOptions.Fields.Remove(ItemFields.OriginalPrimaryImageAspectRatio);
            dtoOptions.Fields.Remove(ItemFields.Path);
            dtoOptions.Fields.Remove(ItemFields.SeriesGenres);
            dtoOptions.Fields.Remove(ItemFields.Settings);
            dtoOptions.Fields.Remove(ItemFields.SyncInfo);

            syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions);

            // TODO: this should be the media source of the transcoded output
            syncedItem.Item.MediaSources = syncedItem.Item.MediaSources
                                           .Where(i => string.Equals(i.Id, jobItem.MediaSourceId))
                                           .ToList();

            var mediaSource = syncedItem.Item.MediaSources
                              .FirstOrDefault(i => string.Equals(i.Id, jobItem.MediaSourceId));

            // This will be null for items that are not audio/video
            if (mediaSource == null)
            {
                syncedItem.OriginalFileName = Path.GetFileName(libraryItem.Path);
            }
            else
            {
                syncedItem.OriginalFileName = Path.GetFileName(mediaSource.Path);
            }

            return(syncedItem);
        }
Exemple #3
0
        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;
            }
        }
Exemple #4
0
        private async Task GetItemSubtitles(IApiClient apiClient,
                                            SyncedItem jobItem,
                                            LocalItem item,
                                            CancellationToken cancellationToken)
        {
            var hasDownloads = false;

            var mediaSource = jobItem.Item.MediaSources.FirstOrDefault();

            if (mediaSource == null)
            {
                _logger.Error("Cannot download subtitles because video has no media source info.");
                return;
            }

            foreach (var file in jobItem.AdditionalFiles.Where(i => i.Type == ItemFileType.Subtitles))
            {
                var subtitleStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Subtitle && i.Index == file.Index);

                if (subtitleStream != null)
                {
                    using (var response = await apiClient.GetSyncJobItemAdditionalFile(jobItem.SyncJobItemId, file.Name, cancellationToken).ConfigureAwait(false))
                    {
                        var path = await _localAssetManager.SaveSubtitles(response, subtitleStream.Codec, item, subtitleStream.Language, subtitleStream.IsForced).ConfigureAwait(false);

                        subtitleStream.Path = path;

                        var files = item.AdditionalFiles.ToList();
                        files.Add(path);
                        item.AdditionalFiles = files.ToArray();
                    }

                    hasDownloads = true;
                }
                else
                {
                    _logger.Error("Cannot download subtitles because matching stream info wasn't found.");
                }
            }

            // Save the changes to the item
            if (hasDownloads)
            {
                await _localAssetManager.AddOrUpdate(item).ConfigureAwait(false);
            }
        }
        private async Task GetItem(IApiClient apiClient,
                                   ServerInfo server,
                                   SyncedItem jobItem,
                                   IProgress <double> progress,
                                   CancellationToken cancellationToken)
        {
            var libraryItem = jobItem.Item;

            var localItem = _localAssetManager.CreateLocalItem(libraryItem, server, jobItem.OriginalFileName);

            // Download item file
            await _localAssetManager.AddOrUpdate(localItem).ConfigureAwait(false);

            var fileTransferProgress = new DoubleProgress();

            fileTransferProgress.RegisterAction(pct => progress.Report(pct * .92));

            // Download item file
            await _fileTransferManager.GetItemFileAsync(apiClient, server, localItem, jobItem.SyncJobItemId, fileTransferProgress, cancellationToken).ConfigureAwait(false);

            progress.Report(92);

            var localFiles = await _localAssetManager.GetFiles(localItem).ConfigureAwait(false);

            // Download images
            await GetItemImages(apiClient, localItem, localFiles, cancellationToken).ConfigureAwait(false);

            progress.Report(95);

            // Download subtitles
            await GetItemSubtitles(apiClient, jobItem, localItem, cancellationToken).ConfigureAwait(false);

            progress.Report(99);

            // Let the server know it was successfully downloaded
            await apiClient.ReportSyncJobItemTransferred(jobItem.SyncJobItemId).ConfigureAwait(false);

            progress.Report(100);
        }
Exemple #6
0
        public LocalItem CreateLocalItem(IServerSyncProvider provider, SyncedItem syncedItem, SyncJob job, SyncTarget target, BaseItemDto libraryItem, string serverId, string serverName, string originalFileName)
        {
            var path = GetDirectoryPath(provider, job, syncedItem, libraryItem, serverName);

            path.Add(GetLocalFileName(provider, libraryItem, originalFileName));

            var localPath = string.Join(PathSeparatorString, path.ToArray());

            foreach (var mediaSource in libraryItem.MediaSources)
            {
                mediaSource.Path     = localPath;
                mediaSource.Protocol = MediaProtocol.File;
            }

            return(new LocalItem
            {
                Item = libraryItem,
                ItemId = libraryItem.Id,
                ServerId = serverId,
                LocalPath = localPath,
                Id = GetLocalId(syncedItem.SyncJobItemId, libraryItem.Id),
                SyncJobItemId = syncedItem.SyncJobItemId
            });
        }
Exemple #7
0
        private SyncedItem GetJobItemInfo(SyncJobItem jobItem)
        {
            var job = _repo.GetJob(jobItem.JobId);

            if (job == null)
            {
                _logger.Error("GetJobItemInfo job id {0} no longer exists", jobItem.JobId);
                return(null);
            }

            var libraryItem = _libraryManager.GetItemById(jobItem.ItemId);

            if (libraryItem == null)
            {
                _logger.Error("GetJobItemInfo library item with id {0} no longer exists", jobItem.ItemId);
                return(null);
            }

            var syncedItem = new SyncedItem
            {
                SyncJobId          = jobItem.JobId,
                SyncJobItemId      = jobItem.Id,
                ServerId           = _appHost.SystemId,
                UserId             = job.UserId,
                SyncJobName        = job.Name,
                SyncJobDateCreated = job.DateCreated,
                AdditionalFiles    = jobItem.AdditionalFiles.Select(i => new ItemFileInfo
                {
                    ImageType = i.ImageType,
                    Name      = i.Name,
                    Type      = i.Type,
                    Index     = i.Index
                }).ToList()
            };

            var dtoOptions = new DtoOptions();

            // Remove some bloat
            dtoOptions.Fields.Remove(ItemFields.MediaStreams);
            dtoOptions.Fields.Remove(ItemFields.IndexOptions);
            dtoOptions.Fields.Remove(ItemFields.MediaSourceCount);
            dtoOptions.Fields.Remove(ItemFields.Path);
            dtoOptions.Fields.Remove(ItemFields.SeriesGenres);
            dtoOptions.Fields.Remove(ItemFields.Settings);
            dtoOptions.Fields.Remove(ItemFields.SyncInfo);
            dtoOptions.Fields.Remove(ItemFields.BasicSyncInfo);

            syncedItem.Item = _dtoService().GetBaseItemDto(libraryItem, dtoOptions);

            var mediaSource = jobItem.MediaSource;

            syncedItem.Item.MediaSources = new List <MediaSourceInfo>();

            syncedItem.OriginalFileName = Path.GetFileName(libraryItem.Path);
            if (string.IsNullOrWhiteSpace(syncedItem.OriginalFileName))
            {
                syncedItem.OriginalFileName = Path.GetFileName(mediaSource.Path);
            }

            // This will be null for items that are not audio/video
            if (mediaSource != null)
            {
                syncedItem.OriginalFileName = Path.ChangeExtension(syncedItem.OriginalFileName, Path.GetExtension(mediaSource.Path));
                syncedItem.Item.MediaSources.Add(mediaSource);
            }
            if (string.IsNullOrWhiteSpace(syncedItem.OriginalFileName))
            {
                syncedItem.OriginalFileName = libraryItem.Name;
            }

            return(syncedItem);
        }
Exemple #8
0
        private List <string> GetDirectoryPath(IServerSyncProvider provider, SyncJob job, SyncedItem syncedItem, BaseItemDto item, string serverName)
        {
            var parts = new List <string>
            {
                serverName
            };

            var profileOption = _syncManager.GetProfileOptions(job.TargetId)
                                .FirstOrDefault(i => string.Equals(i.Id, job.Profile, StringComparison.OrdinalIgnoreCase));

            string name;

            if (profileOption != null && !string.IsNullOrWhiteSpace(profileOption.Name))
            {
                name = profileOption.Name;

                if (job.Bitrate.HasValue)
                {
                    name += "-" + job.Bitrate.Value.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    var qualityOption = _syncManager.GetQualityOptions(job.TargetId)
                                        .FirstOrDefault(i => string.Equals(i.Id, job.Quality, StringComparison.OrdinalIgnoreCase));

                    if (qualityOption != null && !string.IsNullOrWhiteSpace(qualityOption.Name))
                    {
                        name += "-" + qualityOption.Name;
                    }
                }
            }
            else
            {
                name = syncedItem.SyncJobName + "-" + syncedItem.SyncJobDateCreated
                       .ToLocalTime()
                       .ToString("g")
                       .Replace(" ", "-");
            }

            name = GetValidFilename(provider, name);
            parts.Add(name);

            if (item.IsType("episode"))
            {
                parts.Add("TV");
                if (!string.IsNullOrWhiteSpace(item.SeriesName))
                {
                    parts.Add(item.SeriesName);
                }
            }
            else if (item.IsVideo)
            {
                parts.Add("Videos");
                parts.Add(item.Name);
            }
            else if (item.IsAudio)
            {
                parts.Add("Music");

                if (!string.IsNullOrWhiteSpace(item.AlbumArtist))
                {
                    parts.Add(item.AlbumArtist);
                }

                if (!string.IsNullOrWhiteSpace(item.Album))
                {
                    parts.Add(item.Album);
                }
            }
            else if (string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase))
            {
                parts.Add("Photos");

                if (!string.IsNullOrWhiteSpace(item.Album))
                {
                    parts.Add(item.Album);
                }
            }

            return(parts.Select(i => GetValidFilename(provider, i)).ToList());
        }
Exemple #9
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;
            }
        }