public void JobQueuing_WithSpecifiedRangeAndOffset()
    {
        BytesRange range = BytesRangeUtils.Make(450, 830);

        long offset = 512;

        var jobs = ChunkedHttpDownloader.BuildDownloadJobQueue(_url, offset, range, DataSize, _chunksData).ToList();

        Assert.That(jobs.Count, Is.EqualTo(3));

        var firstJob = jobs[0];

        Assert.That(firstJob.Url, Is.EqualTo("test.com/someData.4"));
        Assert.That(firstJob.Range.Start, Is.EqualTo(0));
        Assert.That(firstJob.Range.End, Is.EqualTo(-1));

        var middleJob = jobs[1];

        Assert.That(middleJob.Url, Is.EqualTo("test.com/someData.5"));
        Assert.That(middleJob.Range.Start, Is.EqualTo(0));
        Assert.That(middleJob.Range.End, Is.EqualTo(-1));

        var lastJob = jobs[2];

        Assert.That(lastJob.Url, Is.EqualTo("test.com/someData.6"));

        Assert.That(lastJob.Range.Start, Is.EqualTo(0));
        Assert.That(lastJob.Range.End, Is.EqualTo(63));
    }
    public void JobQueuing_SinglePartScenario()
    {
        BytesRange range = BytesRangeUtils.Make(315, 380);

        var jobs = ChunkedHttpDownloader.BuildDownloadJobQueue(_url, 0, range, DataSize, _chunksData).ToList();

        Assert.That(jobs.Count, Is.EqualTo(1));

        var job = jobs[0];

        Assert.That(job.Url, Is.EqualTo("test.com/someData.2"));
        Assert.That(job.Range.Start, Is.EqualTo(0));
        Assert.That(job.Range.End, Is.EqualTo(-1).Or.EqualTo(127));
    }
    public void JobQueuing_WithFullRange()
    {
        BytesRange range = BytesRangeUtils.Full();

        var jobs             = ChunkedHttpDownloader.BuildDownloadJobQueue(_url, 0, range, DataSize, _chunksData).ToList();
        int expectedJobCount = (int)(DataSize / PartSize) + 1;

        Assert.That(jobs.Count, Is.EqualTo(expectedJobCount));

        var firstJob = jobs[0];

        Assert.That(firstJob.Range.Start, Is.EqualTo(0));
        Assert.That(firstJob.Range.End, Is.EqualTo(-1));

        var lastJob = jobs[expectedJobCount - 1];

        Assert.That(lastJob.Range.Start, Is.EqualTo(0));
        Assert.That(lastJob.Range.End, Is.EqualTo(-1));
    }
Beispiel #4
0
        public override void Execute(CancellationToken cancellationToken)
        {
            base.Execute(cancellationToken);

            foreach (var entry in _entries)
            {
                var tempDirName = _packagePath + string.Format("{0}_{1}_{2}", entry.Name, entry.Offset, entry.Size);
                TemporaryDirectory.ExecuteIn(tempDirName, (tempDir) =>
                {
                    _logger.LogDebug(string.Format("Repairing the file {0}", entry.Name));
                    string packagePath   = Path.Combine(tempDir.Path, ".pack" + Path.GetRandomFileName());
                    string unarchivePath = Path.Combine(tempDir.Path, Path.GetRandomFileName());

                    if (!Directory.Exists(unarchivePath))
                    {
                        DirectoryOperations.CreateDirectory(unarchivePath, cancellationToken);
                    }

                    var downloader = new ChunkedHttpDownloader(packagePath, _resource.ResourceUrls, _resource.ChunksData, _resource.Size);

                    long start = entry.Offset.GetValueOrDefault();
                    long end   = (start + entry.Size.GetValueOrDefault()) - 1; // Offset by 1 to denote a byte index

                    var range = new BytesRange(start, end);

                    downloader.SetRange(range);
                    var effectiveRange = downloader.CalculateContainingChunksRange(range);

                    long totalData = effectiveRange.End == -1 ? _resource.Size - effectiveRange.Start : effectiveRange.End - effectiveRange.Start;

                    var downloadStatus = _entryStatus[entry].DownloadStatus;
                    var repairStatus   = _entryStatus[entry].RepairStatus;

                    downloadStatus.IsActive.Value    = true;
                    downloadStatus.TotalBytes.Value  = totalData;
                    downloadStatus.Description.Value = "Downloading broken file...";
                    downloadStatus.Bytes.Value       = 0;

                    downloader.DownloadProgressChanged += downloadedBytes =>
                    {
                        downloadStatus.Bytes.Value = downloadedBytes;
                    };

                    _logger.LogDebug(string.Format("Downloading the partial package with range {0}-{1}", start, end));
                    downloader.Download(cancellationToken);

                    downloadStatus.IsActive.Value = false;

                    repairStatus.IsActive.Value    = true;
                    repairStatus.Description.Value = "Reparing broken file...";
                    repairStatus.Progress.Value    = 0.0;

                    _logger.LogDebug("Unarchiving the package.");
                    var unarchiver = new Pack1Unarchiver(packagePath, _meta, unarchivePath, _packagePassword, _unpackingSuffix, effectiveRange);
                    unarchiver.UnarchiveProgressChanged += (name, isFile, unarchiveEntry, amount, entryProgress) =>
                    {
                        repairStatus.Progress.Value = entryProgress;
                    };

                    unarchiver.UnarchiveSingleFile(entry, cancellationToken);

                    EmplaceFile(Path.Combine(unarchivePath, entry.Name + _unpackingSuffix), Path.Combine(_localData.Path, entry.Name), cancellationToken);

                    repairStatus.IsActive.Value = false;
                });
            }
        }