├── .gitignore
├── BuildShell.ps1
├── LICENSE
├── README.md
└── src
├── Core
├── Amount.cs
├── AuthIdentity.cs
├── Categorization
│ ├── Analyzer.cs
│ ├── AnalyzerResult.cs
│ ├── CategorizationEngine.cs
│ ├── CategorizationResult.cs
│ ├── Enums.cs
│ ├── IDBLoader.cs
│ ├── IIngredientCommonality.cs
│ ├── IRecipeClassification.cs
│ ├── IToken.cs
│ ├── IngredientToken.cs
│ ├── Ranking.cs
│ ├── RecipeIndex.cs
│ ├── TextToken.cs
│ ├── TimeToken.cs
│ └── Tokenizer.cs
├── Context
│ ├── AlphaTree.cs
│ ├── Configuration.cs
│ ├── ConfigurationBuilder.cs
│ ├── ConnectorVertex.cs
│ ├── DBContext.cs
│ ├── DBContextBuilder.cs
│ ├── DBModelerLoader.cs
│ ├── IConfiguration.cs
│ ├── IConfigurationBuilder.cs
│ ├── IDBAdapter.cs
│ ├── IKPCContext.cs
│ ├── ISearchProvider.cs
│ ├── IngredientNode.cs
│ ├── IngredientParser.cs
│ ├── IngredientSource.cs
│ ├── KPCContext.cs
│ ├── StaticAnomalyLoader.cs
│ ├── StaticContext.cs
│ ├── StaticContextBuilder.cs
│ ├── StaticFormLoader.cs
│ ├── StaticIngredientLoader.cs
│ ├── StaticModelerLoader.cs
│ ├── StaticPrepLoader.cs
│ ├── StaticSearch.cs
│ └── StaticUnitLoader.cs
├── Core.csproj
├── Enums.cs
├── Exceptions.cs
├── Extensions.cs
├── Fluent
│ ├── Menus.cs
│ ├── Modeler.cs
│ ├── Queue.cs
│ ├── Recipes.cs
│ └── ShoppingLists.cs
├── FormConversion.cs
├── Fractions.cs
├── Ingredients
│ ├── Ingredient.cs
│ ├── IngredientAggregation.cs
│ ├── IngredientForm.cs
│ ├── IngredientFormsCollection.cs
│ ├── IngredientMetadata.cs
│ ├── IngredientSection.cs
│ ├── IngredientUsage.cs
│ └── IngredientUsageCollection.cs
├── Linq
│ └── Enumerable.cs
├── Menus
│ ├── GetMenuOptions.cs
│ ├── Menu.cs
│ ├── MenuMove.cs
│ └── MenuResult.cs
├── Modeler
│ ├── CompiledModel.cs
│ ├── DBSnapshot.cs
│ ├── IModelerLoader.cs
│ ├── IUserProfile.cs
│ ├── IngredientBinding.cs
│ ├── IngredientNode.cs
│ ├── IngredientUsage.cs
│ ├── Model.cs
│ ├── ModelerProxy.cs
│ ├── ModelerQuery.cs
│ ├── ModelingSession.cs
│ ├── PantryItem.cs
│ ├── RatingBinding.cs
│ ├── RatingGraph.cs
│ ├── RecipeBinding.cs
│ ├── RecipeNode.cs
│ ├── RecipeRating.cs
│ ├── SuggestedRecipe.cs
│ └── UserProfile.cs
├── NLP
│ ├── AlphaTree.cs
│ ├── Anomalies.cs
│ ├── AnomalousIngredientNode.cs
│ ├── AnomalousMatch.cs
│ ├── AnomalousNode.cs
│ ├── ConnectorVertex.cs
│ ├── CustomUnitNode.cs
│ ├── DefaultPairings.cs
│ ├── DefaultTracer.cs
│ ├── Enums.cs
│ ├── FormNode.cs
│ ├── FormSynonyms.cs
│ ├── IGrammar.cs
│ ├── ISynonymLoader.cs
│ ├── ITracer.cs
│ ├── IngredientNode.cs
│ ├── IngredientSynonyms.cs
│ ├── Match.cs
│ ├── MatchData.cs
│ ├── NameIngredientPair.cs
│ ├── NlpTracer.cs
│ ├── NoMatch.cs
│ ├── NumericNode.cs
│ ├── NumericVocab.cs
│ ├── Pairings.cs
│ ├── Parser.cs
│ ├── PartialMatch.cs
│ ├── PrepNode.cs
│ ├── PrepNotes.cs
│ ├── Preps.cs
│ ├── Result.cs
│ ├── SynonymTree.cs
│ ├── Template.cs
│ ├── TemplateStatistics.cs
│ ├── Tokens
│ │ ├── AmtToken.cs
│ │ ├── AnomToken.cs
│ │ ├── FormToken.cs
│ │ ├── IngToken.cs
│ │ ├── NumericToken.cs
│ │ ├── PrepToken.cs
│ │ ├── StaticToken.cs
│ │ └── UnitToken.cs
│ ├── UnitNode.cs
│ └── UnitSynonyms.cs
├── Properties
│ └── AssemblyInfo.cs
├── Provisioning
│ ├── DTO
│ │ ├── Favorites.cs
│ │ ├── IngredientForms.cs
│ │ ├── IngredientMetadata.cs
│ │ ├── Ingredients.cs
│ │ ├── Menus.cs
│ │ ├── NlpAnomalousIngredients.cs
│ │ ├── NlpDefaultPairings.cs
│ │ ├── NlpFormSynonyms.cs
│ │ ├── NlpIngredientSynonyms.cs
│ │ ├── NlpPrepNotes.cs
│ │ ├── NlpUnitSynonyms.cs
│ │ ├── QueuedRecipes.cs
│ │ ├── RecipeData.cs
│ │ ├── RecipeIngredients.cs
│ │ ├── RecipeMetadata.cs
│ │ ├── RecipeRatings.cs
│ │ ├── Recipes.cs
│ │ ├── ShoppingListItems.cs
│ │ └── ShoppingLists.cs
│ ├── DataStore.cs
│ ├── IProvisionSource.cs
│ ├── IProvisionTarget.cs
│ └── IProvisioner.cs
├── Recipes
│ ├── Enums.cs
│ ├── ReadRecipeOptions.cs
│ ├── Recipe.cs
│ ├── RecipeBrief.cs
│ ├── RecipeQuery.cs
│ ├── RecipeResult.cs
│ ├── RecipeTag.cs
│ ├── RecipeTags.cs
│ └── SearchResults.cs
├── ShoppingLists
│ ├── Enums.cs
│ ├── GetShoppingListOptions.cs
│ ├── IShoppingListSource.cs
│ ├── ShoppingList.cs
│ ├── ShoppingListItem.cs
│ ├── ShoppingListModification.cs
│ ├── ShoppingListResult.cs
│ └── ShoppingListUpdateCommand.cs
├── Unit.cs
├── UnitConverter.cs
├── Weight.cs
└── packages.config
├── DB
├── DB.csproj
├── DatabaseAdapter.cs
├── DatabaseAdapterBuilder.cs
├── DatabaseExporter.cs
├── DatabaseImporter.cs
├── EnumMapper.cs
├── Models
│ ├── Favorites.cs
│ ├── IngredientForms.cs
│ ├── IngredientMetadata.cs
│ ├── Ingredients.cs
│ ├── Menus.cs
│ ├── NlpAnomalousIngredients.cs
│ ├── NlpDefaultPairings.cs
│ ├── NlpFormSynonyms.cs
│ ├── NlpIngredientSynonyms.cs
│ ├── NlpPrepNotes.cs
│ ├── NlpUnitSynonyms.cs
│ ├── QueuedRecipes.cs
│ ├── RecipeIngredients.cs
│ ├── RecipeMetadata.cs
│ ├── RecipeRatings.cs
│ ├── Recipes.cs
│ ├── ShoppingListItems.cs
│ └── ShoppingLists.cs
├── NHSearch.cs
├── NLP
│ ├── AnomalyLoader.cs
│ ├── FormLoader.cs
│ ├── IngredientGraphTransformer.cs
│ ├── IngredientLoader.cs
│ ├── PrepLoader.cs
│ └── UnitLoader.cs
├── Properties
│ └── AssemblyInfo.cs
└── packages.config
├── KitchenPC.sln
├── SampleData
└── KPCData.xml
├── UnitTests
├── Categorization.cs
├── Mock
│ ├── Forms.cs
│ ├── Ingredients.cs
│ ├── MockContext.cs
│ ├── MockImpossibleFilterUserProfile.cs
│ ├── MockImpossiblePantryUserProfile.cs
│ ├── MockModelerDBLoader.cs
│ ├── MockNoRatingsUserProfile.cs
│ ├── MockNormalUserProfile.cs
│ └── Recipes.cs
├── Modeler.cs
├── ModelerData.xml
├── NLP.cs
├── Properties
│ └── AssemblyInfo.cs
├── Tags.cs
├── TestFormLoader.cs
├── TestIngredientLoader.cs
├── TestPrepLoader.cs
├── TestUnitLoader.cs
├── UnitConverter.cs
├── UnitTests.csproj
├── Units.cs
└── packages.config
├── build.xml
└── packages
├── FluentNHibernate.2.0.3.0
├── FluentNHibernate.2.0.3.0.nupkg
├── FluentNHibernate.2.0.3.0.nuspec
└── lib
│ └── net40
│ ├── FluentNHibernate.XML
│ ├── FluentNHibernate.dll
│ └── FluentNHibernate.pdb
├── Iesi.Collections.4.0.1.4000
├── Iesi.Collections.4.0.1.4000.nupkg
├── Iesi.Collections.4.0.1.4000.nuspec
└── lib
│ └── net40
│ ├── Iesi.Collections.dll
│ └── Iesi.Collections.xml
├── NHibernate.4.0.4.4000
├── ConfigurationTemplates
│ ├── FireBird.cfg.xml
│ ├── MSSQL.cfg.xml
│ ├── MySql.cfg.xml
│ ├── Oracle.cfg.xml
│ ├── PostgreSQL.cfg.xml
│ ├── SQLite.cfg.xml
│ ├── SybaseASE.cfg.xml
│ └── SybaseSQLAnywhere.cfg.xml
├── NHibernate.4.0.4.4000.nupkg
├── NHibernate.4.0.4.4000.nuspec
├── NHibernate.license.txt
├── NHibernate.readme.html
├── NHibernate.releasenotes.txt
├── lib
│ └── net40
│ │ ├── NHibernate.dll
│ │ └── NHibernate.xml
├── nhibernate-configuration.xsd
└── nhibernate-mapping.xsd
├── NUnit.3.4.1
├── CHANGES.txt
├── LICENSE.txt
├── NOTICES.txt
├── NUnit.3.4.1.nupkg
├── NUnit.3.4.1.nuspec
└── lib
│ ├── dotnet
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
│ ├── net20
│ ├── NUnit.System.Linq.dll
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
│ ├── net35
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
│ ├── net40
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
│ ├── net45
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
│ └── portable-net45+win8+wp8+wpa81+Xamarin.Mac+MonoAndroid10+MonoTouch10+Xamarin.iOS10
│ ├── nunit.framework.dll
│ └── nunit.framework.xml
├── Npgsql.3.1.7
├── Npgsql.3.1.7.nupkg
├── Npgsql.3.1.7.nuspec
└── lib
│ ├── net45
│ ├── Npgsql.dll
│ └── Npgsql.xml
│ ├── net451
│ ├── Npgsql.dll
│ └── Npgsql.xml
│ └── netstandard1.3
│ ├── Npgsql.dll
│ └── Npgsql.xml
├── log4net.2.0.5
├── lib
│ ├── net10-full
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ ├── net11-full
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ ├── net20-full
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ ├── net35-client
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ ├── net35-full
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ ├── net40-client
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ ├── net40-full
│ │ ├── log4net.dll
│ │ └── log4net.xml
│ └── net45-full
│ │ ├── log4net.dll
│ │ └── log4net.xml
├── log4net.2.0.5.nupkg
└── log4net.2.0.5.nuspec
└── repositories.config
/.gitignore:
--------------------------------------------------------------------------------
1 | src/Core/bin/
2 | src/Core/obj/
3 | src/DB/bin/
4 | src/DB/obj/
5 | src/UnitTests/bin/
6 | src/UnitTests/obj/
7 | *.suo
--------------------------------------------------------------------------------
/BuildShell.ps1:
--------------------------------------------------------------------------------
1 | # KitchenPC Dev Shell setup
2 |
3 | # To use, add the following programs to your system path:
4 | # msbuild.exe (Provided with the .NET Framework)
5 | # nunit-console.exe (Available at http://nunit.org/)
6 |
7 | # Optionally, add the following shortcut to your quick launch or start menu:
8 | # %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -noexit -file "c:\KitchenPC\BuildShell.ps1" "C:\KitchenPC"
9 | # You can substitute C:\KitchenPC with the path to your KitchenPC enlistment.
10 |
11 | param([String]$enlistment="C:\KitchenPC\")
12 | Write-Host "Initializing KitchenPC Dev Shell, Please Wait..." -NoNewLine
13 | $host.ui.RawUI.WindowTitle = "KitchenPC Dev Shell"
14 |
15 | New-PSDrive -name kpc -PSProvider FileSystem -root $enlistment >$null
16 | Set-Alias vs "kpc:\src\KitchenPC.sln"
17 |
18 | function cd..
19 | {
20 | Set-Location ..
21 | }
22 |
23 | function cd\
24 | {
25 | Set-Location \
26 | }
27 |
28 | function Guid
29 | {
30 | Write-Host ([System.Guid]::NewGuid().ToString())
31 | }
32 |
33 | function Test
34 | {
35 | $testpath = Convert-Path('kpc:\src\UnitTests\bin\Debug\')
36 | nunit-console.exe ($testpath + "KitchenPC.UnitTests.dll")
37 | }
38 |
39 | function Build
40 | {
41 | if ($args.Count -gt 0)
42 | {
43 | switch ($args[0].ToUpper())
44 | {
45 | "DEBUG" { msbuild .\build.xml /t:Build /p:Configuration=Debug /verbosity:minimal }
46 | "RELEASE" { msbuild .\build.xml /t:Build /p:Configuration=Release /verbosity:minimal }
47 | }
48 | }
49 | else
50 | {
51 | msbuild .\build.xml /t:Build /p:Configuration=Debug /verbosity:minimal
52 | }
53 | }
54 |
55 | function Clean
56 | {
57 | msbuild .\build.xml /t:Clean
58 | }
59 |
60 | #Set default location
61 | Set-Location kpc:\src\
62 | Write-Host " Done.`n`n"
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 KitchenPC
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | What is KitchenPC?
2 | ====
3 |
4 | KitchenPC is a free, open-source framework written in C# for working with recipes, shopping lists, and menus. It provides a standardized data model for representing normalized ingredient and recipe information, and allows ingredient usage to be aggregated across recipes automatically. The core KitchenPC framework includes:
5 |
6 | 1. Base classes for describing and working with core recipe-related concepts.
7 | 2. A **recipe modeling engine** capable of building sets of recipes that efficiently use a set of ingredients and amounts.
8 | 3. A **natural language parser** which can convert human input ("a dozen eggs") to a normalized ingredient usage structure (whole eggs: 12)
9 | 4. A **categorization engine** which can take recipe objects and catagorize them as breakfast, lunch, dinner or dessert. This engine can also derive nutrional information based on USDA data, a taste profile (sweet, savory, spicy, mild) based on ingredients and amounts used, dietary flags (vegetarian, gluten-free, low-calorie, etc) and other aspects of the recipe.
10 | 5. An extensible framework to define how data is loaded and saved to a persistence mechanism, such as a SQL database or full-text search engine.
11 |
12 | How To Get Started
13 | ====
14 |
15 | Getting started is simple, and data can be loaded locally from an XML file for testing. Sample data is included with the source, which includes a few dozen recipes, along with sample menus and shopping lists.
16 |
17 | The best way to get up and running is to read the blog post titled [Getting Started with KitchenPC](http://blog.kitchenpc.com/2014/02/10/getting-started-with-kitchenpc/) which includes an introduction to core concepts as well as several samples.
18 |
19 | 1. [Getting Started](http://blog.kitchenpc.com/2014/02/10/getting-started-with-kitchenpc/)
20 | 2. [Provisioning a Database](http://blog.kitchenpc.com/2014/02/11/kitchenpc-database-provisioning-101/)
21 | 3. [Logging](http://blog.kitchenpc.com/2014/02/13/kitchenpc-logging-101/)
22 | 4. [Creating a Recipe](http://blog.kitchenpc.com/2014/02/14/lets-make-a-recipe/)
23 |
--------------------------------------------------------------------------------
/src/Core/AuthIdentity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Security.Cryptography;
4 | using System.Security.Principal;
5 | using System.Text;
6 |
7 | namespace KitchenPC
8 | {
9 | /// Represents a user identity within a KitchenPC context. This identity can be stored locally or within the KitchenPC network.
10 | public class AuthIdentity : IIdentity
11 | {
12 | public Guid UserId { get; private set; }
13 | public string Name { get; private set; }
14 |
15 | public AuthIdentity()
16 | {
17 | }
18 |
19 | public AuthIdentity(Guid id, string name)
20 | {
21 | UserId = id;
22 | Name = name;
23 | }
24 |
25 | public string AuthenticationType
26 | {
27 | get
28 | {
29 | return "KPCAuth";
30 | }
31 | }
32 |
33 | public bool IsAuthenticated
34 | {
35 | get
36 | {
37 | return UserId != Guid.Empty;
38 | }
39 | }
40 |
41 | public static string CreateHash(string value)
42 | {
43 | var hasher = MD5.Create();
44 | var bytes = hasher.ComputeHash(Encoding.Unicode.GetBytes(value));
45 | return Convert.ToBase64String(bytes);
46 | }
47 |
48 | public override string ToString()
49 | {
50 | if (IsAuthenticated)
51 | {
52 | return String.Format("{0} ({1})", Name, UserId.ToString());
53 | }
54 | else
55 | {
56 | return "";
57 | }
58 | }
59 |
60 | public static Byte[] Serialize(AuthIdentity identity)
61 | {
62 | var g = identity.UserId.ToByteArray();
63 | var u = Encoding.UTF8.GetBytes(identity.Name);
64 |
65 | return g.Concat(u).ToArray();
66 | }
67 |
68 | public static AuthIdentity Deserialize(Byte[] bytes)
69 | {
70 | if (bytes.Length < 17)
71 | throw new ArgumentException("AuthIdentity must be at least 17 bytes.");
72 |
73 | var g = new byte[16];
74 | var u = new byte[bytes.Length - 16];
75 |
76 | Buffer.BlockCopy(bytes, 0, g, 0, 16);
77 | Buffer.BlockCopy(bytes, 16, u, 0, u.Length);
78 |
79 | return new AuthIdentity(
80 | new Guid(g),
81 | Encoding.UTF8.GetString(u));
82 | }
83 | }
84 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/AnalyzerResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Categorization
4 | {
5 | public class AnalyzerResult
6 | {
7 | public Category FirstPlace { get; private set; }
8 | public Category SecondPlace { get; private set; }
9 |
10 | public AnalyzerResult(Category first, Category second)
11 | {
12 | FirstPlace = first;
13 | SecondPlace = second;
14 | }
15 |
16 | public override string ToString()
17 | {
18 | return SecondPlace == Category.None ? FirstPlace.ToString()
19 | : String.Format("{0}/{1}", FirstPlace, SecondPlace);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/CategorizationResult.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Categorization
2 | {
3 | public class CategorizationResult
4 | {
5 | public bool Diet_GlutenFree;
6 | public bool Diet_NoAnimals;
7 | public bool Diet_NoMeat;
8 | public bool Diet_NoPork;
9 | public bool Diet_NoRedMeat;
10 | public bool Meal_Breakfast;
11 | public bool Meal_Dessert;
12 | public bool Meal_Dinner;
13 | public bool Meal_Lunch;
14 | public bool Nutrition_LowCalorie;
15 | public bool Nutrition_LowCarb;
16 | public bool Nutrition_LowFat;
17 | public bool Nutrition_LowSodium;
18 | public bool Nutrition_LowSugar;
19 | public short Nutrition_TotalCalories;
20 | public short Nutrition_TotalCarbs;
21 | public short Nutrition_TotalFat;
22 | public short Nutrition_TotalSodium;
23 | public short Nutrition_TotalSugar;
24 | public bool Skill_Easy;
25 | public bool Skill_Quick;
26 | public bool Skill_Common;
27 | public byte Taste_MildToSpicy;
28 | public byte Taste_SavoryToSweet;
29 | public float Commonality;
30 |
31 | public bool USDAMatch;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/Enums.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Categorization
2 | {
3 | public enum Category
4 | {
5 | None,
6 | Breakfast,
7 | Lunch,
8 | Dinner,
9 | Dessert
10 | };
11 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/IDBLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.Categorization
4 | {
5 | public interface IDBLoader
6 | {
7 | IEnumerable LoadCommonIngredients();
8 | IEnumerable LoadTrainingData();
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/IIngredientCommonality.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Categorization
4 | {
5 | public interface IIngredientCommonality
6 | {
7 | Guid IngredientId { get; }
8 | Single Commonality { get; }
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/IRecipeClassification.cs:
--------------------------------------------------------------------------------
1 | using KitchenPC.Recipes;
2 |
3 | namespace KitchenPC.Categorization
4 | {
5 | public interface IRecipeClassification
6 | {
7 | Recipe Recipe { get; }
8 |
9 | bool IsBreakfast { get; }
10 | bool IsLunch { get; }
11 | bool IsDinner { get; }
12 | bool IsDessert { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/IToken.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Categorization
2 | {
3 | public interface IToken
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/IngredientToken.cs:
--------------------------------------------------------------------------------
1 | using KitchenPC.Ingredients;
2 |
3 | namespace KitchenPC.Categorization
4 | {
5 | internal class IngredientToken : IToken
6 | {
7 | readonly Ingredient ing;
8 |
9 | public IngredientToken(Ingredient ing)
10 | {
11 | this.ing = ing;
12 | }
13 |
14 | public override bool Equals(object obj)
15 | {
16 | var t1 = obj as IngredientToken;
17 | return (t1 != null && t1.ing.Id.Equals(ing.Id));
18 | }
19 |
20 | public override int GetHashCode()
21 | {
22 | return ing.Id.GetHashCode();
23 | }
24 |
25 | public override string ToString()
26 | {
27 | return "[ING] - " + ing;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/Ranking.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Categorization
2 | {
3 | internal class Ranking
4 | {
5 | public float Score { get; set; }
6 | public Category Type { get; private set; }
7 |
8 | public Ranking(Category type)
9 | {
10 | this.Type = type;
11 | this.Score = 0f;
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/RecipeIndex.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.Categorization
6 | {
7 | public class RecipeIndex
8 | {
9 | readonly Dictionary index = new Dictionary();
10 |
11 | public int EntryCount
12 | {
13 | get
14 | {
15 | return index.Values.Sum();
16 | }
17 | }
18 |
19 | public int GetTokenCount(IToken token)
20 | {
21 | return index.ContainsKey(token) ? index[token] : 0;
22 | }
23 |
24 | public void Add(Recipe recipe)
25 | {
26 | var tokens = Tokenizer.Tokenize(recipe);
27 | foreach (var token in tokens)
28 | {
29 | if (index.ContainsKey(token))
30 | {
31 | index[token]++;
32 | }
33 | else
34 | {
35 | index.Add(token, 1);
36 | }
37 | }
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/TextToken.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Categorization
2 | {
3 | internal class TextToken : IToken
4 | {
5 | readonly string text;
6 |
7 | public TextToken(string text)
8 | {
9 | this.text = text.Trim().ToLower();
10 | }
11 |
12 | public override bool Equals(object obj)
13 | {
14 | var t1 = obj as TextToken;
15 | return (t1 != null && t1.text.Equals(text));
16 | }
17 |
18 | public override int GetHashCode()
19 | {
20 | return text.GetHashCode();
21 | }
22 |
23 | public override string ToString()
24 | {
25 | return text;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/TimeToken.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Categorization
2 | {
3 | internal class TimeToken : IToken
4 | {
5 | enum Classification
6 | {
7 | Quick,
8 | Medium,
9 | Long,
10 | SuperLong
11 | };
12 |
13 | readonly Classification classification;
14 |
15 | public TimeToken(int minutes)
16 | {
17 | if (minutes < 10) classification = Classification.Quick;
18 | else if (minutes < 30) classification = Classification.Medium;
19 | else if (minutes <= 60) classification = Classification.Long;
20 | else classification = Classification.SuperLong;
21 | }
22 |
23 | public override bool Equals(object obj)
24 | {
25 | var t1 = obj as TimeToken;
26 | return (t1 != null && t1.classification.Equals(classification));
27 | }
28 |
29 | public override int GetHashCode()
30 | {
31 | return classification.GetHashCode();
32 | }
33 |
34 | public override string ToString()
35 | {
36 | return classification.ToString();
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Core/Categorization/Tokenizer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text.RegularExpressions;
4 | using KitchenPC.Recipes;
5 |
6 | namespace KitchenPC.Categorization
7 | {
8 | //Takes a Recipe object and returns an enumeration of Token objects
9 | public static class Tokenizer
10 | {
11 | static readonly Regex valid = new Regex(@"[a-z]", RegexOptions.IgnoreCase); //All tokens have to have at least one letter in them
12 |
13 | static IEnumerable ParseText(string text)
14 | {
15 | var parts = Regex.Split(text, @"[^a-z0-9\'\$\-]", RegexOptions.IgnoreCase);
16 | return (from p in parts where valid.IsMatch(p) select new TextToken(p) as IToken);
17 | }
18 |
19 | public static IEnumerable Tokenize(Recipe recipe)
20 | {
21 | var tokens = new List();
22 | tokens.AddRange(ParseText(recipe.Title ?? ""));
23 | tokens.AddRange(ParseText(recipe.Description ?? ""));
24 | //tokens.AddRange(ParseText(recipe.Method ?? ""));
25 | //tokens.Add(new TimeToken(recipe.CookTime.GetValueOrDefault() + recipe.PrepTime.GetValueOrDefault()));
26 | tokens.AddRange(from i in recipe.Ingredients.NeverNull() select new IngredientToken(i.Ingredient) as IToken);
27 |
28 | return tokens;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Core/Context/AlphaTree.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Context
2 | {
3 | public class AlphaTree
4 | {
5 | public Node Head;
6 |
7 | public AlphaTree()
8 | {
9 | Head = new Node();
10 | }
11 |
12 | public class Node
13 | {
14 | readonly Node[] nodes;
15 | public ConnectorVertex connections;
16 |
17 | public Node()
18 | {
19 | nodes = new Node[26];
20 | }
21 |
22 | public Node AddLink(char c)
23 | {
24 | var index = c - 97;
25 | return (nodes[index] = new Node());
26 | }
27 |
28 | public bool HasLink(char c)
29 | {
30 | var index = c - 97;
31 | return (nodes[index] != null);
32 | }
33 |
34 | public Node GetLink(char c)
35 | {
36 | var index = c - 97;
37 | return nodes[index];
38 | }
39 |
40 | public void AddConnection(IngredientNode node)
41 | {
42 | if (connections == null)
43 | {
44 | connections = new ConnectorVertex();
45 | }
46 | else
47 | {
48 | if (connections.HasConnection(node))
49 | return;
50 | }
51 |
52 | connections.AddConnection(node);
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Core/Context/Configuration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | public class Configuration : IConfiguration where T : IKPCContext
6 | {
7 | readonly ConfigurationBuilder builder;
8 |
9 | public T Context { get; set; }
10 |
11 | public static ConfigurationBuilder Build
12 | {
13 | get
14 | {
15 | return new Configuration().builder;
16 | }
17 | }
18 |
19 | public static IConfiguration Xml
20 | {
21 | get
22 | {
23 | // TODO: Read local XML configuration and return ConfigurationBuilder
24 | throw new NotImplementedException();
25 | }
26 | }
27 |
28 | Configuration()
29 | {
30 | builder = new ConfigurationBuilder(this);
31 | }
32 |
33 | public T InitializeContext()
34 | {
35 | Context.Initialize();
36 | return Context;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Core/Context/ConfigurationBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Context
2 | {
3 | /// Fluent interface to create configuration objects
4 | public class ConfigurationBuilder : IConfigurationBuilder> where T : IKPCContext
5 | {
6 | readonly IConfiguration configuration;
7 |
8 | public ConfigurationBuilder(IConfiguration config)
9 | {
10 | configuration = config;
11 | }
12 |
13 | public ConfigurationBuilder Context(IConfigurationBuilder context)
14 | {
15 | configuration.Context = context.Create();
16 | return this;
17 | }
18 |
19 | public IConfiguration Create()
20 | {
21 | return configuration;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Core/Context/ConnectorVertex.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace KitchenPC.Context
5 | {
6 | public class ConnectorVertex
7 | {
8 | readonly List connections;
9 |
10 | public ConnectorVertex()
11 | {
12 | connections = new List();
13 | }
14 |
15 | public IEnumerable Connections
16 | {
17 | get
18 | {
19 | return connections.AsEnumerable();
20 | }
21 | }
22 |
23 | public void AddConnection(IngredientNode node)
24 | {
25 | connections.Add(node);
26 | }
27 |
28 | public bool HasConnection(IngredientNode node)
29 | {
30 | return connections.Contains(node);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Core/Context/DBContextBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | public class DBContextBuilder : IConfigurationBuilder
6 | {
7 | readonly DBContext context;
8 |
9 | public DBContextBuilder(DBContext context)
10 | {
11 | this.context = context;
12 | }
13 |
14 | public DBContextBuilder Adapter(IConfigurationBuilder adapter) where T : IDBAdapter
15 | {
16 | context.Adapter = adapter.Create();
17 | return this;
18 | }
19 |
20 | public DBContextBuilder Identity(Func getIdentity)
21 | {
22 | context.GetIdentity = getIdentity;
23 | return this;
24 | }
25 |
26 | public DBContext Create()
27 | {
28 | return context;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Core/Context/DBModelerLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using KitchenPC.Modeler;
3 |
4 | namespace KitchenPC.Context
5 | {
6 | public class DBModelerLoader : IModelerLoader
7 | {
8 | readonly IDBAdapter adapter;
9 | IEnumerable recipedata;
10 | IEnumerable ingredientdata;
11 | IEnumerable ratingdata;
12 |
13 | public DBModelerLoader(IDBAdapter adapter)
14 | {
15 | this.adapter = adapter;
16 | }
17 |
18 | public IEnumerable LoadRecipeGraph()
19 | {
20 | if (recipedata == null)
21 | recipedata = adapter.LoadRecipeGraph();
22 |
23 | return recipedata;
24 | }
25 |
26 | public IEnumerable LoadIngredientGraph()
27 | {
28 | if (ingredientdata == null)
29 | ingredientdata = adapter.LoadIngredientGraph();
30 |
31 | return ingredientdata;
32 | }
33 |
34 | public IEnumerable LoadRatingGraph()
35 | {
36 | if (ratingdata == null)
37 | ratingdata = adapter.LoadRatingGraph();
38 |
39 | return ratingdata;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Core/Context/IConfiguration.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Context
2 | {
3 | ///
4 | /// Implements an object which holds the configuration for a certain type of context.
5 | ///
6 | /// A type which implements IKPCContext
7 | public interface IConfiguration where T : IKPCContext
8 | {
9 | T Context { get; set; }
10 |
11 | T InitializeContext();
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Core/Context/IConfigurationBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Context
2 | {
3 | ///
4 | /// Implements an object which can build an IConfiguration for a certain type of context.
5 | ///
6 | /// A KitchenPC context type this builder will create a configuration for.
7 | public interface IConfigurationBuilder
8 | {
9 | T Create();
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/Context/ISearchProvider.cs:
--------------------------------------------------------------------------------
1 | using KitchenPC.Recipes;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | ///
6 | /// Provides a KitchenPC database adapter with a way to search for recipes based on a query.
7 | ///
8 | public interface ISearchProvider
9 | {
10 | SearchResults Search(AuthIdentity identity, RecipeQuery query);
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Context/IngredientNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | public class IngredientNode
6 | {
7 | public Guid Id;
8 | public string IngredientName;
9 | public int Popularity;
10 |
11 | public IngredientNode(Guid id, string name, int popularity)
12 | {
13 | Id = id;
14 | IngredientName = name;
15 | Popularity = popularity;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Core/Context/IngredientSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | public class IngredientSource
6 | {
7 | public Guid Id { get; private set; }
8 | public String DisplayName { get; private set; }
9 |
10 | public IngredientSource(Guid id, String displayname)
11 | {
12 | this.Id = id;
13 | this.DisplayName = displayname;
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Core/Context/KPCContext.cs:
--------------------------------------------------------------------------------
1 | using log4net;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | public static class KPCContext
6 | {
7 | public static IKPCContext Current { get; private set; }
8 | public static ILog Log = LogManager.GetLogger(typeof (KPCContext));
9 |
10 | ///
11 | /// Initializes a given KitchenPC context. After calling this method, KPCContext.Current will refer to that context.
12 | ///
13 | /// An instance of a KitchenPC context.
14 | public static void Initialize(IKPCContext context)
15 | {
16 | Log.InfoFormat("Initializing global KitchenPC Context of type {0}", context.GetType().Name);
17 |
18 | context.Initialize();
19 | Current = context;
20 | }
21 |
22 | ///
23 | /// Initializes a given KitchenPC context. After calling this method, KPCContext.Current will refer to that context.
24 | ///
25 | /// A type of KitchenPC context to initialize.
26 | /// A configuration able to build a context of the specified type. A configuration builder can be obtained using Configuration<T>.Build
27 | public static void Initialize(IConfiguration configuration) where T : IKPCContext
28 | {
29 | Initialize(configuration.Context);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Core/Context/StaticContextBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Context
4 | {
5 | public class StaticContextBuilder : IConfigurationBuilder
6 | {
7 | readonly StaticContext context;
8 |
9 | public StaticContextBuilder(StaticContext context)
10 | {
11 | this.context = context;
12 | }
13 |
14 | /// A path on the file system that contains a KitchenPC data file.
15 | public StaticContextBuilder DataDirectory(string path)
16 | {
17 | context.DataDirectory = path;
18 | return this;
19 | }
20 |
21 | /// Configures context to compress the store file on disk to save space.
22 | public StaticContextBuilder CompressedStore
23 | {
24 | get
25 | {
26 | context.CompressedStore = true;
27 | return this;
28 | }
29 | }
30 |
31 | public StaticContextBuilder Identity(Func getIdentity)
32 | {
33 | context.GetIdentity = getIdentity;
34 | return this;
35 | }
36 |
37 | public StaticContext Create()
38 | {
39 | return context;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Core/Context/StaticFormLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using KitchenPC.Data;
4 | using KitchenPC.Ingredients;
5 | using KitchenPC.NLP;
6 |
7 | namespace KitchenPC.Context
8 | {
9 | public class StaticFormLoader : ISynonymLoader
10 | {
11 | readonly DataStore store;
12 |
13 | public StaticFormLoader(DataStore store)
14 | {
15 | this.store = store;
16 | }
17 |
18 | public IEnumerable LoadSynonyms()
19 | {
20 | var formSyn = store.NlpFormSynonyms
21 | .OrderBy(p => p.Name)
22 | .Select(s => s.Name)
23 | .Distinct()
24 | .ToList();
25 |
26 | return new List(formSyn.Select(s => new FormNode(s)));
27 | }
28 |
29 | public Pairings LoadFormPairings()
30 | {
31 | var forms = store.GetIndexedIngredientForms();
32 | var formSyn = store.NlpFormSynonyms;
33 | var pairings = new Pairings();
34 |
35 | foreach (var syn in formSyn)
36 | {
37 | var f = forms[syn.FormId];
38 |
39 | var name = syn.Name;
40 | var ing = syn.IngredientId;
41 | var form = f.IngredientFormId;
42 | var convType = f.UnitType;
43 | var displayName = f.FormDisplayName;
44 | var unitName = f.UnitName;
45 | int convMultiplier = f.ConvMultiplier;
46 | var formAmt = f.FormAmount;
47 | var formUnit = f.FormUnit;
48 | var amount = new Amount(formAmt, formUnit);
49 |
50 | pairings.Add(
51 | new NameIngredientPair(name, ing),
52 | new IngredientForm(form, ing, convType, displayName, unitName, convMultiplier, amount));
53 | }
54 |
55 | return pairings;
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/src/Core/Context/StaticPrepLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using KitchenPC.Data;
5 | using KitchenPC.NLP;
6 |
7 | namespace KitchenPC.Context
8 | {
9 | public class StaticPrepLoader : ISynonymLoader
10 | {
11 | readonly DataStore store;
12 |
13 | public StaticPrepLoader(DataStore store)
14 | {
15 | this.store = store;
16 | }
17 |
18 | public IEnumerable LoadSynonyms()
19 | {
20 | var forms = store.NlpFormSynonyms.Select(p => p.Name);
21 | var preps = store.NlpPrepNotes.Select(p => p.Name);
22 |
23 | var ret = forms
24 | .Concat(preps)
25 | .Distinct()
26 | .Select(p => new PrepNode(p))
27 | .ToList();
28 |
29 | return ret;
30 | }
31 |
32 | public Pairings LoadFormPairings()
33 | {
34 | throw new NotImplementedException();
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Core/Context/StaticUnitLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using KitchenPC.Data;
4 | using KitchenPC.Ingredients;
5 | using KitchenPC.NLP;
6 |
7 | namespace KitchenPC.Context
8 | {
9 | public class StaticUnitLoader : ISynonymLoader
10 | {
11 | readonly DataStore store;
12 |
13 | public StaticUnitLoader(DataStore store)
14 | {
15 | this.store = store;
16 | }
17 |
18 | public IEnumerable LoadSynonyms()
19 | {
20 | var unitSyn = store.NlpUnitSynonyms
21 | .OrderBy(p => p.Name)
22 | .Select(p => p.Name)
23 | .Distinct()
24 | .ToList();
25 |
26 | return new List(unitSyn.Select(s => new CustomUnitNode(s)));
27 | }
28 |
29 | public Pairings LoadFormPairings()
30 | {
31 | var forms = store.GetIndexedIngredientForms();
32 | var unitSyn = store.NlpUnitSynonyms;
33 | var pairings = new Pairings();
34 |
35 | foreach (var syn in unitSyn)
36 | {
37 | var form = forms[syn.FormId];
38 |
39 | pairings.Add(new NameIngredientPair(
40 | syn.Name.Trim(),
41 | syn.IngredientId),
42 | new IngredientForm(
43 | form.IngredientFormId,
44 | form.IngredientId,
45 | form.UnitType,
46 | form.FormDisplayName,
47 | form.UnitName,
48 | form.ConvMultiplier,
49 | new Amount(form.FormAmount, form.FormUnit)));
50 | }
51 |
52 | return pairings;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Core/Enums.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC
2 | {
3 | public enum UnitType
4 | {
5 | Unit = 0,
6 | Volume = 1,
7 | Weight = 2
8 | }
9 |
10 | public enum Units
11 | {
12 | //Individual items
13 | Unit = 0,
14 |
15 | //Volume
16 | Teaspoon = 1,
17 | Tablespoon = 2,
18 | FluidOunce = 3,
19 | Cup = 4,
20 | Pint = 5,
21 | Quart = 6,
22 | Gallon = 7,
23 |
24 | //Weight
25 | Gram = 8,
26 | Ounce = 9,
27 | Pound = 10,
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/Ingredient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Ingredients
4 | {
5 | public class Ingredient
6 | {
7 | public Guid Id;
8 | public String Name;
9 | public UnitType ConversionType;
10 | public String UnitName;
11 | public Weight UnitWeight;
12 |
13 | public IngredientMetadata Metadata;
14 |
15 | public static Ingredient FromId(Guid ingredientId)
16 | {
17 | return new Ingredient
18 | {
19 | Id = ingredientId
20 | };
21 | }
22 |
23 | public Ingredient(Guid id, String name)
24 | {
25 | Id = id;
26 | Name = name;
27 | Metadata = new IngredientMetadata();
28 | }
29 |
30 | public Ingredient(Guid id, String name, IngredientMetadata metadata)
31 | {
32 | Id = id;
33 | Name = name;
34 | Metadata = metadata;
35 | }
36 |
37 | public Ingredient() : this(Guid.Empty, String.Empty)
38 | {
39 | }
40 |
41 | public override string ToString()
42 | {
43 | return Name;
44 | }
45 |
46 | public override bool Equals(object obj)
47 | {
48 | var i = obj as Ingredient;
49 | return (i != null && this.Id == i.Id);
50 | }
51 |
52 | public override int GetHashCode()
53 | {
54 | return Id.GetHashCode();
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/IngredientAggregation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.ShoppingLists;
3 |
4 | namespace KitchenPC.Ingredients
5 | {
6 | public class IngredientAggregation : IShoppingListSource
7 | {
8 | public Ingredient Ingredient;
9 | public Amount Amount;
10 |
11 | public IngredientAggregation(Ingredient ingredient)
12 | {
13 | this.Ingredient = ingredient;
14 |
15 | if (ingredient != null)
16 | {
17 | this.Amount = new Amount();
18 | this.Amount.Unit = Unit.GetDefaultUnitType(ingredient.ConversionType);
19 | }
20 | }
21 |
22 | public IngredientAggregation(Ingredient ingredient, Amount baseAmount)
23 | {
24 | this.Ingredient = ingredient;
25 | this.Amount = baseAmount;
26 | }
27 |
28 | public override string ToString()
29 | {
30 | if (Ingredient != null && Amount != null)
31 | return String.Format("{0}: {1}", Ingredient.Name, Amount);
32 |
33 | if (Ingredient != null)
34 | return Ingredient.Name;
35 |
36 | return String.Empty;
37 | }
38 |
39 | public virtual IngredientAggregation AddUsage(IngredientUsage ingredient)
40 | {
41 | if (ingredient.Ingredient.Id != this.Ingredient.Id)
42 | throw new ArgumentException("Can only call IngredientAggregation::AddUsage() on original ingredient.");
43 |
44 | //Calculate new total
45 | if (this.Amount.Unit == ingredient.Amount.Unit || UnitConverter.CanConvert(this.Amount.Unit, ingredient.Amount.Unit)) //Just add
46 | {
47 | this.Amount += ingredient.Amount;
48 | }
49 | else //Find a conversion path between Ingredient and Form
50 | {
51 | var amount = FormConversion.GetNativeAmountForUsage(this.Ingredient, ingredient);
52 | this.Amount += amount;
53 | }
54 |
55 | return this; // Allows AddUsage calls to be chained together
56 | }
57 |
58 | public virtual ShoppingListItem GetItem()
59 | {
60 | return new ShoppingListItem(Ingredient)
61 | {
62 | Amount = Amount
63 | };
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/IngredientForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Ingredients
4 | {
5 | public class IngredientForm
6 | {
7 | public Guid FormId;
8 | public Guid IngredientId;
9 | public Units FormUnitType;
10 | public string FormDisplayName;
11 | public string FormUnitName;
12 | public int ConversionMultiplier;
13 | public Amount FormAmount;
14 |
15 | public static IngredientForm FromId(Guid id)
16 | {
17 | return new IngredientForm
18 | {
19 | FormId = id
20 | };
21 | }
22 |
23 | public IngredientForm()
24 | {
25 | }
26 |
27 | public IngredientForm(Guid formid, Guid ingredientid, Units unittype, string displayname, string unitname, int convmultiplier, Amount amount)
28 | {
29 | FormId = formid;
30 | IngredientId = ingredientid;
31 | FormUnitType = unittype;
32 | FormDisplayName = displayname;
33 | FormUnitName = unitname;
34 | ConversionMultiplier = convmultiplier;
35 | FormAmount = amount;
36 | }
37 |
38 | public override string ToString()
39 | {
40 | return FormId.ToString();
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/IngredientFormsCollection.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.Ingredients
4 | {
5 | public class IngredientFormsCollection
6 | {
7 | readonly List _forms;
8 |
9 | public IngredientForm[] Forms
10 | {
11 | get
12 | {
13 | return _forms.ToArray();
14 | }
15 |
16 | set
17 | {
18 | _forms.Clear();
19 | foreach (var form in value)
20 | _forms.Add(form);
21 | }
22 | }
23 |
24 | public IngredientFormsCollection()
25 | {
26 | _forms = new List();
27 | }
28 |
29 | public IngredientFormsCollection(IEnumerable forms)
30 | {
31 | _forms = new List(forms);
32 | }
33 |
34 | public void AddForm(IngredientForm form)
35 | {
36 | _forms.Add(form);
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/IngredientMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Ingredients
2 | {
3 | public class IngredientMetadata
4 | {
5 | public bool? HasGluten;
6 | public bool? HasMeat;
7 | public bool? HasRedMeat;
8 | public bool? HasPork;
9 | public bool? HasAnimal;
10 | public short Spicy;
11 | public short Sweet;
12 | public float? FatPerUnit;
13 | public float? SugarPerUnit;
14 | public float? CaloriesPerUnit;
15 | public float? SodiumPerUnit;
16 | public float? CarbsPerUnit;
17 |
18 | public IngredientMetadata()
19 | {
20 | }
21 |
22 | public IngredientMetadata(bool? hasgluten, bool? hasmeat, bool? hasredmeat, bool? haspork, bool? hasanimal, byte spicy, byte sweet, float? fatperunit, float? sugarperunit, float? caloriesperunit, float? sodiumperunit, float? carbsperunit)
23 | {
24 | HasGluten = hasgluten;
25 | HasMeat = hasmeat;
26 | HasRedMeat = hasredmeat;
27 | HasPork = haspork;
28 | HasAnimal = hasanimal;
29 | Spicy = spicy;
30 | Sweet = sweet;
31 | FatPerUnit = fatperunit;
32 | SugarPerUnit = sugarperunit;
33 | CaloriesPerUnit = caloriesperunit;
34 | SodiumPerUnit = sodiumperunit;
35 | CarbsPerUnit = carbsperunit;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/IngredientSection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.Ingredients
6 | {
7 | public class IngredientSection
8 | {
9 | public string SectionName { get; private set; }
10 | public IngredientUsageCollection Ingredients { get; private set; }
11 |
12 | IngredientSection(string name)
13 | {
14 | SectionName = name;
15 | Ingredients = new IngredientUsageCollection();
16 | }
17 |
18 | public static IngredientSection[] GetSections(Recipe recipe)
19 | {
20 | //TODO: This code can probably be done in a LINQ expression, or more efficiently.
21 |
22 | var nullSection = new IngredientSection(null);
23 | var map = new Dictionary();
24 |
25 | foreach (var usage in recipe.Ingredients)
26 | {
27 | if (String.IsNullOrEmpty(usage.Section))
28 | {
29 | nullSection.Ingredients.Add(usage);
30 | }
31 | else
32 | {
33 | var sectionKey = usage.Section.ToLower();
34 |
35 | IngredientSection sectionList;
36 | if (map.TryGetValue(sectionKey, out sectionList))
37 | {
38 | sectionList.Ingredients.Add(usage);
39 | }
40 | else
41 | {
42 | sectionList = new IngredientSection(usage.Section);
43 | sectionList.Ingredients.Add(usage);
44 | map.Add(sectionKey, sectionList);
45 | }
46 | }
47 | }
48 |
49 | var ret = new List();
50 | if (nullSection.Ingredients.Count > 0)
51 | {
52 | ret.Add(nullSection);
53 | }
54 |
55 | ret.AddRange(map.Values);
56 |
57 | return ret.ToArray();
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Core/Ingredients/IngredientUsageCollection.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.Ingredients
4 | {
5 | public class IngredientUsageCollection : List
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/src/Core/Linq/Enumerable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace KitchenPC.Linq
6 | {
7 | /// Linq extensions for KitchenPC data types
8 | public static class Enumerable
9 | {
10 | public static Amount Sum(this IEnumerable source)
11 | {
12 | var total = new Amount();
13 |
14 | return source.Aggregate(total, (current, a) => current + a);
15 | }
16 |
17 | public static Amount Sum(this IEnumerable source, Func selector)
18 | {
19 | var total = new Amount();
20 |
21 | return source.Aggregate(total, (current, a) => (Amount) (current + selector(a)));
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Core/Menus/GetMenuOptions.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Menus
2 | {
3 | public class GetMenuOptions
4 | {
5 | public bool LoadRecipes;
6 |
7 | static readonly GetMenuOptions none = new GetMenuOptions();
8 | static readonly GetMenuOptions loaded = new GetMenuOptions {LoadRecipes = true};
9 |
10 | public static GetMenuOptions None
11 | {
12 | get
13 | {
14 | return none;
15 | }
16 | }
17 |
18 | public static GetMenuOptions WithRecipes
19 | {
20 | get
21 | {
22 | return loaded;
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Core/Menus/Menu.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Menus
5 | {
6 | public struct Menu
7 | {
8 | public Guid? Id;
9 | public String Title;
10 | public RecipeBrief[] Recipes; //Can be null
11 |
12 | public static Menu FromId(Guid menuId)
13 | {
14 | return new Menu(menuId, null);
15 | }
16 |
17 | static readonly Menu favorites = new Menu(null, "Favorites");
18 |
19 | public static Menu Favorites
20 | {
21 | get
22 | {
23 | return favorites;
24 | }
25 | }
26 |
27 | public Menu(Guid? id, String title)
28 | {
29 | Id = id;
30 | Title = title;
31 | Recipes = null;
32 | }
33 |
34 | public Menu(Menu menu)
35 | {
36 | Id = menu.Id;
37 | Title = menu.Title;
38 | Recipes = null;
39 |
40 | if (menu.Recipes != null)
41 | {
42 | Recipes = new RecipeBrief[menu.Recipes.Length];
43 | menu.Recipes.CopyTo(Recipes, 0);
44 | }
45 | }
46 |
47 | public override string ToString()
48 | {
49 | var count = (Recipes != null ? Recipes.Length : 0);
50 |
51 | return String.Format("{0} ({1} {2}",
52 | Title,
53 | count,
54 | count != 1 ? "recipes" : "recipe");
55 | }
56 |
57 | public override bool Equals(object obj)
58 | {
59 | if (false == (obj is Menu))
60 | return false;
61 |
62 | var menu = (Menu) obj;
63 | if (this.Id.HasValue || menu.Id.HasValue)
64 | return this.Id.Equals(menu.Id);
65 |
66 | return this.Title.Equals(menu.Title);
67 | }
68 |
69 | public override int GetHashCode()
70 | {
71 | return this.Id.HasValue ? this.Id.Value.GetHashCode() : this.Title.GetHashCode();
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/src/Core/Menus/MenuMove.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Menus
4 | {
5 | public class MenuMove
6 | {
7 | public Guid? TargetMenu { get; set; }
8 | public Guid[] RecipesToMove { get; set; }
9 | public bool MoveAll { get; set; }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/Menus/MenuResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Menus
4 | {
5 | public class MenuResult
6 | {
7 | public bool MenuCreated;
8 | public bool MenuUpdated;
9 |
10 | public Guid? NewMenuId;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/CompiledModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | ///
7 | /// A fully compiled result set from the modeler containing full recipe briefs and ingredient aggregation data.
8 | ///
9 | public class CompiledModel
10 | {
11 | static CompiledModel empty;
12 |
13 | public RecipeBrief[] Briefs;
14 | public Guid[] RecipeIds { get; set; }
15 | public PantryItem[] Pantry { get; set; }
16 | public SuggestedRecipe[] Recipes { get; set; }
17 |
18 | public int Count
19 | {
20 | get
21 | {
22 | return (Recipes == null ? 0 : Recipes.Length);
23 | }
24 | set
25 | {
26 | }
27 | }
28 |
29 | public static CompiledModel Empty
30 | {
31 | get
32 | {
33 | if (empty == null)
34 | {
35 | empty = new CompiledModel()
36 | {
37 | Briefs = new RecipeBrief[0],
38 | Pantry = new PantryItem[0],
39 | RecipeIds = new Guid[0],
40 | Recipes = new SuggestedRecipe[0]
41 | };
42 | }
43 |
44 | return empty;
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/IModelerLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.Modeler
4 | {
5 | public interface IModelerLoader
6 | {
7 | IEnumerable LoadRecipeGraph();
8 | IEnumerable LoadIngredientGraph();
9 | IEnumerable LoadRatingGraph();
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/IUserProfile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | ///
7 | /// Interface used to transfer user specific runtime properties into the modeler. KPC will be implementation that builds
8 | /// this information from the database, and unit tests will create static instances for testing.
9 | ///
10 | public interface IUserProfile
11 | {
12 | Guid UserId { get; } //DB User ID
13 | RecipeRating[] Ratings { get; } //Every recipe ID user has rated with the rating
14 | PantryItem[] Pantry { get; } //Set of ingredients user has available with amounts
15 | Guid[] FavoriteIngredients { get; } //Ingredients to favor
16 | RecipeTags FavoriteTags { get; } //Tags to favor
17 | Guid[] BlacklistedIngredients { get; } //Ingredients to always avoid
18 | Guid? AvoidRecipe { get; }
19 | RecipeTags AllowedTags { get; } //Only allow recipes that contain at least one of these tags (null to allow all)
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/IngredientBinding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | public struct IngredientBinding
7 | {
8 | public Guid RecipeId { get; set; }
9 | public Guid IngredientId { get; set; }
10 | public Single? Qty { get; set; }
11 | public Units Unit { get; set; }
12 |
13 | public static IngredientBinding Create(Guid ingId, Guid recipeId, Single? qty, Units usageUnit, UnitType convType, Int32 unitWeight,
14 | Units formUnit, Single equivAmount, Units equivUnit)
15 | {
16 | var rawUnit = KitchenPC.Unit.GetDefaultUnitType(convType);
17 |
18 | if (qty.HasValue && rawUnit != usageUnit)
19 | {
20 | if (UnitConverter.CanConvert(usageUnit, rawUnit))
21 | {
22 | qty = UnitConverter.Convert(qty.Value, usageUnit, rawUnit);
23 | }
24 | else
25 | {
26 | var ing = new Ingredient
27 | {
28 | Id = ingId,
29 | ConversionType = convType,
30 | UnitWeight = unitWeight
31 | };
32 |
33 | var form = new IngredientForm
34 | {
35 | FormUnitType = formUnit,
36 | FormAmount = new Amount(equivAmount, equivUnit),
37 | IngredientId = ingId
38 | };
39 |
40 | var usage = new Ingredients.IngredientUsage
41 | {
42 | Form = form,
43 | Ingredient = ing,
44 | Amount = new Amount(qty.Value, usageUnit)
45 | };
46 |
47 | try
48 | {
49 | var newAmt = FormConversion.GetNativeAmountForUsage(ing, usage);
50 | qty = UnitConverter.Convert(newAmt.SizeHigh, newAmt.Unit, rawUnit); //Ingredient graph only stores high amounts
51 | }
52 | catch (Exception e)
53 | {
54 | throw new DataLoadException(e);
55 | }
56 | }
57 | }
58 |
59 | return new IngredientBinding
60 | {
61 | RecipeId = recipeId,
62 | IngredientId = ingId,
63 | Qty = qty.HasValue ? (float?) Math.Round(qty.Value, 3) : null,
64 | Unit = rawUnit
65 | };
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/IngredientNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.Modeler
6 | {
7 | public sealed class IngredientNode
8 | {
9 | public static int NextKey = 0;
10 |
11 | public Int32 Key; //Interally, ingredients will have numeric keys for faster hashing
12 | public Guid IngredientId; //KPC Shopping Ingredient ID
13 | public UnitType ConvType; //Conversion type for this ingredient
14 | public IEnumerable[] RecipesByTag; //Recipes that use this ingredient (does not include Hidden recipes)
15 | public RecipeTags AvailableTags; //Which indices in RecipesByTag are not null
16 |
17 | public IngredientNode()
18 | {
19 | this.Key = NextKey++;
20 | }
21 |
22 | public override int GetHashCode()
23 | {
24 | return Key;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/IngredientUsage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Modeler
4 | {
5 | public struct IngredientUsage
6 | {
7 | public IngredientNode Ingredient; //Reference to IngredientNode describing this ingredient
8 | public Single? Amt; //Amount of ingredient, expressed in default units for ingredient
9 | public Units Unit; //Unit for this amount (will always be compatible with Ingredient.ConvType)
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/Model.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | ///
7 | /// This contains a model generated by a modeling session. The RecipeIDs contain the suggested recipes to make, and the leftover amounts indicate
8 | /// the quantity of given ingredients that would be left in the user's pantry after making the suggested recipes.
9 | ///
10 | public class Model
11 | {
12 | readonly Guid[] _recipeids;
13 | readonly PantryItem[] _pantry;
14 | readonly double _score;
15 |
16 | public Guid[] RecipeIds
17 | {
18 | get
19 | {
20 | return _recipeids;
21 | }
22 | }
23 |
24 | public PantryItem[] Pantry
25 | {
26 | get
27 | {
28 | return _pantry;
29 | }
30 | }
31 |
32 | public int Count
33 | {
34 | get
35 | {
36 | return _recipeids.Length;
37 | }
38 | }
39 |
40 | public double Score
41 | {
42 | get
43 | {
44 | return _score;
45 | }
46 | }
47 |
48 | public Model(RecipeNode[] recipes, PantryItem[] pantry, double score)
49 | {
50 | this._recipeids = recipes.Select(r => { return r.RecipeId; }).ToArray();
51 | this._pantry = pantry;
52 | this._score = score;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/ModelerProxy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Context;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | public class ModelerProxy
7 | {
8 | DBSnapshot db;
9 | readonly IKPCContext context;
10 |
11 | public ModelerProxy(IKPCContext context)
12 | {
13 | this.context = context;
14 | }
15 |
16 | public void LoadSnapshot()
17 | {
18 | db = new DBSnapshot(context);
19 | }
20 |
21 | public ModelingSession CreateSession(IUserProfile profile)
22 | {
23 | if (db == null)
24 | throw new Exception("ModelerProxy has not been initialized.");
25 |
26 | return new ModelingSession(context, db, profile);
27 | }
28 |
29 | public RecipeNode FindRecipe(Guid id)
30 | {
31 | if (db == null)
32 | throw new Exception("ModelerProxy has not been initialized.");
33 |
34 | return db.FindRecipe(id);
35 | }
36 |
37 | public IngredientNode FindIngredient(Guid id)
38 | {
39 | if (db == null)
40 | throw new Exception("ModelerProxy has not been initialized.");
41 |
42 | return db.FindIngredient(id);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/ModelerQuery.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace KitchenPC.Modeler
6 | {
7 | ///
8 | /// Represents a query for the modeler, such as a list of ingredients, recipes to avoid, and a number of recipes to return.
9 | ///
10 | public class ModelerQuery
11 | {
12 | public string[] Ingredients; //User-entered ingredients to be parsed by NLP
13 | public Guid? AvoidRecipe; //Avoid specific recipe, useful for swapping out one recipe for another
14 | public byte NumRecipes;
15 | public byte Scale;
16 |
17 | public string CacheKey
18 | {
19 | get
20 | {
21 | var bytes = new List();
22 | bytes.Add(NumRecipes); //First byte is number of recipes
23 | bytes.Add(Scale); //Second byte is the scale
24 |
25 | if (AvoidRecipe.HasValue)
26 | bytes.AddRange(AvoidRecipe.Value.ToByteArray());
27 |
28 | //Remaining bytes are defined ingredients, delimited by null
29 | if (Ingredients != null && Ingredients.Length > 0)
30 | {
31 | foreach (var ing in Ingredients)
32 | {
33 | bytes.AddRange(Encoding.UTF8.GetBytes(ing.ToLower().Trim()));
34 | bytes.Add(0); //Null delimiter
35 | }
36 | }
37 |
38 | return Convert.ToBase64String(bytes.ToArray());
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/PantryItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Modeler
4 | {
5 | public struct PantryItem
6 | {
7 | public Guid IngredientId; //KPC Shopping Ingredient ID
8 | public Single? Amt; //Optional amount of ingredient, expressed in default units for ingredient
9 |
10 | public PantryItem(Ingredients.IngredientUsage usage)
11 | {
12 | IngredientId = usage.Ingredient.Id;
13 |
14 | //Need to convert IngredientUsage into proper Pantry form
15 | if (usage.Amount != null)
16 | {
17 | var toUnit = Unit.GetDefaultUnitType(usage.Ingredient.ConversionType);
18 | if (UnitConverter.CanConvert(usage.Form.FormUnitType, toUnit))
19 | {
20 | Amt = UnitConverter.Convert(usage.Amount, toUnit).SizeHigh; //Always take high amount for pantry items
21 | }
22 | else //Find conversion path
23 | {
24 | var amount = FormConversion.GetNativeAmountForUsage(usage.Ingredient, usage);
25 | Amt = UnitConverter.Convert(amount, toUnit).SizeHigh; //Always take high amount for pantry items
26 | }
27 | }
28 | else
29 | {
30 | Amt = null;
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/RatingBinding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Modeler
4 | {
5 | public struct RatingBinding
6 | {
7 | public Guid UserId { get; set; }
8 | public Guid RecipeId { get; set; }
9 | public Int16 Rating { get; set; }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/RecipeBinding.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | public struct RecipeBinding
7 | {
8 | public Guid Id { get; set; }
9 | public Byte Rating { get; set; }
10 | public RecipeTags Tags { get; set; }
11 | public Boolean Hidden { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/RecipeNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.Modeler
6 | {
7 | public sealed class RecipeNode
8 | {
9 | static int nextkey = 0;
10 |
11 | public Int32 Key; //Internally, recipes will have numeric keys for faster hashing
12 | public Guid RecipeId;
13 | public IEnumerable Ingredients;
14 | public RecipeTags Tags; //Tags from DB
15 | public Byte Rating; //Public rating from DB
16 | public Boolean Hidden; //Recipe is hidden (won't be picked at random)
17 | public RecipeNode[] Suggestions; //Users who like this recipe might also like these recipes (in order of weight)
18 |
19 | public RecipeNode()
20 | {
21 | this.Key = nextkey++;
22 | }
23 |
24 | public override int GetHashCode()
25 | {
26 | return Key;
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/RecipeRating.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Modeler
4 | {
5 | public struct RecipeRating
6 | {
7 | public Guid RecipeId;
8 | public Byte Rating;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/SuggestedRecipe.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | ///
7 | /// A recipe suggested by the modeler.
8 | ///
9 | public class SuggestedRecipe
10 | {
11 | public Guid Id { get; set; }
12 | public IngredientAggregation[] Ingredients { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Core/Modeler/UserProfile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Modeler
5 | {
6 | public class UserProfile : IUserProfile
7 | {
8 | static IUserProfile anonymous;
9 |
10 | ///
11 | /// Represents a modeling profile that has no user context, such as a saved pantry, favorite ingredients, blacklists, etc.
12 | ///
13 | public static IUserProfile Anonymous
14 | {
15 | get
16 | {
17 | if (anonymous == null)
18 | {
19 | anonymous = new UserProfile
20 | {
21 | UserId = Guid.Empty,
22 | Ratings = new RecipeRating[0],
23 | FavoriteIngredients = new Guid[0],
24 | FavoriteTags = RecipeTags.None,
25 | BlacklistedIngredients = new Guid[0]
26 | };
27 | }
28 |
29 | return anonymous;
30 | }
31 | }
32 |
33 | public Guid UserId { get; set; }
34 | public RecipeRating[] Ratings { get; set; }
35 | public PantryItem[] Pantry { get; set; }
36 | public Guid[] FavoriteIngredients { get; set; }
37 | public RecipeTags FavoriteTags { get; set; }
38 | public Guid[] BlacklistedIngredients { get; set; }
39 | public Guid? AvoidRecipe { get; set; }
40 | public RecipeTags AllowedTags { get; set; }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Core/NLP/AlphaTree.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class AlphaTree
4 | {
5 | public Node Head;
6 |
7 | public AlphaTree()
8 | {
9 | Head = new Node();
10 | }
11 |
12 | public class Node
13 | {
14 | public Node[] nodes;
15 | public ConnectorVertex connections;
16 |
17 | public Node()
18 | {
19 | nodes = new Node[94];
20 | }
21 |
22 | public Node AddLink(char c)
23 | {
24 | var index = c - 32;
25 | return (nodes[index] = new Node());
26 | }
27 |
28 | public bool HasLink(char c)
29 | {
30 | var index = c - 32;
31 | return (nodes[index] != null);
32 | }
33 |
34 | public Node GetLink(char c)
35 | {
36 | var index = c - 32;
37 | return nodes[index];
38 | }
39 |
40 | public void AddConnection(T node)
41 | {
42 | if (connections == null)
43 | {
44 | connections = new ConnectorVertex();
45 | }
46 | else
47 | {
48 | if (connections.HasConnection(node))
49 | return;
50 | }
51 |
52 | connections.AddConnection(node);
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Anomalies.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class Anomalies : SynonymTree
6 | {
7 | static readonly object MapInitLock = new object();
8 |
9 | public static void InitIndex(ISynonymLoader loader)
10 | {
11 | lock (MapInitLock)
12 | {
13 | index = new AlphaTree();
14 | synonymMap = new Dictionary();
15 | var anomalies = loader.LoadSynonyms();
16 |
17 | foreach (var anom in anomalies)
18 | {
19 | IndexString(anom.Name, anom);
20 | }
21 | }
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Core/NLP/AnomalousIngredientNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class AnomalousIngredientNode : IngredientNode
6 | {
7 | public AnomalousIngredientNode(Guid id, string name, UnitType convtype, Weight unitweight, DefaultPairings pairings) : base(id, name, convtype, unitweight, pairings)
8 | {
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/NLP/AnomalousMatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.NLP
5 | {
6 | public class AnomalousMatch : Match
7 | {
8 | readonly AnomalousResult anomaly;
9 |
10 | public AnomalousMatch(string input, AnomalousResult anomaly, IngredientUsage usage) : base(input, usage)
11 | {
12 | this.anomaly = anomaly;
13 | }
14 |
15 | public override string ToString()
16 | {
17 | return String.Format("[AnomalousMatch] ({0}) Usage: {1}", anomaly, usage);
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Core/NLP/AnomalousNode.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class AnomalousNode
4 | {
5 | public string Name;
6 | public AnomalousIngredientNode Ingredient;
7 |
8 | public AnomalousNode(string name, AnomalousIngredientNode ing)
9 | {
10 | Name = name;
11 | Ingredient = ing;
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Core/NLP/ConnectorVertex.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace KitchenPC.NLP
5 | {
6 | public class ConnectorVertex
7 | {
8 | readonly List connections;
9 |
10 | public ConnectorVertex()
11 | {
12 | connections = new List();
13 | }
14 |
15 | public void AddConnection(T node)
16 | {
17 | connections.Add(node);
18 | }
19 |
20 | public bool HasConnection(T node)
21 | {
22 | return connections.Contains(node);
23 | }
24 |
25 | public IEnumerable GetConnections()
26 | {
27 | var e = connections.GetEnumerator();
28 | while (e.MoveNext())
29 | {
30 | yield return e.Current;
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Core/NLP/CustomUnitNode.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class CustomUnitNode : UnitNode
4 | {
5 | public CustomUnitNode(string name) : base(name, Units.Unit)
6 | {
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Core/NLP/DefaultPairings.cs:
--------------------------------------------------------------------------------
1 | using KitchenPC.Ingredients;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public struct DefaultPairings
6 | {
7 | static readonly DefaultPairings empty = new DefaultPairings();
8 |
9 | public static DefaultPairings Empty
10 | {
11 | get
12 | {
13 | return empty;
14 | }
15 | }
16 |
17 | public IngredientForm Unit;
18 | public IngredientForm Volume;
19 | public IngredientForm Weight;
20 |
21 | public bool IsEmpty
22 | {
23 | get
24 | {
25 | return (Unit == null && Volume == null && Weight == null);
26 | }
27 | }
28 |
29 | public bool HasUnit
30 | {
31 | get
32 | {
33 | return Unit != null;
34 | }
35 | }
36 |
37 | public bool HasVolume
38 | {
39 | get
40 | {
41 | return Volume != null;
42 | }
43 | }
44 |
45 | public bool HasWeight
46 | {
47 | get
48 | {
49 | return Weight != null;
50 | }
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/Core/NLP/DefaultTracer.cs:
--------------------------------------------------------------------------------
1 | using log4net;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | /// Implementation of ITracer that uses Log4Net
6 | public class DefaultTracer : ITracer
7 | {
8 | readonly ILog log;
9 |
10 | public DefaultTracer()
11 | {
12 | log = LogManager.GetLogger(typeof (Parser));
13 | log.Info("Initialized logger for new NLP parser.");
14 | }
15 |
16 | public void Trace(TraceLevel level, string message, params object[] args)
17 | {
18 | switch (level)
19 | {
20 | case TraceLevel.Debug:
21 | log.DebugFormat(message, args);
22 | break;
23 | case TraceLevel.Error:
24 | log.ErrorFormat(message, args);
25 | break;
26 | case TraceLevel.Fatal:
27 | log.FatalFormat(message, args);
28 | break;
29 | case TraceLevel.Info:
30 | log.InfoFormat(message, args);
31 | break;
32 | case TraceLevel.Warn:
33 | log.WarnFormat(message, args);
34 | break;
35 | }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Enums.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public enum MatchPrecision
4 | {
5 | None,
6 | Partial,
7 | Exact
8 | };
9 |
10 | public enum MatchResult
11 | {
12 | NoMatch,
13 | UnknownUnit,
14 | NoForm,
15 | UnknownForm,
16 | IncompatibleForm,
17 | PartialMatch,
18 | Match
19 | }
20 |
21 | public enum AnomalousResult
22 | {
23 | Fallthrough,
24 | AutoConvert
25 | }
26 |
27 | public enum TraceLevel
28 | {
29 | Debug,
30 | Error,
31 | Info,
32 | Fatal,
33 | Warn
34 | }
35 | }
--------------------------------------------------------------------------------
/src/Core/NLP/FormNode.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class FormNode
4 | {
5 | public string FormName;
6 |
7 | public FormNode(string name)
8 | {
9 | FormName = name.Trim();
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/NLP/FormSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using KitchenPC.Ingredients;
4 |
5 | namespace KitchenPC.NLP
6 | {
7 | public class FormSynonyms : SynonymTree
8 | {
9 | static readonly object MapInitLock = new object();
10 | static Pairings pairings;
11 |
12 | public static void InitIndex(ISynonymLoader loader)
13 | {
14 | lock (MapInitLock)
15 | {
16 | index = new AlphaTree();
17 | synonymMap = new Dictionary();
18 |
19 | foreach (var form in loader.LoadSynonyms())
20 | {
21 | IndexString(form.FormName, form);
22 | }
23 |
24 | pairings = loader.LoadFormPairings();
25 | }
26 | }
27 |
28 | public static bool TryGetFormForIngredient(string formname, Guid ing, out IngredientForm form)
29 | {
30 | form = null;
31 | FormNode node;
32 | if (false == synonymMap.TryGetValue(formname, out node))
33 | {
34 | return false;
35 | }
36 |
37 | var pair = new NameIngredientPair(formname, ing);
38 | return pairings.TryGetValue(pair, out form);
39 | }
40 |
41 | public static bool TryGetFormForPrep(Preps preps, IngredientNode ing, bool remove, out IngredientForm form)
42 | {
43 | //TODO: Do we need to check all preps, or just the one that was on the input
44 | foreach (var prep in preps)
45 | {
46 | var fMatch = TryGetFormForIngredient(prep.Prep, ing.Id, out form);
47 | if (!fMatch) continue;
48 |
49 | if (remove)
50 | preps.Remove(prep);
51 |
52 | return true;
53 | }
54 |
55 | form = null;
56 | return false;
57 | }
58 | }
59 | }
--------------------------------------------------------------------------------
/src/Core/NLP/IGrammar.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public interface IGrammar
6 | {
7 | ///
8 | /// Reads stream of ingredient usage being parsed and modifies IngredientUsage as fit
9 | ///
10 | /// Stream containing input
11 | /// Usage to modify when data becomes known
12 | ///
13 | bool Read(Stream stream, MatchData usage);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Core/NLP/ISynonymLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public interface ISynonymLoader
6 | {
7 | IEnumerable LoadSynonyms();
8 | Pairings LoadFormPairings(); //Default pairing data for forms of certain ingredients
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Core/NLP/ITracer.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public interface ITracer
4 | {
5 | void Trace(TraceLevel level, string message, params object[] args);
6 | }
7 | }
--------------------------------------------------------------------------------
/src/Core/NLP/IngredientNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class IngredientNode
6 | {
7 | readonly IngredientNode parent; //This node can shadow another node under another name
8 | readonly Guid id;
9 | readonly DefaultPairings pairings;
10 | readonly UnitType convtype;
11 | readonly Weight unitweight;
12 |
13 | public Guid Id
14 | {
15 | get
16 | {
17 | return (parent == null) ? id : parent.id;
18 | }
19 | }
20 |
21 | public DefaultPairings Pairings
22 | {
23 | get
24 | {
25 | return (parent == null) ? pairings : parent.pairings;
26 | }
27 | }
28 |
29 | public IngredientNode Parent
30 | {
31 | get
32 | {
33 | return parent;
34 | }
35 | }
36 |
37 | public string IngredientName; //Name of the ingredient or synonym
38 | public string PrepNote; //If this ingredient is an alias for another, it will use this as a prep note, eg: Ripe Bananas => Bananas (Ripe)
39 |
40 | public UnitType ConversionType
41 | {
42 | get
43 | {
44 | return (parent == null) ? convtype : parent.convtype;
45 | }
46 | } //Default conversion type for this ingredient (from ShoppingIngredients)
47 |
48 | public Weight UnitWeight
49 | {
50 | get
51 | {
52 | return (parent == null) ? unitweight : parent.unitweight;
53 | }
54 | } //How much a single unit weighs (from ShoppingIngredients)
55 |
56 | public IngredientNode(Guid id, string name, UnitType convtype, Weight unitweight, DefaultPairings pairings)
57 | {
58 | this.id = id;
59 | this.pairings = pairings;
60 | this.convtype = convtype;
61 | this.unitweight = unitweight;
62 |
63 | IngredientName = name;
64 | }
65 |
66 | public IngredientNode(IngredientNode root, string synonym, string prepnote)
67 | {
68 | this.parent = root;
69 | IngredientName = synonym;
70 | PrepNote = prepnote;
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/src/Core/NLP/IngredientSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class IngredientSynonyms : SynonymTree
6 | {
7 | static readonly object MapInitLock = new object();
8 |
9 | public static void InitIndex(ISynonymLoader loader)
10 | {
11 | lock (MapInitLock)
12 | {
13 | index = new AlphaTree();
14 | synonymMap = new Dictionary();
15 | var ings = loader.LoadSynonyms();
16 |
17 | foreach (var ing in ings)
18 | {
19 | IndexString(ing.IngredientName, ing);
20 | }
21 | }
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Match.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.NLP
5 | {
6 | public class Match : Result
7 | {
8 | protected IngredientUsage usage;
9 |
10 | public override IngredientUsage Usage
11 | {
12 | get
13 | {
14 | return usage;
15 | }
16 | }
17 |
18 | public override MatchResult Status
19 | {
20 | get
21 | {
22 | return MatchResult.Match;
23 | }
24 | }
25 |
26 | public Match(string input, IngredientUsage usage) : base(input)
27 | {
28 | this.usage = usage;
29 | }
30 |
31 | public override string ToString()
32 | {
33 | return String.Format("[Match] Usage: {0}", usage);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Core/NLP/MatchData.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class MatchData
4 | {
5 | public IngredientNode Ingredient;
6 | public UnitNode Unit;
7 | public FormNode Form;
8 | public Amount Amount;
9 | public Preps Preps;
10 |
11 | public MatchData()
12 | {
13 | Preps = new Preps();
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Core/NLP/NameIngredientPair.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class NameIngredientPair
6 | {
7 | readonly int hash;
8 | public string Name { get; set; }
9 | public Guid IngredientId { get; set; }
10 |
11 | public NameIngredientPair(string name, Guid id)
12 | {
13 | this.Name = name;
14 | this.IngredientId = id;
15 | this.hash = (name + id.ToString()).GetHashCode();
16 | }
17 |
18 | public override int GetHashCode()
19 | {
20 | return this.hash;
21 | }
22 |
23 | public override bool Equals(object obj)
24 | {
25 | var pair = obj as NameIngredientPair;
26 |
27 | if (obj == null)
28 | return false;
29 |
30 | return (this.Name == pair.Name && this.IngredientId == pair.IngredientId);
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Core/NLP/NlpTracer.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public static class NlpTracer
4 | {
5 | static ITracer currentTracer;
6 |
7 | public static void SetTracer(ITracer tracer)
8 | {
9 | currentTracer = tracer; //BUGBUG: Not thread safe, but probably not tracing on the main site
10 | }
11 |
12 | public static void Trace(TraceLevel level, string message, params object[] args)
13 | {
14 | if (currentTracer == null) //No op
15 | {
16 | return;
17 | }
18 |
19 | currentTracer.Trace(level, message, args);
20 | }
21 |
22 | public static void ConditionalTrace(bool condition, TraceLevel level, string message, params object[] args)
23 | {
24 | if (condition)
25 | {
26 | Trace(level, message, args);
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Core/NLP/NoMatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class NoMatch : Result
6 | {
7 | readonly MatchResult status;
8 |
9 | public override MatchResult Status
10 | {
11 | get
12 | {
13 | return status;
14 | }
15 | }
16 |
17 | public NoMatch(string input, MatchResult status) : base(input)
18 | {
19 | this.status = status;
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return String.Format("[NoMatch] Error: {0}", status);
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Core/NLP/NumericNode.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class NumericNode
4 | {
5 | public string Token;
6 | public float Value;
7 |
8 | public NumericNode(string token, float value)
9 | {
10 | Token = token;
11 | Value = value;
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Core/NLP/NumericVocab.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class NumericVocab : SynonymTree
6 | {
7 | static readonly object MapInitLock = new object();
8 |
9 | public static void InitIndex()
10 | {
11 | lock (MapInitLock)
12 | {
13 | index = new AlphaTree();
14 | synonymMap = new Dictionary();
15 |
16 | //Basic numbers, we can add more if needed
17 | string[] numbers = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
18 | for (var i = 0; i < numbers.Length; i++)
19 | {
20 | IndexString(numbers[i], new NumericNode(numbers[i], i + 1));
21 | }
22 |
23 | //Other numeric tokens
24 | NumericNode[] tokens =
25 | {
26 | new NumericNode("a", 1),
27 | new NumericNode("an", 1),
28 | new NumericNode("half a", 0.5f),
29 | new NumericNode("half of a", 0.5f),
30 | new NumericNode("half an", 0.5f),
31 | new NumericNode("half of an", 0.5f),
32 | new NumericNode("a dozen", 12),
33 | new NumericNode("one dozen", 12),
34 | new NumericNode("a couple", 2),
35 | new NumericNode("a couple of", 2)
36 | };
37 |
38 | foreach (var t in tokens)
39 | {
40 | IndexString(t.Token, t);
41 | }
42 | }
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Pairings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.NLP
5 | {
6 | public class Pairings
7 | {
8 | readonly IDictionary pairs;
9 |
10 | public Pairings()
11 | {
12 | pairs = new Dictionary();
13 | }
14 |
15 | public void Add(NameIngredientPair key, IngredientForm value)
16 | {
17 | pairs.Add(key, value);
18 | }
19 |
20 | public bool ContainsKey(NameIngredientPair key)
21 | {
22 | return pairs.ContainsKey(key);
23 | }
24 |
25 | public bool TryGetValue(NameIngredientPair key, out IngredientForm value)
26 | {
27 | return pairs.TryGetValue(key, out value);
28 | }
29 |
30 | public IngredientForm this[NameIngredientPair key]
31 | {
32 | get
33 | {
34 | return pairs[key];
35 | }
36 | set
37 | {
38 | pairs[key] = value;
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Core/NLP/PartialMatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.NLP
5 | {
6 | public class PartialMatch : Match
7 | {
8 | public override MatchResult Status
9 | {
10 | get
11 | {
12 | return MatchResult.PartialMatch;
13 | }
14 | }
15 |
16 | public PartialMatch(string input, Ingredient ingredient, string prep) : base(input, null)
17 | {
18 | this.usage = new IngredientUsage(ingredient, null, null, prep);
19 | }
20 |
21 | public override string ToString()
22 | {
23 | if (String.IsNullOrEmpty(usage.PrepNote))
24 | return String.Format("[PartialMatch] Ingredient: {0}", usage.Ingredient.Name);
25 | else
26 | return String.Format("[PartialMatch] Ingredient: {0} ({1})", usage.Ingredient.Name, usage.PrepNote);
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Core/NLP/PrepNode.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.NLP
2 | {
3 | public class PrepNode
4 | {
5 | public string Prep;
6 |
7 | public PrepNode(string prep)
8 | {
9 | Prep = prep.ToLower().Trim();
10 | }
11 |
12 | public static implicit operator PrepNode(string p)
13 | {
14 | return new PrepNode(p);
15 | }
16 |
17 | public static implicit operator string(PrepNode p)
18 | {
19 | return p.Prep;
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return Prep;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Core/NLP/PrepNotes.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class PrepNotes : SynonymTree
6 | {
7 | static readonly object MapInitLock = new object();
8 |
9 | public static void InitIndex(ISynonymLoader loader)
10 | {
11 | lock (MapInitLock)
12 | {
13 | index = new AlphaTree();
14 | synonymMap = new Dictionary();
15 | var preps = loader.LoadSynonyms();
16 |
17 | foreach (var prep in preps)
18 | {
19 | IndexString(prep.Prep, prep);
20 | }
21 | }
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Preps.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace KitchenPC.NLP
7 | {
8 | public class Preps : IEnumerable
9 | {
10 | readonly List notes;
11 |
12 | public Preps()
13 | {
14 | notes = new List();
15 | }
16 |
17 | public bool HasValue
18 | {
19 | get
20 | {
21 | return notes.Count != 0;
22 | }
23 | }
24 |
25 | public void Add(PrepNode prep)
26 | {
27 | notes.Add(prep);
28 | }
29 |
30 | public void Remove(PrepNode node)
31 | {
32 | notes.Remove(node);
33 | }
34 |
35 | public override string ToString()
36 | {
37 | if (notes.Count == 0)
38 | {
39 | return String.Empty;
40 | }
41 |
42 | return String.Join("//", notes.Select(p => { return p.Prep; }).ToArray());
43 | }
44 |
45 | public IEnumerator GetEnumerator()
46 | {
47 | return notes.GetEnumerator();
48 | }
49 |
50 | IEnumerator IEnumerable.GetEnumerator()
51 | {
52 | return notes.GetEnumerator();
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Core/NLP/SynonymTree.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace KitchenPC.NLP
5 | {
6 | public abstract class SynonymTree
7 | {
8 | protected static AlphaTree index;
9 | protected static Dictionary synonymMap;
10 |
11 | protected static void IndexString(string value, T node)
12 | {
13 | var parsedIng = value.Trim().ToLower();
14 |
15 | if (synonymMap.ContainsKey(parsedIng)) //Uh oh
16 | {
17 | Parser.Log.Error(String.Format("The ingredient synonym '{0}' also exists as a root ingredient.", value));
18 | }
19 | else
20 | {
21 | synonymMap.Add(parsedIng, node);
22 | }
23 |
24 | var curNode = index.Head;
25 | for (var i = 0; i < parsedIng.Length; i++)
26 | {
27 | var c = parsedIng[i];
28 | if (curNode.HasLink(c) == false)
29 | {
30 | curNode = curNode.AddLink(c);
31 | }
32 | else
33 | {
34 | curNode = curNode.GetLink(c);
35 | }
36 |
37 | curNode.AddConnection(node);
38 | }
39 | }
40 |
41 | public MatchPrecision Parse(string substr, out T match)
42 | {
43 | substr = substr.TrimStart(' '); //Strip off any leading spaces, an empty string will always return "Partial" so processing will continue
44 |
45 | if (synonymMap.TryGetValue(substr, out match)) //If they pass in a complete ingredient name, return Exact
46 | {
47 | return MatchPrecision.Exact;
48 | }
49 |
50 | //Figure out if this is a partial match for an ingredient
51 | var node = index.Head;
52 |
53 | for (var i = 0; i < substr.Length; i++)
54 | {
55 | if (node.HasLink(substr[i]) == false) //No possible match here
56 | return MatchPrecision.None;
57 |
58 | node = node.GetLink(substr[i]);
59 | }
60 |
61 | //match = null;
62 | return MatchPrecision.Partial;
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/src/Core/NLP/TemplateStatistics.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | namespace KitchenPC.NLP
6 | {
7 | public class TemplateStatistics : IEnumerable
8 | {
9 | public struct TemplateUsage
10 | {
11 | public string Template;
12 | public int Matches;
13 |
14 | public override string ToString()
15 | {
16 | return String.Format("{0} ---> {1} matches\n", Template, Matches);
17 | }
18 | }
19 |
20 | readonly Dictionary stats;
21 |
22 | public int this[Template t]
23 | {
24 | get
25 | {
26 | return stats[t];
27 | }
28 | set
29 | {
30 | stats[t] = value;
31 | }
32 | }
33 |
34 | public TemplateStatistics()
35 | {
36 | stats = new Dictionary();
37 | }
38 |
39 | public void RecordTemplate(Template template)
40 | {
41 | stats[template] = 0;
42 | }
43 |
44 | public IEnumerator GetEnumerator()
45 | {
46 | var e = stats.GetEnumerator();
47 | while (e.MoveNext())
48 | {
49 | yield return new TemplateUsage() {Template = e.Current.Key.ToString(), Matches = e.Current.Value};
50 | }
51 | }
52 |
53 | IEnumerator IEnumerable.GetEnumerator()
54 | {
55 | var e = stats.GetEnumerator();
56 | while (e.MoveNext())
57 | {
58 | yield return new TemplateUsage() {Template = e.Current.Key.ToString(), Matches = e.Current.Value};
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/AnomToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace KitchenPC.NLP.Tokens
5 | {
6 | public class AnomToken : IGrammar
7 | {
8 | static Anomalies data;
9 |
10 | public bool Read(Stream stream, MatchData matchData)
11 | {
12 | if (data == null)
13 | {
14 | data = new Anomalies();
15 | }
16 |
17 | var buffer = String.Empty;
18 | AnomalousNode foundNode = null;
19 | var fFound = false;
20 | var matchPos = stream.Position;
21 | int curByte;
22 |
23 | while ((curByte = stream.ReadByte()) >= 0)
24 | {
25 | buffer += (char) curByte;
26 |
27 | AnomalousNode node;
28 | var match = data.Parse(buffer, out node);
29 | if (match == MatchPrecision.None)
30 | {
31 | break; //No reason to continue reading stream, let's see what we have..
32 | }
33 |
34 | if (match == MatchPrecision.Exact)
35 | {
36 | matchPos = stream.Position;
37 | foundNode = node;
38 | fFound = true;
39 | }
40 | }
41 |
42 | if (foundNode != null) //Initialize match data with values from this anomaly
43 | {
44 | matchData.Ingredient = foundNode.Ingredient;
45 | }
46 |
47 | stream.Seek(matchPos, SeekOrigin.Begin);
48 | return fFound;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/FormToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace KitchenPC.NLP.Tokens
5 | {
6 | public class FormToken : IGrammar
7 | {
8 | static FormSynonyms data;
9 |
10 | ///
11 | /// Reads stream to match it against a dictionary of all known forms
12 | ///
13 | ///
14 | ///
15 | ///
16 | public bool Read(Stream stream, MatchData matchdata)
17 | {
18 | if (data == null)
19 | {
20 | data = new FormSynonyms();
21 | }
22 |
23 | FormNode node;
24 | matchdata.Form = null;
25 | var buffer = String.Empty;
26 | var matchPos = stream.Position;
27 | int curByte;
28 |
29 | while ((curByte = stream.ReadByte()) >= 0)
30 | {
31 | buffer += (char) curByte;
32 | var match = data.Parse(buffer, out node);
33 | if (match == MatchPrecision.None)
34 | {
35 | break; //No reason to continue reading stream, let's see what we have..
36 | }
37 |
38 | if (match == MatchPrecision.Exact)
39 | {
40 | matchPos = stream.Position;
41 | matchdata.Form = node;
42 | }
43 | }
44 |
45 | stream.Seek(matchPos, SeekOrigin.Begin);
46 | return (matchdata.Form != null);
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/IngToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace KitchenPC.NLP.Tokens
5 | {
6 | public class IngToken : IGrammar
7 | {
8 | static IngredientSynonyms data;
9 |
10 | ///
11 | /// Reads stream to match it against a dictionary of all known ingredients and their aliases
12 | ///
13 | ///
14 | ///
15 | ///
16 | public bool Read(Stream stream, MatchData matchdata)
17 | {
18 | if (data == null)
19 | {
20 | data = new IngredientSynonyms();
21 | }
22 |
23 | IngredientNode node;
24 | matchdata.Ingredient = null;
25 | var buffer = String.Empty;
26 | var matchPos = stream.Position;
27 | int curByte;
28 |
29 | while ((curByte = stream.ReadByte()) >= 0)
30 | {
31 | buffer += (char) curByte;
32 | var match = data.Parse(buffer, out node);
33 | if (match == MatchPrecision.None)
34 | {
35 | break; //No reason to continue reading stream, let's see what we have..
36 | }
37 |
38 | if (match == MatchPrecision.Exact)
39 | {
40 | matchPos = stream.Position;
41 | matchdata.Ingredient = node;
42 | }
43 | }
44 |
45 | //Add any prep notes from this ingredient alias to the prep node collection
46 | if (matchdata.Ingredient != null && matchdata.Ingredient.PrepNote != null)
47 | {
48 | matchdata.Preps.Add(matchdata.Ingredient.PrepNote);
49 | }
50 |
51 | stream.Seek(matchPos, SeekOrigin.Begin);
52 | return (matchdata.Ingredient != null);
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/NumericToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace KitchenPC.NLP.Tokens
5 | {
6 | public class NumericToken : IGrammar
7 | {
8 | static NumericVocab data;
9 |
10 | ///
11 | /// Reads stream to match it against a dictionary of all known units for an ingredient
12 | ///
13 | ///
14 | ///
15 | ///
16 | public bool Read(Stream stream, MatchData matchdata)
17 | {
18 | if (data == null)
19 | {
20 | data = new NumericVocab();
21 | }
22 |
23 | NumericNode node;
24 | var fMatch = false;
25 | var buffer = String.Empty;
26 | var matchPos = stream.Position;
27 | int curByte;
28 |
29 | while ((curByte = stream.ReadByte()) >= 0)
30 | {
31 | buffer += (char) curByte;
32 | var match = data.Parse(buffer, out node);
33 | if (match == MatchPrecision.None)
34 | {
35 | stream.Seek(matchPos, SeekOrigin.Begin);
36 | break; //No reason to continue reading stream, let's see what we have..
37 | }
38 |
39 | if (match == MatchPrecision.Exact)
40 | {
41 | matchPos = stream.Position;
42 | fMatch = true;
43 | matchdata.Amount = new Amount();
44 | matchdata.Amount.SizeHigh = node.Value;
45 | }
46 | }
47 |
48 | return fMatch;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/PrepToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text.RegularExpressions;
4 |
5 | namespace KitchenPC.NLP.Tokens
6 | {
7 | public class PrepToken : IGrammar
8 | {
9 | static PrepNotes data;
10 |
11 | public bool Read(Stream stream, MatchData matchData)
12 | {
13 | if (data == null)
14 | {
15 | data = new PrepNotes();
16 | }
17 |
18 | var buffer = String.Empty;
19 | PrepNode foundPrep = null;
20 | var fFound = false;
21 | var matchPos = stream.Position;
22 | int curByte;
23 |
24 | while ((curByte = stream.ReadByte()) >= 0)
25 | {
26 | buffer += (char) curByte;
27 |
28 | //Prep tokens can have leading commas or parens - so trim these off
29 | buffer = Regex.Replace(buffer, @"^\s*(,|-|\()\s*", "");
30 | buffer = Regex.Replace(buffer, @"\s*\)\s*$", "");
31 |
32 | PrepNode node;
33 | var match = data.Parse(buffer, out node);
34 | if (match == MatchPrecision.None)
35 | {
36 | break; //No reason to continue reading stream, let's see what we have..
37 | }
38 |
39 | if (match == MatchPrecision.Exact)
40 | {
41 | matchPos = stream.Position;
42 | foundPrep = node;
43 | fFound = true;
44 | }
45 | }
46 |
47 | if (foundPrep != null) //Add the prep at the end of the loop in case we found multiple preps along the way
48 | {
49 | matchData.Preps.Add(foundPrep);
50 | }
51 |
52 | stream.Seek(matchPos, SeekOrigin.Begin);
53 | return fFound;
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/StaticToken.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Text;
3 |
4 | namespace KitchenPC.NLP.Tokens
5 | {
6 | public class StaticToken : IGrammar
7 | {
8 | readonly string phrase;
9 |
10 | public StaticToken(string phrase)
11 | {
12 | this.phrase = phrase.TrimStart(' ');
13 | }
14 |
15 | ///
16 | /// Reads stream to match it against a fixed string ignoring any whitespace
17 | ///
18 | ///
19 | ///
20 | ///
21 | public bool Read(Stream stream, MatchData matchdata)
22 | {
23 | while (stream.ReadByte() == ' ')
24 | {
25 | } //Burn off any leading spaces, they should not affect the grammar
26 | stream.Seek(-1, SeekOrigin.Current); //Set stream to first character after any whitespace (kinda a hack, maybe a better way to write this)
27 |
28 | //Read the stream to make sure it matches the complete token, return false if not
29 | var count = this.phrase.Length;
30 | var readBytes = new byte[count];
31 | stream.Read(readBytes, 0, count);
32 |
33 | return (Encoding.Default.GetString(readBytes) == this.phrase);
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Core/NLP/Tokens/UnitToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace KitchenPC.NLP.Tokens
5 | {
6 | public class UnitToken : IGrammar
7 | {
8 | static UnitSynonyms data;
9 |
10 | ///
11 | /// Reads stream to match it against a dictionary of all known units for an ingredient
12 | ///
13 | ///
14 | ///
15 | ///
16 | public bool Read(Stream stream, MatchData matchdata)
17 | {
18 | if (data == null)
19 | {
20 | data = new UnitSynonyms();
21 | }
22 |
23 | UnitNode node;
24 | var fMatch = false;
25 | var buffer = String.Empty;
26 | var matchPos = stream.Position;
27 | int curByte;
28 |
29 | while ((curByte = stream.ReadByte()) >= 0)
30 | {
31 | buffer += (char) curByte;
32 | var match = data.Parse(buffer, out node);
33 | if (match == MatchPrecision.None)
34 | {
35 | stream.Seek(matchPos, SeekOrigin.Begin);
36 | break; //No reason to continue reading stream, let's see what we have..
37 | }
38 |
39 | if (match == MatchPrecision.Exact)
40 | {
41 | matchPos = stream.Position;
42 | fMatch = true;
43 | matchdata.Amount.Unit = node.Unit;
44 | matchdata.Unit = node;
45 | }
46 | }
47 |
48 | return fMatch;
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/Core/NLP/UnitNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.NLP
4 | {
5 | public class UnitNode
6 | {
7 | public string Name;
8 | public Units Unit;
9 |
10 | public UnitNode(string name, Units unit)
11 | {
12 | this.Name = name.Trim();
13 | this.Unit = unit;
14 | }
15 |
16 | public override string ToString()
17 | {
18 | if (String.IsNullOrEmpty(Name))
19 | {
20 | return Name;
21 | }
22 | else
23 | {
24 | return Unit.ToString();
25 | }
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Core/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("KitchenPC")]
8 | [assembly: AssemblyDescription("KitchenPC Core Engine")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("KitchenPC")]
11 | [assembly: AssemblyProduct("Core")]
12 | [assembly: AssemblyCopyright("Copyright © KitchenPC 2014")]
13 | [assembly: AssemblyTrademark("KitchenPC")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("1ed3cf75-f7f5-460c-a55c-3c4523f423e7")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("0.0.9.0")]
35 | [assembly: AssemblyFileVersion("0.0.9.0")]
36 |
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/Favorites.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class Favorites
6 | {
7 | public Guid FavoriteId { get; set; }
8 | public Guid UserId { get; set; }
9 | public Guid RecipeId { get; set; }
10 | public Guid? MenuId { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/IngredientForms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.Data.DTO
5 | {
6 | public class IngredientForms
7 | {
8 | public Guid IngredientFormId { get; set; }
9 | public Guid IngredientId { get; set; }
10 | public short ConvMultiplier { get; set; }
11 | public float FormAmount { get; set; }
12 | public Units UnitType { get; set; }
13 | public string UnitName { get; set; }
14 | public Units FormUnit { get; set; }
15 | public string FormDisplayName { get; set; }
16 |
17 | public static IngredientForm ToIngredientForm(IngredientForms dtoForm)
18 | {
19 | return new IngredientForm
20 | {
21 | FormId = dtoForm.IngredientFormId,
22 | FormUnitType = dtoForm.UnitType,
23 | ConversionMultiplier = dtoForm.ConvMultiplier,
24 | FormDisplayName = dtoForm.FormDisplayName,
25 | FormUnitName = dtoForm.UnitName,
26 | IngredientId = dtoForm.IngredientId,
27 | FormAmount = new Amount(dtoForm.FormAmount, dtoForm.FormUnit)
28 | };
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/IngredientMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class IngredientMetadata
6 | {
7 | public Guid IngredientMetadataId { get; set; }
8 | public Guid IngredientId { get; set; }
9 |
10 | public bool? HasMeat { get; set; }
11 | public float? CarbsPerUnit { get; set; }
12 | public bool? HasRedMeat { get; set; }
13 | public float? SugarPerUnit { get; set; }
14 | public bool? HasPork { get; set; }
15 | public float? FatPerUnit { get; set; }
16 | public float? SodiumPerUnit { get; set; }
17 | public float? CaloriesPerUnit { get; set; }
18 | public short Spicy { get; set; }
19 | public short Sweet { get; set; }
20 | public bool? HasGluten { get; set; }
21 | public bool? HasAnimal { get; set; }
22 |
23 | public static KitchenPC.Ingredients.IngredientMetadata ToIngredientMetadata(IngredientMetadata metadata)
24 | {
25 | return new KitchenPC.Ingredients.IngredientMetadata
26 | {
27 | HasMeat = metadata.HasMeat,
28 | CarbsPerUnit = metadata.CarbsPerUnit,
29 | HasRedMeat = metadata.HasRedMeat,
30 | SugarPerUnit = metadata.SugarPerUnit,
31 | HasPork = metadata.HasPork,
32 | FatPerUnit = metadata.FatPerUnit,
33 | SodiumPerUnit = metadata.SodiumPerUnit,
34 | CaloriesPerUnit = metadata.CaloriesPerUnit,
35 | Spicy = metadata.Spicy,
36 | Sweet = metadata.Sweet,
37 | HasGluten = metadata.HasGluten,
38 | HasAnimal = metadata.HasAnimal
39 | };
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/Ingredients.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 |
4 | namespace KitchenPC.Data.DTO
5 | {
6 | public class Ingredients
7 | {
8 | public Guid IngredientId { get; set; }
9 | public string FoodGroup { get; set; }
10 | public string UsdaId { get; set; }
11 | public string UnitName { get; set; }
12 | public string ManufacturerName { get; set; }
13 | public UnitType ConversionType { get; set; }
14 | public int UnitWeight { get; set; }
15 | public string DisplayName { get; set; }
16 | public string UsdaDesc { get; set; }
17 |
18 | public static Ingredient ToIngredient(Ingredients dtoIngredient, IngredientMetadata metadata = null)
19 | {
20 | return new Ingredient
21 | {
22 | Id = dtoIngredient.IngredientId,
23 | ConversionType = dtoIngredient.ConversionType,
24 | Name = dtoIngredient.DisplayName,
25 | UnitName = dtoIngredient.UnitName,
26 | UnitWeight = dtoIngredient.UnitWeight,
27 | Metadata = (metadata != null ? IngredientMetadata.ToIngredientMetadata(metadata) : null)
28 | };
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/Menus.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Menus;
3 |
4 | namespace KitchenPC.Data.DTO
5 | {
6 | public class Menus
7 | {
8 | public Guid MenuId { get; set; }
9 | public Guid UserId { get; set; }
10 | public String Title { get; set; }
11 | public DateTime CreatedDate { get; set; }
12 |
13 | public static Menu ToMenu(Menus dtoMenu)
14 | {
15 | return new Menu
16 | {
17 | Id = dtoMenu.MenuId,
18 | Title = dtoMenu.Title
19 | };
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/NlpAnomalousIngredients.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class NlpAnomalousIngredients
6 | {
7 | public Guid AnomalousIngredientId { get; set; }
8 | public String Name { get; set; }
9 | public Guid IngredientId { get; set; }
10 | public Guid? WeightFormId { get; set; }
11 | public Guid? VolumeFormId { get; set; }
12 | public Guid? UnitFormId { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/NlpDefaultPairings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class NlpDefaultPairings
6 | {
7 | public virtual Guid DefaultPairingId { get; set; }
8 | public virtual Guid IngredientId { get; set; }
9 | public virtual Guid? WeightFormId { get; set; }
10 | public virtual Guid? VolumeFormId { get; set; }
11 | public virtual Guid? UnitFormId { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/NlpFormSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class NlpFormSynonyms
6 | {
7 | public Guid FormSynonymId { get; set; }
8 | public Guid IngredientId { get; set; }
9 | public Guid FormId { get; set; }
10 | public string Name { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/NlpIngredientSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class NlpIngredientSynonyms
6 | {
7 | public Guid IngredientSynonymId { get; set; }
8 | public Guid IngredientId { get; set; }
9 | public string Alias { get; set; }
10 | public string Prepnote { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/NlpPrepNotes.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Data.DTO
2 | {
3 | public class NlpPrepNotes
4 | {
5 | public string Name { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/NlpUnitSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class NlpUnitSynonyms
6 | {
7 | public Guid UnitSynonymId { get; set; }
8 | public Guid IngredientId { get; set; }
9 | public Guid FormId { get; set; }
10 | public string Name { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/QueuedRecipes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class QueuedRecipes
6 | {
7 | public Guid QueueId { get; set; }
8 | public Guid UserId { get; set; }
9 | public Guid RecipeId { get; set; }
10 | public DateTime QueuedDate { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/RecipeData.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Data.DTO
2 | {
3 | public class RecipeData
4 | {
5 | public Recipes Recipe { get; set; }
6 | public RecipeIngredients[] Ingredients { get; set; }
7 | public RecipeMetadata Metadata { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/RecipeIngredients.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class RecipeIngredients
6 | {
7 | public Guid RecipeIngredientId { get; set; }
8 | public Guid RecipeId { get; set; }
9 | public Guid IngredientId { get; set; }
10 | public Guid? IngredientFormId { get; set; }
11 |
12 | public Units Unit { get; set; }
13 | public float? QtyLow { get; set; }
14 | public short DisplayOrder { get; set; }
15 | public string PrepNote { get; set; }
16 | public float? Qty { get; set; }
17 | public string Section { get; set; }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/RecipeMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Data.DTO
5 | {
6 | public class RecipeMetadata
7 | {
8 | public Guid RecipeMetadataId { get; set; }
9 | public Guid RecipeId { get; set; }
10 |
11 | public int PhotoRes { get; set; }
12 | public float Commonality { get; set; }
13 | public bool UsdaMatch { get; set; }
14 |
15 | public bool MealBreakfast { get; set; }
16 | public bool MealLunch { get; set; }
17 | public bool MealDinner { get; set; }
18 | public bool MealDessert { get; set; }
19 |
20 | public bool DietNomeat { get; set; }
21 | public bool DietGlutenFree { get; set; }
22 | public bool DietNoRedMeat { get; set; }
23 | public bool DietNoAnimals { get; set; }
24 | public bool DietNoPork { get; set; }
25 |
26 | public short NutritionTotalfat { get; set; }
27 | public short NutritionTotalSodium { get; set; }
28 | public bool NutritionLowSodium { get; set; }
29 | public bool NutritionLowSugar { get; set; }
30 | public bool NutritionLowCalorie { get; set; }
31 | public short NutritionTotalSugar { get; set; }
32 | public short NutritionTotalCalories { get; set; }
33 | public bool NutritionLowFat { get; set; }
34 | public bool NutritionLowCarb { get; set; }
35 | public short NutritionTotalCarbs { get; set; }
36 |
37 | public bool SkillQuick { get; set; }
38 | public bool SkillEasy { get; set; }
39 | public bool SkillCommon { get; set; }
40 |
41 | public short TasteMildToSpicy { get; set; }
42 | public short TasteSavoryToSweet { get; set; }
43 |
44 | public static RecipeTags ToRecipeTags(RecipeMetadata metadata)
45 | {
46 | return
47 | (metadata.DietGlutenFree ? 1 << 0 : 0) +
48 | (metadata.DietNoAnimals ? 1 << 1 : 0) +
49 | (metadata.DietNomeat ? 1 << 2 : 0) +
50 | (metadata.DietNoPork ? 1 << 3 : 0) +
51 | (metadata.DietNoRedMeat ? 1 << 4 : 0) +
52 | (metadata.MealBreakfast ? 1 << 5 : 0) +
53 | (metadata.MealDessert ? 1 << 6 : 0) +
54 | (metadata.MealDinner ? 1 << 7 : 0) +
55 | (metadata.MealLunch ? 1 << 8 : 0) +
56 | (metadata.NutritionLowCalorie ? 1 << 9 : 0) +
57 | (metadata.NutritionLowCarb ? 1 << 10 : 0) +
58 | (metadata.NutritionLowFat ? 1 << 11 : 0) +
59 | (metadata.NutritionLowSodium ? 1 << 12 : 0) +
60 | (metadata.NutritionLowSugar ? 1 << 13 : 0) +
61 | (metadata.SkillCommon ? 1 << 14 : 0) +
62 | (metadata.SkillEasy ? 1 << 15 : 0) +
63 | (metadata.SkillQuick ? 1 << 16 : 0);
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/RecipeRatings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class RecipeRatings
6 | {
7 | public Guid RatingId { get; set; }
8 | public Guid UserId { get; set; }
9 | public Guid RecipeId { get; set; }
10 | public Int16 Rating { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/Recipes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Recipes;
3 |
4 | namespace KitchenPC.Data.DTO
5 | {
6 | public class Recipes
7 | {
8 | public Guid RecipeId { get; set; }
9 | public short? CookTime { get; set; }
10 | public string Steps { get; set; }
11 | public short? PrepTime { get; set; }
12 | public short Rating { get; set; }
13 | public string Description { get; set; }
14 | public string Title { get; set; }
15 | public bool Hidden { get; set; }
16 | public string Credit { get; set; }
17 | public string CreditUrl { get; set; }
18 | public DateTime DateEntered { get; set; }
19 | public short ServingSize { get; set; }
20 | public string ImageUrl { get; set; }
21 |
22 | public static RecipeBrief ToRecipeBrief(Recipes dtoRecipe)
23 | {
24 | return new RecipeBrief
25 | {
26 | Id = dtoRecipe.RecipeId,
27 | ImageUrl = dtoRecipe.ImageUrl,
28 | AvgRating = dtoRecipe.Rating,
29 | CookTime = dtoRecipe.CookTime,
30 | PrepTime = dtoRecipe.PrepTime,
31 | Description = dtoRecipe.Description,
32 | Title = dtoRecipe.Title
33 | };
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/ShoppingListItems.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Data.DTO
4 | {
5 | public class ShoppingListItems
6 | {
7 | public Guid ItemId { get; set; }
8 | public String Raw { get; set; }
9 | public float? Qty { get; set; }
10 | public Units? Unit { get; set; }
11 | public Guid UserId { get; set; }
12 | public Guid? IngredientId { get; set; }
13 | public Guid? RecipeId { get; set; }
14 | public Guid? ShoppingListId { get; set; }
15 | public bool CrossedOut { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/DTO/ShoppingLists.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.ShoppingLists;
3 |
4 | namespace KitchenPC.Data.DTO
5 | {
6 | public class ShoppingLists
7 | {
8 | public Guid ShoppingListId { get; set; }
9 | public Guid UserId { get; set; }
10 | public String Title { get; set; }
11 |
12 | public static ShoppingList ToShoppingList(ShoppingLists dtoList)
13 | {
14 | return new ShoppingList
15 | {
16 | Id = dtoList.ShoppingListId,
17 | Title = dtoList.Title
18 | };
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/IProvisionSource.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Data
2 | {
3 | /// Represents a source in which a KitchenPC Context can be provisioned from.
4 | public interface IProvisionSource
5 | {
6 | DataStore Export();
7 | }
8 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/IProvisionTarget.cs:
--------------------------------------------------------------------------------
1 | using KitchenPC.Data;
2 |
3 | namespace KitchenPC.Provisioning
4 | {
5 | /// Represents a target which can be provisioned based on data exported from an IProvisionSource.
6 | public interface IProvisionTarget
7 | {
8 | void Import(IProvisionSource source);
9 | void InitializeStore();
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Core/Provisioning/IProvisioner.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using KitchenPC.Data.DTO;
3 |
4 | namespace KitchenPC.Data
5 | {
6 | public interface IProvisioner
7 | {
8 | // Core Data (Immutable)
9 | IngredientForms[] IngredientForms();
10 | IngredientMetadata[] IngredientMetadata();
11 | DTO.Ingredients[] Ingredients();
12 | NlpAnomalousIngredients[] NlpAnomalousIngredients();
13 | NlpDefaultPairings[] NlpDefaultPairings();
14 | NlpFormSynonyms[] NlpFormSynonyms();
15 | NlpIngredientSynonyms[] NlpIngredientSynonyms();
16 | NlpPrepNotes[] NlpPrepNotes();
17 | NlpUnitSynonyms[] NlpUnitSynonyms();
18 |
19 | // Recipe Data
20 | List Recipes();
21 | List RecipeMetadata();
22 | List RecipeIngredients();
23 |
24 | // User Data
25 | List Favorites();
26 | List Menus();
27 | List QueuedRecipes();
28 | List RecipeRatings();
29 | List ShoppingLists();
30 | List ShoppingListItems();
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Core/Recipes/Enums.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Recipes
2 | {
3 | public enum MealFilter
4 | {
5 | All,
6 | Breakfast,
7 | Lunch,
8 | Dinner,
9 | Dessert
10 | }
11 |
12 | public enum Rating
13 | {
14 | None = 0,
15 |
16 | OneStar = 1,
17 | TwoStars = 2,
18 | ThreeStars = 3,
19 | FourStars = 4,
20 | FiveStars = 5
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Core/Recipes/ReadRecipeOptions.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.Recipes
2 | {
3 | public class ReadRecipeOptions
4 | {
5 | public bool ReturnCommentCount;
6 | public bool ReturnUserRating;
7 | public bool ReturnCookbookStatus;
8 | public bool ReturnMethod;
9 | public bool ReturnPermalink;
10 |
11 | static readonly ReadRecipeOptions none = new ReadRecipeOptions();
12 | static readonly ReadRecipeOptions methodonly = new ReadRecipeOptions {ReturnMethod = true};
13 |
14 | public static ReadRecipeOptions None
15 | {
16 | get
17 | {
18 | return none;
19 | }
20 | }
21 |
22 | public static ReadRecipeOptions MethodOnly
23 | {
24 | get
25 | {
26 | return methodonly;
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Core/Recipes/RecipeBrief.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Recipes
4 | {
5 | public class RecipeBrief
6 | {
7 | Uri recipeimg;
8 |
9 | public Guid Id;
10 | public Guid OwnerId;
11 | public String Permalink;
12 | public String Title;
13 | public String Description;
14 | public String Author;
15 | public short? PrepTime;
16 | public short? CookTime;
17 | public short AvgRating = 0;
18 |
19 | public String ImageUrl
20 | {
21 | get
22 | {
23 | return (recipeimg == null ? "/Images/img_placeholder.png" : recipeimg.ToString());
24 | }
25 |
26 | set
27 | {
28 | if (String.IsNullOrEmpty(value))
29 | {
30 | recipeimg = null;
31 | return;
32 | }
33 |
34 | //UriBuilder builder = new UriBuilder(baseUri);
35 | var builder = new UriBuilder();
36 | builder.Path = "Thumb_" + value;
37 | recipeimg = builder.Uri;
38 | }
39 | }
40 |
41 | public RecipeBrief()
42 | {
43 | }
44 |
45 | public RecipeBrief(Recipe r)
46 | {
47 | this.Id = r.Id;
48 | this.OwnerId = r.OwnerId;
49 | this.Title = r.Title;
50 | this.Description = r.Description;
51 | this.ImageUrl = r.ImageUrl;
52 | this.Author = r.OwnerAlias;
53 | this.PrepTime = r.PrepTime;
54 | this.CookTime = r.CookTime;
55 | this.AvgRating = r.AvgRating;
56 | }
57 |
58 | public override string ToString()
59 | {
60 | return String.Format("{0} ({1})", Title, Id);
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Core/Recipes/RecipeResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Recipes
4 | {
5 | public class RecipeResult
6 | {
7 | public bool RecipeCreated;
8 | public bool RecipeUpdated;
9 |
10 | public Guid? NewRecipeId;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Core/Recipes/SearchResults.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.Recipes
4 | {
5 | public class SearchResults
6 | {
7 | public RecipeBrief[] Briefs;
8 |
9 | public Int64 TotalCount { get; set; }
10 |
11 | public SearchResults(RecipeBrief[] briefs, Int64 total)
12 | {
13 | this.Briefs = briefs;
14 | this.TotalCount = total;
15 | }
16 |
17 | public SearchResults()
18 | {
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/Enums.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.ShoppingLists
2 | {
3 | public enum ShoppingListUpdateType
4 | {
5 | AddItem,
6 | RemoveItem,
7 | ModifyItem
8 | };
9 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/GetShoppingListOptions.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.ShoppingLists
2 | {
3 | public class GetShoppingListOptions
4 | {
5 | public bool LoadItems;
6 |
7 | static readonly GetShoppingListOptions none = new GetShoppingListOptions();
8 | static readonly GetShoppingListOptions loaded = new GetShoppingListOptions {LoadItems = true};
9 |
10 | public static GetShoppingListOptions None
11 | {
12 | get
13 | {
14 | return none;
15 | }
16 | }
17 |
18 | public static GetShoppingListOptions WithItems
19 | {
20 | get
21 | {
22 | return loaded;
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/IShoppingListSource.cs:
--------------------------------------------------------------------------------
1 | namespace KitchenPC.ShoppingLists
2 | {
3 | public interface IShoppingListSource
4 | {
5 | ShoppingListItem GetItem();
6 | }
7 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/ShoppingListItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.ShoppingLists
6 | {
7 | public class ShoppingListItem : IngredientAggregation
8 | {
9 | public string Raw { get; set; }
10 | public Guid? Id { get; set; }
11 | public RecipeBrief Recipe { get; set; }
12 | public bool CrossedOut { get; set; }
13 |
14 | public static ShoppingListItem FromId(Guid id)
15 | {
16 | return new ShoppingListItem(id);
17 | }
18 |
19 | public ShoppingListItem(Guid id) : base(null)
20 | {
21 | Id = id;
22 | }
23 |
24 | public ShoppingListItem(string raw) : base(null)
25 | {
26 | if (String.IsNullOrWhiteSpace(raw))
27 | throw new ArgumentException("Shopping list item cannot be blank.");
28 |
29 | Raw = raw;
30 | }
31 |
32 | public ShoppingListItem(Ingredient ingredient) : base(ingredient)
33 | {
34 | }
35 |
36 | public override IngredientAggregation AddUsage(IngredientUsage usage)
37 | {
38 | if (Ingredient == null)
39 | throw new ArgumentException("Cannot add usage to a non-resolved shopping list item. Create a new shopping list based on an IngredientUsage.");
40 |
41 | return base.AddUsage(usage);
42 | }
43 |
44 | public override ShoppingListItem GetItem()
45 | {
46 | return this;
47 | }
48 |
49 | public override string ToString()
50 | {
51 | return (!String.IsNullOrEmpty(Raw) ? Raw : base.ToString());
52 | }
53 |
54 | public static implicit operator ShoppingListItem(string s)
55 | {
56 | return new ShoppingListItem(s);
57 | }
58 |
59 | public static implicit operator String(ShoppingListItem i)
60 | {
61 | return i.ToString();
62 | }
63 |
64 | public override bool Equals(object obj)
65 | {
66 | var item = obj as ShoppingListItem;
67 | if (item == null)
68 | return false;
69 |
70 | if (this.Ingredient != null && item.Ingredient != null) // If they both represent an ingredient, compare by ingredient
71 | return this.Ingredient.Equals(item.Ingredient);
72 |
73 | // Compare by Raw string
74 | return String.Equals(this.Raw, item.Raw, StringComparison.InvariantCulture);
75 | }
76 |
77 | public override int GetHashCode()
78 | {
79 | return Ingredient != null ? Ingredient.Id.GetHashCode() : Raw.GetHashCode();
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/ShoppingListModification.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.ShoppingLists
4 | {
5 | public class ShoppingListModification
6 | {
7 | public Guid ModifiedItemId { get; private set; }
8 | public Amount NewAmount { get; private set; }
9 | public Boolean? CrossOut { get; private set; }
10 |
11 | public ShoppingListModification(Guid itemId, Amount newAmount, Boolean? crossout)
12 | {
13 | ModifiedItemId = itemId;
14 | NewAmount = newAmount;
15 | CrossOut = crossout;
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/ShoppingListResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC.ShoppingLists
4 | {
5 | public class ShoppingListResult
6 | {
7 | public Guid? NewShoppingListId;
8 | public ShoppingList List;
9 | }
10 | }
--------------------------------------------------------------------------------
/src/Core/ShoppingLists/ShoppingListUpdateCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.ShoppingLists
6 | {
7 | public class ShoppingListUpdateCommand
8 | {
9 | public ShoppingListUpdateType Command { get; set; }
10 |
11 | public Recipe NewRecipe { get; set; }
12 | public Ingredient NewIngredient { get; set; }
13 | public IngredientUsage NewUsage { get; set; }
14 | public String NewRaw { get; set; }
15 |
16 | public Guid? RemoveItem { get; set; }
17 | public ShoppingListModification ModifyItem { get; set; }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Core/UnitConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace KitchenPC
4 | {
5 | public static class UnitConverter
6 | {
7 | static readonly Single[,] ConversionMatrix =
8 | {
9 | {1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, //Unit
10 | {-1, 1.0f, 3.0f, 6.0f, 48.0f, 96.0f, 192.0f, 768.0f, -1, -1, -1}, //Teaspoon
11 | {-1, 1/3.0f, 1, 2.0f, 16.0f, 32.0f, 64.0f, 256.0f, -1, -1, -1}, //Tablespoon
12 | {-1, 1/6.0f, 0.5f, 1, 8.0f, 16.0f, 32.0f, 128.0f, -1, -1, -1}, //FluidOunce
13 | {-1, 1/48.0f, 1/16.0f, 0.125f, 1, 2.0f, 4.0f, 16.0f, -1, -1, -1}, //Cup
14 | {-1, 1/96.0f, 1/32.0f, 1/16.0f, 0.5f, 1, 2.0f, 8.0f, -1, -1, -1}, //Pint
15 | {-1, 1/192.0f, 1/64.0f, 1/32.0f, 0.25f, 0.5f, 1, 4.0f, -1, -1, -1}, //Quart
16 | {-1, 1/768.0f, 1/256.0f, 1/128.0f, 1/16.0f, 0.125f, 0.25f, 1, -1, -1, -1}, //Gallon
17 | {-1, -1, -1, -1, -1, -1, -1, -1, 1, 28.3495231f, 453.59237f}, //Gram
18 | {-1, -1, -1, -1, -1, -1, -1, -1, 1/28.3495231f, 1, 16.0f}, //Ounce
19 | {-1, -1, -1, -1, -1, -1, -1, -1, 1/453.59237f, 0.0625f, 1} //Pound
20 | };
21 |
22 | public static bool CanConvert(Units fromUnit, Units toUnit)
23 | {
24 | return (ConversionMatrix[(int) toUnit, (int) fromUnit] != -1);
25 | }
26 |
27 | public static Single Convert(Single amount, Units fromUnit, Units toUnit)
28 | {
29 | if (fromUnit == toUnit)
30 | return amount;
31 |
32 | if (ConversionMatrix[(int) toUnit, (int) fromUnit] == -1)
33 | throw new ArgumentException("Cannot convert from unit " + Unit.GetSingular(fromUnit) + " to unit " + Unit.GetSingular(toUnit));
34 |
35 | var coefficient = ConversionMatrix[(int) toUnit, (int) fromUnit];
36 | return amount*coefficient;
37 | }
38 |
39 | public static Amount Convert(Amount amount, Units toUnit)
40 | {
41 | var ret = new Amount();
42 | ret.Unit = toUnit;
43 | ret.SizeLow = amount.SizeLow.HasValue ? (float?) Convert(amount.SizeLow.Value, amount.Unit, toUnit) : null;
44 | ret.SizeHigh = Convert(amount.SizeHigh, amount.Unit, toUnit);
45 |
46 | return ret;
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/src/Core/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/DB/DatabaseAdapterBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FluentNHibernate.Cfg.Db;
4 | using FluentNHibernate.Conventions;
5 | using KitchenPC.Context;
6 |
7 | namespace KitchenPC.DB
8 | {
9 | public class DatabaseAdapterBuilder : IConfigurationBuilder
10 | {
11 | readonly DatabaseAdapter adapter;
12 |
13 | public DatabaseAdapterBuilder(DatabaseAdapter adapter)
14 | {
15 | this.adapter = adapter;
16 | }
17 |
18 | public DatabaseAdapterBuilder DatabaseConfiguration(IPersistenceConfigurer config)
19 | {
20 | adapter.DatabaseConfiguration = config;
21 | return this;
22 | }
23 |
24 | public DatabaseAdapterBuilder AddConvention(IConvention convention)
25 | {
26 | if (adapter.DatabaseConventions == null)
27 | adapter.DatabaseConventions = new List();
28 |
29 | adapter.DatabaseConventions.Add(convention);
30 |
31 | return this;
32 | }
33 |
34 | public DatabaseAdapterBuilder SearchProvider(Func createProvider) where T : ISearchProvider
35 | {
36 | adapter.SearchProvider = createProvider(adapter);
37 | return this;
38 | }
39 |
40 | public DatabaseAdapter Create()
41 | {
42 | return adapter;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/DB/EnumMapper.cs:
--------------------------------------------------------------------------------
1 | using System.Data;
2 | using FluentNHibernate.Conventions;
3 | using FluentNHibernate.Conventions.Helpers;
4 | using FluentNHibernate.Mapping;
5 | using NHibernate.SqlTypes;
6 | using NHibernate.Type;
7 |
8 | namespace KitchenPC.DB
9 | {
10 | public class EnumMapper : EnumStringType
11 | {
12 | public override SqlType SqlType
13 | {
14 | get
15 | {
16 | return new SqlType(DbType.Object);
17 | }
18 | }
19 |
20 | public static IPropertyConvention Convention
21 | {
22 | get
23 | {
24 | return ConventionBuilder.Property.When(
25 | c => c.Expect(x => x.Type == typeof (GenericEnumMapper)),
26 | x =>
27 | {
28 | x.CustomType>();
29 | x.CustomSqlType((typeof (T).Name));
30 | });
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/DB/Models/Favorites.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class Favorites
7 | {
8 | public virtual Guid FavoriteId { get; set; }
9 | public virtual Guid UserId { get; set; }
10 | public virtual Recipes Recipe { get; set; }
11 | public virtual Menus Menu { get; set; }
12 | }
13 |
14 | public class FavoritesMap : ClassMap
15 | {
16 | public FavoritesMap()
17 | {
18 | Id(x => x.FavoriteId)
19 | .GeneratedBy.GuidComb()
20 | .UnsavedValue(Guid.Empty);
21 |
22 | Map(x => x.UserId).Not.Nullable().Index("IDX_Favorites_UserId");
23 |
24 | References(x => x.Recipe).Not.Nullable().Index("IDX_Favorites_RecipeId");
25 | References(x => x.Menu);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/DB/Models/IngredientForms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 | using KitchenPC.Ingredients;
4 |
5 | namespace KitchenPC.DB.Models
6 | {
7 | public class IngredientForms
8 | {
9 | public virtual Guid IngredientFormId { get; set; }
10 | public virtual Ingredients Ingredient { get; set; }
11 |
12 | public virtual short ConvMultiplier { get; set; }
13 | public virtual float FormAmount { get; set; }
14 | public virtual Units UnitType { get; set; }
15 | public virtual string UnitName { get; set; }
16 | public virtual Units FormUnit { get; set; }
17 | public virtual string FormDisplayName { get; set; }
18 |
19 | public static IngredientForms FromId(Guid id)
20 | {
21 | return new IngredientForms
22 | {
23 | IngredientFormId = id
24 | };
25 | }
26 |
27 | public virtual IngredientForm AsIngredientForm()
28 | {
29 | return new IngredientForm
30 | {
31 | FormId = IngredientFormId,
32 | FormUnitType = UnitType,
33 | ConversionMultiplier = ConvMultiplier,
34 | FormDisplayName = FormDisplayName,
35 | FormUnitName = UnitName,
36 | IngredientId = Ingredient.IngredientId,
37 | FormAmount = new Amount(FormAmount, FormUnit)
38 | };
39 | }
40 | }
41 |
42 | public class IngredientFormsMap : ClassMap
43 | {
44 | public IngredientFormsMap()
45 | {
46 | Id(x => x.IngredientFormId)
47 | .GeneratedBy.GuidComb()
48 | .UnsavedValue(Guid.Empty);
49 |
50 | Map(x => x.ConvMultiplier).Not.Nullable();
51 | Map(x => x.FormAmount).Not.Nullable();
52 | Map(x => x.UnitType).Not.Nullable();
53 | Map(x => x.UnitName).Length(50);
54 | Map(x => x.FormUnit).Not.Nullable();
55 | Map(x => x.FormDisplayName).Length(200).UniqueKey("UniqueIngredientForm");
56 |
57 | References(x => x.Ingredient).Not.Nullable().UniqueKey("UniqueIngredientForm");
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/DB/Models/IngredientMetadata.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class IngredientMetadata
7 | {
8 | public virtual Guid IngredientMetadataId { get; set; }
9 | public virtual Ingredients Ingredient { get; set; }
10 |
11 | public virtual bool? HasMeat { get; set; }
12 | public virtual float? CarbsPerUnit { get; set; }
13 | public virtual bool? HasRedMeat { get; set; }
14 | public virtual float? SugarPerUnit { get; set; }
15 | public virtual bool? HasPork { get; set; }
16 | public virtual float? FatPerUnit { get; set; }
17 | public virtual float? SodiumPerUnit { get; set; }
18 | public virtual float? CaloriesPerUnit { get; set; }
19 | public virtual short Spicy { get; set; }
20 | public virtual short Sweet { get; set; }
21 | public virtual bool? HasGluten { get; set; }
22 | public virtual bool? HasAnimal { get; set; }
23 |
24 | public virtual KitchenPC.Ingredients.IngredientMetadata AsIngredientMetadata()
25 | {
26 | return new KitchenPC.Ingredients.IngredientMetadata
27 | {
28 | HasMeat = HasMeat,
29 | CarbsPerUnit = CarbsPerUnit,
30 | HasRedMeat = HasRedMeat,
31 | SugarPerUnit = SugarPerUnit,
32 | HasPork = HasPork,
33 | FatPerUnit = FatPerUnit,
34 | SodiumPerUnit = SodiumPerUnit,
35 | CaloriesPerUnit = CaloriesPerUnit,
36 | Spicy = Spicy,
37 | Sweet = Sweet,
38 | HasGluten = HasGluten,
39 | HasAnimal = HasAnimal
40 | };
41 | }
42 | }
43 |
44 | public class IngredientMetadataMap : ClassMap
45 | {
46 | public IngredientMetadataMap()
47 | {
48 | Id(x => x.IngredientMetadataId)
49 | .GeneratedBy.GuidComb()
50 | .UnsavedValue(Guid.Empty);
51 |
52 | Map(x => x.HasMeat);
53 | Map(x => x.CarbsPerUnit);
54 | Map(x => x.HasRedMeat);
55 | Map(x => x.SugarPerUnit);
56 | Map(x => x.HasPork);
57 | Map(x => x.FatPerUnit);
58 | Map(x => x.SodiumPerUnit);
59 | Map(x => x.CaloriesPerUnit);
60 | Map(x => x.Spicy).Not.Nullable();
61 | Map(x => x.Sweet).Not.Nullable();
62 | Map(x => x.HasGluten);
63 | Map(x => x.HasAnimal);
64 |
65 | References(x => x.Ingredient).Not.Nullable().Unique();
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/DB/Models/Ingredients.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FluentNHibernate.Mapping;
4 | using KitchenPC.Ingredients;
5 |
6 | namespace KitchenPC.DB.Models
7 | {
8 | public class Ingredients
9 | {
10 | public virtual Guid IngredientId { get; set; }
11 | public virtual string FoodGroup { get; set; }
12 | public virtual string UsdaId { get; set; }
13 | public virtual string UnitName { get; set; }
14 | public virtual string ManufacturerName { get; set; }
15 | public virtual UnitType ConversionType { get; set; }
16 | public virtual int UnitWeight { get; set; }
17 | public virtual string DisplayName { get; set; }
18 | public virtual string UsdaDesc { get; set; }
19 |
20 | public virtual IList Forms { get; set; }
21 | public virtual IngredientMetadata Metadata { get; set; }
22 |
23 | public virtual Ingredient AsIngredient()
24 | {
25 | return new Ingredient
26 | {
27 | Id = IngredientId,
28 | ConversionType = ConversionType,
29 | Name = DisplayName,
30 | UnitName = UnitName,
31 | UnitWeight = UnitWeight,
32 | Metadata = (Metadata != null ? Metadata.AsIngredientMetadata() : null)
33 | };
34 | }
35 |
36 | public static Ingredients FromId(Guid id)
37 | {
38 | return new Ingredients
39 | {
40 | IngredientId = id
41 | };
42 | }
43 | }
44 |
45 | public class IngredientsMap : ClassMap
46 | {
47 | public IngredientsMap()
48 | {
49 | Id(x => x.IngredientId)
50 | .GeneratedBy.GuidComb()
51 | .UnsavedValue(Guid.Empty);
52 |
53 | Map(x => x.FoodGroup).Length(4);
54 | Map(x => x.UsdaId).Length(5);
55 | Map(x => x.UnitName).Length(50);
56 | Map(x => x.ManufacturerName).Length(65);
57 | Map(x => x.ConversionType).Not.Nullable();
58 | Map(x => x.UnitWeight).Not.Nullable().Default("0");
59 | Map(x => x.DisplayName).Not.Nullable().Length(200).Unique().Index("IDX_Ingredients_DisplayName");
60 | Map(x => x.UsdaDesc).Length(200);
61 |
62 | HasMany(x => x.Forms).KeyColumn("IngredientId");
63 | HasOne(x => x.Metadata).PropertyRef(x => x.Ingredient).Cascade.All();
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/src/DB/Models/Menus.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FluentNHibernate.Mapping;
4 | using KitchenPC.Menus;
5 |
6 | namespace KitchenPC.DB.Models
7 | {
8 | public class Menus
9 | {
10 | public virtual Guid MenuId { get; set; }
11 | public virtual Guid UserId { get; set; }
12 | public virtual String Title { get; set; }
13 | public virtual DateTime CreatedDate { get; set; }
14 |
15 | public virtual IList Recipes { get; set; }
16 |
17 | public static Menus FromId(Guid id)
18 | {
19 | return new Menus
20 | {
21 | MenuId = id
22 | };
23 | }
24 |
25 | public virtual Menu AsMenu()
26 | {
27 | return new Menu
28 | {
29 | Id = MenuId,
30 | Title = Title,
31 | };
32 | }
33 |
34 | public static bool operator !=(Menu menu, Menus dbMenu)
35 | {
36 | return !(menu == dbMenu);
37 | }
38 |
39 | public static bool operator ==(Menu menu, Menus dbMenu)
40 | {
41 | if (dbMenu == null)
42 | {
43 | return !menu.Id.HasValue;
44 | }
45 |
46 | return menu.Id == dbMenu.MenuId;
47 | }
48 |
49 | public override bool Equals(object obj)
50 | {
51 | if (false == (obj is Menus))
52 | return false;
53 |
54 | var menu = (Menus) obj;
55 | return MenuId.Equals(menu.MenuId);
56 | }
57 |
58 | public override int GetHashCode()
59 | {
60 | return MenuId.GetHashCode();
61 | }
62 | }
63 |
64 | public class MenusMap : ClassMap
65 | {
66 | public MenusMap()
67 | {
68 | Id(x => x.MenuId)
69 | .GeneratedBy.GuidComb()
70 | .UnsavedValue(Guid.Empty);
71 |
72 | Map(x => x.UserId).Not.Nullable().Index("IDX_Menus_UserId").UniqueKey("UserTitle");
73 | Map(x => x.Title).Not.Nullable().UniqueKey("UserTitle");
74 | Map(x => x.CreatedDate).Not.Nullable();
75 |
76 | HasMany(x => x.Recipes)
77 | .KeyColumn("MenuId")
78 | .Cascade.Delete(); // If Menu is deleted, delete all the Favorites that reference this menu
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/src/DB/Models/NlpAnomalousIngredients.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class NlpAnomalousIngredients
7 | {
8 | public virtual Guid AnomalousIngredientId { get; set; }
9 | public virtual String Name { get; set; }
10 | public virtual Ingredients Ingredient { get; set; }
11 | public virtual IngredientForms WeightForm { get; set; }
12 | public virtual IngredientForms VolumeForm { get; set; }
13 | public virtual IngredientForms UnitForm { get; set; }
14 | }
15 |
16 | public class NlpAnomalousIngredientsMap : ClassMap
17 | {
18 | public NlpAnomalousIngredientsMap()
19 | {
20 | Id(x => x.AnomalousIngredientId)
21 | .GeneratedBy.GuidComb()
22 | .UnsavedValue(Guid.Empty);
23 |
24 | Map(x => x.Name).Not.Nullable().Length(100).Unique();
25 |
26 | References(x => x.Ingredient).Not.Nullable();
27 | References(x => x.WeightForm);
28 | References(x => x.VolumeForm);
29 | References(x => x.UnitForm);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/DB/Models/NlpDefaultPairings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class NlpDefaultPairings
7 | {
8 | public virtual Guid DefaultPairingId { get; set; }
9 | public virtual Ingredients Ingredient { get; set; }
10 | public virtual IngredientForms WeightForm { get; set; }
11 | public virtual IngredientForms VolumeForm { get; set; }
12 | public virtual IngredientForms UnitForm { get; set; }
13 | }
14 |
15 | public class NlpDefaultPairingsMap : ClassMap
16 | {
17 | public NlpDefaultPairingsMap()
18 | {
19 | Id(x => x.DefaultPairingId)
20 | .GeneratedBy.GuidComb()
21 | .UnsavedValue(Guid.Empty);
22 |
23 | References(x => x.Ingredient).Unique().Not.Nullable();
24 | References(x => x.WeightForm);
25 | References(x => x.VolumeForm);
26 | References(x => x.UnitForm);
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/DB/Models/NlpFormSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class NlpFormSynonyms
7 | {
8 | public virtual Guid FormSynonymId { get; set; }
9 | public virtual Ingredients Ingredient { get; set; }
10 | public virtual IngredientForms Form { get; set; }
11 | public virtual string Name { get; set; }
12 | }
13 |
14 | public class NlpFormSynonymsMap : ClassMap
15 | {
16 | public NlpFormSynonymsMap()
17 | {
18 | Id(x => x.FormSynonymId)
19 | .GeneratedBy.GuidComb()
20 | .UnsavedValue(Guid.Empty);
21 |
22 | Map(x => x.Name).Length(50).UniqueKey("FormName");
23 |
24 | References(x => x.Ingredient).Not.Nullable().UniqueKey("FormName");
25 | References(x => x.Form).Not.Nullable();
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/DB/Models/NlpIngredientSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class NlpIngredientSynonyms
7 | {
8 | public virtual Guid IngredientSynonymId { get; set; }
9 | public virtual Ingredients Ingredient { get; set; }
10 | public virtual string Alias { get; set; }
11 | public virtual string Prepnote { get; set; }
12 | }
13 |
14 | public class NlpIngredientSynonymsMap : ClassMap
15 | {
16 | public NlpIngredientSynonymsMap()
17 | {
18 | Id(x => x.IngredientSynonymId)
19 | .GeneratedBy.GuidComb()
20 | .UnsavedValue(Guid.Empty);
21 |
22 | Map(x => x.Alias).Length(200).Unique();
23 | Map(x => x.Prepnote).Length(50);
24 |
25 | References(x => x.Ingredient).Not.Nullable();
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/DB/Models/NlpPrepNotes.cs:
--------------------------------------------------------------------------------
1 | using FluentNHibernate.Mapping;
2 |
3 | namespace KitchenPC.DB.Models
4 | {
5 | public class NlpPrepNotes
6 | {
7 | public virtual string Name { get; set; }
8 | }
9 |
10 | public class NlpPrepNotesMap : ClassMap
11 | {
12 | public NlpPrepNotesMap()
13 | {
14 | Id(x => x.Name).Length(50);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/DB/Models/NlpUnitSynonyms.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class NlpUnitSynonyms
7 | {
8 | public virtual Guid UnitSynonymId { get; set; }
9 | public virtual Ingredients Ingredient { get; set; }
10 | public virtual IngredientForms Form { get; set; }
11 | public virtual string Name { get; set; }
12 | }
13 |
14 | public class NlpUnitSynonymsMap : ClassMap
15 | {
16 | public NlpUnitSynonymsMap()
17 | {
18 | Id(x => x.UnitSynonymId)
19 | .GeneratedBy.GuidComb()
20 | .UnsavedValue(Guid.Empty);
21 |
22 | Map(x => x.Name).Length(50).UniqueKey("UniquePair");
23 |
24 | References(x => x.Ingredient).Not.Nullable().UniqueKey("UniquePair");
25 | References(x => x.Form).Not.Nullable();
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/DB/Models/QueuedRecipes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class QueuedRecipes
7 | {
8 | public virtual Guid QueueId { get; set; }
9 | public virtual Guid UserId { get; set; }
10 | public virtual Recipes Recipe { get; set; }
11 | public virtual DateTime QueuedDate { get; set; }
12 | }
13 |
14 | public class QueuedRecipesMap : ClassMap
15 | {
16 | public QueuedRecipesMap()
17 | {
18 | Id(x => x.QueueId)
19 | .GeneratedBy.GuidComb()
20 | .UnsavedValue(Guid.Empty);
21 |
22 | Map(x => x.UserId).Not.Nullable().Index("IDX_QueuedRecipes_UserId").UniqueKey("UniqueRecipe");
23 | Map(x => x.QueuedDate).Not.Nullable();
24 |
25 | References(x => x.Recipe).Not.Nullable().UniqueKey("UniqueRecipe");
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/DB/Models/RecipeIngredients.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class RecipeIngredients
7 | {
8 | public virtual Guid RecipeIngredientId { get; set; }
9 | public virtual Recipes Recipe { get; set; }
10 | public virtual Ingredients Ingredient { get; set; }
11 | public virtual IngredientForms IngredientForm { get; set; }
12 |
13 | public virtual Units Unit { get; set; }
14 | public virtual float? QtyLow { get; set; }
15 | public virtual short DisplayOrder { get; set; }
16 | public virtual string PrepNote { get; set; }
17 | public virtual float? Qty { get; set; }
18 | public virtual string Section { get; set; }
19 | }
20 |
21 | public class RecipeIngredientsMap : ClassMap
22 | {
23 | public RecipeIngredientsMap()
24 | {
25 | Id(x => x.RecipeIngredientId)
26 | .GeneratedBy.GuidComb()
27 | .UnsavedValue(Guid.Empty);
28 |
29 | Map(x => x.Unit).Not.Nullable();
30 | Map(x => x.QtyLow);
31 | Map(x => x.DisplayOrder).Not.Nullable();
32 | Map(x => x.PrepNote).Length(50);
33 | Map(x => x.Qty);
34 | Map(x => x.Section).Length(50);
35 |
36 | References(x => x.Recipe).Column("RecipeId").Not.Nullable().Index("IDX_RecipeIngredients_RecipeId");
37 | References(x => x.Ingredient).Column("IngredientId").Not.Nullable().Index("IDX_RecipeIngredients_IngredientId");
38 | References(x => x.IngredientForm).Column("IngredientFormId");
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/DB/Models/RecipeRatings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using FluentNHibernate.Mapping;
3 |
4 | namespace KitchenPC.DB.Models
5 | {
6 | public class RecipeRatings
7 | {
8 | public virtual Guid RatingId { get; set; }
9 | public virtual Guid UserId { get; set; }
10 | public virtual Recipes Recipe { get; set; }
11 | public virtual Int16 Rating { get; set; }
12 | }
13 |
14 | public class RecipeRatingsMap : ClassMap
15 | {
16 | public RecipeRatingsMap()
17 | {
18 | Id(x => x.RatingId)
19 | .GeneratedBy.GuidComb()
20 | .UnsavedValue(Guid.Empty);
21 |
22 | Map(x => x.UserId).Not.Nullable().Index("IDX_RecipeRatings_UserId").UniqueKey("UserRating");
23 | Map(x => x.Rating).Not.Nullable();
24 |
25 | References(x => x.Recipe).Not.Nullable().Index("IDX_RecipeRatings_RecipeId").UniqueKey("UserRating");
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/DB/Models/Recipes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FluentNHibernate.Mapping;
4 | using KitchenPC.Recipes;
5 |
6 | namespace KitchenPC.DB.Models
7 | {
8 | public class Recipes
9 | {
10 | public virtual Guid RecipeId { get; set; }
11 | public virtual short? CookTime { get; set; }
12 | public virtual string Steps { get; set; }
13 | public virtual short? PrepTime { get; set; }
14 | public virtual short Rating { get; set; }
15 | public virtual string Description { get; set; }
16 | public virtual string Title { get; set; }
17 | public virtual bool Hidden { get; set; }
18 | public virtual string Credit { get; set; }
19 | public virtual string CreditUrl { get; set; }
20 | public virtual DateTime DateEntered { get; set; }
21 | public virtual short ServingSize { get; set; }
22 | public virtual string ImageUrl { get; set; }
23 |
24 | public virtual IList Ingredients { get; set; }
25 | public virtual RecipeMetadata RecipeMetadata { get; set; }
26 |
27 | public virtual RecipeBrief AsRecipeBrief()
28 | {
29 | return new RecipeBrief
30 | {
31 | Id = RecipeId,
32 | ImageUrl = ImageUrl,
33 | AvgRating = Rating,
34 | CookTime = CookTime,
35 | PrepTime = PrepTime,
36 | Description = Description,
37 | Title = Title
38 | };
39 | }
40 |
41 | public static Recipes FromId(Guid id)
42 | {
43 | return new Recipes
44 | {
45 | RecipeId = id
46 | };
47 | }
48 | }
49 |
50 | public class RecipesMap : ClassMap
51 | {
52 | public RecipesMap()
53 | {
54 | Id(x => x.RecipeId)
55 | .GeneratedBy.GuidComb()
56 | .UnsavedValue(Guid.Empty);
57 |
58 | Map(x => x.CookTime).Index("IDX_Recipes_Cooktime");
59 | Map(x => x.Steps).Length(10000);
60 | Map(x => x.PrepTime).Index("IDX_Recipes_Preptime");
61 | Map(x => x.Rating).Not.Nullable().Index("IDX_Recipes_Rating");
62 | Map(x => x.Description).Length(512);
63 | Map(x => x.Title).Not.Nullable().Length(100);
64 | Map(x => x.Hidden).Not.Nullable().Index("IDX_Recipes_Hidden");
65 | Map(x => x.Credit).Length(100);
66 | Map(x => x.CreditUrl).Length(1024);
67 | Map(x => x.DateEntered).Not.Nullable();
68 | Map(x => x.ServingSize).Not.Nullable().Check("ServingSize > 0");
69 | Map(x => x.ImageUrl).Length(100);
70 |
71 | HasMany(x => x.Ingredients).KeyColumn("RecipeId");
72 | HasOne(x => x.RecipeMetadata).PropertyRef(x => x.Recipe).Cascade.All();
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/src/DB/Models/ShoppingLists.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using FluentNHibernate.Mapping;
4 | using KitchenPC.ShoppingLists;
5 |
6 | namespace KitchenPC.DB.Models
7 | {
8 | public class ShoppingLists
9 | {
10 | public virtual Guid ShoppingListId { get; set; }
11 | public virtual Guid UserId { get; set; }
12 | public virtual String Title { get; set; }
13 |
14 | public virtual IList Items { get; set; }
15 |
16 | public static ShoppingLists FromId(Guid id)
17 | {
18 | return new ShoppingLists
19 | {
20 | ShoppingListId = id
21 | };
22 | }
23 |
24 | public virtual ShoppingList AsShoppingList()
25 | {
26 | return new ShoppingList
27 | {
28 | Id = ShoppingListId,
29 | Title = Title
30 | };
31 | }
32 | }
33 |
34 | public class ShoppingListsMap : ClassMap
35 | {
36 | public ShoppingListsMap()
37 | {
38 | Id(x => x.ShoppingListId)
39 | .GeneratedBy.GuidComb()
40 | .UnsavedValue(Guid.Empty);
41 |
42 | Map(x => x.UserId).Not.Nullable().Index("IDX_ShoppingLists_UserId").UniqueKey("UniqueTitle");
43 | Map(x => x.Title).Not.Nullable().UniqueKey("UniqueTitle");
44 |
45 | HasMany(x => x.Items)
46 | .KeyColumn("ShoppingListId")
47 | .Inverse()
48 | .Cascade.All();
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/DB/NLP/FormLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using KitchenPC.DB.Models;
4 | using KitchenPC.Ingredients;
5 | using KitchenPC.NLP;
6 | using NHibernate.Criterion;
7 | using NHibernate.Linq;
8 |
9 | namespace KitchenPC.DB
10 | {
11 | public class FormLoader : ISynonymLoader
12 | {
13 | readonly DatabaseAdapter adapter;
14 |
15 | public FormLoader(DatabaseAdapter adapter)
16 | {
17 | this.adapter = adapter;
18 | }
19 |
20 | public IEnumerable LoadSynonyms()
21 | {
22 | using (var session = adapter.GetStatelessSession())
23 | {
24 | //Load synonyms
25 | var formSyn = session.Query()
26 | .OrderBy(p => p.Name)
27 | .Select(s => s.Name)
28 | .Distinct()
29 | .ToList();
30 |
31 | return new List(formSyn.Select(s => new FormNode(s)));
32 | }
33 | }
34 |
35 | public Pairings LoadFormPairings()
36 | {
37 | using (var session = adapter.GetStatelessSession())
38 | {
39 | var formSyn = session.QueryOver()
40 | .Fetch(prop => prop.Form).Eager()
41 | .List();
42 |
43 | //Load all form pairings from db
44 | var pairings = new Pairings();
45 |
46 | foreach (var syn in formSyn)
47 | {
48 | var name = syn.Name;
49 | var ing = syn.Ingredient.IngredientId;
50 | var form = syn.Form.IngredientFormId;
51 | var convType = syn.Form.UnitType;
52 | var displayName = syn.Form.FormDisplayName;
53 | var unitName = syn.Form.UnitName;
54 | int convMultiplier = syn.Form.ConvMultiplier;
55 | var formAmt = syn.Form.FormAmount;
56 | var formUnit = syn.Form.FormUnit;
57 | var amount = new Amount(formAmt, formUnit);
58 |
59 | pairings.Add(
60 | new NameIngredientPair(name, ing),
61 | new IngredientForm(form, ing, convType, displayName, unitName, convMultiplier, amount));
62 | }
63 |
64 | return pairings;
65 | }
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/DB/NLP/IngredientGraphTransformer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using KitchenPC.Modeler;
4 | using NHibernate.Transform;
5 |
6 | namespace KitchenPC.DB
7 | {
8 | public class IngredientGraphTransformer : IResultTransformer
9 | {
10 | public static IngredientGraphTransformer Create()
11 | {
12 | return new IngredientGraphTransformer();
13 | }
14 |
15 | IngredientGraphTransformer()
16 | {
17 | }
18 |
19 | public IList TransformList(IList collection)
20 | {
21 | return collection;
22 | }
23 |
24 | public object TransformTuple(object[] tuple, string[] aliases)
25 | {
26 | return IngredientBinding.Create
27 | (
28 | (Guid) tuple[0], //R.IngredientId
29 | (Guid) tuple[1], //R.RecipeId
30 | (Single?) tuple[2], //R.Qty
31 | (Units) tuple[3], //R.Unit
32 | (UnitType) tuple[4], //I.ConversionType
33 | (int) tuple[5], //I.UnitWeight
34 |
35 | (Units) tuple[6], //F.UnitType
36 | (float) tuple[7], //F.FormAmount
37 | (Units) tuple[8] //F.FormUnit
38 | );
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/DB/NLP/PrepLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using KitchenPC.DB.Models;
5 | using KitchenPC.NLP;
6 |
7 | namespace KitchenPC.DB
8 | {
9 | public class PrepLoader : ISynonymLoader
10 | {
11 | readonly DatabaseAdapter adapter;
12 |
13 | public PrepLoader(DatabaseAdapter adapter)
14 | {
15 | this.adapter = adapter;
16 | }
17 |
18 | public IEnumerable LoadSynonyms()
19 | {
20 | using (var session = adapter.GetStatelessSession())
21 | {
22 | var forms = session.QueryOver().Select(p => p.Name).List();
23 | var preps = session.QueryOver().Select(p => p.Name).List();
24 |
25 | var ret = forms
26 | .Concat(preps)
27 | .Distinct()
28 | .Select(p => new PrepNode(p))
29 | .ToList();
30 |
31 | return ret;
32 | }
33 | }
34 |
35 | public Pairings LoadFormPairings()
36 | {
37 | throw new NotImplementedException();
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/DB/NLP/UnitLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using KitchenPC.DB.Models;
4 | using KitchenPC.Ingredients;
5 | using KitchenPC.NLP;
6 | using NHibernate.Criterion;
7 | using NHibernate.Linq;
8 |
9 | namespace KitchenPC.DB
10 | {
11 | public class UnitLoader : ISynonymLoader
12 | {
13 | readonly DatabaseAdapter adapter;
14 |
15 | public UnitLoader(DatabaseAdapter adapter)
16 | {
17 | this.adapter = adapter;
18 | }
19 |
20 | public IEnumerable LoadSynonyms()
21 | {
22 | using (var session = adapter.GetStatelessSession())
23 | {
24 | //Load synonyms
25 | var unitSyn = session.Query()
26 | .OrderBy(p => p.Name)
27 | .Select(p => p.Name)
28 | .Distinct()
29 | .ToList();
30 |
31 | return new List(unitSyn.Select(s => new CustomUnitNode(s)));
32 | }
33 | }
34 |
35 | public Pairings LoadFormPairings()
36 | {
37 | using (var session = adapter.GetStatelessSession())
38 | {
39 | //Load all form pairings from db
40 | var unitSyn = session.QueryOver()
41 | .Fetch(prop => prop.Form).Eager()
42 | .List();
43 |
44 | var pairings = new Pairings();
45 | foreach (var syn in unitSyn)
46 | {
47 | pairings.Add(new NameIngredientPair(
48 | syn.Name.Trim(),
49 | syn.Ingredient.IngredientId),
50 | new IngredientForm(
51 | syn.Form.IngredientFormId,
52 | syn.Ingredient.IngredientId,
53 | syn.Form.UnitType,
54 | syn.Form.FormDisplayName,
55 | syn.Form.UnitName,
56 | syn.Form.ConvMultiplier,
57 | new Amount(syn.Form.FormAmount, syn.Form.FormUnit)));
58 | }
59 |
60 | return pairings;
61 | }
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/src/DB/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("KitchenPC.DB")]
9 | [assembly: AssemblyDescription("KitchenPC Database Adapter")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("KitchenPC")]
12 | [assembly: AssemblyProduct("DB")]
13 | [assembly: AssemblyCopyright("Copyright © KitchenPC 2014")]
14 | [assembly: AssemblyTrademark("KitchenPC")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5050f0e8-e97f-40c7-807f-3a78de83298d")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.0.9.0")]
36 | [assembly: AssemblyFileVersion("0.0.9.0")]
37 |
--------------------------------------------------------------------------------
/src/DB/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/UnitTests/Mock/MockModelerDBLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Xml.Linq;
5 | using KitchenPC;
6 | using KitchenPC.Modeler;
7 | using KitchenPC.Recipes;
8 |
9 | namespace KPCServer.UnitTests
10 | {
11 | internal class MockModelerDBLoader : IModelerLoader
12 | {
13 | readonly RecipeBinding[] _dsRecipes;
14 | readonly IngredientBinding[] _dsIngredients;
15 | readonly RatingBinding[] _dsRatings;
16 |
17 | public MockModelerDBLoader(string filename)
18 | {
19 | var doc = XDocument.Load(filename);
20 |
21 | _dsRecipes = (from r in doc.Descendants("Recipe")
22 | select new RecipeBinding()
23 | {
24 | Id = new Guid(r.Attribute("Id").Value),
25 | Rating = Convert.ToByte(r.Attribute("Rating").Value),
26 | Tags = RecipeTags.Parse(r.Attribute("Tags").Value)
27 | }).ToArray();
28 |
29 | _dsIngredients = (from u in doc.Descendants("Usage")
30 | select new IngredientBinding()
31 | {
32 | RecipeId = new Guid(u.Attribute("RecipeId").Value),
33 | IngredientId = new Guid(u.Attribute("IngredientId").Value),
34 | Qty = Convert.ToSingle(u.Attribute("Qty").Value),
35 | Unit = Unit.Parse(u.Attribute("Unit").Value)
36 | }).ToArray();
37 |
38 | _dsRatings = (from r in doc.Descendants("Rating")
39 | select new RatingBinding()
40 | {
41 | UserId = new Guid(r.Attribute("UserId").Value),
42 | RecipeId = new Guid(r.Attribute("RecipeId").Value),
43 | Rating = Convert.ToByte(r.Attribute("Rating").Value)
44 | }).ToArray();
45 | }
46 |
47 | public IEnumerable LoadRecipeGraph()
48 | {
49 | return _dsRecipes;
50 | }
51 |
52 | public IEnumerable LoadIngredientGraph()
53 | {
54 | return _dsIngredients;
55 | }
56 |
57 | public IEnumerable LoadRatingGraph()
58 | {
59 | return _dsRatings;
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/UnitTests/Mock/Recipes.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using KitchenPC.Ingredients;
3 | using KitchenPC.Recipes;
4 |
5 | namespace KitchenPC.UnitTests.Mock
6 | {
7 | internal static class Recipes
8 | {
9 | public static Recipe MockRecipe(string title, string desc, RecipeTags tags = null)
10 | {
11 | var ret = new Recipe(Guid.NewGuid(), title, desc, null);
12 |
13 | ret.Method = "This is a mock recipe.";
14 | ret.OwnerAlias = "Fake Owner";
15 | ret.OwnerId = Guid.NewGuid();
16 | ret.Permalink = "http://www.kitchenpc.com/123";
17 | ret.ServingSize = 5;
18 | ret.Tags = tags;
19 |
20 | return ret;
21 | }
22 |
23 | public static Recipe BEST_BROWNIES
24 | {
25 | get
26 | {
27 | var r = new Recipe(new Guid("b11a64a9-95b3-402f-8b82-312bad539d4e"), "Best Brownies", "from scratch!", "");
28 |
29 | r.Tags = RecipeTag.NoMeat | RecipeTag.NoPork | RecipeTag.NoRedMeat | RecipeTag.Dessert;
30 | r.AvgRating = 5;
31 | r.CookTime = 40;
32 | r.PrepTime = 15;
33 | r.ServingSize = 24;
34 | r.AddIngredients(new IngredientUsage[]
35 | {
36 | new IngredientUsage(Ingredients.MARGARINE, Forms.MARGARINE_VOLUME, new Amount(1, Units.Cup), "in chunks"),
37 | new IngredientUsage(Ingredients.UNSWEETENED_BAKING_CHOCOLATE_SQUARES, Forms.UNSWEETENED_BAKING_CHOCOLATE_SQUARES_WEIGHT, new Amount(1, Units.Ounce), ""),
38 | new IngredientUsage(Ingredients.GRANULATED_SUGAR, Forms.GRANULATED_SUGAR_VOLUME, new Amount(2.66667f, Units.Cup), ""),
39 | new IngredientUsage(Ingredients.EGGS, Forms.EGGS_UNIT, new Amount(4, Units.Unit), "large"),
40 | new IngredientUsage(Ingredients.VANILLA_EXTRACT, Forms.VANILLA_EXTRACT_VOLUME, new Amount(2, Units.Teaspoon), ""),
41 | new IngredientUsage(Ingredients.ALL_PURPOSE_FLOUR, Forms.ALL_PURPOSE_FLOUR_SIFTED, new Amount(1, Units.Cup), "")
42 | });
43 |
44 | return r;
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/UnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("KitchenPC")]
9 | [assembly: AssemblyDescription("KitchenPC Unit Tests")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("KitchenPC")]
12 | [assembly: AssemblyProduct("UnitTests")]
13 | [assembly: AssemblyCopyright("Copyright © KitchenPC 2014")]
14 | [assembly: AssemblyTrademark("KitchenPC")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("9f663b61-439d-4171-b953-c69d42ff2893")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.0.9.0")]
36 | [assembly: AssemblyFileVersion("0.0.9.0")]
37 |
--------------------------------------------------------------------------------
/src/UnitTests/TestFormLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using KitchenPC.Ingredients;
3 | using KitchenPC.NLP;
4 |
5 | namespace KitchenPC.UnitTests
6 | {
7 | internal class TestFormLoader : ISynonymLoader
8 | {
9 | public IEnumerable LoadSynonyms()
10 | {
11 | FormNode[] nodes =
12 | {
13 | new FormNode("melted"),
14 | new FormNode("shredded"),
15 | new FormNode("diced")
16 | };
17 |
18 | return nodes;
19 | }
20 |
21 | public Pairings LoadFormPairings()
22 | {
23 | //TODO: This will come from a database of pairs that maps every possible unit to a default form of an ingredient
24 | var pairings = new Pairings();
25 | pairings.Add(new NameIngredientPair("melted", TestIngredientLoader.ING_CHEESE), new IngredientForm(TestIngredientLoader.FORM_CHEESE_MELTED, TestIngredientLoader.ING_CHEESE, Units.Cup, "melted", "", 0, null));
26 | pairings.Add(new NameIngredientPair("shredded", TestIngredientLoader.ING_CHEESE), new IngredientForm(TestIngredientLoader.FORM_CHEESE_SHREDDED, TestIngredientLoader.ING_CHEESE, Units.Cup, "shredded", "", 0, null));
27 | pairings.Add(new NameIngredientPair("diced", TestIngredientLoader.ING_CHEESE), new IngredientForm(TestIngredientLoader.FORM_CHEESE_DICED, TestIngredientLoader.ING_CHEESE, Units.Cup, "diced", "", 0, null));
28 |
29 | return pairings;
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/UnitTests/TestPrepLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using KitchenPC.NLP;
4 |
5 | namespace KitchenPC.UnitTests
6 | {
7 | internal class TestPrepLoader : ISynonymLoader
8 | {
9 | public Pairings LoadFormPairings()
10 | {
11 | throw new NotImplementedException();
12 | }
13 |
14 | public IEnumerable LoadSynonyms()
15 | {
16 | return new PrepNode[]
17 | {
18 | "sliced", "shredded", "crumbled", "diced", "chopped" //Test prep nodes (approved prep notes for any ingredient)
19 | };
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/UnitTests/TestUnitLoader.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using KitchenPC.Ingredients;
3 | using KitchenPC.NLP;
4 |
5 | namespace KitchenPC.UnitTests
6 | {
7 | internal class TestUnitLoader : ISynonymLoader
8 | {
9 | public IEnumerable LoadSynonyms()
10 | {
11 | //Add some test unit types, this will eventually come from database
12 | UnitNode[] units =
13 | {
14 | new CustomUnitNode("head"), new CustomUnitNode("heads")
15 | };
16 |
17 | return units;
18 | }
19 |
20 | public Pairings LoadFormPairings()
21 | {
22 | //TODO: This will come from a database of pairs that maps every possible unit to a default form of an ingredient
23 | var pairings = new Pairings();
24 | var pair = new NameIngredientPair("head", TestIngredientLoader.ING_LETTUCE);
25 | var form = new IngredientForm(TestIngredientLoader.FORM_LETTUCE_HEAD, TestIngredientLoader.ING_LETTUCE, Units.Unit, null, "head/heads", 0, null);
26 | pairings.Add(pair, form);
27 |
28 | return pairings;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/UnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | .
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/packages/FluentNHibernate.2.0.3.0/FluentNHibernate.2.0.3.0.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/FluentNHibernate.2.0.3.0/FluentNHibernate.2.0.3.0.nupkg
--------------------------------------------------------------------------------
/src/packages/FluentNHibernate.2.0.3.0/FluentNHibernate.2.0.3.0.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | FluentNHibernate
5 | 2.0.3.0
6 | FluentNHibernate
7 | James Gregory and contributors
8 | James Gregory and contributors
9 | http://github.com/jagregory/fluent-nhibernate/raw/master/LICENSE.txt
10 | http://fluentnhibernate.org/
11 | false
12 | Fluent, XML-less, compile safe, automated, convention-based mappings for NHibernate.
13 | en-US
14 | orm dal nhibernate conventions
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/packages/FluentNHibernate.2.0.3.0/lib/net40/FluentNHibernate.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/FluentNHibernate.2.0.3.0/lib/net40/FluentNHibernate.dll
--------------------------------------------------------------------------------
/src/packages/FluentNHibernate.2.0.3.0/lib/net40/FluentNHibernate.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/FluentNHibernate.2.0.3.0/lib/net40/FluentNHibernate.pdb
--------------------------------------------------------------------------------
/src/packages/Iesi.Collections.4.0.1.4000/Iesi.Collections.4.0.1.4000.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/Iesi.Collections.4.0.1.4000/Iesi.Collections.4.0.1.4000.nupkg
--------------------------------------------------------------------------------
/src/packages/Iesi.Collections.4.0.1.4000/Iesi.Collections.4.0.1.4000.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Iesi.Collections
5 | 4.0.1.4000
6 | Aidant Systems, Jason Smith, NHibernate community
7 | Aidant Systems, Jason Smith, NHibernate community
8 | https://github.com/nhibernate/iesi.collections
9 | false
10 | The System.Collections namespace in the .NET Framework provides a number of collection types that are extremely useful for manipulating data in memory. However, some specialized implementations of ISet are not available. Iesi.Collections 4.0 for .Net 4.0 contains the LinkedHashSet (preserves insertion order), the ReadOnlySet and the SynchronizedSet. The latter two wrap an actual set.
11 | Additional implementations of System.Collections.Generic.ISet<T>.
12 | en-US
13 | Collections
14 |
15 |
--------------------------------------------------------------------------------
/src/packages/Iesi.Collections.4.0.1.4000/lib/net40/Iesi.Collections.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/Iesi.Collections.4.0.1.4000/lib/net40/Iesi.Collections.dll
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/FireBird.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
17 |
18 |
19 | NHibernate.Driver.FirebirdClientDriver
20 |
21 | Server=localhost;
22 | Database=C:\nhibernate.fdb;
23 | User=SYSDBA;Password=masterkey
24 |
25 | false
26 | NHibernate.Dialect.FirebirdDialect
27 | 60
28 | true 1, false 0, yes 1, no 0
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/MSSQL.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | NHibernate.Driver.SqlClientDriver
11 |
12 | Server=(local);initial catalog=nhibernate;Integrated Security=SSPI
13 |
14 | NHibernate.Dialect.MsSql2008Dialect
15 |
16 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/MySql.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | NHibernate.Driver.MySqlDataDriver
11 |
12 | Database=test;Data Source=someip;User Id=blah;Password=blah
13 |
14 | NHibernate.Dialect.MySQLDialect
15 |
16 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/Oracle.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 | NHibernate.Driver.OracleClientDriver
11 |
12 | User ID=nhibernate;Password=nhibernate;Data Source=localhost
13 |
14 | false
15 | NHibernate.Dialect.OracleDialect
16 | true 1, false 0, yes 'Y', no 'N'
17 |
18 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/PostgreSQL.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | NHibernate.Driver.NpgsqlDriver
10 |
11 | Server=localhost;Database=nhibernate;User ID=nhibernate;Password=nhibernate;
12 |
13 | NHibernate.Dialect.PostgreSQL82Dialect
14 |
15 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/SQLite.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | NHibernate.Driver.SQLite20Driver
10 |
11 | Data Source=nhibernate.db
12 |
13 | NHibernate.Dialect.SQLiteDialect
14 |
15 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/SybaseASE.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | NHibernate.Driver.SybaseAseClientDriver
10 |
11 | Data Source=10.0.0.1;Port=5000;Database=nhibernate;User ID=nhibernate;Password=password
12 |
13 | NHibernate.Dialect.SybaseASE15Dialect
14 | true=1;false=0
15 |
16 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/ConfigurationTemplates/SybaseSQLAnywhere.cfg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | NHibernate.Driver.SybaseSQLAnywhereDriver
10 |
11 | UID=DBA;PWD=sql;Server=localhost;DBN=nhibernate;DBF=c:\nhibernate.db;ASTOP=No
12 |
13 | NHibernate.Dialect.SybaseSQLAnywhere12Dialect
14 | true=1;false=0
15 |
16 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/NHibernate.4.0.4.4000.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NHibernate.4.0.4.4000/NHibernate.4.0.4.4000.nupkg
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/NHibernate.4.0.4.4000.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NHibernate
5 | 4.0.4.4000
6 | NHibernate community, Hibernate community
7 | NHibernate community, Hibernate community
8 | https://raw.github.com/nhibernate/nhibernate-core/master/lgpl.txt
9 | http://nhibernate.info
10 | https://raw.github.com/nhibernate/nhibernate-core/master/logo/NHibernate-NuGet.png
11 | false
12 | NHibernate is a mature, open source object-relational mapper for the .NET framework. It is actively developed, fully featured and used in thousands of successful projects.
13 | NHibernate is a mature, open source object-relational mapper for the .NET framework. It is actively developed, fully featured and used in thousands of successful projects.
14 | en-US
15 | ORM DataBase DAL ObjectRelationalMapping
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/NHibernate.releasenotes.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NHibernate.4.0.4.4000/NHibernate.releasenotes.txt
--------------------------------------------------------------------------------
/src/packages/NHibernate.4.0.4.4000/lib/net40/NHibernate.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NHibernate.4.0.4.4000/lib/net40/NHibernate.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Charlie Poole
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
21 |
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/NOTICES.txt:
--------------------------------------------------------------------------------
1 | NUnit 3.0 is based on earlier versions of NUnit, with Portions
2 |
3 | Copyright (c) 2002-2014 Charlie Poole or
4 | Copyright (c) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov or
5 | Copyright (c) 2000-2002 Philip A. Craig
6 |
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/NUnit.3.4.1.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/NUnit.3.4.1.nupkg
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/NUnit.3.4.1.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NUnit
5 | 3.4.1
6 | NUnit
7 | Charlie Poole
8 | Charlie Poole
9 | http://nunit.org/nuget/nunit3-license.txt
10 | http://nunit.org/
11 | http://nunit.org/nuget/nunitv3_32x32.png
12 | false
13 | NUnit features a fluent assert syntax, parameterized, generic and theory tests and is user-extensible.
14 |
15 | This package includes the NUnit 3.0 framework assembly, which is referenced by your tests. You will need to install version 3.0 of the nunit3-console program or a third-party runner that supports NUnit 3.0 in order to execute tests. Runners intended for use with NUnit 2.x will not run 3.0 tests correctly.
16 |
17 | Supported platforms:
18 | - .NET 2.0+
19 | - .NET Core (Universal Windows Apps 10+, DNX Core 5+)
20 | - Windows 8
21 | - Windows Phone 8 (Silverlight)
22 | - Universal (Windows Phone 8.1+, Windows 8.1+)
23 | - Xamarin (MonoTouch, MonoAndroid, Xamarin iOS Universal)
24 | - Portable Libraries (supporting Profile259)
25 | NUnit is a unit-testing framework for all .Net languages with a strong TDD focus.
26 | This package includes the NUnit 3.0 framework assembly, which is referenced by your tests. You will need to install version 3.0 of the nunit3-console program or a third-party runner that supports NUnit 3.0 in order to execute tests. Runners intended for use with NUnit 2.x will not run 3.0 tests correctly.
27 | Copyright (c) 2016 Charlie Poole
28 | en-US
29 | nunit test testing tdd framework fluent assert theory plugin addin
30 |
31 |
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/dotnet/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/dotnet/nunit.framework.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/net20/NUnit.System.Linq.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/net20/NUnit.System.Linq.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/net20/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/net20/nunit.framework.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/net35/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/net35/nunit.framework.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/net40/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/net40/nunit.framework.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/net45/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/net45/nunit.framework.dll
--------------------------------------------------------------------------------
/src/packages/NUnit.3.4.1/lib/portable-net45+win8+wp8+wpa81+Xamarin.Mac+MonoAndroid10+MonoTouch10+Xamarin.iOS10/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/NUnit.3.4.1/lib/portable-net45+win8+wp8+wpa81+Xamarin.Mac+MonoAndroid10+MonoTouch10+Xamarin.iOS10/nunit.framework.dll
--------------------------------------------------------------------------------
/src/packages/Npgsql.3.1.7/Npgsql.3.1.7.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/Npgsql.3.1.7/Npgsql.3.1.7.nupkg
--------------------------------------------------------------------------------
/src/packages/Npgsql.3.1.7/Npgsql.3.1.7.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Npgsql
5 | 3.1.7
6 | Npgsql
7 | Npgsql
8 | https://raw.githubusercontent.com/npgsql/npgsql/develop/LICENSE.txt
9 | http://www.npgsql.org/img/postgresql.gif
10 | false
11 | Npgsql
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/packages/Npgsql.3.1.7/lib/net45/Npgsql.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/Npgsql.3.1.7/lib/net45/Npgsql.dll
--------------------------------------------------------------------------------
/src/packages/Npgsql.3.1.7/lib/net451/Npgsql.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/Npgsql.3.1.7/lib/net451/Npgsql.dll
--------------------------------------------------------------------------------
/src/packages/Npgsql.3.1.7/lib/netstandard1.3/Npgsql.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/Npgsql.3.1.7/lib/netstandard1.3/Npgsql.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net10-full/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net10-full/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net11-full/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net11-full/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net20-full/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net20-full/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net35-client/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net35-client/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net35-full/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net35-full/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net40-client/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net40-client/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net40-full/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net40-full/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/lib/net45-full/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/lib/net45-full/log4net.dll
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/log4net.2.0.5.nupkg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KitchenPC/core/34e0729f4aa947ed66d3ebb7d43d078acb3fe352/src/packages/log4net.2.0.5/log4net.2.0.5.nupkg
--------------------------------------------------------------------------------
/src/packages/log4net.2.0.5/log4net.2.0.5.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | log4net
5 | 2.0.5
6 | log4net [1.2.15]
7 | Apache Software Foundation
8 | Apache Software Foundation
9 | http://logging.apache.org/log4net/license.html
10 | http://logging.apache.org/log4net/
11 | false
12 | log4net is a tool to help the programmer output log statements to a variety of output targets. In case of problems with an application, it is helpful to enable logging so that the problem can be located. With log4net it is possible to enable logging at runtime without modifying the application binary. The log4net package is designed so that log statements can remain in shipped code without incurring a high performance cost. It follows that the speed of logging (or rather not logging) is crucial.
13 |
14 | At the same time, log output can be so voluminous that it quickly becomes overwhelming. One of the distinctive features of log4net is the notion of hierarchical loggers. Using these loggers it is possible to selectively control which log statements are output at arbitrary granularity.
15 |
16 | log4net is designed with two distinct goals in mind: speed and flexibility
17 | The Apache log4net library is a tool to help the programmer output log statements to a variety of output targets.
18 | logging log tracing logfiles
19 |
20 |
--------------------------------------------------------------------------------
/src/packages/repositories.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------