public override void Execute(CancellationToken cancellationToken) { base.Execute(cancellationToken); Checks.FileExists(_packagePath); if (_versionDiffSummary.CompressionMethod == "pack1") { Assert.IsTrue(File.Exists(_packageMetaPath), "Compression method is pack1, but meta file does not exist"); DebugLogger.Log("Parsing package meta file"); _pack1Meta = Pack1Meta.ParseFromFile(_packageMetaPath); DebugLogger.Log("Package meta file parsed succesfully"); } DebugLogger.Log("Installing diff."); var packageDirPath = _temporaryData.GetUniquePath(); DebugLogger.LogVariable(packageDirPath, "packageDirPath"); DebugLogger.Log("Creating package directory."); DirectoryOperations.CreateDirectory(packageDirPath); try { DebugLogger.Log("Unarchiving files."); string usedSuffix; IUnarchiver unarchiver = CreateUnrachiver(packageDirPath, out usedSuffix); _unarchivePackageStatusReporter.OnProgressChanged(0.0, "Unarchiving package..."); unarchiver.UnarchiveProgressChanged += (name, isFile, entry, amount, entryProgress) => { var entryMinProgress = Mathf.Max(0, entry - 1) / (double)amount; // entry could be zero var entryMaxProgress = entry / (double)amount; var progress = entryMinProgress + (entryMaxProgress - entryMinProgress) * entryProgress; _unarchivePackageStatusReporter.OnProgressChanged(progress, "Unarchiving package..."); }; unarchiver.Unarchive(cancellationToken); _unarchivePackageStatusReporter.OnProgressChanged(1.0, string.Empty); ProcessAddedFiles(packageDirPath, usedSuffix, cancellationToken); ProcessRemovedFiles(cancellationToken); ProcessModifiedFiles(packageDirPath, usedSuffix, cancellationToken); DeleteEmptyMacAppDirectories(); } finally { DebugLogger.Log("Deleting package directory."); if (Directory.Exists(packageDirPath)) { DirectoryOperations.Delete(packageDirPath, true); } } }
public override void Execute(CancellationToken cancellationToken) { base.Execute(cancellationToken); Checks.FileExists(_packagePath); if (_versionDiffSummary.CompressionMethod == "pack1") { Assert.IsTrue(File.Exists(_packageMetaPath), "Compression method is pack1, but meta file does not exist"); DebugLogger.Log("Parsing package meta file"); _pack1Meta = Pack1Meta.ParseFromFile(_packageMetaPath); DebugLogger.Log("Package meta file parsed succesfully"); } DebugLogger.Log("Installing diff."); var packageDirPath = _temporaryData.GetUniquePath(); DebugLogger.LogVariable(packageDirPath, "packageDirPath"); DebugLogger.Log("Creating package directory."); DirectoryOperations.CreateDirectory(packageDirPath); try { DebugLogger.Log("Unarchiving files."); IUnarchiver unarchiver = CreateUnrachiver(packageDirPath); unarchiver.UnarchiveProgressChanged += (name, isFile, entry, amount) => { _unarchivePackageStatusReporter.OnProgressChanged(entry / (double)amount); }; unarchiver.Unarchive(cancellationToken); _unarchivePackageStatusReporter.OnProgressChanged(1.0); ProcessAddedFiles(packageDirPath, cancellationToken); ProcessRemovedFiles(cancellationToken); ProcessModifiedFiles(packageDirPath, cancellationToken); } finally { DebugLogger.Log("Deleting package directory."); if (Directory.Exists(packageDirPath)) { DirectoryOperations.Delete(packageDirPath, true); } } }
public RepairFilesCommand( RemoteResource resource, Pack1Meta meta, Pack1Meta.FileEntry[] fileEntries, string destinationPackagePath, string packagePassword, ILocalDirectory localData) { _resource = resource; _meta = meta; _entries = fileEntries; _packagePath = destinationPackagePath; _packagePassword = packagePassword; _localData = localData; _logger = PatcherLogManager.DefaultLogger; }
private void ReadPack1MetaFile() { _logger.LogDebug("Parsing package meta file..."); _logger.LogTrace("packageMetaPath = " + _packageMetaPath); if (!File.Exists(_packageMetaPath)) { throw new MissingPackageMetaFileException("Pack1 meta file does not exist."); } _pack1Meta = Pack1Meta.ParseFromFile(_packageMetaPath); _logger.LogDebug("Meta file parsed."); _logger.LogTrace("pack1Meta.iv = " + _pack1Meta.Iv); _logger.LogTrace("pack1Meta.version = " + _pack1Meta.Version); _logger.LogTrace("pack1Meta.encryption = " + _pack1Meta.Encryption); for (int i = 0; i < _pack1Meta.Files.Length; i++) { _logger.LogTrace(string.Format("pack1Meta.files[{0}] = {1}", i, _pack1Meta.Files[i])); } }
public void Unpack() { string archivePath = TestFixtures.GetFilePath("pack1/test.pack1"); string metaPath = TestFixtures.GetFilePath("pack1/test.pack1.meta"); string metaString = File.ReadAllText(metaPath); Pack1Meta meta = Pack1Meta.Parse(metaString); var pack1Unarchiver = new Pack1Unarchiver(archivePath, meta, _tempDir, Key); pack1Unarchiver.Unarchive(new CancellationToken()); Assert.True(Directory.Exists(Path.Combine(_tempDir, "dir"))); var rakefile = Path.Combine(_tempDir, "dir/Rakefile"); Assert.True(File.Exists(rakefile)); Assert.AreEqual("d2974b45f816b3ddaca7a984a9101707", Md5File(rakefile)); var rubocopFile = Path.Combine(_tempDir, ".rubocop.yml"); Assert.True(File.Exists(rubocopFile)); Assert.AreEqual("379cc2261c048e4763969cca74974237", Md5File(rubocopFile)); }
public override void Execute(CancellationToken cancellationToken) { base.Execute(cancellationToken); Checks.FileExists(_packagePath); Assert.IsTrue(_localMetaData.GetRegisteredEntries().Length == 0, "Cannot install content if previous version is still present."); if (_versionContentSummary.CompressionMethod == "pack1") { Assert.IsTrue(File.Exists(_packageMetaPath), "Compression method is pack1, but meta file does not exist"); DebugLogger.Log("Parsing package meta file"); _pack1Meta = Pack1Meta.ParseFromFile(_packageMetaPath); DebugLogger.Log("Package meta file parsed succesfully"); } DebugLogger.Log("Installing content."); var packageDirPath = _temporaryData.GetUniquePath(); DebugLogger.LogVariable(packageDirPath, "destinationDir"); DebugLogger.Log("Creating package directory."); DirectoryOperations.CreateDirectory(packageDirPath); try { DebugLogger.Log("Unarchiving package."); IUnarchiver unarchiver = CreateUnrachiver(packageDirPath); unarchiver.UnarchiveProgressChanged += (name, isFile, entry, amount) => { _unarchivePackageStatusReporter.OnProgressChanged(entry / (double)amount); }; unarchiver.Unarchive(cancellationToken); _unarchivePackageStatusReporter.OnProgressChanged(1.0); DebugLogger.Log("Copying files."); for (int i = 0; i < _versionContentSummary.Files.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); InstallFile(_versionContentSummary.Files[i].Path, packageDirPath); _copyFilesStatusReporter.OnProgressChanged((i + 1) / (double)_versionContentSummary.Files.Length); } _copyFilesStatusReporter.OnProgressChanged(1.0); } finally { DebugLogger.Log("Deleting package directory."); if (Directory.Exists(packageDirPath)) { DirectoryOperations.Delete(packageDirPath, true); } } }
public override void Execute(CancellationToken cancellationToken) { base.Execute(cancellationToken); Checks.FileExists(_packagePath); Assert.IsTrue(_localMetaData.GetRegisteredEntries().Length == 0, "Cannot install content if previous version is still present."); if (_versionContentSummary.CompressionMethod == "pack1") { Assert.IsTrue(File.Exists(_packageMetaPath), "Compression method is pack1, but meta file does not exist"); DebugLogger.Log("Parsing package meta file"); _pack1Meta = Pack1Meta.ParseFromFile(_packageMetaPath); DebugLogger.Log("Package meta file parsed succesfully"); } DebugLogger.Log("Installing content."); TemporaryDirectory.ExecuteIn(_packagePath + ".temp_unpack_" + Path.GetRandomFileName(), (packageDir) => { DebugLogger.LogVariable(packageDir.Path, "packageDirPath"); DebugLogger.Log("Unarchiving package."); string usedSuffix; IUnarchiver unarchiver = CreateUnrachiver(packageDir.Path, out usedSuffix); _unarchivePackageStatus.IsActive.Value = true; _unarchivePackageStatus.Description.Value = "Unarchiving package..."; _unarchivePackageStatus.Progress.Value = 0.0; unarchiver.UnarchiveProgressChanged += (name, isFile, entry, amount, entryProgress) => { var entryMinProgress = (entry - 1) / (double)amount; var entryMaxProgress = entry / (double)amount; _unarchivePackageStatus.Progress.Value = entryMinProgress + (entryMaxProgress - entryMinProgress) * entryProgress; _unarchivePackageStatus.Description.Value = string.Format("Unarchiving package ({0}/{1})...", entry, amount); }; unarchiver.Unarchive(cancellationToken); _unarchivePackageStatus.Progress.Value = 1.0; _unarchivePackageStatus.IsActive.Value = false; DebugLogger.Log("Copying files."); _copyFilesStatus.IsActive.Value = true; _copyFilesStatus.Description.Value = "Installing..."; _copyFilesStatus.Progress.Value = 0.0; for (int i = 0; i < _versionContentSummary.Files.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); InstallFile(_versionContentSummary.Files[i].Path, packageDir.Path, usedSuffix, cancellationToken); _copyFilesStatus.Progress.Value = (i + 1) / (double)_versionContentSummary.Files.Length; _copyFilesStatus.Description.Value = string.Format("Installing ({0}/{1})...", i + 1, _versionContentSummary.Files.Length); } _copyFilesStatus.Progress.Value = 1.0; _copyFilesStatus.IsActive.Value = false; }); }
public void Update(CancellationToken cancellationToken) { _logger.LogDebug("Executing content repair strategy."); var installedVersionId = _context.App.GetInstalledVersionId(); string metaDestination = _context.App.DownloadDirectory.GetDiffPackageMetaPath(installedVersionId); var commandFactory = new AppUpdaterCommandFactory(); var validateLicense = commandFactory.CreateValidateLicenseCommand(_context); validateLicense.Prepare(_status, cancellationToken); validateLicense.Execute(cancellationToken); var geolocateCommand = commandFactory.CreateGeolocateCommand(); geolocateCommand.Prepare(_status, cancellationToken); geolocateCommand.Execute(cancellationToken); var resource = _context.App.RemoteData.GetContentPackageResource( installedVersionId, validateLicense.KeySecret, geolocateCommand.CountryCode, cancellationToken); if (!resource.HasMetaUrls()) { throw new ArgumentException("Cannot execute content repair strategy without meta files."); } _logger.LogDebug("Downloading the meta file."); var downloader = new HttpDownloader(metaDestination, resource.GetMetaUrls()); downloader.Download(cancellationToken); ICheckVersionIntegrityCommand checkVersionIntegrityCommand = commandFactory.CreateCheckVersionIntegrityCommand(installedVersionId, _context, true, true, cancellationToken); checkVersionIntegrityCommand.Prepare(_status, cancellationToken); checkVersionIntegrityCommand.Execute(cancellationToken); var meta = Pack1Meta.ParseFromFile(metaDestination); FileIntegrity[] filesIntegrity = checkVersionIntegrityCommand.Results.Files; var contentSummary = _context.App.RemoteMetaData.GetContentSummary(installedVersionId, cancellationToken); foreach (var invalidVersionIdFile in filesIntegrity.Where(x => x.Status == FileIntegrityStatus.InvalidVersion).ToArray()) { var fileName = invalidVersionIdFile.FileName; var file = contentSummary.Files.First(x => x.Path == fileName); var localPath = _context.App.LocalDirectory.Path.PathCombine(file.Path); string actualFileHash = HashCalculator.ComputeFileHash(localPath); if (actualFileHash != file.Hash) { FileOperations.Delete(localPath, cancellationToken); _context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId); invalidVersionIdFile.Status = FileIntegrityStatus.MissingData; } else { _context.App.LocalMetaData.RegisterEntry(fileName, installedVersionId); invalidVersionIdFile.Status = FileIntegrityStatus.Ok; } } Pack1Meta.FileEntry[] brokenFiles = filesIntegrity // Filter only files with invalid size, hash or missing entirely .Where(f => f.Status == FileIntegrityStatus.InvalidHash || f.Status == FileIntegrityStatus.InvalidSize || f.Status == FileIntegrityStatus.MissingData) // Map to file entires from meta .Select(integrity => meta.Files.SingleOrDefault(file => file.Name == integrity.FileName)) // Filter only regular files .Where(file => file.Type == Pack1Meta.RegularFileType) .ToArray(); if (brokenFiles.Length == 0) { _logger.LogDebug("Nothing to repair."); return; } _logger.LogDebug(string.Format("Broken files count: {0}", brokenFiles.Length)); IRepairFilesCommand repairCommand = commandFactory.CreateRepairFilesCommand( installedVersionId, _context, resource, brokenFiles, meta); repairCommand.Prepare(_status, cancellationToken); repairCommand.Execute(cancellationToken); }
public IRepairFilesCommand CreateRepairFilesCommand(int versionId, AppUpdaterContext context, RemoteResource resource, Pack1Meta.FileEntry[] brokenFiles, Pack1Meta meta) { var packagePath = context.App.DownloadDirectory.GetContentPackagePath(versionId); var packagePassword = context.App.RemoteData.GetContentPackageResourcePassword(versionId); return(new RepairFilesCommand(resource, meta, brokenFiles, packagePath, packagePassword, context.App.LocalDirectory)); }
public override void Execute(CancellationToken cancellationToken) { base.Execute(cancellationToken); Checks.FileExists(_packagePath); Assert.IsTrue(_localMetaData.GetRegisteredEntries().Length == 0, "Cannot install content if previous version is still present."); if (_versionContentSummary.CompressionMethod == "pack1") { Assert.IsTrue(File.Exists(_packageMetaPath), "Compression method is pack1, but meta file does not exist"); DebugLogger.Log("Parsing package meta file"); _pack1Meta = Pack1Meta.ParseFromFile(_packageMetaPath); DebugLogger.Log("Package meta file parsed succesfully"); } DebugLogger.Log("Installing content."); TemporaryDirectory.ExecuteIn(_packagePath + ".temp_unpack_" + Path.GetRandomFileName(), (packageDir) => { DebugLogger.LogVariable(packageDir.Path, "packageDirPath"); DebugLogger.Log("Unarchiving package."); string usedSuffix; IUnarchiver unarchiver = CreateUnrachiver(packageDir.Path, out usedSuffix); _unarchivePackageStatus.IsActive.Value = true; _unarchivePackageStatus.Description.Value = "Unarchiving package..."; _unarchivePackageStatus.Progress.Value = 0.0; unarchiver.UnarchiveProgressChanged += (name, isFile, entry, amount, entryProgress) => { var entryMinProgress = (entry - 1) / (double)amount; var entryMaxProgress = entry / (double)amount; _unarchivePackageStatus.Progress.Value = entryMinProgress + (entryMaxProgress - entryMinProgress) * entryProgress; _unarchivePackageStatus.Description.Value = string.Format("Unarchiving package ({0}/{1})...", entry, amount); }; // Allow to unpack with errors. This allows to install content even on corrupted hard drives, and attempt to fix these later unarchiver.ContinueOnError = true; unarchiver.Unarchive(cancellationToken); NeedRepair = unarchiver.HasErrors; _unarchivePackageStatus.Progress.Value = 1.0; _unarchivePackageStatus.IsActive.Value = false; DebugLogger.Log("Moving files."); _copyFilesStatus.IsActive.Value = true; _copyFilesStatus.Description.Value = "Installing..."; _copyFilesStatus.Progress.Value = 0.0; for (int i = 0; i < _versionContentSummary.Files.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); var sourceFile = new SourceFile(_versionContentSummary.Files[i].Path, packageDir.Path, usedSuffix); if (unarchiver.HasErrors && !sourceFile.Exists()) // allow unexistent file only if does not have errors { DebugLogger.LogWarning("Skipping unexisting file because I've been expecting unpacking errors: " + sourceFile.Name); } else { InstallFile(sourceFile, cancellationToken); } _copyFilesStatus.Progress.Value = (i + 1) / (double)_versionContentSummary.Files.Length; _copyFilesStatus.Description.Value = string.Format("Installing ({0}/{1})...", i + 1, _versionContentSummary.Files.Length); } _copyFilesStatus.Progress.Value = 1.0; _copyFilesStatus.IsActive.Value = false; }); }