예제 #1
0
        public void DetermineUniqueFilename_given_duplicate_filename_returns_unique_filename()
        {
            var dir       = $"test_{GetType().Name}_DetermineUniqueFilename";
            var directory = Path.Combine(Directory.GetCurrentDirectory(), dir);

            var inputname    = "notunique.jpg";
            var expectedname = "notunique (2).jpg";

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (File.Exists(Path.Combine(directory, expectedname)))
            {
                File.Delete(Path.Combine(directory, expectedname));
            }

            File.Create(Path.Combine(directory, "notunique.jpg")).Dispose();
            File.Create(Path.Combine(directory, "notunique (1).jpg")).Dispose();

            var output = Filenamer.DetermineUniqueFilename(Path.Combine(directory, inputname));

            Assert.Equal(Path.Combine(directory, expectedname), output);
        }
예제 #2
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.");
            });
        }
예제 #3
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);
        }
예제 #4
0
        private void MenuItemSave_OnClick(object sender, RoutedEventArgs e)
        {
            var image = RenderImage();

            var filename = SettingsManager.LastFilename;

            filename = string.IsNullOrWhiteSpace(filename) ? SettingsManager.DefaultFilename : filename;
            var dialog = new Microsoft.Win32.SaveFileDialog
            {
                Title        = "Choose save location",
                FileName     = filename,
                DefaultExt   = ".png",
                AddExtension = true,
                Filter       = "All Files|*.*"
            };

            //Manually handle storing information about the last directory so that we can determine if a file with the name already exists.
            var lastSaveDirectory = SettingsManager.LastSaveDirectory;

            if (!string.IsNullOrWhiteSpace(lastSaveDirectory) && Directory.Exists(lastSaveDirectory))
            {
                dialog.InitialDirectory = lastSaveDirectory;
                var uniqueFilename = Filenamer.UniqueFilename(lastSaveDirectory, filename, dialog.DefaultExt);
                dialog.FileName = uniqueFilename;
            }

            var result = dialog.ShowDialog();

            if (result != null && result.Value)
            {
                if (!dialog.FileName.EndsWith(".png"))
                {
                    dialog.FileName = dialog.FileName + ".png";
                }
                image.Save(dialog.FileName, ImageFormat.Png);

                //Save the filename for next time the user saves something, stripping (1), (2), etc. incase the user uses the unique suggested name and the original suggestion already existed.
                var actualfilename = Path.GetFileNameWithoutExtension(dialog.FileName);
                var filenameregex  = new Regex(@"^(?<name>.*)\([1-9]*\) *$");
                var match          = filenameregex.Match(actualfilename);
                if (match.Success)
                {
                    actualfilename = match.Groups["name"].Value.Trim();
                }

                SettingsManager.LastFilename      = actualfilename;
                SettingsManager.LastSaveDirectory = Path.GetDirectoryName(dialog.FileName);
            }
        }
예제 #5
0
        public void DetermineUniqueFilename_given_unique_filename_returns_identical_filename()
        {
            var dir       = $"test_{GetType().Name}_DetermineUniqueFilename";
            var directory = Path.Combine(Directory.GetCurrentDirectory(), dir);

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            var path   = Path.Combine(directory, "unique.test");
            var output = Filenamer.DetermineUniqueFilename(path);

            Assert.Equal(path, output);
        }
예제 #6
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.");
            });
        }
예제 #7
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.");
            });
        }
예제 #8
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.");
            });
        }