async Task FetchFileOrDirectory(IpfsFile file) { if (file.Node.IsDirectory) { foreach (var link in file.Node.Links) { var next = new IpfsFile { Path = Path.Combine(file.Path, link.Name), Node = await Parent.CoreApi.FileSystem.ListFileAsync(link.Id) }; ++requested; fetch.Post(next); } } else { if (zip != null) { await SaveToZip(file); } else { await SaveToDisk(file); } } if (++processed == requested) { fetch.Complete(); } }
async Task SaveToZip(IpfsFile file) { using (var instream = await Parent.CoreApi.FileSystem.ReadFileAsync(file.Node.Id)) using (await ZipLock.LockAsync()) using (var entryStream = zip.CreateEntry(file.Path).Open()) { await instream.CopyToAsync(entryStream); } }
async Task SaveToDisk(IpfsFile file) { var outputPath = Path.GetFullPath(Path.Combine(OutputBasePath, file.Path)); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var instream = await Parent.CoreApi.FileSystem.ReadFileAsync(file.Node.Id)) using (var outstream = File.Create(outputPath)) { await instream.CopyToAsync(outstream); } }
protected override async Task <int> OnExecute(CommandLineApplication app) { OutputBasePath = OutputBasePath ?? Path.Combine(".", IpfsPath); if (Compress) { var zipPath = Path.GetFullPath(OutputBasePath); if (!Path.HasExtension(zipPath)) { zipPath = Path.ChangeExtension(zipPath, ".zip"); } app.Out.WriteLine($"Saving to {zipPath}"); zip = ZipFile.Open(zipPath, ZipArchiveMode.Create); } try { var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 }; fetch = new ActionBlock <IpfsFile>(FetchFileOrDirectory, options); var first = new IpfsFile { Path = zip == null ? "" : IpfsPath, Node = await Parent.CoreApi.FileSystem.ListFileAsync(IpfsPath) }; fetch.Post(first); await fetch.Completion; } finally { if (zip != null) { zip.Dispose(); } } return(0); }