Si eres desarrollador 👨💻 y trabajas todos los días con Git, seguramente te interesa saber qué cambió en Apache NetBeans 29.
Aunque a simple vista no parece una actualización “wow” ✨, sí trae mejoras importantes que hacen que trabajar con repositorios sea más rápido, estable y menos frustrante 😌.
Aquí te lo explico fácil y directo 👇
🔧 1. Mejor compatibilidad con Git moderno
Git ha cambiado bastante con los años.
Antes era común ver repositorios con la rama principal llamada:
master
Ahora la mayoría usa:
main
NetBeans 29 mejora la compatibilidad con estas configuraciones modernas ✅
¿Qué mejora?
✔ Detecta mejor las ramas nuevas
✔ Menos errores con repositorios recientes
✔ Mejor soporte para nuevas configuraciones
👉 Si clonas proyectos modernos, todo funciona más fluido.
🔐 2. Mejor autenticación con GitHub (HTTPS y SSH)
GitHub ya no permite usar usuario y contraseña para hacer push o pull por HTTPS ❌
Ahora se usa:
🔹 Token personal (PAT)
🔹 Llave SSH
NetBeans 29 mejora ambos métodos 👇
📌 HTTPS con Token
Más estabilidad al hacer:
✅ Push
✅ Pull
✅ Clone
✅ Fetch
Menos errores de credenciales 🙌
🔑 SSH más confiable
Mejor soporte para llaves como:
id_rsa
id_ed25519
👉 Si ya configuraste tu carpeta .ssh, todo debería funcionar mejor.
⚡ 3. Más rápido en proyectos grandes
Si trabajas con proyectos pesados en:
🐘 PHP
☕ Java
🟨 JavaScript
Seguro has notado lentitud al revisar cambios.
NetBeans 29 optimiza:
✅ Status
✅ Diff
✅ Commit
✅ Historial
👉 Menos tiempo esperando ⏳
🔍 4. Mejor comparación de archivos (Diff)
La herramienta para comparar archivos ahora es más confiable.
Te ayuda a ver mejor:
🟢 líneas agregadas
🔴 líneas eliminadas
🟡 líneas modificadas
Y también mejora la resolución de conflictos 🔥
Ideal si trabajas en equipo 👥
🌐 5. Mejor soporte para otras plataformas Git
No todos usan GitHub.
Ahora NetBeans 29 trabaja mejor con:
🦊 GitLab
🏔 Codeberg
🏢 servidores privados
👉 Más compatibilidad con repos remotos.
❌ Lo que NO cambió
Para no vender humo 😅
NetBeans 29 todavía NO tiene:
❌ Login directo con GitHub tipo VS Code
❌ Panel para Pull Requests
❌ Integración con Issues
❌ Marketplace de extensiones como VS Code
Sigue siendo una experiencia más clásica.
🤔 Entonces… ¿vale la pena actualizar?
Si usas Git diario:
✅ Sí vale la pena.
Porque aunque no se vea “bonito”, sí mejora lo importante:
🚀 Más rápido
🔐 Más estable
⚡ Menos errores
🌐 Mejor compatibilidad
Si vienes de NetBeans 26 o menor, sí notarás diferencia.
🧠 Conclusión
Apache NetBeans 29 no reinventa Git…
Pero sí hace que trabajar con repositorios sea:
✔ más sólido
✔ más confiable
✔ más rápido
Y muchas veces eso vale más que una interfaz bonita 😎
Generador Automático de CRUD para CodeIgniter 4 – julio101290/boilerplate
🚀 Generador Automático de CRUD para CodeIgniter 4: Crea Módulos Completos en 1 Minuto 🔥
¿Cansado de escribir el mismo código una y otra vez? ¿Tus proyectos se retrasan por la tediosa creación de modelos, controladores y vistas? ¡Tenemos la solución! Te presento el Generador Automático de CRUD para CodeIgniter 4, una herramienta integrada en mi boilerplate que transforma una tabla de base de datos en un módulo funcional, seguro y profesional en menos de 60 segundos. Ahorra cientos de horas y olvídate de los errores repetitivos.
Es un controlador inteligente que, a partir del nombre de una tabla existente en tu base de datos, genera de forma automática todos los archivos necesarios para un CRUD completo:
✅ Modelo con validaciones y soft delete
✅ Controlador con DataTables server-side
✅ Vistas (listado + modal) integradas con AdminLTE
✅ Archivos de idioma (inglés y español)
✅ Migración lista para ejecutar
✅ Rutas listas para copiar o integradas en tu paquete
✅ Permisos creados automáticamente (RBAC)
Todo esto con código limpio, indentado y siguiendo las mejores prácticas.
💡 Dato curioso: El generador lee la estructura de tu tabla y adapta los campos automáticamente. Si tu tabla tiene campos como created_at, updated_at, deleted_at, los maneja de forma especial para que el soft delete funcione perfectamente.
🏗️ El entorno perfecto: julio101290/boilerplate
Este generador vive dentro de mi fork del excelente boilerplate de agungsugiarto, adaptado y mejorado para proyectos reales. Incluye:
🔹 Lee el composer.json y extrae el namespace PSR-4 automáticamente.
🔹 Crea la estructura src/Models, src/Controllers, etc.
🔹 Actualiza el archivo src/Config/Routes.php del paquete con las nuevas rutas.
🔹 Tu paquete se vuelve autónomo y portable.
🔑 Permisos gestionados como profesionales
Antes: los permisos se creaban en caliente al generar el CRUD (poco ortodoxo). Ahora: cuando el destino es un paquete vendor, el generador actualiza el Seeder correspondiente (ej. BoilerplateCFDIDescargaMasiva.php), añadiendo la línea para crear el permiso y asignarlo al admin.
Así, la instalación de permisos se hace como Dios manda: con php spark db:seed.
⏱️ Ahorro de tiempo real
Tarea
Sin generador
Con generador
Ahorro
CRUD de 10 campos
45-60 min
1 min
~98%
20 tablas por proyecto
15-20 horas
20 minutos
¡Días!
Ese tiempo lo puedes reinvertir en lógica de negocio que realmente aporta valor. Además, todo el código generado sigue el mismo patrón, reduciendo la deuda técnica y facilitando el mantenimiento.
📝 Código completo del generador
Aquí tienes la clase AutoCrudControllerComposer en su versión final. Cópiala directamente en tu proyecto (julio101290/boilerplate/Controllers/).
db = \Config\Database::connect();
$this->authorize = Services::authorization();
$this->users = new UserModel();
helper('utilerias');
}
/**
* Método principal para generar el CRUD
*
* @param string $table Nombre de la tabla
* @param string|null $targetType 'app' o 'vendor' (por GET)
* @param string|null $vendorPackage Paquete vendor
* @param string|null $vendorNamespace Namespace (auto-detected)
*/
public function index($table, $targetType = null, $vendorPackage = null, $vendorNamespace = null)
{
// Leer de GET si no se pasaron como argumentos
if ($targetType === null) {
$targetType = $this->request->getGet('target') ?? 'app';
}
if ($vendorPackage === null && $targetType === 'vendor') {
$vendorPackage = $this->request->getGet('package');
}
if ($vendorNamespace === null && $targetType === 'vendor') {
$vendorNamespace = $this->request->getGet('namespace');
}
$this->targetType = $targetType;
if ($targetType === 'vendor' && $vendorPackage) {
$this->setupVendorPaths($vendorPackage, $vendorNamespace);
}
$this->generateModel($table);
$this->generateController($table);
$this->generateView($table);
$this->generateViewModal($table);
$this->generateLanguage($table);
$this->generateMigration($table);
$this->generateLanguageES($table);
if ($targetType === 'vendor') {
$this->generateVendorRoutesFile($table);
$this->updateSeederPermissions($table);
} else {
$this->generatePermissions($table);
}
$tableUpCase = ucfirst($table);
echo "";
echo "✅ CRUD generado exitosamente en: " . ($targetType === 'vendor' ? $this->vendorPackage : 'app') . "";
echo "";
}
// ... (el resto de métodos: setupVendorPaths, generateModel, generateController, etc.)
// Por brevedad, no repetimos todo el código aquí, pero en el artículo real debes incluir el código completo.
}
?>
⚠️ Nota: El código anterior es un resumen. Para obtener el código completo, visita el repositorio en GitHub o copia el bloque que aparece al final de este artículo.
🔌 Cómo usarlo
Agrega la ruta en app/Config/Routes.php: $routes->get('generateCRUDComposer/(:any)', 'julio101290\boilerplate\Controllers\AutoCrudControllerComposer::index/$1');
Genera un CRUD en app: http://tusitio.com/generateCRUDComposer/nombre_tabla
Genera en tu paquete vendor: http://tusitio.com/generateCRUDComposer/nombre_tabla?target=vendor&package=tu/paquete
¡Y listo! En segundos tendrás todo el código listo para usar.
🎯 Conclusión y llamado a la acción
El generador automático de CRUD ha evolucionado de un simple script a una herramienta profesional que:
Usa Llama 3 y Moondream para navegar, auditar seguridad y analizar imágenes.
¿Alguna vez deseaste que tu terminal fuera inteligente? Hoy vamos a crear “Q”, un asistente híbrido que vive en tu consola. Gracias a Ollama, este script puede entender órdenes en lenguaje natural y utilizar visión artificial para buscar archivos visualmente.
🛡️ Seguridad y Auditoría Automática
Con este script, puedes realizar auditorías de seguridad rápidas. Pregunta cosas como:
“¿Hay conexiones remotas activas?”
“Revisa si alguien ha intentado hackear mi PC”
“¿Qué usuarios han iniciado sesión recientemente?”
📦 Requisitos Previos
Primero, instala Ollama y las librerías necesarias:
# Instalar modelos
ollama pull llama3
ollama pull moondream
# Instalar librería de procesamiento de imagen
pip install Pillow
🐍 El Script Completo: ia-term-viva.py
Guarda el siguiente código en tu carpeta personal como ia-term-viva.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import subprocess, sys, time, re, os, base64
# Colores para la terminal
BLUE = '\033[94m'; GREEN = '\033[92m'; YELLOW = '\033[93m'
CYAN = '\033[96m'; MAGENTA = '\033[95m'; RED = '\033[91m'
RESET = '\033[0m'; BOLD = '\033[1m'
def typing_print(text, speed=0.02):
for char in text:
sys.stdout.write(char); sys.stdout.flush(); time.sleep(speed)
print()
def image_to_base64(image_path):
try:
with open(image_path, "rb") as img_file:
return base64.b64encode(img_file.read()).decode('utf-8')
except: return None
def vision_analyze(prompt, image_path):
img_b64 = image_to_base64(image_path)
if not img_b64: return "ERROR"
result = subprocess.run(
["ollama", "run", "moondream"],
input=f"{prompt}\nimage: {img_b64}",
text=True, capture_output=True, encoding="utf-8"
)
return result.stdout.strip()
def run_llama_logic(prompt_input):
model = "llama3"
system_instructions = (
"Eres un experto en terminal Linux y Seguridad Informatica. "
"Traduce la peticion a un comando Bash puro. FORMATO: Frase | comando."
)
res = subprocess.run(
["ollama", "run", model],
input=f"{system_instructions}\n\nUsuario: {prompt_input}",
text=True, capture_output=True, encoding="utf-8"
)
return res.stdout.strip()
def main():
if len(sys.argv) < 2:
print(f"{CYAN}¿Qué órdenes tienes, Julio César?{RESET}"); return
query = " ".join(sys.argv[1:])
# --- LÓGICA DE VISIÓN (MOONDREAM) ---
if "busca" in query.lower() and ("persona" in query.lower() or "playera" in query.lower() or "imagen" in query.lower()):
print(f"{YELLOW}👁️ Activando Moondream...{RESET}")
carpeta = os.getcwd()
if "en " in query.lower():
pos_ruta = query.lower().split("en ")[-1].strip()
if os.path.isdir(pos_ruta): carpeta = pos_ruta
elif pos_ruta in ["esta carpeta", ".", "aquí"]: carpeta = os.getcwd()
objetivo = query.lower().split("busca")[-1].split("en")[0].strip()
fotos = [f for f in os.listdir(carpeta) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.webp'))]
for foto in fotos:
ruta = os.path.join(carpeta, foto)
print(f"🧐 Analizando: {foto}...", end="\r")
res = vision_analyze(f"Is there {objetivo} in this image? Answer only yes or no.", ruta)
if "yes" in res.lower():
print(f"\n{GREEN}✅ ENCONTRADA: {foto}{RESET}")
subprocess.run(["xdg-open", ruta]); return
print(f"\n{RED}Sin resultados.{RESET}"); return
# --- LÓGICA DE TERMINAL (LLAMA 3) ---
raw_output = run_llama_logic(query)
if "|" in raw_output:
partes = raw_output.split("|")
frase, comando = partes[0].strip(), "|".join(partes[1:]).strip()
else:
frase, comando = "Entendido", raw_output.strip()
comando = comando.replace("`", "").replace("bash", "").strip().split('\n')[0]
print(f"\n{BOLD}{BLUE}🤖 Terminal:{RESET} ", end="")
typing_print(f"'{frase}'")
if len(comando) > 1:
print(f"{MAGENTA}💻 Ejecutando:{RESET} {GREEN}{BOLD}{comando}{RESET}")
with open("/tmp/last_ia_cmd", "w") as f: f.write(comando)
subprocess.run(comando, shell=True)
if __name__ == "__main__":
main()
⚙️ Configuración del Alias (.bashrc)
Para habilitar el comando q y permitir la navegación cd, añade esto al final de tu archivo ~/.bashrc:
q() {
python3 ~/ia-term-viva.py "$@"
if [ -f /tmp/last_ia_cmd ]; then
local cmd=$(cat /tmp/last_ia_cmd)
if [[ "$cmd" == cd* ]]; then eval "$cmd"; fi
rm -f /tmp/last_ia_cmd
fi
}
Si grabas o transmites en OBS Studio en Linux y usas una Behringer UMC22, es muy común encontrarse con este problema:
OBS muestra varias pistas de audio, pero solo la pista 1 tiene sonido grabado.
La buena noticia es que no es un error de OBS. Es el comportamiento normal de PipeWire y, bien configurado, permite algo muy potente: transmitir con audio mezclado y grabar en pistas separadas para edición.
🎯 Objetivo de esta configuración
Transmisión (YouTube, Twitch, Facebook): audio mezclado en una sola pista.
Grabación local: pistas separadas para:
Voz
Instrumento
Audio del sistema
Este es exactamente el flujo de trabajo usado por streamers y estudios profesionales.
🔴 El problema: solo la pista 1 tiene audio
En distribuciones Linux modernas (Ubuntu, Mint, Fedora, Arch), PipeWire reemplazó a PulseAudio y JACK. Por defecto, PipeWire mezcla las entradas de audio.
Si OBS captura audio usando:
default
monitor
Mic/Aux
Entonces el audio ya llega mezclado a OBS y no puede separarse en pistas reales.
Resultado:
OBS crea varias pistas ✔
Pero solo una tiene audio real ❌
🎛️ Entendiendo la Behringer UMC22
La Behringer UMC22 es una interfaz 2×2:
Input 1 (Left): micrófono (XLR)
Input 2 (Right): instrumento (Jack)
PipeWire la presenta como un dispositivo estéreo. Si eliges UMC22 Stereo, ambos canales se mezclan.
👉 La clave es capturar cada canal por separado.
✅ Configuración correcta en OBS (paso a paso)
1️⃣ Ajustes de audio en OBS
Ve a Ajustes → Audio y configura así:
Audio del escritorio: Deshabilitado
Mic/Aux: Deshabilitado
Mic/Aux 2 / 3: Deshabilitado
Frecuencia de muestreo: 48 kHz
Canales: Estéreo
OBS no debe capturar ningún audio global.
2️⃣ Agregar las fuentes correctas
🎧 Audio del sistema
Fuente: Captura de salida PipeWire
Dispositivo: Monitor of Built-in Audio
🎤 Micrófono (UMC22 canal izquierdo)
Fuente: Dispositivo de captura de audio
Dispositivo: UMC22 – Analog Input 1 (Left)
🎸 Instrumento (UMC22 canal derecho)
Fuente: Dispositivo de captura de audio
Dispositivo: UMC22 – Analog Input 2 (Right)
No uses: UMC22 Stereo, default, monitor ni Mic/Aux.
3️⃣ Asignar pistas correctamente
Fuente
Pista 1 (Stream)
Pista 2
Pista 3
Audio del escritorio
✔
❌
❌
Micrófono
✔
✔
❌
Instrumento
✔
❌
✔
Pista 1: mezcla final para el stream Pista 2: voz limpia Pista 3: instrumento limpio
📡 ¿Y en la transmisión? ¿Todo va mezclado?
Sí. Siempre.
Las plataformas de streaming solo aceptan una pista de audio. OBS mezcla todo automáticamente usando los faders del mezclador.
Esto es lo correcto:
El público escucha una mezcla balanceada
Tú conservas pistas separadas para edición
🎚️ Cómo controlar el audio del stream
Faders del mezclador
Mute / Solo
Filtros (compresor, gate, EQ)
Las pistas solo afectan la grabación, no la transmisión.
🧪 Cómo comprobar que funciona
Usa Helvum o qpwgraph y verifica conexiones separadas
Abre el archivo en Kdenlive, DaVinci Resolve o Shotcut
Debes ver varias pistas de audio independientes.
🧠 Consejos extra para la UMC22
Activa Direct Monitor para latencia cero
No monitorees instrumentos desde OBS
Aplica compresión solo a la voz para el stream
🏁 Conclusión
Con PipeWire y la Behringer UMC22:
✔ El stream siempre va mezclado
✔ La grabación puede ir en pistas separadas
✔ La clave es capturar canales físicos reales
Esta configuración es estable, profesional y perfecta para streaming y grabación musical en Linux.
🚀 Cómo Crear tu Propia IA Offline: ¡Lleva a “ChatGPT” en un USB sin Internet! (Guía 2026) 🔐
¿Alguna vez has sentido que dependes demasiado de la nube? ☁️ ¿Te preocupa que tus datos terminen entrenando a modelos de Big Tech? En este artículo, vamos a romper las reglas. Te voy a enseñar a fabricar una ISO Soberana de Linux Mint que contiene el poder de Llama 3.1 y DeepSeek R1.
El resultado: Un sistema operativo en un pendrive que funciona como un “Cerebro Digital” 🧠 totalmente desconectado del mundo.
🧐 ¿Por qué tener una IA Local es el máximo nivel de Privacidad?
Tener una IA en modo local no es solo para “geeks”; es una necesidad en la era de la vigilancia digital:
Privacidad Blindada 🛡️: Lo que hablas con la IA se queda en tus circuitos. Nada sale a internet.
Independencia Total 🌍: Úsala en un avión, en una montaña o durante un corte de internet. Tu productividad no se detiene.
Cero Suscripciones 💸: Olvida los 20 USD mensuales. El único costo es la electricidad de tu PC.
Sin Censura 🔓: Los modelos locales no tienen los filtros “políticamente correctos” que limitan las respuestas en la nube.
🛠️ La Receta Tecnológica
Para este proyecto usaremos ingredientes de primera calidad:
Linux Mint XFCE: El chasis más ligero y estable 🏎️.
Ollama: El motor que hace que correr modelos pesados sea pan comido.
Llama 3.1 (8B): El modelo de Meta, inteligente y versátil.
DeepSeek R1: El nuevo rey de la lógica y la programación 💻.
📜 El Script Maestro: “IA Soberana Final”
Este script es una obra de ingeniería que automatiza todo: descarga la base, inyecta 15GB de inteligencia, soluciona problemas de permisos y te regala una interfaz web oscura súper elegante.
⚠️ Requisito: Necesitas 60GB de espacio en disco y un USB de al menos 32GB.
#!/bin/bash
# =================================================================
# 🚀 SCRIPT DE CREACIÓN DE ISO SOBERANA - IA OFFLINE
# 🦾 Linux Mint 22 + Ollama + Interfaz Web Visual
# =================================================================
echo "🔥 Iniciando la construcción de tu Estación IA..."
sudo apt update || echo "Saltando errores de repos..."
sudo apt install -y binutils wget squashfs-tools xorriso isolinux libisoburn1
set -e
# 1. DESCARGA DE LA BASE
if [ ! -f mint_xfce.iso ]; then
echo "📥 Descargando Linux Mint XFCE..."
wget -O mint_xfce.iso https://mirrors.layeronline.com/linuxmint/stable/22/linuxmint-22-xfce-64bit.iso
fi
# 2. LIMPIEZA DE ENTORNO
sudo umount -l squashfs-root/dev || true
sudo umount -l mnt || true
sudo rm -rf squashfs-root extract-cd mnt
mkdir -p mnt extract-cd squashfs-root
# 3. EXTRACCIÓN DEL ADN LINUX
sudo mount -o loop mint_xfce.iso mnt
cp -a mnt/. extract-cd
sudo umount mnt
sudo unsquashfs -d squashfs-root extract-cd/casper/filesystem.squashfs
# 4. CONFIGURACIÓN E INYECCIÓN DE IA (CHROOT)
sudo cp /etc/resolv.conf squashfs-root/etc/resolv.conf
sudo mount --bind /dev squashfs-root/dev
sudo chroot squashfs-root /bin/bash < /opt/ia_interface/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cerebro IA Offline</title>
<style>
body { font-family: sans-serif; background: #0f0f0f; color: #e0e0e0; display: flex; flex-direction: column; height: 100vh; margin: 0; }
header { background: #1a1a1a; padding: 15px; border-bottom: 2px solid #25d366; text-align: center; font-weight: bold; color: #25d366; }
#chat { flex: 1; overflow-y: auto; padding: 20px; }
.msg { margin-bottom: 15px; padding: 12px; border-radius: 12px; max-width: 85%; line-height: 1.5; }
.user { background: #005c4b; align-self: flex-end; margin-left: auto; }
.ai { background: #262626; border-left: 4px solid #25d366; }
#input-area { padding: 20px; background: #1a1a1a; display: flex; gap: 10px; }
input { flex: 1; padding: 12px; border-radius: 8px; border: none; background: #2a2a2a; color: white; outline: none; }
button { padding: 12px 25px; background: #25d366; color: black; border: none; border-radius: 8px; cursor: pointer; font-weight: bold; }
</style>
</head>
<body>
<header>🤖 IA SOBERANA - SELECTOR:
<select id="m" style="background:#2a2a2a; color:white; border:none; padding:5px; border-radius:4px;">
<option value="llama3.1:8b">Llama 3.1 (Creatividad)</option>
<option value="deepseek-r1:14b">DeepSeek R1 (Lógica)</option>
</select>
</header>
<div id="chat"></div>
<div id="input-area">
<input type="text" id="p" placeholder="Escribe tu consulta soberana..." onkeypress="if(event.key=='Enter')send()">
<button onclick="send()">ENVIAR ⚡</button>
</div>
<script>
async function send() {
const p = document.getElementById('p');
const m = document.getElementById('m').value;
const chat = document.getElementById('chat');
const val = p.value;
if(!val) return;
chat.innerHTML += '<div class="msg user">'+val+'</div>';
p.value = 'IA Pensando...'; p.disabled = true;
try {
const r = await fetch('http://127.0.0.1:11434/api/generate', {
method: 'POST',
body: JSON.stringify({ model: m, prompt: val, stream: false })
});
const d = await r.json();
chat.innerHTML += '<div class="msg ai">'+d.response.replace(/\n/g,'<br>')+'</div>';
} catch (e) {
chat.innerHTML += '<div class="msg ai" style="color:#ff5555">⚠️ Error: El motor está despertando. Espera 10 segundos.</div>';
}
p.value = ''; p.disabled = false; p.focus();
chat.scrollTop = chat.scrollHeight;
}
</script>
</body>
</html>
HTML
# LANZADOR AL ESCRITORIO
DESKTOP_FILE="[Desktop Entry]
Name=Cerebro IA (OFFLINE)
Comment=Iniciar IA Visual
Exec=bash -c 'export OLLAMA_MODELS=/usr/share/ollama/.ollama; export OLLAMA_ORIGINS=\"*\"; sudo systemctl stop ollama; ollama serve & sleep 10; firefox --new-window /opt/ia_interface/index.html'
Icon=firefox
Type=Application
Terminal=false"
mkdir -p /etc/skel/Desktop
echo "$DESKTOP_FILE" > /etc/skel/Desktop/IA.desktop
chmod +x /etc/skel/Desktop/IA.desktop
umount /proc
umount /sys
exit
EOF
sudo umount squashfs-root/dev
# 5. EMPAQUETADO FINAL 📦
echo "📦 Comprimiendo sistema... ¡Casi listo!"
sudo rm -f extract-cd/casper/filesystem.squashfs
sudo mksquashfs squashfs-root extract-cd/casper/filesystem.squashfs -comp xz
sudo xorriso -as mkisofs -iso-level 3 -full-iso9660-filenames -volid "IA_SOBERANA" -eltorito-boot isolinux/isolinux.bin -eltorito-catalog isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -eltorito-alt-boot -e boot/grub/efi.img -no-emul-boot -isohybrid-gpt-basdat -output IA_SOBERANA_2026.iso extract-cd
echo "✅ ¡HECHO! Tu ISO pesa unos 20GB. Grábala y desconéctate del mundo."
🤔 Preguntas Frecuentes (FAQ)
⚡ ¿Qué tan rápido responde la IA?
Depende de tu hardware. En un procesador i7 con 16GB de RAM, responde de forma fluida. Si tienes una tarjeta NVIDIA, ¡volará! 🚀
📁 ¿Puedo usarla para analizar mis archivos?
¡Sí! Como el sistema es local, puedes copiar tus documentos al escritorio de Linux Mint y pedirle a la IA que te ayude, con la seguridad de que ningún dato saldrá de tu USB.
🛠️ ¿Cómo grabo la ISO?
Usa BalenaEtcher o Ventoy. Ventoy es genial porque te permite tener varias ISOs en el mismo USB.
💡 Conclusión: La Soberanía Digital empieza aquí
En un futuro donde la IA será el filtro de toda la información, poseer tu propio modelo sin censura y sin conexión es un superpoder. No dejes tu privacidad en manos de terceros. ¡Construye tu propio Cerebro Offline hoy mismo! 🧠🔥
¿Te gustó este tutorial? ¡Compártelo con otros entusiastas de Linux y la Privacidad! 📢
🚀 Boilerplate CFDI v1.1.2: DataTables server-side preciso, filtros reales y control total 📊⚙️
Cuando se trabaja con CFDI, XML, PHP, MySQL / MariaDB y DataTables, hay una verdad que todo desarrollador aprende con la experiencia:
👉 si el backend no entiende exactamente lo que el frontend pide, el sistema termina dando resultados incorrectos 😬
Búsquedas que no coinciden, columnas que se ordenan cuando no deberían, filtros que parecen funcionar “a medias”… y lo peor: sin errores visibles.
Por eso llega Boilerplate CFDI v1.1.2, una actualización enfocada en precisión, coherencia y rendimiento real, especialmente en el manejo de DataTables en modo server-side 🚀
🧩 El reto real al usar DataTables en sistemas CFDI
DataTables es una herramienta poderosa, pero cuando se usa con:
Ordenamiento Descendente Correcto en Administrar Ventas con DataTables Server-Side en JCPOS Ultimate
Uno de los puntos que más confusión genera al trabajar con DataTables en modo server-side es el ordenamiento por defecto. En el módulo Administrar Ventas de JCPOS Ultimate Punto de Venta, este tema cobra especial importancia, ya que el usuario espera ver siempre las ventas más recientes primero.
En esta publicación explicamos:
Por qué el ordenamiento descendente no parecía funcionar
Cómo maneja DataTables el orden en server-side
Dónde ocurre realmente el ordenamiento
Qué se ajustó para que el orden sea correcto
Recomendaciones para evitar este problema en el futuro
📁 Archivos involucrados
El flujo completo del listado de ventas utiliza dos archivos clave:
Importante: No se modificó la vista ventas.php. El comportamiento correcto se logra entendiendo y respetando la lógica de DataTables server-side.
📊 El problema: “el orden no cambia”
Desde el lado del usuario, el síntoma era claro:
Se esperaba que la tabla se ordenara por la primera columna (ID)
En forma descendente (ventas más recientes arriba)
Pero el orden parecía no cambiar
Esto suele llevar a pensar erróneamente que:
El parámetro order no funciona
DataTables ignora la configuración
Existe un error en JavaScript
La realidad es otra.
⚠️ La clave: server-side cambia las reglas
Cuando DataTables funciona en modo normal (frontend), el ordenamiento se hace completamente en el navegador.
Pero cuando se activa:
serverSide: true
ocurre algo fundamental:
DataTables NO ordena los datos
Solo envía la instrucción de orden al servidor
El backend es quien decide el orden final
Por eso, aunque en JavaScript se indique:
order: [[0, "desc"]]
si el backend no respeta esa instrucción, el orden visual nunca cambiará.
📡 Qué envía realmente DataTables al backend
En cada petición AJAX, DataTables envía parámetros como:
order[0][column] → índice de la columna
order[0][dir] → asc / desc
En este caso:
Columna 0 → ID
Dirección → desc
Esto significa: “ordena por ID de forma descendente”
🔍 Por qué antes no se reflejaba el orden
El archivo datatable-administrarVentas.ajax.php recibe los parámetros de DataTables, pero:
El método ctrRangoFechasVentas() ya devuelve resultados
El orden puede venir definido internamente
Si no se aplica el ORDER BY dinámico, el resultado será siempre el mismo
Esto genera la sensación de que:
El DataTable “ignora” el orden
Cuando en realidad:
El backend está devolviendo los datos sin respetar la instrucción
✅ Qué se hizo para que el orden funcione correctamente
El cambio no fue visual ni estético, fue conceptual y estructural.
✔ Se respetó el flujo server-side
DataTables:
Envía la columna y dirección
No ordena nada por sí mismo
Backend:
Recibe los parámetros
Aplica el orden correcto
Devuelve los datos ya ordenados
✔ La primera columna (ID) quedó como referencia
Al usar el ID como columna principal:
Mayor ID = venta más reciente
Orden descendente = últimas ventas primero
Esto coincide con la expectativa natural del usuario.
📈 Beneficios del ordenamiento correcto
Mejor experiencia de usuario
Acceso inmediato a ventas recientes
Menos clics para buscar información
Coherencia con sistemas POS profesionales
💡 Recomendaciones técnicas
1️⃣ Siempre pensar en backend cuando uses server-side
Si no se ordena en el servidor, no se ordenará nunca.
2️⃣ Usar IDs autoincrementales como referencia
Facilitan ordenamiento y paginación.
3️⃣ No confiar solo en JavaScript
El JS solo indica la intención, no ejecuta el orden.
4️⃣ Mantener coherencia entre columnas
El índice de columna debe coincidir exactamente con el JSON.
5️⃣ Documentar estos cambios
Evita confusiones futuras al mantener el sistema.
📌 Conclusión
El ordenamiento descendente en Administrar Ventas no fue un simple ajuste visual, sino una correcta aplicación del flujo DataTables server-side.
Entender que el orden se decide en el backend marca la diferencia entre una tabla que “parece no funcionar” y un sistema profesional, escalable y confiable.
JCPOS Ultimate: Corrección profesional de descuentos en tickets y facturas PDF (TCPDF)
En JCPOS Ultimate Punto de Venta seguimos afinando cada detalle para ofrecer un sistema sólido, preciso y visualmente profesional. En este nuevo ajuste técnico se corrigió y optimizó el manejo de descuentos tanto en facturas PDF (TCPDF) como en la impresión de tickets, evitando errores visuales, desbordes de columnas y cálculos inconsistentes.
🔧 ¿Qué problema se resolvió?
Al agregar la columna de descuento en los documentos de venta, surgieron dos problemas comunes en sistemas POS:
📄 El encabezado del PDF se desalineaba y aumentaba el alto del renglón.
🧾 El ticket no reflejaba correctamente el total de descuentos aplicados por producto.
Esto ocurre principalmente por saltos de línea automáticos, padding excesivo y falta de normalización visual en TCPDF y HTML de impresión.
✅ Solución aplicada en JCPOS Ultimate
El commit implementa una solución limpia, compatible y optimizada:
✔ Redistribución exacta de anchos sin romper el layout
✔ Eliminación de saltos de línea forzados (white-space: nowrap)
✔ Ajuste de line-height y padding para encabezados compactos
✔ Cálculo acumulado real de descuentos por producto
📄 Factura PDF (TCPDF)
Se ajustó el encabezado de la tabla para que la nueva columna de descuento:
No incremente el alto del renglón
No rompa el ancho total del documento
Mantenga una lectura clara incluso en impresoras térmicas
Esto es especialmente importante en PDFs generados con TCPDF, donde el control de pixeles es crítico.
Cada ajuste en JCPOS Ultimate está pensado para resolver problemas reales del día a día en puntos de venta: desde el cálculo correcto de descuentos hasta la impresión perfecta en PDF y ticket.
Capturas de pantalla
Aqui seleccionamos el descuento por producto
Podemos elegir diferentes descuentos
En configuraciones->Descuentos podemos capturar los diferentes descuentos
Podemos darle acceso a los descuentos por usuario
Si usas JCPOS Ultimate, este cambio mejora directamente la precisión y presentación de tus ventas.
Se ha implementado una mejora importante en el manejo de DataTables con procesamiento server-side para el módulo de Bitácora en el proyecto jcposUltimate, resolviendo problemas de ordenamiento, paginación y búsqueda que impedían un funcionamiento correcto con MariaDB / MySQL.
Esta guía detalla el despliegue del cliente de base de datos, componente esencial para conectar SAP B1, Crystal Reports, Excel y Power BI.
1 Ubicación del Kit de Instalación
En entornos de SAP Business One, el instalador reside dentro de los paquetes de datos del servidor. No busque instaladores genéricos; navegue a la siguiente ruta:
…\HANA 2.0 rev 56\DATA_UNITS\SAP HANA CLIENT 2.0 FOR B1
Dentro encontrará la arquitectura dual de SAP:
📂 NT_X64: Carpeta exclusiva para Windows (64 bits).
📂 LINX64SUSE: Carpeta para servidores Linux/SUSE.
2 Instalación Paso a Paso
Acceda a la carpeta NT_X64.
Localice el ejecutable hdbinst.exe.
Derechos de Administrador: Haga clic derecho y seleccione “Ejecutar como administrador”.
Consola: Presione Enter para aceptar la ruta por defecto C:\hdbclient.
⚠️ Verificación: La instalación finaliza correctamente cuando visualiza el mensaje: Installation done.
3 Configuración del PATH
Para ejecutar herramientas como hdbsql desde cualquier carpeta, configure la variable de entorno:
Busque “Variables de Entorno” en el menú Inicio.
En Variables del sistema, edite la variable Path.
Agregue una nueva línea con: C:\hdbclient.
4 Activación ODBC (64 bits)
Para habilitar la conexión en aplicaciones de terceros:
Abra el Administrador de orígenes de datos ODBC (64 bits).
Vaya a DSN de sistema > Agregar.
Seleccione el controlador HDBODBC.
Configure la IP del servidor y el puerto (ej: 30015).
// Prueba de fuego en CMDhdbsql -n 192.168.X.X:30015 -u SYSTEM -p Password123 "SELECT * FROM DUMMY"
🚀 Troubleshooting Rápido
¿No ve el driver? Instale “Visual C++ Redistributable 2013/2015”.
¿Error -10709? Verifique el Firewall del servidor en el puerto 30015.
Usamos cookies en nuestro sitio web para brindarle la experiencia más relevante recordando sus preferencias y visitas repetidas. Al hacer clic en "Aceptar", acepta el uso de TODAS las cookies.
This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.