using BotSharp.Abstraction.Browsing; using Microsoft.EntityFrameworkCore; using System.IO; using System.Linq; using System.Threading; namespace BotSharp.Core.Files; public partial class BotSharpFileService { public IEnumerable GetChatImages(string conversationId, string source, List conversations, int? offset = null) { var files = new List(); if (string.IsNullOrEmpty(conversationId) || conversations.IsNullOrEmpty()) { return files; } if (offset <= 0) { offset = MIN_OFFSET; } else if (offset > MAX_OFFSET) { offset = MAX_OFFSET; } var messageIds = new List(); if (offset.HasValue) { messageIds = conversations.Select(x => x.MessageId).Distinct().TakeLast(offset.Value).ToList(); } else { messageIds = conversations.Select(x => x.MessageId).Distinct().ToList(); } files = GetMessageFiles(conversationId, messageIds, source, imageOnly: true).ToList(); return files; } public IEnumerable GetMessageFiles(string conversationId, IEnumerable messageIds, string source, bool imageOnly = false) { var files = new List(); if (messageIds.IsNullOrEmpty()) return files; foreach (var messageId in messageIds) { var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER, messageId, source); if (!ExistDirectory(dir)) { continue; } foreach (var subDir in Directory.GetDirectories(dir)) { var index = subDir.Split(Path.DirectorySeparatorChar).Last(); foreach (var file in Directory.GetFiles(subDir)) { var contentType = GetFileContentType(file); if (imageOnly && !_allowedImageTypes.Contains(contentType)) { continue; } var fileName = Path.GetFileNameWithoutExtension(file); var extension = Path.GetExtension(file); var fileType = extension.Substring(1); var model = new MessageFileModel() { MessageId = messageId, FileUrl = $"/conversation/{conversationId}/message/{messageId}/{source}/file/{index}/{fileName}", FileStorageUrl = file, FileName = fileName, FileType = fileType, ContentType = contentType }; files.Add(model); } } } return files; } public string GetMessageFile(string conversationId, string messageId, string source, string index, string fileName) { var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER, messageId, source, index); if (!ExistDirectory(dir)) { return string.Empty; } var found = Directory.GetFiles(dir).FirstOrDefault(f => Path.GetFileNameWithoutExtension(f).IsEqualTo(fileName)); return found; } public bool HasConversationUserFiles(string conversationId) { if (string.IsNullOrEmpty(conversationId)) return false; var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER, USER_FILE_FOLDER); if (!ExistDirectory(dir)) return false; return Directory.GetDirectories(dir).Count() > 0; } public bool SaveMessageFiles(string conversationId, string messageId, string source, List files) { if (files.IsNullOrEmpty()) return false; var dir = GetConversationFileDirectory(conversationId, messageId, createNewDir: true); if (!ExistDirectory(dir)) return false; //var contextId = string.Empty; //var web = _services.GetRequiredService(); //var isNeedScreenShot = files.Any(x => _allowScreenShotTypes.Contains(Path.GetExtension(x.FileName))); //var preFixPath = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER, messageId); try { //if (isNeedScreenShot) //{ // var state = _services.GetRequiredService(); // contextId = state.GetConversationId() ?? Guid.NewGuid().ToString(); // await web.LaunchBrowser(contextId, string.Empty); //} for (int i = 0; i < files.Count; i++) { var file = files[i]; if (string.IsNullOrEmpty(file.FileData)) { continue; } var (_, bytes) = GetFileInfoFromData(file.FileData); Thread.Sleep(100); var subDir = Path.Combine(dir, source, $"{i + 1}"); if (!ExistDirectory(subDir)) { Directory.CreateDirectory(subDir); } File.WriteAllBytes(Path.Combine(subDir, file.FileName), bytes); //if (isNeedScreenShot && _allowScreenShotTypes.Contains(fileType)) //{ // var path = Path.Combine(preFixPath, fileName); // await web.GoToPage(contextId, path); // path = Path.Combine(preFixPath, $"{Guid.NewGuid()}.{i + 1}.png"); // await web.ScreenshotAsync(contextId, path); //} } //if (isNeedScreenShot) //{ // await web.CloseBrowser(contextId); //} return true; } catch (Exception ex) { _logger.LogWarning($"Error when saving conversation files: {ex.Message}"); return false; } } public bool DeleteMessageFiles(string conversationId, IEnumerable messageIds, string targetMessageId, string? newMessageId = null) { if (string.IsNullOrEmpty(conversationId) || messageIds == null) return false; if (!string.IsNullOrEmpty(targetMessageId) && !string.IsNullOrEmpty(newMessageId)) { var prevDir = GetConversationFileDirectory(conversationId, targetMessageId); var newDir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER, newMessageId); if (ExistDirectory(prevDir)) { if (ExistDirectory(newDir)) { Directory.Delete(newDir, true); } Directory.Move(prevDir, newDir); Thread.Sleep(100); var botDir = Path.Combine(newDir, BOT_FILE_FOLDER); if (ExistDirectory(botDir)) { Directory.Delete(botDir, true); } } } foreach (var messageId in messageIds) { var dir = GetConversationFileDirectory(conversationId, messageId); if (!ExistDirectory(dir)) continue; Thread.Sleep(100); Directory.Delete(dir, true); } return true; } public bool DeleteConversationFiles(IEnumerable conversationIds) { if (conversationIds.IsNullOrEmpty()) return false; foreach (var conversationId in conversationIds) { var convDir = FindConversationDirectory(conversationId); if (!ExistDirectory(convDir)) continue; Directory.Delete(convDir, true); } return true; } #region Private methods private string GetConversationFileDirectory(string? conversationId, string? messageId, bool createNewDir = false) { if (string.IsNullOrEmpty(conversationId) || string.IsNullOrEmpty(messageId)) { return string.Empty; } var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId, FILE_FOLDER, messageId); if (!Directory.Exists(dir) && createNewDir) { Directory.CreateDirectory(dir); } return dir; } private string? FindConversationDirectory(string conversationId) { if (string.IsNullOrEmpty(conversationId)) return null; var dir = Path.Combine(_baseDir, CONVERSATION_FOLDER, conversationId); return dir; } #endregion }