diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs
index bbf5b9b1..9df16428 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs
@@ -11,6 +11,7 @@ public class ConversationSetting
public bool EnableExecutionLog { get; set; }
public bool EnableContentLog { get; set; }
public bool EnableStateLog { get; set; }
+ public bool EnableTranslationMemory { get; set; }
public CleanConversationSetting CleanSetting { get; set; } = new CleanConversationSetting();
public RateLimitSetting RateLimit { get; set; } = new RateLimitSetting();
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Files/Converters/IPdf2ImageConverter.cs b/src/Infrastructure/BotSharp.Abstraction/Files/Converters/IPdf2ImageConverter.cs
new file mode 100644
index 00000000..54ad3a6d
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Files/Converters/IPdf2ImageConverter.cs
@@ -0,0 +1,12 @@
+namespace BotSharp.Abstraction.Files.Converters;
+
+public interface IPdf2ImageConverter
+{
+ ///
+ /// Convert pdf pages to images, and return a list of image file paths
+ ///
+ /// Pdf file location
+ /// Image folder location
+ ///
+ Task> ConvertPdfToImages(string pdfLocation, string imageFolderLocation);
+}
diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
index 2bbaacc6..e8a9aa7a 100644
--- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
+++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj
@@ -181,7 +181,11 @@
+
+
+
+
diff --git a/src/Infrastructure/BotSharp.Core/Files/BotSharpFileService.Conversation.cs b/src/Infrastructure/BotSharp.Core/Files/BotSharpFileService.Conversation.cs
index 61e12145..a072e6fe 100644
--- a/src/Infrastructure/BotSharp.Core/Files/BotSharpFileService.Conversation.cs
+++ b/src/Infrastructure/BotSharp.Core/Files/BotSharpFileService.Conversation.cs
@@ -1,5 +1,5 @@
-using BotSharp.Abstraction.Browsing;
-using BotSharp.Abstraction.Browsing.Models;
+using BotSharp.Abstraction.Files.Converters;
+using BotSharp.Core.Files.Converters;
using Microsoft.EntityFrameworkCore;
using System.IO;
using System.Linq;
@@ -51,18 +51,8 @@ public partial class BotSharpFileService
try
{
- var msgInfo = new MessageInfo
- {
- ContextId = Guid.NewGuid().ToString()
- };
- var web = _services.GetRequiredService();
var preFixPath = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER);
- if (isNeedScreenShot)
- {
- await web.LaunchBrowser(msgInfo);
- }
-
foreach (var messageId in messageIds)
{
var dir = Path.Combine(preFixPath, messageId, source);
@@ -91,40 +81,40 @@ public partial class BotSharpFileService
var screenShotDir = Path.Combine(subDir, SCREENSHOT_FILE_FOLDER);
if (ExistDirectory(screenShotDir) && Directory.GetFiles(screenShotDir).Any())
{
- file = Directory.GetFiles(screenShotDir).First();
- contentType = GetFileContentType(file);
-
- var model = new MessageFileModel()
+ foreach (var screenShot in Directory.GetFiles(screenShotDir))
{
- MessageId = messageId,
- FileStorageUrl = file,
- ContentType = contentType
- };
- files.Add(model);
+ contentType = GetFileContentType(screenShot);
+ if (!_allowedImageTypes.Contains(contentType)) continue;
+
+ var model = new MessageFileModel()
+ {
+ MessageId = messageId,
+ FileStorageUrl = screenShot,
+ ContentType = contentType
+ };
+ files.Add(model);
+ }
}
else
{
- await web.GoToPage(msgInfo, new PageActionArgs { Url = file });
- var path = Path.Combine(subDir, SCREENSHOT_FILE_FOLDER, $"{Guid.NewGuid()}.png");
- await web.ScreenshotAsync(msgInfo, path);
- contentType = GetFileContentType(path);
+ var screenShotPath = Path.Combine(subDir, SCREENSHOT_FILE_FOLDER);
+ var images = await ConvertPdfToImages(file, screenShotPath);
- var model = new MessageFileModel()
+ foreach (var image in images)
{
- MessageId = messageId,
- FileStorageUrl = path,
- ContentType = contentType
- };
- files.Add(model);
+ contentType = GetFileContentType(image);
+ var model = new MessageFileModel()
+ {
+ MessageId = messageId,
+ FileStorageUrl = image,
+ ContentType = contentType
+ };
+ files.Add(model);
+ }
}
}
}
}
-
- if (isNeedScreenShot)
- {
- await web.CloseBrowser(msgInfo.ContextId);
- }
}
catch (Exception ex)
{
@@ -227,9 +217,13 @@ public partial class BotSharpFileService
Directory.CreateDirectory(subDir);
}
- using var fs = new FileStream(Path.Combine(subDir, file.FileName), FileMode.Create);
- fs.Write(bytes, 0, bytes.Length);
- fs.Flush(true);
+ using (var fs = new FileStream(Path.Combine(subDir, file.FileName), FileMode.Create))
+ {
+ fs.Write(bytes, 0, bytes.Length);
+ fs.Flush(true);
+ fs.Close();
+ Thread.Sleep(100);
+ }
}
return true;
@@ -318,5 +312,20 @@ public partial class BotSharpFileService
var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId);
return dir;
}
+
+ private async Task> ConvertPdfToImages(string pdfLoc, string imageLoc)
+ {
+ var converters = _services.GetServices();
+ if (converters.IsNullOrEmpty()) return Enumerable.Empty();
+
+ var converter = converters.FirstOrDefault(x => x.GetType().Name != typeof(PdfiumConverter).Name);
+ if (converter == null)
+ {
+ converter = converters.FirstOrDefault(x => x.GetType().Name == typeof(PdfiumConverter).Name);
+ if (converter == null) return Enumerable.Empty();
+ }
+
+ return await converter.ConvertPdfToImages(pdfLoc, imageLoc);
+ }
#endregion
}
diff --git a/src/Infrastructure/BotSharp.Core/Files/Converters/PdfiumConverter.cs b/src/Infrastructure/BotSharp.Core/Files/Converters/PdfiumConverter.cs
new file mode 100644
index 00000000..4ee0e3da
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core/Files/Converters/PdfiumConverter.cs
@@ -0,0 +1,39 @@
+using BotSharp.Abstraction.Files.Converters;
+using PdfiumViewer;
+using System.IO;
+
+namespace BotSharp.Core.Files.Converters;
+
+public class PdfiumConverter : IPdf2ImageConverter
+{
+ public async Task> ConvertPdfToImages(string pdfLocation, string imageFolderLocation)
+ {
+ var paths = new List();
+ if (string.IsNullOrWhiteSpace(imageFolderLocation)) return paths;
+
+ if (Directory.Exists(imageFolderLocation))
+ {
+ Directory.Delete(imageFolderLocation, true);
+ }
+ Directory.CreateDirectory(imageFolderLocation);
+
+ var guid = Guid.NewGuid().ToString();
+ using (var document = PdfDocument.Load(pdfLocation))
+ {
+ var pages = document.PageCount;
+
+ for (var page = 0; page < pages; page++)
+ {
+ var size = document.PageSizes[page];
+ using (var image = document.Render(page, (int)size.Width, (int)size.Height, 96, 96, true))
+ {
+ var imagePath = Path.Combine(imageFolderLocation, $"{guid}_pg_{page + 1}.png");
+ image.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png);
+ paths.Add(imagePath);
+ }
+ }
+ }
+
+ return await Task.FromResult(paths);
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Core/Files/FilePlugin.cs b/src/Infrastructure/BotSharp.Core/Files/FilePlugin.cs
index e549011b..a3256051 100644
--- a/src/Infrastructure/BotSharp.Core/Files/FilePlugin.cs
+++ b/src/Infrastructure/BotSharp.Core/Files/FilePlugin.cs
@@ -1,3 +1,5 @@
+using BotSharp.Abstraction.Files.Converters;
+using BotSharp.Core.Files.Converters;
using BotSharp.Core.Files.Hooks;
using Microsoft.Extensions.Configuration;
@@ -16,7 +18,8 @@ public class FilePlugin : IBotSharpPlugin
{
services.AddScoped();
- services.AddScoped();
+ services.AddScoped();
services.AddScoped();
+ services.AddScoped();
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs b/src/Infrastructure/BotSharp.Core/Files/Hooks/FileAnalyzerHook.cs
similarity index 91%
rename from src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs
rename to src/Infrastructure/BotSharp.Core/Files/Hooks/FileAnalyzerHook.cs
index 8fc1c11d..24c9b4f5 100644
--- a/src/Infrastructure/BotSharp.Core/Files/Hooks/AttachmentProcessingHook.cs
+++ b/src/Infrastructure/BotSharp.Core/Files/Hooks/FileAnalyzerHook.cs
@@ -1,12 +1,12 @@
namespace BotSharp.Core.Files.Hooks;
-public class AttachmentProcessingHook : AgentHookBase
+public class FileAnalyzerHook : AgentHookBase
{
private static string TOOL_ASSISTANT = Guid.Empty.ToString();
public override string SelfId => string.Empty;
- public AttachmentProcessingHook(IServiceProvider services, AgentSettings settings)
+ public FileAnalyzerHook(IServiceProvider services, AgentSettings settings)
: base(services, settings)
{
}
diff --git a/src/Infrastructure/BotSharp.Core/Translation/TranslationService.cs b/src/Infrastructure/BotSharp.Core/Translation/TranslationService.cs
index 399f9c0d..f9aa73e3 100644
--- a/src/Infrastructure/BotSharp.Core/Translation/TranslationService.cs
+++ b/src/Infrastructure/BotSharp.Core/Translation/TranslationService.cs
@@ -13,6 +13,7 @@ public class TranslationService : ITranslationService
{
private readonly IServiceProvider _services;
private readonly IBotSharpRepository _db;
+ private readonly ConversationSetting _convSettings;
private readonly ILogger _logger;
private readonly BotSharpOptions _options;
private Agent _router;
@@ -22,11 +23,13 @@ public class TranslationService : ITranslationService
public TranslationService(
IServiceProvider services,
IBotSharpRepository db,
+ ConversationSetting convSettings,
ILogger logger,
BotSharpOptions options)
{
_services = services;
_db = db;
+ _convSettings = convSettings;
_logger = logger;
_options = options;
}
@@ -69,18 +72,23 @@ public class TranslationService : ITranslationService
HashText = Utilities.HashTextSha256(x),
Language = language
}).ToList();
- var memories = _db.GetTranslationMemories(queries);
- var memoryHashes = memories.Select(x => x.HashText).ToList();
+ var outOfMemoryList = queries;
- foreach (var memory in memories)
+ if (_convSettings.EnableTranslationMemory)
{
- map[memory.OriginalText] = memory.TranslatedText;
- }
+ var memories = _db.GetTranslationMemories(queries);
+ var memoryHashes = memories.Select(x => x.HashText).ToList();
- var outOfMemoryList = queries.Where(x => !memoryHashes.Contains(x.HashText)).ToList();
+ foreach (var memory in memories)
+ {
+ map[memory.OriginalText] = memory.TranslatedText;
+ }
+
+ outOfMemoryList = queries.Where(x => !memoryHashes.Contains(x.HashText)).ToList();
+ }
#endregion
- var texts = outOfMemoryList.ToArray()
+ var texts = outOfMemoryList
.Select((text, i) => new TranslationInput
{
Id = i + 1,
@@ -123,7 +131,10 @@ public class TranslationService : ITranslationService
});
}
- _db.SaveTranslationMemories(memoryInputs);
+ if (_convSettings.EnableTranslationMemory)
+ {
+ _db.SaveTranslationMemories(memoryInputs);
+ }
}
clonedData = Assign(clonedData, map);
diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json
index b5a15122..6439e25a 100644
--- a/src/WebStarter/appsettings.json
+++ b/src/WebStarter/appsettings.json
@@ -136,6 +136,7 @@
"EnableExecutionLog": true,
"EnableContentLog": true,
"EnableStateLog": true,
+ "EnableTranslationMemory": false,
"CleanSetting": {
"Enable": true,
"BatchSize": 50,