public async Task Download(IPhilomenaImage image, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null) { foreach (IPhilomenaImageDownloader downloader in Downloaders) { await downloader.Download(image, cancellationToken, progress); } }
private bool ImageExists(IPhilomenaImage image) { // Exclude images already downloaded. // This is a simple way of determining this that will fail if file names are not the same each download. A database could be used here instead. string imageFile = GetFileForImage(image); return(File.Exists(imageFile)); }
public async Task RunExample() { PhilomenaClient client = new PhilomenaClient("https://derpibooru.org"); IPhilomenaImage image = await client.GetImageSearch("fluttershy").BeginSearch().FirstAsync(); string filename = $"ExampleDownloads/DownloadImageToFile/{image.Id}.{image.Format}"; await image.DownloadToFile(filename); }
public override async Task Download(IPhilomenaImage downloadItem, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null) { bool shouldDownloadImage = _shouldDownloadImage(downloadItem); _logger.LogDebug("Condition for downloading image {ImageId}: {ConditionResult}", downloadItem.Id, shouldDownloadImage); if (shouldDownloadImage) { await _downloader.Download(downloadItem, cancellationToken, progress); } }
public override async Task Download(IPhilomenaImage downloadItem, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null) { if (!downloadItem.IsSvgImage) { _logger.LogDebug("Cannot download SVG since image {ImageId} is not an SVG image", downloadItem.Id); return; } try { string file = _getFileForImage(downloadItem); // Create directory for image download string?imageDirectory = Path.GetDirectoryName(file); if (imageDirectory is null) { throw new DirectoryNotFoundException($"The file does not have a parent directory: {file}"); } Directory.CreateDirectory(imageDirectory); // Create stream progress info IProgress <StreamProgressInfo> streamProgress = new SyncProgress <StreamProgressInfo>(streamProgress => { progress?.Report(new PhilomenaImageDownloadProgressInfo { Current = streamProgress.BytesRead, Total = streamProgress.BytesTotal, Action = $"Downloading image {downloadItem.Id} (SVG)" }); }); // Get the download stream for the image using Stream downloadStream = await GetDownloadStream(downloadItem, cancellationToken, streamProgress, isSvgVersion : true); _logger.LogDebug("Saving SVG image {ImageId} to {File}", downloadItem.Id, file); // Write to a temp file first string tempFile = file + "." + _tempExtension; using (FileStream tempFileStream = File.OpenWrite(tempFile)) { await downloadStream.CopyToAsync(tempFileStream, cancellationToken); } // Move the temp file to the destination file File.Move(tempFile, file, overwrite: true); } catch (Exception ex) when(ex is FlurlHttpException or IOException) { _logger.LogWarning(ex, "Failed to download SVG image {ImageId}", downloadItem.Id); } } }
public async Task RunExample() { PhilomenaClient client = new PhilomenaClient("https://derpibooru.org"); // Get an image IPhilomenaImage image = await client.GetImageSearch("fluttershy").BeginSearch().FirstAsync(); Log.Information("Listing tags for image {ImageId}", image.Id); // Get the tags from the IDs foreach (int tagId in image.TagIds) { TagModel tag = await client.GetTagById(tagId); Log.Information("{TagId}: {TagName} (On {TagImages} images)", tagId, tag.Name, tag.Images); } }
public override async Task Download(IPhilomenaImage downloadItem, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null) { try { string file = _getFileForImage(downloadItem); // Create directory for image download string?imageDirectory = Path.GetDirectoryName(file); if (imageDirectory is null) { throw new DirectoryNotFoundException($"The file does not have a parent directory: {file}"); } Directory.CreateDirectory(imageDirectory); // Metadata is already downloaded, so just report 0 or 1 for progress void reportProgress(bool isFinished) { progress?.Report(new PhilomenaImageDownloadProgressInfo { Current = isFinished ? 1 : 0, Total = 1, Action = $"Downloading image {downloadItem.Id} Metadata", }); } reportProgress(isFinished: false); _logger.LogDebug("Saving image {ImageId} metadata to {File}", downloadItem.Id, file); // Write to a temp file first string tempFile = file + "." + _tempExtension; await File.WriteAllTextAsync(tempFile, downloadItem.RawMetadata, Encoding.UTF8, cancellationToken); // Move the temp file to the destination file File.Move(tempFile, file, overwrite: true); reportProgress(isFinished: true); } catch (IOException ex) { _logger.LogWarning(ex, "Failed to download image {ImageId} metadata", downloadItem.Id); } }
/// <summary> /// Gets a stream for downloading an image /// </summary> /// <param name="image">The image to download</param> /// <param name="cancellationToken">The cancellation token</param> /// <param name="progress">The progress of the image download</param> /// <exception cref="FlurlHttpException">Thrown when the image fails to download</exception> /// <returns>A stream for downloading an image</returns> protected async Task <Stream> GetDownloadStream(IPhilomenaImage image, CancellationToken cancellationToken, IProgress <StreamProgressInfo>?progress, bool isSvgVersion = false) { string? imageUrl = isSvgVersion ? image.ShortSvgViewUrl : image.ShortViewUrl; IFlurlResponse response = await imageUrl.GetAsync(cancellationToken, HttpCompletionOption.ResponseHeadersRead); // Attempt to read the length of the stream from the header long?length = null; if (response.Headers.TryGetFirst("Content-Length", out string lengthString)) { if (long.TryParse(lengthString, out long parsedLength)) { length = parsedLength; } } // Open the image stream Stream downloadStream = await response.GetStreamAsync(); _logger.LogDebug("Opened download stream for image {ImageId} with size {DownloadSize}: {DownloadUrl}", image.Id, length, image.ShortViewUrl); // Create progress stream wrapper for reporting download progress return(new StreamProgressReporter(downloadStream, progress, length)); }
public abstract Task Download(IPhilomenaImage downloadItem, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null);
public static async Task DownloadToFile(this IPhilomenaImage image, string filename, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null) { PhilomenaImageFileDownloader downloader = new PhilomenaImageFileDownloader(image => filename); await downloader.Download(image, cancellationToken, progress); }
private bool SkipImagesAlreadyDownloaded(IPhilomenaImage image) { return(!ImageExists(image)); }
private string GetMetadataFileForImage(IPhilomenaImage image) { // A custom file naming scheme could be used here to generate file names return($"ExampleDownloads/EnumerateSearchQuery/{image.Id}.json"); }