internal async Task <IEnumerable <Resource> > RipAsync(RipMode ripMode, int depth) { if (_ripped) { return(Enumerable.Empty <Resource>()); } lock (this) { if (_ripped) { return(Enumerable.Empty <Resource>()); } _ripped = true; } await DownloadAsync(ripMode); if (_hyperlink) { depth++; } var subResources = await Task.WhenAll(Parser.GetResources(_ripper, depth, this) .Select(subResource => subResource.RipAsync(ripMode, depth))); return(subResources.SelectMany(subResource => subResource.ToList()).Prepend(this)); }
public async Task RipAsync(RipMode ripMode) { if (_cancellationTokenSource != null) { throw new InvalidOperationException("Ripping has already started."); } using (_cancellationTokenSource = new CancellationTokenSource()) { await RipAsyncInternal(ripMode); } }
public void Rip(RipMode ripMode) { if (_cancellationTokenSource != null) { throw new InvalidOperationException("Ripping has already started."); } using (_cancellationTokenSource = new CancellationTokenSource()) { RipAsyncInternal(ripMode).Wait(CancellationToken); } }
async Task RipAsyncInternal(RipMode ripMode) { switch (ripMode) { case RipMode.Create: case RipMode.CreateNew: case RipMode.Update: case RipMode.UpdateOrCreate: case RipMode.Truncate: break; default: throw new ArgumentOutOfRangeException("ripMode"); } try { _uris.Add(Resource.OriginalUri, Resource); _resources.Add(Resource, Resource.OriginalUri); var directory = new DirectoryInfo(RootPath); if (directory.Exists) { switch (ripMode) { case RipMode.CreateNew: if (directory.EnumerateFileSystemInfos().Any()) { throw new IOException("Root path already exists."); } break; case RipMode.Create: case RipMode.Truncate: directory.Clear(); break; } } else { switch (ripMode) { case RipMode.Update: case RipMode.Truncate: throw new DirectoryNotFoundException("Root path does not exist."); } directory.Create(); } await Resource.RipAsync(ripMode, 0); } finally { if (_resources != null) { foreach (var resource in _resources.Keys) { resource.Dispose(); } _resources.Clear(); } if (_uris != null) { _uris.Clear(); } } }
async Task DownloadAsync(RipMode ripMode) { if (_downloader == null) { return; } try { var path = NewUri.LocalPath; var file = new FileInfo(path); if (file.Exists) { switch (ripMode) { case RipMode.Update: case RipMode.UpdateOrCreate: if (file.LastWriteTime >= LastModified) { return; } break; default: throw new IOException(string.Format("File '{0}' already exists.", file)); } } var parentPath = file.DirectoryName; if (parentPath != null) { Directory.CreateDirectory(parentPath); } using (var responseStream = _downloader.GetResponseStream()) { try { using (var writer = new FileStream(path, ripMode == RipMode.Create ? FileMode.CreateNew : FileMode.Create, FileAccess.Write)) { var totalBytesToReceive = _downloader.ContentLength; var progress = totalBytesToReceive > 0 ? new Progress <long>(bytesReceived => { _ripper.OnDownloadProgressChanged(new DownloadProgressChangedEventArgs(OriginalUri, bytesReceived, totalBytesToReceive)); }) : null; if (totalBytesToReceive <= 0) { _ripper.OnDownloadProgressChanged(new DownloadProgressChangedEventArgs(OriginalUri, 0, totalBytesToReceive)); } const int downloadBufferSize = 4096; var totalBytesReceived = await responseStream.CopyToAsync(writer, downloadBufferSize, progress, _ripper.CancellationToken); if (totalBytesToReceive <= 0) { _ripper.OnDownloadProgressChanged(new DownloadProgressChangedEventArgs(OriginalUri, totalBytesReceived, totalBytesReceived)); } } } catch { if (File.Exists(path)) { File.Delete(path); } throw; } } } finally { Dispose(); } }