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