private string[] GetRemoteSubtitlePath(LocalItem item, MediaStream stream, IServerSyncProvider provider, SyncTarget target)
        {
            var filename = GetSubtitleSaveFileName(item, stream.Language, stream.IsForced) + "." + stream.Codec.ToLower();

            var pathParts = item.LocalPath.Split(PathSeparatorChar);
            var list      = pathParts.Take(pathParts.Length - 1).ToList();

            list.Add(filename);

            return(list.ToArray());
        }
Example #2
0
 private async Task <SendFileResult> SendFile(IServerSyncProvider provider, string inputPath, LocalItem item, SyncTarget target, CancellationToken cancellationToken)
 {
     using (var stream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
     {
         return(await provider.SendFile(stream, item.LocalPath, target, new Progress <double>(), cancellationToken).ConfigureAwait(false));
     }
 }
Example #3
0
        private async Task <List <ItemFileInfo> > GetFiles(IServerSyncProvider provider, LocalItem item, SyncTarget target, CancellationToken cancellationToken)
        {
            var path = item.LocalPath;

            path = provider.GetParentDirectoryPath(path, target);

            var list = await provider.GetFileSystemEntries(path, target, cancellationToken).ConfigureAwait(false);

            var itemFiles = new List <ItemFileInfo>();

            var name = Path.GetFileNameWithoutExtension(item.LocalPath);

            foreach (var file in list.Where(f => f.Name.Contains(name)))
            {
                var itemFile = new ItemFileInfo
                {
                    Path = file.Path,
                    Name = file.Name
                };

                if (IsSubtitleFile(file.Name))
                {
                    itemFile.Type = ItemFileType.Subtitles;
                }

                itemFiles.Add(itemFile);
            }

            return(itemFiles);
        }
Example #4
0
 public Task <List <LocalItem> > GetItemsBySyncJobItemId(SyncTarget target, string serverId, string syncJobItemId)
 {
     return(GetData(false, items => items.Where(i => string.Equals(i.ServerId, serverId, StringComparison.OrdinalIgnoreCase) && string.Equals(i.SyncJobItemId, syncJobItemId, StringComparison.OrdinalIgnoreCase)).ToList()));
 }
Example #5
0
 public Task <Stream> GetFile(string id, SyncTarget target, IProgress <double> progress, CancellationToken cancellationToken)
 {
     return(Task.FromResult(_fileSystem.OpenRead(id)));
 }
 public string GetFullPath(IEnumerable <string> path, SyncTarget target)
 {
     return("/" + string.Join("/", path));
 }
Example #7
0
 public Task Delete(SyncTarget target, string id)
 {
     return(UpdateData(items => items.Where(i => !string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase)).ToList()));
 }
        public Task DeleteFile(string id, SyncTarget target, CancellationToken cancellationToken)
        {
            var googleCredentials = GetGoogleCredentials(target);

            return(_googleDriveService.DeleteFile(id, googleCredentials, cancellationToken));
        }
Example #9
0
        private IEnumerable <SyncQualityOption> GetQualityOptions(ISyncProvider provider, SyncTarget target)
        {
            var hasQuality = provider as IHasSyncQuality;

            if (hasQuality != null)
            {
                return(hasQuality.GetQualityOptions(target));
            }

            // Default options for providers that don't override
            return(new List <SyncQualityOption>
            {
                new SyncQualityOption
                {
                    Name = "High",
                    Id = "high",
                    IsDefault = true
                },
                new SyncQualityOption
                {
                    Name = "Medium",
                    Id = "medium"
                },
                new SyncQualityOption
                {
                    Name = "Low",
                    Id = "low"
                },
                new SyncQualityOption
                {
                    Name = "Custom",
                    Id = "custom"
                }
            });
        }
Example #10
0
        private IEnumerable <SyncQualityOption> GetQualityOptions(ISyncProvider provider, SyncTarget target, User user)
        {
            var hasQuality = provider as IHasSyncQuality;

            if (hasQuality != null)
            {
                var options = hasQuality.GetQualityOptions(target);

                if (user != null && !user.Policy.EnableSyncTranscoding)
                {
                    options = options.Where(i => i.IsOriginalQuality);
                }

                return(options);
            }

            // Default options for providers that don't override
            return(new List <SyncQualityOption>
            {
                new SyncQualityOption
                {
                    Name = "High",
                    Id = "high",
                    IsDefault = true
                },
                new SyncQualityOption
                {
                    Name = "Medium",
                    Id = "medium"
                },
                new SyncQualityOption
                {
                    Name = "Low",
                    Id = "low"
                },
                new SyncQualityOption
                {
                    Name = "Custom",
                    Id = "custom"
                }
            });
        }
 public string GetFullPath(IEnumerable <string> path, SyncTarget target)
 {
     return(Path.Combine(path.ToArray()));
 }
Example #12
0
 public SyncAction(SyncActionType syncActionType, SyncTarget syncTarget)
 {
     this.SyncActionType = syncActionType;
     this.SyncTarget     = syncTarget;
     Guid = Guid.NewGuid();
 }
        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 async Task <SyncedFileInfo> SendFile(IServerSyncProvider provider, string inputPath, string[] pathParts, SyncTarget target, SyncOptions options, IProgress <double> progress, CancellationToken cancellationToken)
        {
            _logger.Debug("Sending {0} to {1}. Remote path: {2}", inputPath, provider.Name, string.Join("/", pathParts));
            var supportsDirectCopy = provider as ISupportsDirectCopy;

            if (supportsDirectCopy != null)
            {
                return(await supportsDirectCopy.SendFile(inputPath, pathParts, target, progress, cancellationToken).ConfigureAwait(false));
            }

            using (var fileStream = _fileSystem.GetFileStream(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read, true))
            {
                Stream stream = fileStream;

                if (options.UploadSpeedLimitBytes > 0 && provider is IRemoteSyncProvider)
                {
                    stream = new ThrottledStream(stream, options.UploadSpeedLimitBytes);
                }

                return(await provider.SendFile(stream, pathParts, target, progress, cancellationToken).ConfigureAwait(false));
            }
        }
        public Task <QueryResult <FileSystemMetadata> > GetFiles(SyncTarget target, CancellationToken cancellationToken)
        {
            var syncAccount = _configurationRetriever.GetSyncAccount(target.Id);

            return(FindFilesMetadata(syncAccount.AccessToken, cancellationToken));
        }
Example #16
0
        private IEnumerable <SyncProfileOption> GetProfileOptions(ISyncProvider provider, SyncTarget target)
        {
            var hasQuality = provider as IHasSyncQuality;

            if (hasQuality != null)
            {
                return(hasQuality.GetProfileOptions(target));
            }

            var list = new List <SyncProfileOption>();

            list.Add(new SyncProfileOption
            {
                Name                 = "Original",
                Id                   = "Original",
                Description          = "Syncs original files as-is.",
                EnableQualityOptions = false
            });

            list.Add(new SyncProfileOption
            {
                Name        = "Baseline",
                Id          = "baseline",
                Description = "Designed for compatibility with all devices, including web browsers. Targets H264/AAC video and MP3 audio."
            });

            list.Add(new SyncProfileOption
            {
                Name        = "General",
                Id          = "general",
                Description = "Designed for compatibility with Chromecast, Roku, Smart TV's, and other similar devices. Targets H264/AAC/AC3 video and MP3 audio.",
                IsDefault   = true
            });

            return(list);
        }
        public async Task <SyncedFileInfo> SendFile(SyncJob syncJob, string originalMediaPath, Stream inputStream, bool isMedia, string[] outputPathParts, SyncTarget target, IProgress <double> progress, CancellationToken cancellationToken)
        {
            var path = GetFullPath(outputPathParts, target);

            _logger.Debug("Sending file {0} to {1}", path, target.Name);

            var syncAccount = _configurationRetriever.GetSyncAccount(target.Id);

            await UploadFile(path, inputStream, progress, syncAccount.AccessToken, cancellationToken).ConfigureAwait(false);

            return(new SyncedFileInfo
            {
                Id = path,
                Path = path,
                Protocol = MediaProtocol.Http
            });
        }
Example #18
0
 public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target)
 {
     return(_dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost.SystemId, _logger, _json, _fileSystem, _config.CommonApplicationPaths)));
 }
Example #19
0
 public DeviceProfile GetDeviceProfile(SyncTarget target)
 {
     return(new DeviceProfile());
 }
Example #20
0
 private OneDriveCredentials CreateOneDriveCredentials(SyncTarget target)
 {
     return(new OneDriveCredentials(_configurationRetriever, _liveAuthenticationApi, target));
 }
Example #21
0
 public Task <LocalItem> Get(SyncTarget target, string id)
 {
     return(GetData(true, items => items.FirstOrDefault(i => string.Equals(i.Id, id, StringComparison.OrdinalIgnoreCase))));
 }
Example #22
0
        private async Task <QueryResult <FileMetadata> > TryGetFiles(FileQuery query, SyncTarget target, CancellationToken cancellationToken)
        {
            var oneDriveCredentials = CreateOneDriveCredentials(target);

            if (!string.IsNullOrEmpty(query.Id))
            {
                return(await GetFileById(query.Id, oneDriveCredentials, cancellationToken));
            }

            if (query.FullPath != null && query.FullPath.Length > 0)
            {
                var path = GetFullPath(query.FullPath);
                return(await GetFileByPath(path, oneDriveCredentials, cancellationToken));
            }

            return(await GetAllFiles(oneDriveCredentials, cancellationToken));
        }
Example #23
0
        public async Task <SyncedFileInfo> SendFile(Stream stream, string[] remotePath, SyncTarget target, IProgress <double> progress, CancellationToken cancellationToken)
        {
            var fullPath = GetFullPath(remotePath, target);

            _fileSystem.CreateDirectory(Path.GetDirectoryName(fullPath));

            _logger.Debug("Folder sync saving stream to {0}", fullPath);

            using (var fileStream = _fileSystem.GetFileStream(fullPath, FileMode.Create, FileAccess.Write, FileShare.Read, true))
            {
                await stream.CopyToAsync(fileStream).ConfigureAwait(false);

                return(GetSyncedFileInfo(fullPath));
            }
        }
Example #24
0
        public async Task <SyncedFileInfo> SendFile(Stream stream, string[] pathParts, SyncTarget target, IProgress <double> progress, CancellationToken cancellationToken)
        {
            string path = GetFullPath(pathParts);

            _logger.Debug("Sending file {0} to {1}", path, target.Name);

            var oneDriveCredentials = CreateOneDriveCredentials(target);

            await CreateFolderHierarchy(pathParts, oneDriveCredentials, cancellationToken);

            var uploadSession = await _oneDriveApi.CreateUploadSession(path, oneDriveCredentials, cancellationToken);

            var id = await UploadFile(uploadSession.uploadUrl, stream, oneDriveCredentials, cancellationToken);

            return(new SyncedFileInfo
            {
                Id = id,
                Path = path,
                Protocol = MediaProtocol.Http
            });
        }
Example #25
0
        private async Task GetItem(IServerSyncProvider provider,
                                   ISyncDataProvider dataProvider,
                                   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));

            var localItem = CreateLocalItem(provider, jobItem.SyncJobId, jobItem.SyncJobItemId, target, libraryItem, serverId, jobItem.OriginalFileName);

            await _syncManager.ReportSyncJobItemTransferBeginning(internalSyncJobItem.Id);

            var       transferSuccess   = false;
            Exception transferException = null;

            try
            {
                var sendFileResult = await SendFile(provider, internalSyncJobItem.OutputPath, localItem, target, 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.SupportsTranscoding = false;
                    }
                }

                // Create db record
                await dataProvider.AddOrUpdate(target, localItem).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;
            }
        }
Example #26
0
        public async Task <SyncedFileInfo> SendFile(Stream stream, string[] pathParts, SyncTarget target, IProgress <double> progress, CancellationToken cancellationToken)
        {
            _logger.Debug("Sending file {0} to {1}", string.Join("/", pathParts), target.Name);

            var syncAccount = _configurationRetriever.GetSyncAccount(target.Id);

            var googleCredentials = GetGoogleCredentials(target);

            var file = await _googleDriveService.UploadFile(stream, pathParts, syncAccount.FolderId, googleCredentials, progress, cancellationToken);

            return(new SyncedFileInfo
            {
                Path = file.Item2,
                Protocol = MediaProtocol.Http,
                Id = file.Item1
            });
        }
Example #27
0
        public LocalItem CreateLocalItem(IServerSyncProvider provider, string syncJobId, string syncJobItemId, SyncTarget target, BaseItemDto libraryItem, string serverId, string originalFileName)
        {
            var path = GetDirectoryPath(provider, syncJobId, libraryItem, serverId);

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

            var localPath = provider.GetFullPath(path, target);

            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(syncJobItemId, libraryItem.Id)
            });
        }
        public Task <QueryResult <FileSystemMetadata> > GetFiles(string[] directoryPathParts, SyncTarget target, CancellationToken cancellationToken)
        {
            var syncAccount = _configurationRetriever.GetSyncAccount(target.Id);
            var path        = FindPathFromFileQuery(directoryPathParts, target);

            return(FilesInFolder(path, syncAccount.AccessToken, cancellationToken));
        }
Example #29
0
 public IEnumerable <SyncProfileOption> GetProfileOptions(SyncTarget target)
 {
     return(new List <SyncProfileOption>());
 }
        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);
            }
        }