Fix 1830
This commit is contained in:
		| @@ -10,93 +10,74 @@ 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; | ||||
|  | ||||
|     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 | ||||
|         var processInfo = new ProcessStartInfo("curl", arguments) | ||||
|         { | ||||
|       StartInfo = new ProcessStartInfo | ||||
|       { | ||||
|         FileName = "curl", | ||||
|         Arguments = arguments, | ||||
|             RedirectStandardOutput = true, | ||||
|             RedirectStandardError = true, | ||||
|             UseShellExecute = false, | ||||
|             CreateNoWindow = true, | ||||
|       } | ||||
|         }; | ||||
|  | ||||
|     process.Start(); | ||||
|         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}. Error: {Error}", process.ExitCode, error); | ||||
|       return (-1, error); | ||||
|             _logger.LogError("Error al ejecutar curl. Exit Code: {ExitCode}. Stderr: {Error}", process.ExitCode, error); | ||||
|             return (process.ExitCode, error.Length > 0 ? error : output); | ||||
|         } | ||||
|  | ||||
|     // 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 | ||||
|         // --- CREDENCIALES Y URL HARDCODEADAS --- | ||||
|         var username = "30500094156@elecciones2025.onmicrosoft.com"; | ||||
|         var password = "PTP847elec"; | ||||
|         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}'"; | ||||
|         // --- 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); | ||||
|  | ||||
|         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) | ||||
|     { | ||||
|       _logger.LogError("Curl falló al ejecutar el comando. Salida de error: {Output}", output); | ||||
|         if (status != 200) { | ||||
|             _logger.LogError("Curl falló al obtener el token. Salida recibida: {Output}", output); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|     try | ||||
|     { | ||||
|       // Añadimos opciones para ser más flexibles con el JSON que venga | ||||
|         try { | ||||
|             var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; | ||||
|             var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(output, jsonOptions); | ||||
|              | ||||
|       // Log de éxito | ||||
|       _logger.LogInformation("Token obtenido exitosamente!"); | ||||
|             _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 HTML (probablemente un error). Respuesta recibida: {Output}", output); | ||||
|         } 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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   // 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); | ||||
|     // --- 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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user