add get message file screenshots
This commit is contained in:
parent
0af2085c33
commit
32e1da62c0
|
|
@ -6,19 +6,12 @@ public interface IFileStorageService
|
|||
{
|
||||
#region Conversation
|
||||
/// <summary>
|
||||
/// Get the files that have been uploaded in the chat.
|
||||
/// If includeScreenShot is true, it will take the screenshots of non-image files, such as pdf, and return the screenshots instead of the original file.
|
||||
/// Get the message file screenshots for specific content types, e.g., pdf
|
||||
/// </summary>
|
||||
/// <param name="conversationId"></param>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="dialogs"></param>
|
||||
/// <param name="contentTypes"></param>
|
||||
/// <param name="includeScreenShot"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="messageIds"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<MessageFileModel>> GetChatFiles(string conversationId, string source,
|
||||
IEnumerable<RoleDialogModel> dialogs, IEnumerable<string>? contentTypes,
|
||||
bool includeScreenShot = false, int? offset = null);
|
||||
Task<IEnumerable<MessageFileModel>> GetMessageFileScreenshots(string conversationId, IEnumerable<string> messageIds);
|
||||
|
||||
/// <summary>
|
||||
/// Get the files that have been uploaded in the chat. No screenshot images are included.
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public class FileBase
|
|||
/// <summary>
|
||||
/// File extension without dot
|
||||
/// </summary>
|
||||
[JsonPropertyName("file_type")]
|
||||
[JsonPropertyName("file_extension")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? FileType { get; set; } = string.Empty;
|
||||
public string? FileExtension { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@ public class MessageFileModel : FileBase
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"File name: {FileName}, File type: {FileType}, Content type: {ContentType}, Source: {FileSource}";
|
||||
return $"File name: {FileName}, File extension: {FileExtension}, Content type: {ContentType}, Source: {FileSource}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,48 @@ namespace BotSharp.Abstraction.Files.Models;
|
|||
|
||||
public class SelectFileOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Llm provider
|
||||
/// </summary>
|
||||
public string? Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Llm model id
|
||||
/// </summary>
|
||||
public string? ModelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Agent id
|
||||
/// </summary>
|
||||
public string? AgentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Template (prompt) name
|
||||
/// </summary>
|
||||
public string? Template { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Description that user provides to select files
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether include bot generated files
|
||||
/// </summary>
|
||||
public bool IncludeBotFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Conversation breakpoint
|
||||
/// </summary>
|
||||
public bool FromBreakpoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Message offset from last
|
||||
/// </summary>
|
||||
public int? Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File content types. If null, all types of files will be retrived
|
||||
/// </summary>
|
||||
public IEnumerable<string>? ContentTypes { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(TargetFramework)</TargetFramework>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public partial class FileInstructService
|
|||
{
|
||||
var promptFiles = files.Select((x, idx) =>
|
||||
{
|
||||
return $"id: {idx + 1}, file_name: {x.FileName}.{x.FileType}, content_type: {x.ContentType}, author: {x.FileSource}";
|
||||
return $"id: {idx + 1}, file_name: {x.FileName}.{x.FileExtension}, content_type: {x.ContentType}, author: {x.FileSource}";
|
||||
}).ToList();
|
||||
|
||||
var agentId = !string.IsNullOrWhiteSpace(options.AgentId) ? options.AgentId : BuiltInAgentId.UtilityAssistant;
|
||||
|
|
|
|||
|
|
@ -6,22 +6,20 @@ namespace BotSharp.Core.Files.Services;
|
|||
|
||||
public partial class LocalFileStorageService
|
||||
{
|
||||
public async Task<IEnumerable<MessageFileModel>> GetChatFiles(string conversationId, string source,
|
||||
IEnumerable<RoleDialogModel> dialogs, IEnumerable<string>? contentTypes = null,
|
||||
bool includeScreenShot = false, int? offset = null)
|
||||
public async Task<IEnumerable<MessageFileModel>> GetMessageFileScreenshots(string conversationId, IEnumerable<string> messageIds)
|
||||
{
|
||||
var files = new List<MessageFileModel>();
|
||||
if (string.IsNullOrEmpty(conversationId) || dialogs.IsNullOrEmpty())
|
||||
if (string.IsNullOrEmpty(conversationId) || messageIds.IsNullOrEmpty())
|
||||
{
|
||||
return files;
|
||||
}
|
||||
|
||||
var messageIds = GetMessageIds(dialogs, offset);
|
||||
var source = FileSourceType.User;
|
||||
var pathPrefix = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER);
|
||||
|
||||
foreach (var messageId in messageIds)
|
||||
{
|
||||
var dir = Path.Combine(pathPrefix, messageId, source);
|
||||
var dir = Path.Combine(pathPrefix, messageId, FileSourceType.User);
|
||||
if (!ExistDirectory(dir)) continue;
|
||||
|
||||
foreach (var subDir in Directory.GetDirectories(dir))
|
||||
|
|
@ -30,18 +28,49 @@ public partial class LocalFileStorageService
|
|||
if (file == null) continue;
|
||||
|
||||
var contentType = FileUtility.GetFileContentType(file);
|
||||
if (!contentTypes.IsNullOrEmpty() && !contentTypes.Contains(contentType))
|
||||
var screenshotDir = Path.Combine(subDir, SCREENSHOT_FILE_FOLDER);
|
||||
|
||||
if (ExistDirectory(screenshotDir) && !Directory.GetFiles(screenshotDir).IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
foreach (var screenshot in Directory.GetFiles(screenshotDir))
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(screenshot);
|
||||
var fileExtension = Path.GetExtension(screenshot).Substring(1);
|
||||
var screenshotContentType = FileUtility.GetFileContentType(screenshot);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileExtension = fileExtension,
|
||||
FileStorageUrl = screenshot,
|
||||
ContentType = screenshotContentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
else if (contentType == MediaTypeNames.Application.Pdf)
|
||||
{
|
||||
var images = await ConvertPdfToImages(file, screenshotDir);
|
||||
foreach (var image in images)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(image);
|
||||
var fileExtension = Path.GetExtension(image).Substring(1);
|
||||
var screenshotContentType = FileUtility.GetFileContentType(image);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileExtension = fileExtension,
|
||||
FileStorageUrl = image,
|
||||
ContentType = screenshotContentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
|
||||
var foundFiles = await GetMessageFiles(file, subDir, contentType, messageId, source, includeScreenShot);
|
||||
if (foundFiles.IsNullOrEmpty()) continue;
|
||||
|
||||
files.AddRange(foundFiles);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
|
@ -72,14 +101,14 @@ public partial class LocalFileStorageService
|
|||
}
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(file);
|
||||
var fileType = Path.GetExtension(file).Substring(1);
|
||||
var fileExtension = Path.GetExtension(file).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileUrl = $"/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}",
|
||||
FileStorageUrl = file,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileExtension = fileExtension,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
|
|
@ -268,85 +297,6 @@ public partial class LocalFileStorageService
|
|||
return messageIds;
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<MessageFileModel>> GetMessageFiles(string file, string fileDir, string contentType,
|
||||
string messageId, string source, bool includeScreenShot)
|
||||
{
|
||||
var files = new List<MessageFileModel>();
|
||||
|
||||
try
|
||||
{
|
||||
if (!_imageTypes.Contains(contentType) && includeScreenShot)
|
||||
{
|
||||
var screenShotDir = Path.Combine(fileDir, SCREENSHOT_FILE_FOLDER);
|
||||
if (ExistDirectory(screenShotDir) && !Directory.GetFiles(screenShotDir).IsNullOrEmpty())
|
||||
{
|
||||
foreach (var screenShot in Directory.GetFiles(screenShotDir))
|
||||
{
|
||||
contentType = FileUtility.GetFileContentType(screenShot);
|
||||
if (!_imageTypes.Contains(contentType)) continue;
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(screenShot);
|
||||
var fileType = Path.GetExtension(file).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileStorageUrl = screenShot,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
else if (contentType == MediaTypeNames.Application.Pdf)
|
||||
{
|
||||
var images = await ConvertPdfToImages(file, screenShotDir);
|
||||
foreach (var image in images)
|
||||
{
|
||||
contentType = FileUtility.GetFileContentType(image);
|
||||
var fileName = Path.GetFileNameWithoutExtension(image);
|
||||
var fileType = Path.GetExtension(image).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileStorageUrl = image,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(file);
|
||||
var fileType = Path.GetExtension(file).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileStorageUrl = file,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning($"Error when getting message files {file} (messageId: {messageId}), Error: {ex.Message}\r\n{ex.InnerException}");
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<string>> ConvertPdfToImages(string pdfLoc, string imageLoc)
|
||||
{
|
||||
var converters = _services.GetServices<IPdf2ImageConverter>();
|
||||
|
|
@ -9,11 +9,6 @@ public partial class LocalFileStorageService : IFileStorageService
|
|||
private readonly IUserIdentity _user;
|
||||
private readonly ILogger<LocalFileStorageService> _logger;
|
||||
private readonly string _baseDir;
|
||||
private readonly IEnumerable<string> _imageTypes = new List<string>
|
||||
{
|
||||
MediaTypeNames.Image.Png,
|
||||
MediaTypeNames.Image.Jpeg
|
||||
};
|
||||
|
||||
private const string CONVERSATION_FOLDER = "conversations";
|
||||
private const string FILE_FOLDER = "files";
|
||||
|
|
@ -10,8 +10,8 @@ public class MessageFileViewModel
|
|||
[JsonPropertyName("file_name")]
|
||||
public string FileName { get; set; }
|
||||
|
||||
[JsonPropertyName("file_type")]
|
||||
public string FileType { get; set; }
|
||||
[JsonPropertyName("file_extension")]
|
||||
public string FileExtension { get; set; }
|
||||
|
||||
[JsonPropertyName("content_type")]
|
||||
public string ContentType { get; set; }
|
||||
|
|
@ -30,7 +30,7 @@ public class MessageFileViewModel
|
|||
{
|
||||
FileUrl = model.FileUrl,
|
||||
FileName = model.FileName,
|
||||
FileType = model.FileType,
|
||||
FileExtension = model.FileExtension,
|
||||
ContentType = model.ContentType,
|
||||
FileSource = model.FileSource
|
||||
};
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
||||
var settingsService = _services.GetRequiredService<ILlmProviderService>();
|
||||
var settings = settingsService.GetSetting(Provider, _model);
|
||||
var allowMultiModal = settings != null && settings.MultiModal;
|
||||
|
|
@ -262,13 +263,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
{
|
||||
foreach (var file in message.Files)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(file.FileUrl))
|
||||
{
|
||||
var uri = new Uri(file.FileUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(uri, ImageChatMessageContentPartDetail.Low);
|
||||
contentParts.Add(contentPart);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(file.FileData))
|
||||
if (!string.IsNullOrEmpty(file.FileData))
|
||||
{
|
||||
var (contentType, bytes) = FileUtility.GetFileInfoFromData(file.FileData);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(BinaryData.FromBytes(bytes), contentType, ImageChatMessageContentPartDetail.Low);
|
||||
|
|
@ -277,8 +272,14 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
else if (!string.IsNullOrEmpty(file.FileStorageUrl))
|
||||
{
|
||||
var contentType = FileUtility.GetFileContentType(file.FileStorageUrl);
|
||||
using var stream = File.OpenRead(file.FileStorageUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(BinaryData.FromStream(stream), contentType, ImageChatMessageContentPartDetail.Low);
|
||||
var bytes = fileStorage.GetFileBytes(file.FileStorageUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(BinaryData.FromBytes(bytes), contentType, ImageChatMessageContentPartDetail.Low);
|
||||
contentParts.Add(contentPart);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(file.FileUrl))
|
||||
{
|
||||
var uri = new Uri(file.FileUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(uri, ImageChatMessageContentPartDetail.Low);
|
||||
contentParts.Add(contentPart);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
using BotSharp.Abstraction.Files.Utilities;
|
||||
using MailKit.Net.Smtp;
|
||||
using MailKit.Security;
|
||||
using MimeKit;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Plugin.EmailHandler.Functions;
|
||||
|
||||
|
|
@ -92,7 +90,7 @@ public class HandleEmailSenderFn : IFunctionCallback
|
|||
|
||||
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
||||
var fileBytes = fileStorage.GetFileBytes(file.FileStorageUrl);
|
||||
builder.Attachments.Add($"{file.FileName}.{file.FileType}", fileBytes, ContentType.Parse(file.ContentType));
|
||||
builder.Attachments.Add($"{file.FileName}.{file.FileExtension}", fileBytes, ContentType.Parse(file.ContentType));
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public class EditImageFn : IFunctionCallback
|
|||
stream.Close();
|
||||
SaveGeneratedImage(result?.GeneratedImages?.FirstOrDefault());
|
||||
|
||||
return $"Image \"{image.FileName}.{image.FileType}\" is successfylly editted.";
|
||||
return $"Image \"{image.FileName}.{image.FileExtension}\" is successfylly editted.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,12 +8,6 @@ public class ReadImageFn : IFunctionCallback
|
|||
private readonly IServiceProvider _services;
|
||||
private readonly ILogger<ReadImageFn> _logger;
|
||||
|
||||
private readonly IEnumerable<string> _imageContentTypes = new List<string>
|
||||
{
|
||||
MediaTypeNames.Image.Png,
|
||||
MediaTypeNames.Image.Jpeg,
|
||||
};
|
||||
|
||||
public ReadImageFn(
|
||||
IServiceProvider services,
|
||||
ILogger<ReadImageFn> logger)
|
||||
|
|
@ -52,7 +46,14 @@ public class ReadImageFn : IFunctionCallback
|
|||
}
|
||||
|
||||
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
||||
var images = await fileStorage.GetChatFiles(conversationId, FileSourceType.User, dialogs, _imageContentTypes);
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
|
||||
var messageIds = dialogs.Select(x => x.MessageId).Distinct().ToList();
|
||||
var images = fileStorage.GetMessageFiles(conversationId, messageIds, FileSourceType.User, new List<string>
|
||||
{
|
||||
MediaTypeNames.Image.Png,
|
||||
MediaTypeNames.Image.Jpeg
|
||||
});
|
||||
|
||||
foreach (var dialog in dialogs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,11 +51,16 @@ public class ReadPdfFn : IFunctionCallback
|
|||
}
|
||||
|
||||
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
||||
var files = await fileStorage.GetChatFiles(conversationId, FileSourceType.User, dialogs, _pdfContentTypes, includeScreenShot: true);
|
||||
var fileInstruct = _services.GetRequiredService<IFileInstructService>();
|
||||
|
||||
var messageIds = dialogs.Select(x => x.MessageId).Distinct().ToList();
|
||||
var screenshots = await fileStorage.GetMessageFileScreenshots(conversationId, messageIds);
|
||||
|
||||
if (screenshots.IsNullOrEmpty()) return dialogs;
|
||||
|
||||
foreach (var dialog in dialogs)
|
||||
{
|
||||
var found = files.Where(x => x.MessageId == dialog.MessageId).ToList();
|
||||
var found = screenshots.Where(x => x.MessageId == dialog.MessageId).ToList();
|
||||
if (found.IsNullOrEmpty()) continue;
|
||||
|
||||
dialog.Files = found.Select(x => new BotSharpFile
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var fileStorage = _services.GetRequiredService<IFileStorageService>();
|
||||
var settingsService = _services.GetRequiredService<ILlmProviderService>();
|
||||
var settings = settingsService.GetSetting(Provider, _model);
|
||||
var allowMultiModal = settings != null && settings.MultiModal;
|
||||
|
|
@ -263,13 +264,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
{
|
||||
foreach (var file in message.Files)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(file.FileUrl))
|
||||
{
|
||||
var uri = new Uri(file.FileUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(uri, ImageChatMessageContentPartDetail.Low);
|
||||
contentParts.Add(contentPart);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(file.FileData))
|
||||
if (!string.IsNullOrEmpty(file.FileData))
|
||||
{
|
||||
var (contentType, bytes) = FileUtility.GetFileInfoFromData(file.FileData);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(BinaryData.FromBytes(bytes), contentType, ImageChatMessageContentPartDetail.Low);
|
||||
|
|
@ -278,8 +273,14 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
else if (!string.IsNullOrEmpty(file.FileStorageUrl))
|
||||
{
|
||||
var contentType = FileUtility.GetFileContentType(file.FileStorageUrl);
|
||||
using var stream = File.OpenRead(file.FileStorageUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(BinaryData.FromStream(stream), contentType, ImageChatMessageContentPartDetail.Low);
|
||||
var bytes = fileStorage.GetFileBytes(file.FileStorageUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(BinaryData.FromBytes(bytes), contentType, ImageChatMessageContentPartDetail.Low);
|
||||
contentParts.Add(contentPart);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(file.FileUrl))
|
||||
{
|
||||
var uri = new Uri(file.FileUrl);
|
||||
var contentPart = ChatMessageContentPart.CreateImageMessageContentPart(uri, ImageChatMessageContentPartDetail.Low);
|
||||
contentParts.Add(contentPart);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using AspectInjector.Broker;
|
||||
using BotSharp.Abstraction.Files.Converters;
|
||||
using BotSharp.Abstraction.Files.Enums;
|
||||
using BotSharp.Abstraction.Files.Utilities;
|
||||
|
|
@ -7,38 +8,68 @@ namespace BotSharp.Plugin.TencentCos.Services;
|
|||
|
||||
public partial class TencentCosService
|
||||
{
|
||||
public async Task<IEnumerable<MessageFileModel>> GetChatFiles(string conversationId, string source,
|
||||
IEnumerable<RoleDialogModel> dialogs, IEnumerable<string>? contentTypes = null,
|
||||
bool includeScreenShot = false, int? offset = null)
|
||||
public async Task<IEnumerable<MessageFileModel>> GetMessageFileScreenshots(string conversationId, IEnumerable<string> messageIds)
|
||||
{
|
||||
var files = new List<MessageFileModel>();
|
||||
if (string.IsNullOrEmpty(conversationId) || dialogs.IsNullOrEmpty())
|
||||
if (string.IsNullOrEmpty(conversationId) || messageIds.IsNullOrEmpty())
|
||||
{
|
||||
return files;
|
||||
}
|
||||
|
||||
var messageIds = GetMessageIds(dialogs, offset);
|
||||
var source = FileSourceType.User;
|
||||
var pathPrefix = $"{CONVERSATION_FOLDER}/{conversationId}/{FILE_FOLDER}";
|
||||
|
||||
foreach (var messageId in messageIds)
|
||||
{
|
||||
var dir = $"{pathPrefix}/{messageId}/{source}";
|
||||
|
||||
foreach (var subDir in _cosClient.BucketClient.GetDirectories(dir))
|
||||
{
|
||||
var file = _cosClient.BucketClient.GetDirFiles(subDir).FirstOrDefault();
|
||||
if (file == null) continue;
|
||||
|
||||
var contentType = FileUtility.GetFileContentType(file);
|
||||
if (!contentTypes.IsNullOrEmpty() && !contentTypes.Contains(contentType))
|
||||
var screenshotDir = $"{subDir}/{SCREENSHOT_FILE_FOLDER}/";
|
||||
var screenshots = _cosClient.BucketClient.GetDirFiles(screenshotDir);
|
||||
if (!screenshots.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
foreach (var screenshot in screenshots)
|
||||
{
|
||||
var screenshotContentType = FileUtility.GetFileContentType(screenshot);
|
||||
var fileName = Path.GetFileNameWithoutExtension(screenshot);
|
||||
var fileExtension = Path.GetExtension(screenshot).Substring(1);
|
||||
var model = new MessageFileModel
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileExtension = fileExtension,
|
||||
FileUrl = BuilFileUrl(screenshot),
|
||||
FileStorageUrl = screenshot,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
else if (contentType == MediaTypeNames.Application.Pdf)
|
||||
{
|
||||
var images = await ConvertPdfToImages(file, screenshotDir);
|
||||
foreach (var image in images)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(image);
|
||||
var fileExtension = Path.GetExtension(image).Substring(1);
|
||||
var screenshotContentType = FileUtility.GetFileContentType(image);
|
||||
var model = new MessageFileModel
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileExtension = fileExtension,
|
||||
FileUrl = BuilFileUrl(image),
|
||||
FileStorageUrl = image,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
|
||||
var foundFiles = await GetMessageFiles(file, subDir, contentType, messageId, source, includeScreenShot);
|
||||
if (foundFiles.IsNullOrEmpty()) continue;
|
||||
|
||||
files.AddRange(foundFiles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,14 +101,14 @@ public partial class TencentCosService
|
|||
}
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(file);
|
||||
var fileType = Path.GetExtension(file).Substring(1);
|
||||
var fileExtension = Path.GetExtension(file).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileUrl = BuilFileUrl(file),
|
||||
FileStorageUrl = file,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileExtension = fileExtension,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
|
|
@ -94,7 +125,6 @@ public partial class TencentCosService
|
|||
var dir = $"{CONVERSATION_FOLDER}/{conversationId}/{FILE_FOLDER}/{source}/{index}/";
|
||||
|
||||
var fileList = _cosClient.BucketClient.GetDirFiles(dir);
|
||||
|
||||
var found = fileList.FirstOrDefault(f => Path.GetFileNameWithoutExtension(f).IsEqualTo(fileName));
|
||||
return found;
|
||||
}
|
||||
|
|
@ -246,88 +276,6 @@ public partial class TencentCosService
|
|||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<MessageFileModel>> GetMessageFiles(string file, string fileDir, string contentType,
|
||||
string messageId, string source, bool includeScreenShot)
|
||||
{
|
||||
var files = new List<MessageFileModel>();
|
||||
try
|
||||
{
|
||||
if (!_imageTypes.Contains(contentType) && includeScreenShot)
|
||||
{
|
||||
var screenShotDir = $"{fileDir}/{SCREENSHOT_FILE_FOLDER}/";
|
||||
var fileList = _cosClient.BucketClient.GetDirFiles(screenShotDir);
|
||||
|
||||
if (!fileList.IsNullOrEmpty())
|
||||
{
|
||||
foreach (var screenShot in fileList)
|
||||
{
|
||||
contentType = FileUtility.GetFileContentType(screenShot);
|
||||
if (!_imageTypes.Contains(contentType)) continue;
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(screenShot);
|
||||
var fileType = Path.GetExtension(file).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileUrl = BuilFileUrl(screenShot),
|
||||
FileStorageUrl = screenShot,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
else if (contentType == MediaTypeNames.Application.Pdf)
|
||||
{
|
||||
var images = await ConvertPdfToImages(file, screenShotDir);
|
||||
foreach (var image in images)
|
||||
{
|
||||
contentType = FileUtility.GetFileContentType(image);
|
||||
var fileName = Path.GetFileNameWithoutExtension(image);
|
||||
var fileType = Path.GetExtension(image).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileUrl = BuilFileUrl(image),
|
||||
FileStorageUrl = image,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(file);
|
||||
var fileType = Path.GetExtension(file).Substring(1);
|
||||
var model = new MessageFileModel()
|
||||
{
|
||||
MessageId = messageId,
|
||||
FileName = fileName,
|
||||
FileType = fileType,
|
||||
FileUrl = BuilFileUrl(file),
|
||||
FileStorageUrl = file,
|
||||
ContentType = contentType,
|
||||
FileSource = source
|
||||
};
|
||||
files.Add(model);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning($"Error when getting message files {file} (messageId: {messageId}), Error: {ex.Message}\r\n{ex.InnerException}");
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<string>> ConvertPdfToImages(string pdfLoc, string imageLoc)
|
||||
{
|
||||
var converters = _services.GetServices<IPdf2ImageConverter>();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public partial class TencentCosService : IFileStorageService
|
|||
_user = user;
|
||||
_logger = logger;
|
||||
_services = services;
|
||||
_fullBuketName = $"{_settings.BucketName}-{_settings.AppId}";
|
||||
_fullBuketName = $"{settings.BucketName}-{settings.AppId}";
|
||||
_cosClient = cosClient;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue