Fix 1830
This commit is contained in:
		| @@ -10,99 +10,80 @@ using static Elecciones.Core.DTOs.BancaDto; | |||||||
|  |  | ||||||
| namespace Elecciones.Infrastructure.Services; | namespace Elecciones.Infrastructure.Services; | ||||||
|  |  | ||||||
| // Implementación de emergencia que usa el comando 'curl' del sistema operativo |  | ||||||
| public class CurlElectoralApiService : IElectoralApiService | public class CurlElectoralApiService : IElectoralApiService | ||||||
| { | { | ||||||
|   private readonly ILogger<CurlElectoralApiService> _logger; |     private readonly ILogger<CurlElectoralApiService> _logger; | ||||||
|   private readonly IConfiguration _configuration; |  | ||||||
|   private readonly string _baseUrl; |  | ||||||
|  |  | ||||||
|   public CurlElectoralApiService(ILogger<CurlElectoralApiService> logger, IConfiguration configuration) |     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 |  | ||||||
|     { |     { | ||||||
|       StartInfo = new ProcessStartInfo |         _logger = logger; | ||||||
|       { |  | ||||||
|         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); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Extraemos el código de estado HTTP del final del stderr si usamos -w |     private async Task<(int, string)> ExecuteCurlCommand(string arguments) | ||||||
|     // (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) |  | ||||||
|     { |     { | ||||||
|       _logger.LogError("Curl falló al ejecutar el comando. Salida de error: {Output}", output); |         var processInfo = new ProcessStartInfo("curl", arguments) | ||||||
|       return null; |         { | ||||||
|  |             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 |         // --- CREDENCIALES Y URL HARDCODEADAS --- | ||||||
|       var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; |         var username = "30500094156@elecciones2025.onmicrosoft.com"; | ||||||
|       var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(output, jsonOptions); |         var password = "PTP847elec"; | ||||||
|  |         var url = "https://api.eleccionesbonaerenses.gba.gob.ar/api/createtoken"; | ||||||
|  |  | ||||||
|       // Log de éxito |         // --- FORMATO DE ARGUMENTOS CORREGIDO (SIN ESPACIOS) --- | ||||||
|       _logger.LogInformation("Token obtenido exitosamente!"); |         var arguments = $"-s -H \"username:{username}\" -H \"password:{password}\" \"{url}\""; | ||||||
|       return tokenResponse?.Data?.AccessToken; |          | ||||||
|     } |         _logger.LogInformation("Ejecutando comando curl con argumentos: {Arguments}", arguments); | ||||||
|     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; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Implementa los demás métodos de la interfaz usando el mismo patrón |         var (status, output) = await ExecuteCurlCommand(arguments); | ||||||
|   // ... |  | ||||||
|   // Por ahora, solo necesitamos GetAuthTokenAsync para validar la conexión. |         if (status != 200) { | ||||||
|   public Task<List<CategoriaDto>?> GetCategoriasAsync(string authToken) => Task.FromResult<List<CategoriaDto>?>(null); |             _logger.LogError("Curl falló al obtener el token. Salida recibida: {Output}", output); | ||||||
|   public Task<List<CatalogoDto>?> GetCatalogoCompletoAsync(string authToken) => Task.FromResult<List<CatalogoDto>?>(null); |             return 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); |         try { | ||||||
|   public Task<List<string[]>?> GetTelegramasTotalizadosAsync(string authToken, string distritoId, string seccionId) => Task.FromResult<List<string[]>?>(null); |             var jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; | ||||||
|   public Task<TelegramaFileDto?> GetTelegramaFileAsync(string authToken, string mesaId) => Task.FromResult<TelegramaFileDto?>(null); |             var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(output, jsonOptions); | ||||||
|   public Task<ResumenDto?> GetResumenAsync(string authToken, string distritoId) => Task.FromResult<ResumenDto?>(null); |              | ||||||
|   public Task<EstadoRecuentoGeneralDto?> GetEstadoRecuentoGeneralAsync(string authToken, string distritoId) => Task.FromResult<EstadoRecuentoGeneralDto?>(null); |             _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