Fix 1830
This commit is contained in:
@@ -10,99 +10,80 @@ using static Elecciones.Core.DTOs.BancaDto;
|
||||
|
||||
namespace Elecciones.Infrastructure.Services;
|
||||
|
||||
// Implementación de emergencia que usa el comando 'curl' del sistema operativo
|
||||
public class CurlElectoralApiService : IElectoralApiService
|
||||
{
|
||||
private readonly ILogger<CurlElectoralApiService> _logger;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly string _baseUrl;
|
||||
private readonly ILogger<CurlElectoralApiService> _logger;
|
||||
|
||||
public CurlElectoralApiService(ILogger<CurlElectoralApiService> logger, IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
_baseUrl = _configuration["ElectoralApi:BaseUrl"] ?? "";
|
||||
}
|
||||
|
||||
private async Task<(int, string)> ExecuteCurlCommand(string arguments)
|
||||
{
|
||||
var process = new Process
|
||||
public CurlElectoralApiService(ILogger<CurlElectoralApiService> logger, IConfiguration configuration)
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "curl",
|
||||
Arguments = arguments,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
string output = await process.StandardOutput.ReadToEndAsync();
|
||||
string error = await process.StandardError.ReadToEndAsync();
|
||||
await process.WaitForExitAsync();
|
||||
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
_logger.LogError("Error al ejecutar curl. Exit Code: {ExitCode}. Error: {Error}", process.ExitCode, error);
|
||||
return (-1, error);
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
// Extraemos el código de estado HTTP del final del stderr si usamos -w
|
||||
// (Simplificación: asumimos 200 si el ExitCode es 0)
|
||||
return (200, output);
|
||||
}
|
||||
|
||||
public async Task<string?> GetAuthTokenAsync()
|
||||
{
|
||||
// Leemos las claves simples del .env
|
||||
var username = _configuration["API_USER"];
|
||||
var password = _configuration["API_PASSWORD"];
|
||||
|
||||
// Hardcodeamos la URL para estar 100% seguros
|
||||
var url = "https://api.eleccionesbonaerenses.gba.gob.ar/api/createtoken";
|
||||
|
||||
// Usamos comillas simples para los headers para proteger caracteres especiales en el shell
|
||||
var arguments = $"-s -H 'username: {username}' -H 'password: {password}' '{url}'";
|
||||
|
||||
var (status, output) = await ExecuteCurlCommand(arguments);
|
||||
|
||||
// Si el ExitCode no es 0, la respuesta de curl es un error, no el cuerpo de la página.
|
||||
if (status != 200)
|
||||
private async Task<(int, string)> ExecuteCurlCommand(string arguments)
|
||||
{
|
||||
_logger.LogError("Curl falló al ejecutar el comando. Salida de error: {Output}", output);
|
||||
return null;
|
||||
var processInfo = new ProcessStartInfo("curl", arguments)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
|
||||
using var process = Process.Start(processInfo);
|
||||
if (process == null) return (-1, "No se pudo iniciar el proceso curl.");
|
||||
|
||||
string output = await process.StandardOutput.ReadToEndAsync();
|
||||
string error = await process.StandardError.ReadToEndAsync();
|
||||
await process.WaitForExitAsync();
|
||||
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
_logger.LogError("Error al ejecutar curl. Exit Code: {ExitCode}. Stderr: {Error}", process.ExitCode, error);
|
||||
return (process.ExitCode, error.Length > 0 ? error : output);
|
||||
}
|
||||
return (200, output);
|
||||
}
|
||||
|
||||
try
|
||||
public async Task<string?> GetAuthTokenAsync()
|
||||
{
|
||||
// Añadimos opciones para ser más flexibles con el JSON que venga
|
||||
var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(output, jsonOptions);
|
||||
// --- CREDENCIALES Y URL HARDCODEADAS ---
|
||||
var username = "30500094156@elecciones2025.onmicrosoft.com";
|
||||
var password = "PTP847elec";
|
||||
var url = "https://api.eleccionesbonaerenses.gba.gob.ar/api/createtoken";
|
||||
|
||||
// Log de éxito
|
||||
_logger.LogInformation("Token obtenido exitosamente!");
|
||||
return tokenResponse?.Data?.AccessToken;
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
_logger.LogError(ex, "Falló la deserialización del JSON. El servidor respondió con HTML (probablemente un error). Respuesta recibida: {Output}", output);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// --- FORMATO DE ARGUMENTOS CORREGIDO (SIN ESPACIOS) ---
|
||||
var arguments = $"-s -H \"username:{username}\" -H \"password:{password}\" \"{url}\"";
|
||||
|
||||
_logger.LogInformation("Ejecutando comando curl con argumentos: {Arguments}", arguments);
|
||||
|
||||
// Implementa los demás métodos de la interfaz usando el mismo patrón
|
||||
// ...
|
||||
// Por ahora, solo necesitamos GetAuthTokenAsync para validar la conexión.
|
||||
public Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken) => Task.FromResult<List<CategoriaDto>?>(null);
|
||||
public Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken) => Task.FromResult<List<CatalogoDto>?>(null);
|
||||
public Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId) => Task.FromResult<List<AgrupacionDto>?>(null);
|
||||
public Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) => Task.FromResult<ResultadosDto?>(null);
|
||||
public Task<RepartoBancasDto?> GetBancasAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<RepartoBancasDto?>(null);
|
||||
public Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<List<string[]>?>(null);
|
||||
public Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId) => Task.FromResult<TelegramaFileDto?>(null);
|
||||
public Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId) => Task.FromResult<ResumenDto?>(null);
|
||||
public Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId) => Task.FromResult<EstadoRecuentoGeneralDto?>(null);
|
||||
var (status, output) = await ExecuteCurlCommand(arguments);
|
||||
|
||||
if (status != 200) {
|
||||
_logger.LogError("Curl falló al obtener el token. Salida recibida: {Output}", output);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
|
||||
var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(output, jsonOptions);
|
||||
|
||||
_logger.LogInformation("¡VICTORIA! Token obtenido exitosamente. La sincronización debería comenzar.");
|
||||
return tokenResponse?.Data?.AccessToken;
|
||||
} catch (JsonException ex) {
|
||||
_logger.LogError(ex, "Falló la deserialización del JSON. El servidor respondió con un error HTML. Respuesta recibida: {Output}", output);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// --- El resto de los métodos se mantienen igual (no se usarán en este primer paso) ---
|
||||
public async Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken) { _logger.LogInformation("Obteniendo categorías..."); /* Aquí iría la lógica de curl */ await Task.Delay(1); return null; }
|
||||
// ... (copia y pega el resto de los métodos vacíos que ya tenías)
|
||||
public Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken) => Task.FromResult<List<CatalogoDto>?>(null);
|
||||
public Task<List<AgrupacionDto>?> GetAgrupacionesAsync(string authToken, string distritoId, int categoriaId) => Task.FromResult<List<AgrupacionDto>?>(null);
|
||||
public Task<ResultadosDto?> GetResultadosAsync(string authToken, string distritoId, string seccionId, string municipioId) => Task.FromResult<ResultadosDto?>(null);
|
||||
public Task<RepartoBancasDto?> GetBancasAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<RepartoBancasDto?>(null);
|
||||
public Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<List<string[]>?>(null);
|
||||
public Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId) => Task.FromResult<TelegramaFileDto?>(null);
|
||||
public Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId) => Task.FromResult<ResumenDto?>(null);
|
||||
public Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId) => Task.FromResult<EstadoRecuentoGeneralDto?>(null);
|
||||
}
|
||||
Reference in New Issue
Block a user