first commit
This commit is contained in:
364
Classes/Helpers.cs
Normal file
364
Classes/Helpers.cs
Normal file
@@ -0,0 +1,364 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace EFCDesk.Classes
|
||||
{
|
||||
public static class Helpers
|
||||
{
|
||||
|
||||
// Lista de extensiones permitidas
|
||||
private static readonly HashSet<string> ExtensionesPermitidas = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".png",
|
||||
".gif",
|
||||
".bmp",
|
||||
".pdf",
|
||||
".txt",
|
||||
".csv"
|
||||
};
|
||||
|
||||
// Lista de extensiones prohibidas (opcional, para mayor seguridad)
|
||||
private static readonly HashSet<string> ExtensionesProhibidas = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
".exe",
|
||||
".bat",
|
||||
".cmd",
|
||||
".msi",
|
||||
".sh",
|
||||
".js",
|
||||
".vbs",
|
||||
".ps1",
|
||||
".jar",
|
||||
".com",
|
||||
".msp",
|
||||
".scr",
|
||||
".docm",
|
||||
".xlsm",
|
||||
".pptm"
|
||||
};
|
||||
|
||||
public static bool ValidarArchivo(string rutaArchivo)
|
||||
{
|
||||
string extension = Path.GetExtension(rutaArchivo);
|
||||
|
||||
// Revisar primero si está en la lista prohibida
|
||||
if (ExtensionesProhibidas.Contains(extension))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//// Solo permitir si está en la lista de permitidas
|
||||
//return ExtensionesPermitidas.Contains(extension);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obtiene el tamaño de un archivo en bytes.
|
||||
/// </summary>
|
||||
/// <param name="rutaArchivo">Ruta completa del archivo.</param>
|
||||
/// <returns>Tamaño en bytes, o -1 si el archivo no existe.</returns>
|
||||
public static long ObtenerTamanoEnBytes(string rutaArchivo)
|
||||
{
|
||||
if (!File.Exists(rutaArchivo))
|
||||
return -1;
|
||||
|
||||
FileInfo info = new FileInfo(rutaArchivo);
|
||||
return info.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obtiene el tamaño de un archivo en formato legible (KB, MB, GB).
|
||||
/// </summary>
|
||||
/// <param name="rutaArchivo">Ruta completa del archivo.</param>
|
||||
/// <returns>Cadena con el tamaño formateado, o mensaje de error.</returns>
|
||||
public static string ObtenerTamanoFormateado(string rutaArchivo)
|
||||
{
|
||||
if (!File.Exists(rutaArchivo))
|
||||
return "El archivo no existe";
|
||||
|
||||
long bytes = new FileInfo(rutaArchivo).Length;
|
||||
|
||||
string[] sufijos = { "B", "KB", "MB", "GB", "TB" };
|
||||
int indice = 0;
|
||||
double tamaño = bytes;
|
||||
|
||||
while (tamaño >= 1024 && indice < sufijos.Length - 1)
|
||||
{
|
||||
tamaño /= 1024;
|
||||
indice++;
|
||||
}
|
||||
|
||||
return $"{tamaño:0.##} {sufijos[indice]}";
|
||||
}
|
||||
/// <summary>
|
||||
/// Obtiene la url del endpoint para obtener el pedimento.
|
||||
/// </summary>
|
||||
/// <returns>Cadena del endpoint.</returns>
|
||||
public static string ObtenerEndpointPedimentos()
|
||||
{
|
||||
return @"/api/v1/customs/pedimentos/?pedimento_app=";
|
||||
}
|
||||
/// <summary>
|
||||
/// Obtiene la url del endpoint para obtener el documento.
|
||||
/// </summary>
|
||||
/// <returns>Cadena del endpoint.</returns>
|
||||
public static string ObtenerEndpointDocumentos()
|
||||
{
|
||||
return @"/api/v1/record/documents/";
|
||||
}
|
||||
public static string CrearEndpointpedimentoDesk()
|
||||
{
|
||||
return @"/api/v1/customs/pedimentos/bulk-create-pedimento_desk/";
|
||||
}
|
||||
/// <summary>
|
||||
/// Espera hasta que todos los archivos dentro de la carpeta estén libres (no en uso)
|
||||
/// </summary>
|
||||
public static bool EsperarArchivosListos(string carpetaRaiz, int timeoutSegundos = 30)
|
||||
{
|
||||
var archivos = Directory.GetFiles(carpetaRaiz, "*.*", SearchOption.AllDirectories);
|
||||
var inicio = DateTime.Now;
|
||||
|
||||
while ((DateTime.Now - inicio).TotalSeconds < timeoutSegundos)
|
||||
{
|
||||
bool todosListos = true;
|
||||
|
||||
foreach (var archivo in archivos)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream stream = new FileStream(archivo, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
|
||||
{
|
||||
// Archivo disponible
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
todosListos = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (todosListos)
|
||||
return true;
|
||||
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Obtiene la carpeta raíz según aplicaWinsaii
|
||||
/// </summary>
|
||||
public static (string RutaRaiz, string NombreRaiz) ObtenerCarpetaRaiz(string ruta)
|
||||
{
|
||||
SQLiteHelper sqliteHelper = new SQLiteHelper(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "historico.db"));
|
||||
ConfiguracionExpediente config = ConfiguracionExpediente.ObtenerDesdeBaseDeDatos(sqliteHelper);
|
||||
bool aplicaWinsaii = config.UsarEstructuraPedimentosWinsaai;
|
||||
|
||||
string? carpetaActual = EsCarpeta(ruta) ? ruta : Path.GetDirectoryName(ruta);
|
||||
string carpetaBase = Path.GetFullPath(config.FolderParaGenerarExpediente);
|
||||
carpetaActual = Path.GetFullPath(carpetaActual);
|
||||
|
||||
string[] segmentosBase = carpetaBase.Trim(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar);
|
||||
string[] segmentosActual = carpetaActual.Trim(Path.DirectorySeparatorChar).Split(Path.DirectorySeparatorChar);
|
||||
|
||||
int nivelDeseado = aplicaWinsaii ? segmentosBase.Length + 2 : segmentosBase.Length + 1;
|
||||
|
||||
if (segmentosActual.Length > nivelDeseado)
|
||||
segmentosActual = segmentosActual.Take(nivelDeseado).ToArray();
|
||||
|
||||
string carpetaRaiz = string.Join(Path.DirectorySeparatorChar.ToString(), segmentosActual);
|
||||
if (!Path.IsPathRooted(carpetaRaiz))
|
||||
carpetaRaiz = Path.DirectorySeparatorChar + carpetaRaiz;
|
||||
|
||||
string nombreRaiz = Path.GetFileName(carpetaRaiz);
|
||||
return (carpetaRaiz, nombreRaiz);
|
||||
|
||||
|
||||
}
|
||||
public static bool EsCarpeta(string ruta)
|
||||
{
|
||||
return Directory.Exists(ruta);
|
||||
}
|
||||
|
||||
public static string DominioExpedienteElectronico()
|
||||
{
|
||||
string efc = Properties.Settings.Default.urlEFC as string;
|
||||
return efc;
|
||||
}
|
||||
|
||||
public static bool EsValidaNomeclaturaCarpeta(string pathCarpeta)
|
||||
{
|
||||
var nombre = Path.GetFileName(pathCarpeta);
|
||||
string pattern = @"^\d{2}-\d{4}-\d{7}$|^\d{2}-\d{2}-\d{4}-\d{7}$";
|
||||
bool esValido = System.Text.RegularExpressions.Regex.IsMatch(nombre, pattern);
|
||||
if (!esValido)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool EsValidaNomeclaturaSAAIM3(string pathArchivo)
|
||||
{
|
||||
var nombre = Path.GetFileName(pathArchivo);
|
||||
string pattern = @"^[m|M]\d{7}\.\d{3}$";
|
||||
bool esValido = System.Text.RegularExpressions.Regex.IsMatch(nombre, pattern);
|
||||
if (!esValido)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool EsArchivoXMl(string rutaArchivo)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
string extension = Path.GetExtension(rutaArchivo);
|
||||
if (!extension.Equals(".xml", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
XDocument xdoc = XDocument.Load(rutaArchivo);
|
||||
|
||||
|
||||
}
|
||||
catch (XmlException exception)
|
||||
{
|
||||
Globales.logger.LogError("Helpers - EsArchivoXML", exception);
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Globales.logger.LogError("Helpers - EsArchivoXML", ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static byte[] CrearZipEnMemoria(string nombreArchivo, byte[] contenido)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
using (var zip = new System.IO.Compression.ZipArchive(memoryStream, System.IO.Compression.ZipArchiveMode.Create, leaveOpen: true))
|
||||
{
|
||||
|
||||
// Aquí puedes agregar archivos al archivo ZIP si es necesario
|
||||
var entry = zip.CreateEntry(nombreArchivo);
|
||||
|
||||
using (var entryStream = entry.Open())
|
||||
{
|
||||
entryStream.Write(contenido, 0, contenido.Length);
|
||||
}
|
||||
|
||||
}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Manejo de la excepción (puedes registrar el error o lanzar una excepción personalizada)
|
||||
Globales.logger.LogError("Helpers", ex);
|
||||
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static string CalcularHashMD5(string rutaArchivo)
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
{
|
||||
using (var stream = File.OpenRead(rutaArchivo))
|
||||
{
|
||||
var hashBytes = md5.ComputeHash(stream);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (var b in hashBytes)
|
||||
{
|
||||
sb.Append(b.ToString("x2"));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Crea un ZIP de un solo archivo en una carpeta temporal única.
|
||||
/// </summary>
|
||||
/// <param name="rutaArchivo">Archivo a comprimir.</param>
|
||||
/// <param name="nombreArchivoZip">Nombre del ZIP que se generará.</param>
|
||||
/// <param name="autoLimpiar">Si es true, borra la carpeta temporal automáticamente después de crear el ZIP.</param>
|
||||
/// <returns>Ruta completa del ZIP generado.</returns>
|
||||
public static string CrearZipArchivoEnTemp(string rutaArchivo, string nombreArchivoZip, bool autoLimpiar = false)
|
||||
{
|
||||
// Obtiene la ruta raíz de la carpeta temporal del sistema
|
||||
string tempRoot = Path.Combine(Path.GetTempPath(), "temp-efc-desk");
|
||||
//string tempRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),"tempEFCDesk");
|
||||
|
||||
// Crea una subcarpeta temporal única
|
||||
string tempFolder = Path.Combine(tempRoot, Guid.NewGuid().ToString().ToLower().Replace("-","").Substring(0,8));
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
|
||||
// Ruta completa del archivo ZIP dentro de la carpeta temporal
|
||||
string zipPath = Path.Combine(tempFolder, nombreArchivoZip);
|
||||
|
||||
try
|
||||
{
|
||||
// Verifica que el archivo exista
|
||||
if (!File.Exists(rutaArchivo))
|
||||
{
|
||||
throw new FileNotFoundException($"El archivo no existe: {rutaArchivo}");
|
||||
}
|
||||
|
||||
// Crea el ZIP y agrega el archivo
|
||||
using (var zip = ZipFile.Open(zipPath, ZipArchiveMode.Create))
|
||||
{
|
||||
zip.CreateEntryFromFile(rutaArchivo, Path.GetFileName(rutaArchivo));
|
||||
}
|
||||
|
||||
return zipPath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Globales.logger.LogError("Helpers - CrearZipArchivoEnTemp", ex);
|
||||
return "";
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (autoLimpiar)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Espera un momento para asegurarse de que el ZIP no esté bloqueado
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
|
||||
// Borra toda la carpeta temporal
|
||||
if (Directory.Exists(tempFolder))
|
||||
{
|
||||
Directory.Delete(tempFolder, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Globales.logger.LogError("Helpers - No se pudo limpiar la carpeta temporal", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user