Ejemplo n.º 1
0
        public static List <TreeNode> GetRecipes()
        {
            var categoryNodes = new List <TreeNode>();

            foreach (var dict in Locate.GetCategorizedRecipes())
            {
                string    category = dict.Key;
                IRecipe[] recipes  = dict.Value;

                var categoryNode = new TreeNode(category);
                categoryNodes.Add(categoryNode);

                foreach (IRecipe recipe in recipes)
                {
                    categoryNode.Items.Add(new TreeNode(recipe));
                }
            }

            return(categoryNodes);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Use REFLECTION to locate all recipes, execute them and save the output images.
        /// </summary>
        /// <returns>array of recipes found using reflection</returns>
        public static IRecipe[] Generate(string outputPath, int width = 600, int height = 400, int thumbJpegQuality = 95)
        {
            outputPath = Path.GetFullPath(outputPath);
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            IRecipe[] recipes = Locate.GetRecipes();

            EncoderParameters thumbJpegEncoderParameters = new(1);

            thumbJpegEncoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, thumbJpegQuality);
            ImageCodecInfo thumbJpegEncoder = ImageCodecInfo.GetImageEncoders().Where(x => x.MimeType == "image/jpeg").First();

            Parallel.ForEach(recipes, recipe =>
            {
                var sw  = System.Diagnostics.Stopwatch.StartNew();
                var plt = new Plot(width, height);
                recipe.ExecuteRecipe(plt);

                // save full size image
                Bitmap bmp      = plt.Render();
                string filePath = Path.Combine(outputPath, recipe.ID.ToLower() + ".png");
                bmp.Save(filePath, ImageFormat.Png);

                // calculate image hash
                Console.WriteLine($"{recipe.ID},{Tools.BitmapHash(bmp)},{sw.Elapsed.TotalMilliseconds}");

                // thumbnail
                int thumbHeight      = 180;
                int thumbWidth       = thumbHeight * bmp.Width / bmp.Height;
                Bitmap thumb         = Drawing.GDI.Resize(bmp, thumbWidth, thumbHeight);
                string thumbFilePath = Path.Combine(outputPath, recipe.ID.ToLower() + "_thumb.jpg");
                thumb.Save(thumbFilePath, thumbJpegEncoder, thumbJpegEncoderParameters);
            });

            return(recipes);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Use a combination of file reading and reflection to get fields and source code for all recipes
        /// </summary>
        public List <(string id, string title, string description, string source)> GetRecipeSources(string sourcePath)
        {
            sourcePath = Path.GetFullPath(sourcePath);
            if (!File.Exists(Path.Combine(sourcePath, "IRecipe.cs")))
            {
                throw new ArgumentException("IRecipe.cs can not be found in the given source colder");
            }

            var sources = new List <(string id, string title, string description, string source)>();

            string[] projectCsFiles = Directory.GetFiles(sourcePath, "*.cs", SearchOption.AllDirectories);
            foreach (string csFilePath in projectCsFiles)
            {
                string sourceCode = File.ReadAllText(csFilePath);

                // ensure the source code is not from this file
                if (Path.GetFileName(csFilePath) == "Chef.cs")
                {
                    continue;
                }

                // ensure the start of the recipe is in the file
                string recipeStart = ": IRecipe";
                if (!sourceCode.Contains(recipeStart))
                {
                    continue;
                }

                // isolate individual recipes from files with multiple recipes
                string[] sourceCodeByClass = sourceCode.Split(
                    separator: new string[] { recipeStart },
                    options: StringSplitOptions.RemoveEmptyEntries)
                                             .Skip(1)
                                             .ToArray();

                foreach (string singleClassSourceCode in sourceCodeByClass)
                {
                    // ensure functions are at the correct indentation level
                    int    executionMethodCount = Regex.Matches(singleClassSourceCode, ExecutionMethod).Count;
                    string indentedMethod       = "\n        " + ExecutionMethod;
                    int    indentedMethodCount  = Regex.Matches(singleClassSourceCode, indentedMethod).Count;
                    if (executionMethodCount != indentedMethodCount)
                    {
                        throw new InvalidOperationException($"Source code parsing error in: {csFilePath}\n\n" +
                                                            "This is typically caused by an error in indentation and whitespace before '{ExecutionMethod}'.\n\n" +
                                                            "Ensure cookbook classes are standalone classes not encased by another class.");
                    }

                    // read the file's source code for primary recipe components
                    string  id     = GetRecipeID(singleClassSourceCode);
                    IRecipe recipe = Locate.GetRecipe(id);
                    string  source = $"var plt = new ScottPlot.Plot({Width}, {Height});\n\n" +
                                     GetRecipeSource(singleClassSourceCode, csFilePath) + "\n\n" +
                                     $"plt.SaveFig(\"{id}{Ext}\");";

                    sources.Add((recipe.ID, recipe.Title, recipe.Description, source));
                }
            }

            return(sources);
        }