347 lines
11 KiB
C#
347 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
using _0_Framework.Application;
|
|
using _0_Framework.Application.FaceEmbedding;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Http;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace _0_Framework.Infrastructure;
|
|
|
|
/// <summary>
|
|
/// پیادهسازی سرویس ارتباط با API پایتون برای مدیریت Embeddings چهره
|
|
/// </summary>
|
|
public class FaceEmbeddingService : IFaceEmbeddingService
|
|
{
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
private readonly ILogger<FaceEmbeddingService> _logger;
|
|
private readonly IFaceEmbeddingNotificationService _notificationService;
|
|
private readonly string _apiBaseUrl;
|
|
|
|
public FaceEmbeddingService(IHttpClientFactory httpClientFactory, ILogger<FaceEmbeddingService> logger,
|
|
IFaceEmbeddingNotificationService notificationService = null)
|
|
{
|
|
_httpClientFactory = httpClientFactory;
|
|
_logger = logger;
|
|
_notificationService = notificationService;
|
|
_apiBaseUrl = "http://localhost:8000";
|
|
}
|
|
|
|
public async Task<OperationResult> GenerateEmbeddingsAsync(long employeeId, long workshopId,
|
|
string employeeFullName, string picture1Path, string picture2Path)
|
|
{
|
|
try
|
|
{
|
|
var httpClient = _httpClientFactory.CreateClient();
|
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
|
|
|
using var content = new MultipartFormDataContent();
|
|
|
|
// Add form fields
|
|
content.Add(new StringContent(employeeId.ToString()), "employee_id");
|
|
content.Add(new StringContent(workshopId.ToString()), "workshop_id");
|
|
content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name");
|
|
|
|
// Add picture files
|
|
if (File.Exists(picture1Path))
|
|
{
|
|
var picture1Bytes = await File.ReadAllBytesAsync(picture1Path);
|
|
var picture1Content = new ByteArrayContent(picture1Bytes);
|
|
picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
|
content.Add(picture1Content, "picture1", "1.jpg");
|
|
}
|
|
else
|
|
{
|
|
_logger.LogWarning("Picture1 not found at path: {Path}", picture1Path);
|
|
return new OperationResult { IsSuccedded = false, Message = "تصویر اول یافت نشد" };
|
|
}
|
|
|
|
if (File.Exists(picture2Path))
|
|
{
|
|
var picture2Bytes = await File.ReadAllBytesAsync(picture2Path);
|
|
var picture2Content = new ByteArrayContent(picture2Bytes);
|
|
picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
|
content.Add(picture2Content, "picture2", "2.jpg");
|
|
}
|
|
else
|
|
{
|
|
_logger.LogWarning("Picture2 not found at path: {Path}", picture2Path);
|
|
return new OperationResult { IsSuccedded = false, Message = "تصویر دوم یافت نشد" };
|
|
}
|
|
|
|
// Send request to Python API
|
|
var response = await httpClient.PostAsync("embeddings", content);
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
_logger.LogInformation("Embeddings generated successfully for Employee {EmployeeId}, Workshop {WorkshopId}",
|
|
employeeId, workshopId);
|
|
|
|
// ارسال اطلاعرسانی به سایر سیستمها
|
|
if (_notificationService != null)
|
|
{
|
|
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
|
|
}
|
|
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = true,
|
|
Message = "Embedding با موفقیت ایجاد شد"
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
_logger.LogError("Failed to generate embeddings. Status: {StatusCode}, Error: {Error}",
|
|
response.StatusCode, errorContent);
|
|
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = $"خطا در تولید Embedding: {response.StatusCode}"
|
|
};
|
|
}
|
|
}
|
|
catch (HttpRequestException ex)
|
|
{
|
|
_logger.LogError(ex, "HTTP error while calling embeddings API for Employee {EmployeeId}", employeeId);
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = "خطا در ارتباط با سرور Embedding"
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error while calling embeddings API for Employee {EmployeeId}", employeeId);
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = "خطای غیرمنتظره در تولید Embedding"
|
|
};
|
|
}
|
|
}
|
|
|
|
public async Task<OperationResult> GenerateEmbeddingsFromStreamAsync(long employeeId, long workshopId,
|
|
string employeeFullName, Stream picture1Stream, Stream picture2Stream)
|
|
{
|
|
try
|
|
{
|
|
var httpClient = _httpClientFactory.CreateClient();
|
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
|
|
|
using var content = new MultipartFormDataContent();
|
|
|
|
// Add form fields
|
|
content.Add(new StringContent(employeeId.ToString()), "employee_id");
|
|
content.Add(new StringContent(workshopId.ToString()), "workshop_id");
|
|
content.Add(new StringContent(employeeFullName ?? ""), "employee_full_name");
|
|
|
|
// Add picture streams
|
|
var picture1Content = new StreamContent(picture1Stream);
|
|
picture1Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
|
content.Add(picture1Content, "picture1", "1.jpg");
|
|
|
|
var picture2Content = new StreamContent(picture2Stream);
|
|
picture2Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
|
|
content.Add(picture2Content, "picture2", "2.jpg");
|
|
|
|
// Send request to Python API
|
|
var response = await httpClient.PostAsync("embeddings", content);
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
_logger.LogInformation("Embeddings generated successfully from streams for Employee {EmployeeId}", employeeId);
|
|
|
|
// ارسال اطلاعرسانی به سایر سیستمها
|
|
if (_notificationService != null)
|
|
{
|
|
await _notificationService.NotifyEmbeddingCreatedAsync(workshopId, employeeId, employeeFullName);
|
|
}
|
|
|
|
return new OperationResult { IsSuccedded = true, Message = "Embedding با موفقیت ایجاد شد" };
|
|
}
|
|
else
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
_logger.LogError("Failed to generate embeddings from streams. Status: {StatusCode}, Error: {Error}",
|
|
response.StatusCode, errorContent);
|
|
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = $"خطا در تولید Embedding: {response.StatusCode}"
|
|
};
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error while generating embeddings from streams for Employee {EmployeeId}", employeeId);
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = "خطا در تولید Embedding"
|
|
};
|
|
}
|
|
}
|
|
|
|
public async Task<OperationResult> RefineEmbeddingAsync(long employeeId, long workshopId, float[] embedding,
|
|
float confidence, Dictionary<string, object> metadata = null)
|
|
{
|
|
try
|
|
{
|
|
var httpClient = _httpClientFactory.CreateClient();
|
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
|
|
|
var requestBody = new
|
|
{
|
|
employeeId,
|
|
workshopId,
|
|
embedding,
|
|
confidence,
|
|
metadata = metadata ?? new Dictionary<string, object>()
|
|
};
|
|
|
|
var response = await httpClient.PostAsJsonAsync("embeddings/refine", requestBody);
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
_logger.LogInformation("Embedding refined successfully for Employee {EmployeeId}", employeeId);
|
|
|
|
// ارسال اطلاعرسانی به سایر سیستمها
|
|
if (_notificationService != null)
|
|
{
|
|
await _notificationService.NotifyEmbeddingRefinedAsync(workshopId, employeeId);
|
|
}
|
|
|
|
return new OperationResult { IsSuccedded = true, Message = "Embedding بهبود یافت" };
|
|
}
|
|
else
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
_logger.LogError("Failed to refine embedding. Status: {StatusCode}, Error: {Error}",
|
|
response.StatusCode, errorContent);
|
|
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = $"خطا در بهبود Embedding: {response.StatusCode}"
|
|
};
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error while refining embedding for Employee {EmployeeId}", employeeId);
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = "خطا در بهبود Embedding"
|
|
};
|
|
}
|
|
}
|
|
|
|
public async Task<OperationResult> DeleteEmbeddingAsync(long employeeId, long workshopId)
|
|
{
|
|
try
|
|
{
|
|
var httpClient = _httpClientFactory.CreateClient();
|
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
|
|
|
var response = await httpClient.DeleteAsync($"embeddings/{workshopId}/{employeeId}");
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
_logger.LogInformation("Embedding deleted successfully for Employee {EmployeeId}", employeeId);
|
|
|
|
// ارسال اطلاعرسانی به سایر سیستمها
|
|
if (_notificationService != null)
|
|
{
|
|
await _notificationService.NotifyEmbeddingDeletedAsync(workshopId, employeeId);
|
|
}
|
|
|
|
return new OperationResult { IsSuccedded = true, Message = "Embedding حذف شد" };
|
|
}
|
|
else
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
_logger.LogError("Failed to delete embedding. Status: {StatusCode}, Error: {Error}",
|
|
response.StatusCode, errorContent);
|
|
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = $"خطا در حذف Embedding: {response.StatusCode}"
|
|
};
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error while deleting embedding for Employee {EmployeeId}", employeeId);
|
|
return new OperationResult
|
|
{
|
|
IsSuccedded = false,
|
|
Message = "خطا در حذف Embedding"
|
|
};
|
|
}
|
|
}
|
|
|
|
public async Task<OperationResult<FaceEmbeddingResponse>> GetEmbeddingAsync(long employeeId, long workshopId)
|
|
{
|
|
try
|
|
{
|
|
var httpClient = _httpClientFactory.CreateClient();
|
|
httpClient.BaseAddress = new Uri(_apiBaseUrl);
|
|
httpClient.Timeout = TimeSpan.FromSeconds(30);
|
|
|
|
var response = await httpClient.GetAsync($"embeddings/{workshopId}/{employeeId}");
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
var embeddingData = JsonSerializer.Deserialize<FaceEmbeddingResponse>(content,
|
|
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
|
|
_logger.LogInformation("Embedding retrieved successfully for Employee {EmployeeId}", employeeId);
|
|
|
|
return new OperationResult<FaceEmbeddingResponse>
|
|
{
|
|
IsSuccedded = true,
|
|
Message = "Embedding دریافت شد",
|
|
Data = embeddingData
|
|
};
|
|
}
|
|
else
|
|
{
|
|
var errorContent = await response.Content.ReadAsStringAsync();
|
|
_logger.LogError("Failed to get embedding. Status: {StatusCode}, Error: {Error}",
|
|
response.StatusCode, errorContent);
|
|
|
|
return new OperationResult<FaceEmbeddingResponse>
|
|
{
|
|
IsSuccedded = false,
|
|
Message = $"خطا در دریافت Embedding: {response.StatusCode}"
|
|
};
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error while getting embedding for Employee {EmployeeId}", employeeId);
|
|
return new OperationResult<FaceEmbeddingResponse>
|
|
{
|
|
IsSuccedded = false,
|
|
Message = "خطا در دریافت Embedding"
|
|
};
|
|
}
|
|
}
|
|
}
|