/// <summary> /// Installs the resource. /// </summary> /// <param name="resource">The resource.</param> /// <param name="targetParatextId">The target paratext identifier.</param> /// <param name="needsToBeCloned">If set to <c>true</c>, the resource needs to be cloned.</param> /// <remarks> /// <paramref name="targetParatextId" /> is required because the resource may be a source or target. /// </remarks> private void InstallResource(ParatextResource resource, string targetParatextId, bool needsToBeCloned) { if (resource.InstallableResource != null) { // Install the resource if it is missing or out of date if (!resource.IsInstalled || resource.AvailableRevision > resource.InstalledRevision || resource.InstallableResource.IsNewerThanCurrentlyInstalled()) { resource.InstallableResource.Install(); needsToBeCloned = true; } // Extract the resource to the source directory if (needsToBeCloned) { string path = Path.Combine(SyncDir, targetParatextId, "target"); _fileSystemService.CreateDirectory(path); resource.InstallableResource.ExtractToDirectory(path); } } else { _logger.LogWarning($"The installable resource is not available for {resource.ParatextId}"); } }
/// <summary> /// Synchronizes the text and notes data on the SF server with the data on the Paratext server. /// </summary> public async Task SendReceiveAsync(UserSecret userSecret, string ptTargetId, IProgress <ProgressState> progress = null) { if (userSecret == null || ptTargetId == null) { throw new ArgumentNullException(); } IInternetSharedRepositorySource source = await GetInternetSharedRepositorySource(userSecret.Id); IEnumerable <SharedRepository> repositories = source.GetRepositories(); IEnumerable <ProjectMetadata> projectsMetadata = source.GetProjectsMetaData(); IEnumerable <string> projectGuids = projectsMetadata.Select(pmd => pmd.ProjectGuid.Id); Dictionary <string, ParatextProject> ptProjectsAvailable = GetProjects(userSecret, repositories, projectsMetadata).ToDictionary(ptProject => ptProject.ParatextId); if (!projectGuids.Contains(ptTargetId)) { // See if this is a resource IReadOnlyList <ParatextResource> resources = await this.GetResourcesInternalAsync(userSecret.Id, true); ParatextResource resource = resources.SingleOrDefault(r => r.ParatextId == ptTargetId); if (resource != null) { ptProjectsAvailable.Add(resource.ParatextId, resource); } else { _logger.LogWarning($"The target project did not have a full name available {ptTargetId}"); } } if (!ptProjectsAvailable.TryGetValue(ptTargetId, out ParatextProject targetPtProject)) { throw new ArgumentException( $"PT projects with the following PT ids were requested but without access or they don't exist: {ptTargetId}"); } EnsureProjectReposExists(userSecret, targetPtProject, source); StartProgressReporting(progress); if (!(targetPtProject is ParatextResource)) { SharedProject targetSharedProj = SharingLogicWrapper.CreateSharedProject(ptTargetId, targetPtProject.ShortName, source.AsInternetSharedRepositorySource(), repositories); string username = GetParatextUsername(userSecret); // Specifically set the ScrText property of the SharedProject to indicate the project is available locally targetSharedProj.ScrText = ScrTextCollection.FindById(username, ptTargetId); targetSharedProj.Permissions = targetSharedProj.ScrText.Permissions; List <SharedProject> sharedPtProjectsToSr = new List <SharedProject> { targetSharedProj }; // TODO report results List <SendReceiveResult> results = Enumerable.Empty <SendReceiveResult>().ToList(); bool success = false; bool noErrors = SharingLogicWrapper.HandleErrors(() => success = SharingLogicWrapper .ShareChanges(sharedPtProjectsToSr, source.AsInternetSharedRepositorySource(), out results, sharedPtProjectsToSr)); if (!noErrors || !success) { throw new InvalidOperationException( "Failed: Errors occurred while performing the sync with the Paratext Server."); } } }