Skip to content

user avatar #466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ public interface IBotSharpFileService
string GetDirectory(string conversationId);
IEnumerable<MessageFileModel> GetChatImages(string conversationId, List<RoleDialogModel> conversations, int offset = 2);
IEnumerable<MessageFileModel> GetMessageFiles(string conversationId, IEnumerable<string> messageIds, bool imageOnly = false);
string? GetMessageFile(string conversationId, string messageId, string fileName);
void SaveMessageFiles(string conversationId, string messageId, List<BotSharpFile> files);
string GetMessageFile(string conversationId, string messageId, string fileName);
bool SaveMessageFiles(string conversationId, string messageId, List<BotSharpFile> files);

string GetUserAvatar();
bool SaveUserAvatar(BotSharpFile file);

/// <summary>
/// Delete files under messages
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
using Microsoft.AspNetCore.StaticFiles;
using System.IO;
using System.Threading;

namespace BotSharp.Core.Files;

public partial class BotSharpFileService
{
public IEnumerable<MessageFileModel> GetChatImages(string conversationId, List<RoleDialogModel> conversations, int offset = 1)
{
var files = new List<MessageFileModel>();
if (string.IsNullOrEmpty(conversationId) || conversations.IsNullOrEmpty())
{
return files;
}

if (offset <= 0)
{
offset = MIN_OFFSET;
}
else if (offset > MAX_OFFSET)
{
offset = MAX_OFFSET;
}

var messageIds = conversations.Select(x => x.MessageId).Distinct().TakeLast(offset).ToList();
files = GetMessageFiles(conversationId, messageIds, imageOnly: true).ToList();
return files;
}

public IEnumerable<MessageFileModel> GetMessageFiles(string conversationId, IEnumerable<string> messageIds, bool imageOnly = false)
{
var files = new List<MessageFileModel>();
if (messageIds.IsNullOrEmpty()) return files;

foreach (var messageId in messageIds)
{
var dir = GetConversationFileDirectory(conversationId, messageId);
if (!ExistDirectory(dir))
{
continue;
}

foreach (var file in Directory.GetFiles(dir))
{
var contentType = GetFileContentType(file);
if (imageOnly && !_allowedTypes.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}/file/{fileName}",
FileStorageUrl = file,
FileName = fileName,
FileType = fileType,
ContentType = contentType
};
files.Add(model);
}
}

return files;
}

public string GetMessageFile(string conversationId, string messageId, string fileName)
{
var dir = GetConversationFileDirectory(conversationId, messageId);
if (!ExistDirectory(dir))
{
return string.Empty;
}

var found = Directory.GetFiles(dir).FirstOrDefault(f => Path.GetFileNameWithoutExtension(f).IsEqualTo(fileName));
return found;
}

public bool SaveMessageFiles(string conversationId, string messageId, List<BotSharpFile> files)
{
if (files.IsNullOrEmpty()) return false;

var dir = GetConversationFileDirectory(conversationId, messageId, createNewDir: true);
if (!ExistDirectory(dir)) return false;

try
{
for (int i = 0; i < files.Count; i++)
{
var file = files[i];
if (string.IsNullOrEmpty(file.FileData))
{
continue;
}

var (_, bytes) = GetFileInfoFromData(file.FileData);
var fileType = Path.GetExtension(file.FileName);
var fileName = $"{i + 1}{fileType}";
Thread.Sleep(100);
File.WriteAllBytes(Path.Combine(dir, fileName), bytes);
}
return true;
}
catch (Exception ex)
{
_logger.LogWarning($"Error when saving conversation files: {ex.Message}");
return false;
}
}



public bool DeleteMessageFiles(string conversationId, IEnumerable<string> 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);
}
}

foreach (var messageId in messageIds)
{
var dir = GetConversationFileDirectory(conversationId, messageId);
if (string.IsNullOrEmpty(dir)) continue;

Thread.Sleep(100);
Directory.Delete(dir, true);
}

return true;
}

public bool DeleteConversationFiles(IEnumerable<string> 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
}
65 changes: 65 additions & 0 deletions src/Infrastructure/BotSharp.Core/Files/BotSharpFileService.User.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.IO;

namespace BotSharp.Core.Files;

public partial class BotSharpFileService
{
public string GetUserAvatar()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserById(_user.Id);
var dir = GetUserAvatarDir(user?.Id);

if (!ExistDirectory(dir)) return string.Empty;

var found = Directory.GetFiles(dir).FirstOrDefault() ?? string.Empty;
return found;
}

public bool SaveUserAvatar(BotSharpFile file)
{
if (file == null || string.IsNullOrEmpty(file.FileData)) return false;

try
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var user = db.GetUserById(_user.Id);
var dir = GetUserAvatarDir(user?.Id);

if (string.IsNullOrEmpty(dir)) return false;

if (Directory.Exists(dir))
{
Directory.Delete(dir, true);
}

dir = GetUserAvatarDir(user?.Id, createNewDir: true);
var (_, bytes) = GetFileInfoFromData(file.FileData);
File.WriteAllBytes(Path.Combine(dir, file.FileName), bytes);
return true;
}
catch (Exception ex)
{
_logger.LogWarning($"Error when saving user avatar: {ex.Message}");
return false;
}
}


#region Private methods
private string GetUserAvatarDir(string? userId, bool createNewDir = false)
{
if (string.IsNullOrEmpty(userId))
{
return string.Empty;
}

var dir = Path.Combine(_baseDir, USERS_FOLDER, userId, USER_AVATAR_FOLDER);
if (!Directory.Exists(dir) && createNewDir)
{
Directory.CreateDirectory(dir);
}
return dir;
}
#endregion
}
Loading