Example #1
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);

            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;
        }
Example #2
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;

                        item.AdditionalFiles.Add(path);
                    }

                    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);
            }
        }
Example #3
0
        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.SyncJobItemId, jobItem.OriginalFileName);

            // Create db record
            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);

            // Download images
            await GetItemImages(apiClient, localItem, 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);
        }
Example #4
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();
        }
Example #5
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
            };
        }
Example #6
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;
            }
        }