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);
                }
            }
        }
Ejemplo n.º 2
0
        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);
                }
            }
        }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        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]));
            }
        }
Ejemplo n.º 5
0
    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;
            });
        }