예제 #1
0
        /// <summary>
        /// <see cref="IHandler{T,K}.FetchContent(x,string,x,ICollection{string})"/>
        /// </summary>
        public override async Task FetchContent(IApiCollection <IApiImage> parsedSource, string targetFolder, ImgurFilter filter, ICollection <string> outputLog)
        {
            await Task.Run(async() =>
            {
                if (parsedSource.GetImages() != null)
                {
                    outputLog.Add($"Starting download of {parsedSource.GetImages().Count()} images.");

                    var sync = new object();

                    foreach (var image in parsedSource.GetImages().Where(image => image != null).AsParallel())
                    {
                        var imageName = Filenamer.Clean(await image.GetImageName());

                        try
                        {
                            if (filter(await image.GetHeight(), await image.GetWidth(), await image.GetAspectRatio()))
                            {
                                var path         = Filenamer.DetermineUniqueFilename(Path.Combine(targetFolder, imageName));
                                var fileContents = await image.GetImage();

                                File.WriteAllBytes(path, fileContents);

                                lock (sync)
                                {
                                    outputLog.Add($"Image saved: {imageName}");
                                    image.Dispose();
                                }
                            }
                            else
                            {
                                lock (sync)
                                {
                                    outputLog.Add($"Image skipped: {imageName}");
                                    image.Dispose();
                                }
                            }
                        }
                        catch (WebException)
                        {
                            lock (sync)
                            {
                                outputLog.Add($"Unable to download image: {imageName}");
                                image.Dispose();
                            }
                        }
                        catch (IOException)
                        {
                            lock (sync)
                            {
                                outputLog.Add($"IO Failure - Error occured while saving image: {imageName}");
                                image.Dispose();
                            }
                        }
                    }
                }

                outputLog.Add("Download finished.");
            });
        }
예제 #2
0
        public void Clean_given_string_containing_invalid_characters_returns_cleaned_string()
        {
            var input  = $"test {new string(Path.GetInvalidFileNameChars())}{new string(Path.GetInvalidPathChars())}";
            var output = Filenamer.Clean(input);

            Assert.Equal("test ", output);
        }
예제 #3
0
        /// <summary>
        /// <see cref="IHandler{T,K}.FetchContent(x,string,x,ICollection{string})"/>
        /// </summary>
        public override async Task FetchContent(LocalDirectory parsedSource, string targetFolder, LocalFilter filter, ICollection <string> outputLog, bool saveNestedCollectionsInNestedFolders = false)
        {
            await Task.Run(() =>
            {
                if (parsedSource.GetImages() != null)
                {
                    outputLog.Add($"Starting filtering of {parsedSource.GetImages().Count()} images.");

                    var sync = new object();
                    //Limit degree of parallelism to avoid sending too many http-requests at the same time.
                    //  8 seems like a reasonable amount of requests to have in-flight at a time.
                    var parallelOptions = new ParallelOptions {
                        MaxDegreeOfParallelism = 8
                    };

                    Parallel.ForEach(parsedSource.GetImages().Where(image => image != null), parallelOptions, image =>
                    {
                        var localTargetFolder = targetFolder;
                        if (saveNestedCollectionsInNestedFolders)
                        {
                            var path = Path.GetDirectoryName(image.ImagePath);
                            if (!string.IsNullOrWhiteSpace(path))
                            {
                                Debug.Assert(parsedSource.Directory.Length <= path.Length, $"Directory length longer than path.\nDirectory: {parsedSource.Directory}\nPath: {path}");
                                Debug.Assert(path.Substring(0, parsedSource.Directory.Length) == parsedSource.Directory, $"Directory doesn't exist in image path.\nDirectory: {parsedSource.Directory}\nPath: {path}");

                                var sourceDir    = new DirectoryInfo(parsedSource.Directory);
                                var innerFolders = new List <string>();
                                var innerFolder  = new DirectoryInfo(path);
                                while (sourceDir.FullName != innerFolder?.FullName)
                                {
                                    innerFolders.Add(innerFolder.Name);
                                    innerFolder = innerFolder.Parent;
                                }

                                innerFolders.Add(targetFolder);
                                innerFolders.Reverse();
                                localTargetFolder = Path.Combine(innerFolders.ToArray());
                            }
                        }

                        using (image)
                        {
                            var imageName = Filenamer.Clean(image.GetImageName().Result);

                            try
                            {
                                if (filter(image.GetHeight().Result, image.GetWidth().Result, image.GetAspectRatio().Result))
                                {
                                    //Dont create the folder unless we actually have something to save in it.
                                    if (!Directory.Exists(localTargetFolder))
                                    {
                                        Directory.CreateDirectory(localTargetFolder);
                                    }

                                    var path = Filenamer.DetermineUniqueFilename(Path.Combine(localTargetFolder, imageName));
                                    File.WriteAllBytes(path, image.GetImage().Result);
                                    WriteToLog(sync, outputLog, $"Image copied: {imageName}");
                                }
                                else
                                {
                                    WriteToLog(sync, outputLog, $"Image skipped: {imageName}");
                                }
                            }
                            catch (IOException)
                            {
                                WriteToLog(sync, outputLog, $"IO Failure - Error occured while saving or loading image: {imageName}");
                            }
                        }
                    });
                }

                outputLog.Add("Filtering finished.");
            });
        }
예제 #4
0
        /// <summary>
        /// <see cref="IHandler{T,K}.FetchContent(x,string,x,ICollection{string})"/>
        /// </summary>
        /// <param name="saveNestedCollectionsInNestedFolders">Imgur collections
        /// cannot contain nested albums, so the parameter has no effect.</param>
        public override async Task FetchContent(IApiCollection <IApiImage> parsedSource, string targetFolder, ImgurFilter filter, ICollection <string> outputLog, bool saveNestedCollectionsInNestedFolders = false)
        {
            await Task.Run(() =>
            {
                if (parsedSource.GetImages() != null)
                {
                    outputLog.Add($"Starting download of {parsedSource.GetImages().Count()} images.");

                    var sync = new object();
                    //Limit degree of parallelism to avoid sending too many http-requests at the same time.
                    //  8 seems like a reasonable amount of requests to have in-flight at a time.
                    var parallelOptions = new ParallelOptions {
                        MaxDegreeOfParallelism = 8
                    };

                    Parallel.ForEach(parsedSource.GetImages().Where(image => image != null), parallelOptions, image =>
                    {
                        using (image)
                        {
                            var imageName = Filenamer.Clean(image.GetImageName().Result);

                            try
                            {
                                if (filter(image.GetHeight().Result, image.GetWidth().Result, image.GetAspectRatio().Result))
                                {
                                    var path         = Filenamer.DetermineUniqueFilename(Path.Combine(targetFolder, imageName));
                                    var fileContents = image.GetImage().Result;

                                    File.WriteAllBytes(path, fileContents);
                                    WriteToLog(sync, outputLog, $"Image saved: {imageName}");
                                }
                                else
                                {
                                    WriteToLog(sync, outputLog, $"Image skipped: {imageName}");
                                }
                            }
                            catch (WebException)
                            {
                                WriteToLog(sync, outputLog, $"Unable to download image: {imageName}");
                            }
                            catch (IOException)
                            {
                                WriteToLog(sync, outputLog, $"IO Failure - Error occured while saving image: {imageName}");
                            }
                            catch (AggregateException ex)
                            {
                                if (ex.InnerException is WebException)
                                {
                                    WriteToLog(sync, outputLog, $"Unable to download image: {imageName}");
                                }
                                else
                                {
                                    WriteToLog(sync, outputLog, $"Unknown error occured for {imageName}. Error message is: " + ex.InnerException.Message);
                                }
                            }
                        }
                    });
                }

                outputLog.Add("Download finished.");
            });
        }
예제 #5
0
        /// <summary>
        /// <see cref="IHandler{T,K}.FetchContent(x,string,x,ICollection{string})"/>
        /// </summary>
        public override async Task FetchContent(RedditListing parsedSource, string targetFolder, RedditFilter filter, ICollection <string> outputLog, bool saveNestedCollectionsInNestedFolders = false)
        {
            await Task.Run(() =>
            {
                if (parsedSource.GetCollections() != null)
                {
                    outputLog.Add($"Starting download of {parsedSource.GetImages().Count()} images.");


                    foreach (var redditPost in parsedSource.GetCollections().Where(image => image != null))
                    {
                        if (redditPost.GetImages() == null)
                        {
                            continue;
                        }
                        var sync = new object();
                        var localTargetFolder = targetFolder;

                        //If the images will be saved in their own album, then there is no reason to prefix them with the reddit-title, since the folder has that info already.
                        string imageNamePrefix;

                        if (redditPost.IsAlbum && saveNestedCollectionsInNestedFolders)
                        {
                            localTargetFolder = Path.Combine(localTargetFolder, Filenamer.Clean(redditPost.ShortTitle));
                            imageNamePrefix   = string.Empty;
                        }
                        else
                        {
                            imageNamePrefix = Filenamer.Clean(redditPost.ShortTitle) + " - ";
                        }

                        //Limit degree of parallelism to avoid sending too many http-requests at the same time.
                        //  8 seems like a reasonable amount of requests to have in-flight at a time.
                        var parallelOptions = new ParallelOptions {
                            MaxDegreeOfParallelism = 8
                        };

                        Parallel.ForEach(redditPost.GetImages().Where(image => image != null), parallelOptions, image =>
                        {
                            using (image)
                            {
                                var imageName = imageNamePrefix + Filenamer.Clean(image.GetImageName().Result);

                                try
                                {
                                    if (filter(image.GetHeight().Result, image.GetWidth().Result, redditPost.Over_18,
                                               redditPost.Album != null, image.GetAspectRatio().Result))
                                    {
                                        //Dont create the folder unless we actually have something to save in it.
                                        if (!Directory.Exists(localTargetFolder))
                                        {
                                            Directory.CreateDirectory(localTargetFolder);
                                        }

                                        var path         = Filenamer.DetermineUniqueFilename(Path.Combine(localTargetFolder, imageName));
                                        var fileContents = image.GetImage().Result;

                                        File.WriteAllBytes(path, fileContents);
                                        WriteToLog(sync, outputLog, $"Image saved: {imageName}");
                                    }
                                    else
                                    {
                                        WriteToLog(sync, outputLog, $"Image skipped: {imageName}");
                                    }
                                }
                                catch (WebException)
                                {
                                    WriteToLog(sync, outputLog, $"Unable to download image: {imageName}");
                                }
                                catch (IOException)
                                {
                                    WriteToLog(sync, outputLog,
                                               $"IO Failure - Error occured while saving image: {imageName}");
                                }
                                catch (AggregateException ex)
                                {
                                    if (ex.InnerException is WebException)
                                    {
                                        WriteToLog(sync, outputLog, $"Unable to download image: {imageName}");
                                    }
                                    else
                                    {
                                        WriteToLog(sync, outputLog, $"Unknown error occured for {imageName}. Error message is: " + ex.InnerException.Message);
                                    }
                                }
                            }
                        });
                    }
                }

                outputLog.Add("Download finished.");
            });
        }