diff --git a/.gitignore b/.gitignore index 585f8689..f0892edc 100644 --- a/.gitignore +++ b/.gitignore @@ -290,3 +290,4 @@ __pycache__/ /Data /docs/_build *.RestApi.xml +/BotSharp.WebHost/App_Data/AgentStorage diff --git a/BotSharp.Core/AgentStorage/AgentStorageInFile.cs b/BotSharp.Core/AgentStorage/AgentStorageInFile.cs new file mode 100644 index 00000000..a930be30 --- /dev/null +++ b/BotSharp.Core/AgentStorage/AgentStorageInFile.cs @@ -0,0 +1,115 @@ +using BotSharp.Platform.Abstraction; +using BotSharp.Platform.Models; +using CSRedis; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BotSharp.Core.AgentStorage +{ + public class AgentStorageInFile : IAgentStorage + where TAgent : AgentBase + { + private static CSRedisClient csredis; + private static string prefix = String.Empty; + + private static string storageDir; + + public AgentStorageInFile() + { + IConfiguration config = (IConfiguration)AppDomain.CurrentDomain.GetData("Configuration"); + var db = config.GetSection("Database:Default").Value; + storageDir = config.GetSection($"Database:ConnectionStrings:{db}").Value; + string contentDir = AppDomain.CurrentDomain.GetData("DataPath").ToString(); + storageDir = storageDir.Replace("|DataDirectory|", contentDir + Path.DirectorySeparatorChar); + + if (!Directory.Exists(storageDir)) + { + Directory.CreateDirectory(storageDir); + } + } + + public async Task FetchById(string agentId) + { + string dataPath = Path.Combine(storageDir, agentId + ".json"); + if (File.Exists(dataPath)) + { + string json = File.ReadAllText(dataPath); + return JsonConvert.DeserializeObject(json); + } + else + { + return default(TAgent); + } + } + + public async Task FetchByName(string agentName) + { + var files = Directory.GetFiles(storageDir); + for (int i = 0; i < files.Length; i++) + { + var file = files[i]; + string json = File.ReadAllText(file); + var agent = JsonConvert.DeserializeObject(json); + if (agent.Name.ToLower() == agentName.ToLower()) + { + return agent; + } + } + + return default(TAgent); + } + + public async Task Persist(TAgent agent) + { + if (String.IsNullOrEmpty(agent.Id)) + { + agent.Id = Guid.NewGuid().ToString(); + } + + var json = JsonConvert.SerializeObject(agent, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented, + }); + + string dataPath = Path.Combine(storageDir, agent.Id + ".json"); + + File.WriteAllText(dataPath, json); + + return true; + } + + public async Task PurgeAllAgents() + { + var files = Directory.GetFiles(storageDir); + for (int i = 0; i < files.Length; i++) + { + File.Delete(files[i]); + } + + return files.Length; + } + + public async Task> Query() + { + var agents = new List(); + + var files = Directory.GetFiles(storageDir); + for (int i = 0; i < files.Length; i++) + { + var file = files[i]; + string json = File.ReadAllText(file); + var agent = JsonConvert.DeserializeObject(json); + agents.Add(agent); + } + + return agents; + } + } +} diff --git a/BotSharp.Core/AgentStorage/AgentStorageServiceRegister.cs b/BotSharp.Core/AgentStorage/AgentStorageServiceRegister.cs index 535bb2d1..3c8f30c7 100644 --- a/BotSharp.Core/AgentStorage/AgentStorageServiceRegister.cs +++ b/BotSharp.Core/AgentStorage/AgentStorageServiceRegister.cs @@ -17,6 +17,7 @@ namespace BotSharp.Core.AgentStorage services.AddSingleton>(); services.AddSingleton>(); + services.AddSingleton>(); services.AddSingleton(factory => { @@ -30,6 +31,10 @@ namespace BotSharp.Core.AgentStorage { return factory.GetService>(); } + else if (key.Equals("AgentStorageInFile")) + { + return factory.GetService>(); + } else { throw new ArgumentException($"Not Support key : {key}"); diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj index 1332e91a..127c3644 100644 --- a/BotSharp.Core/BotSharp.Core.csproj +++ b/BotSharp.Core/BotSharp.Core.csproj @@ -21,13 +21,13 @@ If you feel that this project is helpful to you, please Star on the project, we MIT https://github.com/Oceania2018/BotSharp NLU, Chatbot, Bot, AI Bot, Artificial Intelligence - 1.7.1 + 1.7.2 Monthly Update. Integrated with Tencent Wechat. If you feel that this project is helpful to you, please Star on the project, we will be very grateful. Since 2018 Haiping Chen https://github.com/Oceania2018/BotSharp - 1.7.1.0 + 1.7.2.0 https://raw.githubusercontent.com/Oceania2018/BotSharp/master/BotSharp.WebHost/wwwroot/images/BotSharp.png https://github.com/Oceania2018/BotSharp/blob/master/LICENSE diff --git a/BotSharp.Core/Modules/ModulesStartup.cs b/BotSharp.Core/Modules/ModulesStartup.cs index 3dbae39c..16ccc2e6 100644 --- a/BotSharp.Core/Modules/ModulesStartup.cs +++ b/BotSharp.Core/Modules/ModulesStartup.cs @@ -32,6 +32,11 @@ namespace BotSharp.Core.Modules throw new ArgumentNullException(nameof(configuration)); ModulesOptions options = configuration.Get(); + if (options.Modules.Count == 0) + { + Console.WriteLine($"Platform emulator not found.", Color.Red); + } + this._modules = options.Modules .Select(s => { @@ -48,6 +53,7 @@ namespace BotSharp.Core.Modules else { IModule module = (IModule)Activator.CreateInstance(type); + Console.WriteLine($"Loaded module \"{s.Type}\"", Color.Green); return module; } } @@ -82,6 +88,7 @@ namespace BotSharp.Core.Modules { foreach (IModule module in this._modules) { + if (module == null) continue; module.Configure(app, env); } } diff --git a/BotSharp.Core/PlatformBuilderBase.cs b/BotSharp.Core/PlatformBuilderBase.cs index 1d991f6a..334f8c2b 100644 --- a/BotSharp.Core/PlatformBuilderBase.cs +++ b/BotSharp.Core/PlatformBuilderBase.cs @@ -36,6 +36,8 @@ namespace BotSharp.Core public async Task LoadAgentFromFile(string dataDir) where TImporter : IAgentImporter, new() { + Console.WriteLine($"Loading agent from folder {dataDir}"); + var meta = LoadMeta(dataDir); var importer = new TImporter { @@ -54,6 +56,8 @@ namespace BotSharp.Core // Load system buildin entities await importer.LoadBuildinEntities(agent); + Console.WriteLine($"Loaded agent: {agent.Name} {agent.Id}"); + return agent; } diff --git a/BotSharp.Core/PlatformSettingsBase.cs b/BotSharp.Core/PlatformSettingsBase.cs index a2d00268..5eeebd92 100644 --- a/BotSharp.Core/PlatformSettingsBase.cs +++ b/BotSharp.Core/PlatformSettingsBase.cs @@ -15,7 +15,7 @@ namespace BotSharp.Core public PlatformSettingsBase() { BotEngine = "BotSharpNLU"; - AgentStorage = "AgentStorageInMemory"; + AgentStorage = "AgentStorageInFile"; } public string BotEngine { get; set; } diff --git a/BotSharp.WebHost/BotSharp.WebHost.csproj b/BotSharp.WebHost/BotSharp.WebHost.csproj index 2f90f4e5..a145174e 100644 --- a/BotSharp.WebHost/BotSharp.WebHost.csproj +++ b/BotSharp.WebHost/BotSharp.WebHost.csproj @@ -30,11 +30,13 @@ + + @@ -42,11 +44,13 @@ + + diff --git a/BotSharp.WebHost/Settings/DialogflowAi.json b/BotSharp.WebHost/Settings/DialogflowAi.json index 3e97eb18..062c51ce 100644 --- a/BotSharp.WebHost/Settings/DialogflowAi.json +++ b/BotSharp.WebHost/Settings/DialogflowAi.json @@ -1,7 +1,7 @@ { // if you want to override platform setting, please set corresponding value, otherwise you don't need this section. - "dialogflowAi": { - "botEngine": "BotSharpNLU", - "agentStorage": "AgentStorageInRedis" - } + "dialogflowAi": { + "botEngine": "BotSharpNLU", + "agentStorage": "AgentStorageInFile" + } } diff --git a/BotSharp.WebHost/Settings/app.json b/BotSharp.WebHost/Settings/app.json index 49abd0bf..c79a99a9 100644 --- a/BotSharp.WebHost/Settings/app.json +++ b/BotSharp.WebHost/Settings/app.json @@ -4,19 +4,11 @@ "platformModuleName": "DialogflowAi", - "machineLearning": { - "dataDir": "D:\\Projects\\BotSharp\\Data" - }, - "modules": [ - { + /*{ "Name": "DialogflowAi", "Type": "BotSharp.Platform.Dialogflow" }, - { - "Name": "WeixinChannel", - "Type": "BotSharp.Channel.Weixin" - }/*, { "Name": "RasaAi", "Type": "BotSharp.Platform.Rasa", diff --git a/BotSharp.WebHost/Settings/db.json b/BotSharp.WebHost/Settings/db.json index 63b7fcae..4482fb34 100644 --- a/BotSharp.WebHost/Settings/db.json +++ b/BotSharp.WebHost/Settings/db.json @@ -1,11 +1,12 @@ { "Database": { - "Default": "Redis", + "Default": "File", "ConnectionStrings": { "InMemory": "DataSource=:memory:", "Redis": "127.0.0.1:6379,defaultDatabase=BotSharp,poolsize=50,ssl=false,writeBuffer=10240,prefix=agent_", "Sqlite": "Data Source=|DataDirectory|BotSharp.db;", - "SqlServer": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=BotSharp;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" + "SqlServer": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=BotSharp;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False", + "File": "|DataDirectory|AgentStorage" } } } \ No newline at end of file diff --git a/BotSharp.WebHost/Startup.cs b/BotSharp.WebHost/Startup.cs index 9ef2eecf..57853e80 100644 --- a/BotSharp.WebHost/Startup.cs +++ b/BotSharp.WebHost/Startup.cs @@ -40,7 +40,7 @@ namespace BotSharp.WebHost options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); - PlatformModuleAssembyLoader.LoadAssemblies(Configuration, assembly => mvcBuilder.AddApplicationPart(assembly)); + //PlatformModuleAssembyLoader.LoadAssemblies(Configuration, assembly => mvcBuilder.AddApplicationPart(assembly)); this.modulesStartup.ConfigureServices(services);