commit 5dceeb5b70160728a3d456af2a922fc1f591e02d
Author: David Itehua Xalamihua
+ El objetivo de esta subrutina
+ simple pero muy útil, generar un índice de todas las hojas que hay en el
+ archivo y a su vez a cada hoja colocarle el hipervínculo que te mande a la hoja principal de índices.
+
+ Para el uso de la sibrutina debes a agregar una hoja nueva de cálculo en tu archivo de excel que quieres indexar,
+ esa hoja nueva debe estar completamente vacia y tener la primera posición de izquierda a derecha, dejas esa hoja
+ activa (Imágen A), posteriormente abres el editor de código de Visual
+ Basic for Applications (VBA) , una vez dentro, en un módulo pegas el código de abajo y lo ejecutas.
+
+ Ejemplo:
+ Imágen B:
+
+ Para poder habilitar que el usuario se conecte y que se le requiera su contraseña necesitaremos modificar el archivo
+ pg_hba.conf el cual se encuentra en la ruta /etc/postgresql/[psql_version]/main/, para este
+ ejemplo práctico usaré la version 16, por lo tanto para editar el archivo debes ejecutar el siguiente comando con sudo y usaré el editor de nano:
+ Te recomiendo que siempre hagas una copia del archivo original. Nos movemos hasta las línea que dicen:
+ Vamos a comentar la segunda línea del código anterior para ello necesitamos añadir el prefijo '#' en la linea, yo
+ suelo añadir al final otro signo '#'' y poner una pequeña nota de cuando la modifiqué, tambien añadiremos una
+ tercera linea donde indicaremos que todos los usuarios que se intenten conectar a la base de datos se deberan
+ autenticar por medio de contraseña.
+
+ Diferencia en claves: Luego nos vamos a las líneas:
+ Del código anterior comentamos la segunda linea y añadimos una tercera línea que requiera que el usuario se
+ auntentifique cada que se conecte al servidor de la base de datos:
+
+ Para guardar todos los cambios realizados en nano debes de oprimir la combinación de teclas CTRL + s y para
+ cerrar el editor oprime la combinación de teclas CTRL + x.
+ Tenemos que editar el archivo postgresql.conf el cual está en la ruta /etc/postgresql/[psql_version]/main/ para ello ejecutamos el
+ comando:
+
+ El archivo es muy extenso, con muchas configuraciones, sin embargo la modicación que le harémos está en la primera
+ sección llamada CONNECTIONS AND AUTHENTICATION
+
+ Donde dice:
+
+ Debes cambiar el localhost por un *, ejemplo:
+
+ En el editor de nano guardamos oprimiendo la combinación de teclas Ctrl + s y cerramos con la combinación de
+ teclas Ctrl + x, luego procedemos a reiniciar el servicio de postgres con el comando:
+
+ En los pasos anteriores logramos hacer que postgresql acepte peticiones de cualquier punto de nuestra red local, el
+ puerto por default por el que escucha las
+ peticiones es el 5432, sin embargo a pesar de haber aplicado los ajustes puede que la maquina en este caso linux o
+ wsl no tengan el puerto abierto por lo tanto ahora abriremos el puerto para hacer que las peticiones si llegue, para
+ ello ejecutamos el siguiente comando:
+
+ Una vez hecho todo lo anterior ya podras hacer peticiones a tu servidor o equipo donde esta almacenada la base de
+ datos.
+
+ Este script básico sirve para obtener los datos de la base de datos, la idea principal es que sepas como conectarte
+ y posteriormente manipules los datos ya sea con pandas, excel o cualquier herramienta de analisis de datos.
+
+ Antes de ejecutar este Script, en caso de que la
+ base de datos este en otro equipo de la red local deberas asegurarte de que el servidor de base de datos acepte
+ peticiones dentro de la red local y no solo del localhost, además debes de conecer la IP del equipo y el nombre de la base de datos a la que que te
+ vas a conectar.
+
+ Creamos un archivo nuevo con el nombre que quieras y con extensión .py o .ipynb, posteriormente abrimos la terminal
+ e instalamos la librería psycopg2, para ello el comando es:
+
+ Luego usamos el siguiente script:
+
+ Como podemos ver al ejecutar el script anterior de la iteración obtendremos la información de la base de datos, pero
+ este script básico es el inicio más importante para que tu inicies tu análisis de datos en alguna herramienta y ahora
+ ya sabes como acceder a la base de datos y obtener tu insumo.
+
+ Este manual aplica para darle permisos a usuarios de PostgreSQL (no usuario postgres) para la ejecución de
+ scripts, primero necesitamos el nombre de la base de datos a la que vamos a afectar, el nombre del usuario con
+ el cual nos
+ vamos a identificar en PostgreSQL y la IP del equipo.
+ Una vez conociendo esos datos, tendremos que modificar el archivo de configuración pg_hba.conf, que es crucial
+ para la seguridad y configuración de acceso en PostgreSQL, ya que define quién puede conectarse y cómo deben
+ autenticarse. Este archivo se encuentra ubicado en la ruta /etc/postgresql/[psql_version]/main/. Para modificarlo, ejecutamos el siguiente comando:
+
+ Nos vamos hasta el final del archivo donde encontraremos el texto comentado
+
+ Debajo de ese texto agregaremos una nueva línea, asegurándonos de respetar la indentación, con la siguiente información.para ello el TYPE
+ hace referencia al tipo de conexión, nosotros le colocaremos el tipo local, en DATABASE el nombre de la base de datos,
+ USER es el nombre del usuario permitido, ADDRESS lo dejaremos vacio y METHOD md5 quedando el archivo de configuración
+ de la siguiente manera:
+
+ Guardamos los cambios con Ctrl + S y cerramos con Ctrl + X, despues reiniciamos el servicio.
+
+ Una vez ejecutados todos los pasos anteriores, ya podremos ejecutar scripts de SQL., abriremos una terminal donde
+ tengas
+ tu archivo DUMP , como mencioné al inicio de la
+ nota, deberás conocer la ip del servidor de base de datos, el nombre del usuario que te vas a autenticar y
+ adicionalmente la ruta de tu archivo dump.
+
+ Una vez ejecutado el comando anterior, vas a dar enter y te solicitará la contraseña, la ingresas y las instrucciones
+ de tu archivo .sql se empezarán a ejecutar.
+
+ Los ambientes virtuales se ubican dentro de una
+ carpeta principal que en este caso mi
+ carpeta contenedora del proyecto será PROJECT_VENV la cual contendrá toda la información del proyecto, desde
+ dependencias y código fuente de la aplicación,
+ para este ejemplo crearemos una carpeta llamada init_venv con la ayuda de VENV:
+
+ Una vez creado el ambiente virtual debemos activarlo para poder instalar las dependencias necesarias:
+
+ Cuando actives el ambiente verás en consola una salida muy similar a esta:
+ Cuando actives el ambiente verás en consola una salida muy similar a esta:
+ En este punto nuestro ambiente virtual está en blanco, no tenemos nada instalado, si queremos confirmarlo podemos
+ ejecutar el comando:
+
+ La salida del comando anterior no retornará nada por lo tanto sabemos que no hay nada instalado, para instalar por
+ ejemplo pandas en ambos casos el comando base para instalar en windows y linux es exactamente el mismo, pip
+ install:
+ Cuando instalemos pandas veremos que se instalarán además de pandas tambien se agragan las dependencias básicas para
+ que funcione pandas y la salida del comando debe ser algo muy similar a esta:
+ si vuelves a ejecutar el comando pip freeze podrás ver ahora si todas las dependencias que se han instalado:
+
+ Ahora si, en este supuesto que solo necesitaras pandas ya podrás empezar a trabajar en tu proyecto sin problemas,
+ dentro de tu carpeta y con el ambiente activo
+ deberás de abrir tu editor de código en mi caso VS Code y el comando es:
+
+ En tu editor de código ya podrás añadir archivos de python donde uses pandas y al momento de ejecutar el código por
+ primera vez, en este caso VS Code detectara que hay un ambiente activo y te pedira que selecciones el ambiente, da
+ click en la opción "Python Environments..."
+
+ Despues selecciona el ambiente que este caso es "init_venv (Python 3.12.4)".
+
+ Para desactivar el ambiente virtual en Windows o Linux solo necesitas ejecutar en la terminal el comando
+ deactivate.
+
+ Si llegaras a necesitar más dependencias, primero debes regresar a la consola e instalarlas ejecutar el comando base
+ pip install nombre_dependencia y despues
+ importarlas en tus archivos de python.
+ Del comando anterior lo que hace es que pip freeze lista las dependencias instaladas y
+ requirements.txt indica que almacenará la información que salga de pip freeze en un archivo llamado
+ requirements.txt, para este ejemplo práctico y sencillo si compartes tu proyecto solo compartirías la carpeta
+ contenedora del proyecto, el archivo donde importas pandas y el archivo requirements.txt
+
+ A veces cuando descargues un proyecto por ejemplo de GitHub o te compartan un proyecto de python, veras que tiene un
+ archivo comunmente llamado requirements.txt, entonces eso es una gran ayuda ya que no necesitas estar adivinando que
+ dependencias necesitas instalar, por lo tanto el proceso es muy simple, primero necesitaremos crear un ambiente
+ virtual en blanco, para este ejemplo lo llamaremos init_venv.
+ Una vez creado el ambiente virtual lo activamos:
+ Cuando actives el ambiente verás en consola una salida muy similar a esta:
+ Cuando actives el ambiente verás en consola una salida muy similar a esta:
+ Una vez activado el ambiente ejecutamos el comando de instalación de las dependencias, con el comando:
+
+ Una vez hecho eso ya podrás ejecutar cualquier archivo de python sin estar instalando las dependencias una por una.
+
+ A veces vas a encontrar una función o crear tus propias funciones UDF y hago esta nota para que sepas como guardarla
+ y como importarla para usarla, por lo tanto digamos que encontramos esta función sencilla llamada saludar, la cual
+ recibe un parámetro denominado nombre de tipo cadena de texto (string):
+
+ Lo que tenemos que hacer es abrir una instancia nueva de excel, luego vamos a oprimir la combinación de teclas
+ Alt + F11 para abrir el editor de código de VBA, en la parte superior izquierda veremos un pequeño ícono de
+ cuadritos naranjas que parecen ventanitas, lo seleccionamos y en el menú que se despliega seleccionamos la opción de
+ "módulo".
+
+ Nos aparecerá un nuevo elemento denominado módulo, que al darle doble clic veremos un lienzo en blanco en el cual
+ pegaremos el código de nuestra función:
+
+ Ahora podemos cerrar el editor de código de VBA dando clic en el botón "X" de la parte superior derecha, para hacer
+ el llamado de la función es muy simple, solo en una celda escribimos el signo igual y ponemos el nombre de la
+ función que en este caso es saludar y cómo le debemos pasar el parámetro nombre le colocaré "David":
+
+ Ya vimos que la función se ejecuta correctamente al llamarla, ahora bien esta función solo opera en nuestro libro
+ actual, si guardamos y cerramos y abrimos un nuevo libro y hacemos en llamado de la función veremos que no va a
+ funcionar, por lo tanto el libro de excel que contiene la función la guardaremos de la siguiente manera:
+
+ Una vez guardada la extensión y con el fin de poderla usar en cualquier libro existente o de nueva creación debemos
+ de
+ importarla en las funciones de excel para ello abrimos excel no importa si es un libro en blanco, y seguimos los
+ siguientes pasos:
+
+ Una vez hecho los pasos anteriores ya puedes usar la función de saludar en cualquier libro de ese equipo, considera
+ que si compartes ese archivo a una compañero de trabajo la función no servira por lo tanto debes compartir el
+ complemento (archivo con extensión .xlam) y repetir los pasos anteriores.
+
+ La UDF NumeroATextoMoneda sirve para
+ convertir
+ números a textos en formato moneda (pesos mexicanos), ejemplo:
+ A continuación te dejo el código de la UDF para que la revises y la puedas usar o modificar.
+
+ Esta función al igual que la de sumar por color la hice por que en un trabajo llevaban un registro en excel donde la
+ clásificación era por dos categorías y
+ por colores del relleno de la celda, y a veces eran varios colores, como los colores eran una constante y el rango
+ era un rango variable pues lo mejor era hacer una
+ función en lugar de hacer siempre filtrados por cada color:
+ Te dejo el código de la UDF en caso de que quieras
+ usarla o modificarla:
+
+ Cuando veía viáticos había automatizado el almacenamiento de unos documentos y dentro del nombre del archivo quería
+ que tuviera las iniciales del empleado, ejemplo:
+ Yo aplico este método de crear variables de
+ entorno para almacenar datos sensibles en proyectos en desarrollo de los
+ cuales si compartes el proyecto en un repositorio público la información no sea visible.
+
+ Para este ejemplo práctico vamos a crear una variable de entorno de tipo JSON muy sencilla donde la variable de
+ entorno se llamara 'usr_db' la cual tendra dos llaves, una será nombre y la otra será password:
+
+ Una vez conociendo los datos que queremos que tenga nuestra variable de entorno lo que sigue es guardarla en el
+ sistema y para ello tenemos dos opciones.
+
+ En mi opinión es la más sencilla, para ello abrimos la terminal de windows o el shell de PowerShell y escribirmos
+ lo
+ siguiente:
+
+ Despues de ingresar el código anterior y haber dado enter la consola te debe retornar un mensaje como el
+ siguiente:
+
+ Del comando anterior podemos resaltar:
+
+ Para este proceso sigue los siguientes pasos:
+
+ Del proceso anterior podemos destacar los siguientes puntos:
+
+ 1 Ya sea que añadas variables de entorno o a tráves de la interfaz gráfica, en ambos casos,
+ puedes ver
+ tus
+ variables de entorno en esta ventana, de igual forma las podrás editar o eliminar.
+
+ Una vez hecho lo anterior deberas de oprimir la combinación de teclas Windows + r y en la venta ejecutar escribiras lo
+ siguiente:
+
+ Una vez escrito el comando y dado enter ya podrás usar las variables de entorno y podras abrir el editor de código y
+ las terminales que necesites.
+
+ Está función retorna una suma considerando un color dentro de un rango y los valores en cada una de ellas, ejemplo:
+
+ Esta función a partir de un criterio y un color de celda suma los valores de un rango, los parámetros que requiere
+ son 3:
+
+ Ejemplo, en el rango A2:A41 tengo diferentes conceptos con diferentes colores, y en el rango B2:B41 tengo los
+ valores
+ númericos a ser sumados, en la celda D1 tengo el criterio "Bolígrafo" con fondo verde, quiero saber cuanto es la
+ sumatorioa considerando ese concepto y ese color de relleno, entonces en la celda E1 hago el llamado de la función
+ donde:
+ =sumarPorColorYConcepto(D1,D1,$A$2:$A$41,1)
+ Esta función la hice hace ya varios años, en un foro sobre temas de Excel una chica
+ quería saber si existia alguna forma de obtener la IP
+ de un equipo en Excel y fue así que hice esta solución.
+
+ El uso es muy sencillo, solo debes ingresar en cualquier celda =getMyIP(), una vez hecho te retornara la
+ información, ejemplo:
+ Esta función la hice pensando en que a veces quiero obtener de forma recursiva el listado de archivos en mi equipo
+ para eliminarlos, renombrarlos u ordenarlos, por ello hice una función que retorna en un archivo txt:
+
+ La forma de usarlo es muy sencilla, en tu terminal mueve a la carpeta que deseas obtener de forma recursiva el
+ listado
+ de archivos, luego llama a la función, ejemplo:
+ Cómo podemos ver en la imagen anterior, el archivo se guardará como carpeta_descargas y al final te dice en
+ que ruta se guardará el documento, te recomiendo que abras un nuevo archivo de excel e importes el documento para
+ que veas la información tabulada.
+
+ Esta función la hice para hacer conteo de archivos ya sea de forma recursiva o no de los archivos en un directorio,
+ la forma de usarlo es muy sencilla, en la terminal muevete al directorio donde quieres realizar el conteo, la función
+ tiene un parámetro llamado IsRecursive el cual es obligatorio
+ y puede ser T y F donde T = True, hace el conteo de todos los subdirectorios y F = False, hace el conteo solo de los
+ archivos en el direcotrio principal sin considerar subdirectorios,
+ ejemplo:
+
+ De la imagen anterior podemos ver que no es recursivo el conteo, pero que encuentra 4 archivos y no hay subfolders,
+ hay 2 archivos pdf, 1 docx y 1 xlsx.
+
+ Esta función la hice por que a veces tengo que analizar archivos del INEGI y al momento de descargar los datos
+ abiertos vienen comprimidos en multiples archivos zip y como era una
+ tarea repetitiva ví que podía automatizarla de tal forma que pueda descomprimir todos los archivos zip en un
+ directorio, para usarla es muy sencillo, solo debes de moverte
+ en la terminal hasta el directorio donde están todos tus archivos zip y luego hacer el llamado de la función,
+ ejemplo:
+ La salida del comando nos informa de forma iterativa el nombre del archivo que se va descomprimiendo y el número de
+ archivo del total de archivos a descomprimir, al final nos informa que ya se han descomprimido los archivos.
+
+ Para generar una llave SSH primedo debemos
+ colocarnos en la carpeta .ssh que tanto en Ubuntu, Debian o Windows la ruta ~/.ssh:
+ Una vez dentro de la carpeta de SSH de tu sistema, debemos ejecutar el comando que generara nuestra llave:
+ El comando genera una nueva clave SSH RSA de 4096 bits con el comentario "tu_correo_electronico@email.com",
+ explicación:
+ Como resultado del comando anterior son dos archivos con el mismo nombre id_rsa pero uno sin extensión
+ y otro con una
+ extensión .pub, debes copiar el contenido del archivo con extensión .pub.
+
+ Se mostrara en consola el contenido del archivo .pub, copialo.
+ El comando anterior copia el contenido a tu portapapeles.
+ Conectate a tu maquina Linux via SSH como normalmente lo haces y muevete a la carpeta .ssh, encontraras un archivo
+ llamado authorized_keys, lo modificaremos con ayuda de nano:
+
+ Una vez abierto el editor pegaras el contenido que copiaste del archivo id_rsa.pub, guarda los cambios con CTRL +
+ S y cierra el editor con CTRL + X, finalmente puedes salirte de la conexión SSH y volver a conectarte,
+ veras que ahora ya no te requiere contraseña
+ alguna para establecer la conexión.
+ En caso de que no haya funcionado, verifica que el archivo authorized_keys tenga los
+ permisos correctos:
+ Para poder añadir usuarios primero debemos cambiar a super usuario:
+ Para añadir un nuevo usuario simple sin permisos de administrador el comando es:
+ El sistema te pedirá que ingreses la contraseña para el usuario nuevo que estás creando y otros detalles,
+ como
+ el
+ nombre completo, el número de telefónico, etc. Puedes ingresar esta información opcionalmente, los puedes
+ dejar
+ vacios y dar enter.
+
+ Después de configurar la contraseña y otros detalles, el comando 'adduser' creará el nuevo usuario y su
+ directorio
+ de inicio en '/home/nuevo_usuario'. También asignará permisos adecuados para el nuevo usuario.
+
+ Para validar el acceso al usuario, puedes conectarte vía ssh y confirmarlo.
+ Para asignar permisos de super usuario al nuevo usuario el comando es: Esto permitirá que el nuevo usuario ejecute comandos con privilegios de administrador utilizando 'sudo'. Para eliminar a un usuario el comando es:
+ Este comando eliminará el usuario llamado usuario_nuevo. Ten en cuenta que este comando eliminará el
+ usuario pero no
+ eliminará los archivos del usuario en el sistema. Si deseas eliminar también los archivos asociados al
+ usuario, puedes usar la opción --remove-home:
+
+ Recuerda que es importante tener cuidado al eliminar usuarios, especialmente si tienen archivos importantes
+ asociados. Asegúrate de realizar copias de seguridad o mover archivos importantes antes de eliminar un
+ usuario.
+
+ Para poder habilitar SSH deberas instalar
+ openssh-server con ayuda del comando:
+
+ Una vez instalado openssh-server debemos verificar el estatus del servidor ssh:
+
+ Si te aparece que el servicio esta deshabilitado (disabled) entonces debemos ejecutar el comando para habilitarlo y
+ que acepte conexiones tanto de salida como de entrada:
+ El servidor SSH ya esta activo y finalmente nos queda abrir el puerto SSH en el firewall mediante el uso de ufw para
+ permitir conexiones SSH entrantes:
+ Este comando añade una regla a la tabla de iptables para aceptar tráfico entrante en el puerto 8080:
+
+
+ Este comando añade una regla al cortafuegos UFW (Uncomplicated Firewall) para permitir tráfico TCP en el puerto
+ 8080:
+
+
{% if btn | default(true) %} Copiar código{% endif %}
+
+
diff --git a/templates/components/footer.html b/templates/components/footer.html
new file mode 100644
index 0000000..1a0ab43
--- /dev/null
+++ b/templates/components/footer.html
@@ -0,0 +1,36 @@
+
+{{ codigo }}
+
+
+{{ ele[1] }}
+
+ {{ ele[2] | safe }}
+
+
+
Imagen A:
+
+
+
+
+
+ El contenido de las últimas 15 filas del archivo pg_hba.conf debe ser muy similar al siguiente:
+
+ - peer: la autenticación basada en el nombre de usuario del sistema operativo.
+ - md5: la autenticación basada en contraseña almacenada en formato MD5 para el usuario específico `postgres`.
+ En resumen, la elección entre `peer` y `md5` depende de cómo deseas gestionar la autenticación de los usuarios
+ locales en PostgreSQL: si prefieres que se autentiquen automáticamente utilizando su nombre de usuario del sistema
+ operativo (`peer`) o si deseas que proporcionen una contraseña específica (`md5`).
+
+ Finalmente para aplicar cambios debemos ejecutar el comando:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Te recomiendo que siempre antes de desactivar el ambiente virtual exportes una lista de las dependencias ya que si
+ compartes el proyecto la carpeta donde esta
+ ubicado
+ el ambiente virtual no se comparte ya que vuelve pesado el proyecto, la buena práctica es compartir solo la lista
+ con todos las carpetas necesarias sin el dictorio
+ del ambiente virtual (init_venv), para exportar la lista de dependencias debes ejecutar el comando:
+ Copiar código
+
+ python3 -m venv init_venv
Copiar código
+
+ python -m venv init_venv
Copiar código
+ source init_venv/bin/activate
+
+
Copiar código
+ .\init_venv\Scripts\activate
+
+
Copiar código
+pip install -r requirements.txt
Copiar código
+
+Function saludar(nombre As String)
+ saludar = "hola " & nombre
+End Function
+
+
+
+
+
+
+
+
+ En la celda C1 tenemos la cantidad en número 3050.8, y en la celda C2 ingresamos =NumeroATextoMoneda(C1) y
+ obtendremos el siguiente resultado:
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/18.html b/templates/html_template/18.html
new file mode 100644
index 0000000..4172ce8
--- /dev/null
+++ b/templates/html_template/18.html
@@ -0,0 +1,40 @@
+
+
+Function NumeroATextoMoneda(Numero)
+ Application.Volatile
+ Dim texto
+ Dim Billones
+ Dim Millones
+ Dim Miles
+ Dim Cientos
+ Dim Decimales
+ Dim Cadena
+ Dim CadBillones
+ Dim CadMillones
+ Dim CadMiles
+ Dim CadCientos
+ texto = Numero
+ texto = FormatNumber(texto, 2)
+ texto = Right(Space(18) & texto, 18)
+ Billones = Mid(texto, 1, 3)
+ Millones = Mid(texto, 5, 3)
+ Miles = Mid(texto, 9, 3)
+ Cientos = Mid(texto, 13, 3)
+ Decimales = Mid(texto, 17, 2)
+ CadBillones = ConvierteCifra(Billones, 1)
+ CadMillones = ConvierteCifra(Millones, 1)
+ CadMiles = ConvierteCifra(Miles, 1)
+ CadCientos = ConvierteCifra(Cientos, 0)
+ If Trim(CadBillones) > "" Then
+ If Trim(CadBillones) = "UN" Then
+ Cadena = CadBillones & " BILLON"
+ Else
+ Cadena = CadBillones & " BILLONES"
+ End If
+ End If
+ If Trim(CadMillones) > "" Then
+ If Trim(CadMillones) = "UN" Then
+ Cadena = CadMillones & " MILLON"
+ Else
+ Cadena = CadMillones & " MILLONES"
+ End If
+ End If
+ If Trim(CadMiles) > "" Then
+ Cadena = Cadena & " " & CadMiles & " MIL"
+ End If
+ If Trim(CadMiles & CadCientos) = "UN0" Then
+ Cadena = Cadena & "UN PESO " & Decimales & "/100 M.N."
+ Else
+ If Miles & Cientos = "000000" Then
+ Cadena = Cadena & " " & Trim(CadCientos) & " PESOS " & Decimales & "/100 M.N."
+ Else
+ Cadena = Cadena & " " & Trim(CadCientos) & " PESOS " & Decimales & "/100 M.N. "
+ End If
+ End If
+ Select Case Numero
+ Case Is < 0
+ Cadena = "El valor es negativo"
+ Case Is > 999999999999.99
+ Cadena = "El valor excede el limite de la función"
+ Case Is < 1
+ Cadena = "CERO PESOS " & Decimales & "/100 M.N."
+ Case Is < 2
+ Cadena = "UN PESO " & Decimales & "/100 M.N."
+ End Select
+ NumeroATextoMoneda = Trim(Cadena)
+
+End Function
+
+Function ConvierteCifra(texto, SW)
+ Dim Centena
+ Dim Decena
+ Dim Unidad
+ Dim txtCentena
+ Dim txtDecena
+ Dim txtUnidad
+ Centena = Mid(texto, 1, 1)
+ Decena = Mid(texto, 2, 1)
+ Unidad = Mid(texto, 3, 1)
+ Select Case Centena
+ Case "1"
+ txtCentena = "CIEN"
+ If Decena & Unidad <> "00" Then
+ txtCentena = "CIENTO"
+ End If
+ Case "2"
+ txtCentena = "DOSCIENTOS"
+ Case "3"
+ txtCentena = "TRESCIENTOS"
+ Case "4"
+ txtCentena = "CUATROCIENTOS"
+ Case "5"
+ txtCentena = "QUINIENTOS"
+ Case "6"
+ txtCentena = "SEISCIENTOS"
+ Case "7"
+ txtCentena = "SETECIENTOS"
+ Case "8"
+ txtCentena = "OCHOCIENTOS"
+ Case "9"
+ txtCentena = "NOVECIENTOS"
+ End Select
+
+ Select Case Decena
+ Case "1"
+ txtDecena = "DIEZ"
+ Select Case Unidad
+ Case "1"
+ txtDecena = "ONCE"
+ Case "2"
+ txtDecena = "DOCE"
+ Case "3"
+ txtDecena = "TRECE"
+ Case "4"
+ txtDecena = "CATORCE"
+ Case "5"
+ txtDecena = "QUINCE"
+ Case "6"
+ txtDecena = "DIECISEIS"
+ Case "7"
+ txtDecena = "DIECISIETE"
+ Case "8"
+ txtDecena = "DIECIOCHO"
+ Case "9"
+ txtDecena = "DIECINUEVE"
+ End Select
+ Case "2"
+ txtDecena = "VEINTE"
+ If Unidad <> "0" Then
+ txtDecena = "VEINTI"
+ End If
+ Case "3"
+ txtDecena = "TREINTA"
+ If Unidad <> "0" Then
+ txtDecena = "TREINTA Y "
+ End If
+ Case "4"
+ txtDecena = "CUARENTA"
+ If Unidad <> "0" Then
+ txtDecena = "CUARENTA Y "
+ End If
+ Case "5"
+ txtDecena = "CINCUENTA"
+ If Unidad <> "0" Then
+ txtDecena = "CINCUENTA Y "
+ End If
+ Case "6"
+ txtDecena = "SESENTA"
+ If Unidad <> "0" Then
+ txtDecena = "SESENTA Y "
+ End If
+ Case "7"
+ txtDecena = "SETENTA"
+ If Unidad <> "0" Then
+ txtDecena = "SETENTA Y "
+ End If
+ Case "8"
+ txtDecena = "OCHENTA"
+ If Unidad <> "0" Then
+ txtDecena = "OCHENTA Y "
+ End If
+ Case "9"
+ txtDecena = "NOVENTA"
+ If Unidad <> "0" Then
+ txtDecena = "NOVENTA Y "
+ End If
+ End Select
+
+ If Decena <> "1" Then
+ Select Case Unidad
+ Case "1"
+ If SW Then
+ txtUnidad = "UN"
+ Else
+ txtUnidad = "UN"
+ End If
+ Case "2"
+ txtUnidad = "DOS"
+ Case "3"
+ txtUnidad = "TRES"
+ Case "4"
+ txtUnidad = "CUATRO"
+ Case "5"
+ txtUnidad = "CINCO"
+ Case "6"
+ txtUnidad = "SEIS"
+ Case "7"
+ txtUnidad = "SIETE"
+ Case "8"
+ txtUnidad = "OCHO"
+ Case "9"
+ txtUnidad = "NUEVE"
+ End Select
+ End If
+ ConvierteCifra = txtCentena & " " & txtDecena & txtUnidad
+End Function
+
+
+ En esta función para poder funcionar necesita que ingreses dos parámetros, el primer parámetro es la celda que
+ contiene el color que deseas obtener el conteo,
+ el segundo parámetro es el rango que contiene las celdas con los colores a contar, ejemplo:
+ De la celda A1 a la celda A29 tenemos varios conceptos y varios colores pero nos interesa saber cuantas celdas
+ tienen el color verde de relleno, entonces
+ en la celda C1 colocamos el color verde (no importa si colocas texto en la celda solo valida el color de fondo), en
+ la celda D1 hacemos el llamado de la función
+ ingresando =contarPorColor(C1,$A$1:$A$29).
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/19.html b/templates/html_template/19.html
new file mode 100644
index 0000000..b609541
--- /dev/null
+++ b/templates/html_template/19.html
@@ -0,0 +1,33 @@
+
+
+Function contarPorColor(celda As Range, rango As Range) As Long
+ Application.Volatile
+ Dim conteo As Integer
+ Dim obj As Object
+ conteo = 0
+ For Each obj In rango
+ If obj.Interior.Color = celda.Interior.Color Then
+ conteo = conteo + 1
+ End If
+ Next obj
+ contarPorColor = conteo
+End Function
+
+ La celda C1 tiene el valor de "José Hernández Pérez", y en la celda C2 hacemos el llamado de nuestra función
+ =INICIALES(C1), el resultado es JHP:
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/2.html b/templates/html_template/2.html
new file mode 100644
index 0000000..9e314a2
--- /dev/null
+++ b/templates/html_template/2.html
@@ -0,0 +1,149 @@
+
+
+
+
+Function INICIALES(texto As Range) As String
+ Application.Volatile
+ Dim resultado As String
+ Dim palabras() As String
+
+ palabras = Split(AjustarEspacios(texto))
+ For i = LBound(palabras) To UBound(palabras)
+ resultado = resultado & Left(palabras(i), 1)
+ Next
+ INICIALES = resultado
+End Function
+
+Private Function AjustarEspacios(ByVal texto As String) As String
+ Dim resultado As String
+ resultado = Trim(texto)
+ Do While InStr(resultado, " ")
+ resultado = Replace(resultado, " ", " ")
+ Loop
+ AjustarEspacios = resultado
+End Function
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ En el rango C1:C20 tenemos múltiples valores y cada cenda dentro del rango tiene diferente color de fondo, en la celda
+ E1 ponemos un color de fondo del cual queremos obtener
+ la sumatorio a partir del color y en la celda F1 hacemos el llamado de la función =SUMARCOLOR(E1,$C$1:$C:20) y
+ nos debe dar la suma del rango considerando los valores
+ de cada celda y el color de fondo de las celdas:
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/21.html b/templates/html_template/21.html
new file mode 100644
index 0000000..9a6454f
--- /dev/null
+++ b/templates/html_template/21.html
@@ -0,0 +1,47 @@
+
+
+Function SUMARCOLOR(color As Range, rango As Range) As Long
+ 'color: La celda que contiene el color a sumar
+ 'rango: El rango de celdas a considerar en la suma
+
+ Dim resultado 'Almacenará el resultado de la suma
+ Dim celda As Range
+
+ 'Recorrer cada celda del rango
+ For Each celda In rango
+ 'Sumar si el color de la celda es igual al color especificado
+ If celda.Interior.ColorIndex = color.Interior.ColorIndex Then
+ resultado = resultado + celda.Value
+ End If
+ Next celda
+
+ SUMARCOLOR = resultado
+End Function
+
+
+
+
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/22.html b/templates/html_template/22.html
new file mode 100644
index 0000000..b076eae
--- /dev/null
+++ b/templates/html_template/22.html
@@ -0,0 +1,58 @@
+
+
+Function sumarPorColorYConcepto(color_de_referencia, concepto_de_referencia, rango_de_colores_y_conceptos As Range, columnas_de_desplazamiento As Integer) As Double
+ 'sumarPorColorYConcepto(Ctrl + Shift + A)-> para obtener en mini tooltip
+ Application.Volatile
+ Dim conteo As Double
+ Dim obj As Object
+ conteo = 0
+ For Each obj In rango_de_colores_y_conceptos
+ If obj.Interior.Color = color_de_referencia.Interior.Color And obj.Value = concepto_de_referencia.Value Then
+ conteo = conteo + obj.Offset(0, columnas_de_desplazamiento).Value
+ End If
+ Next obj
+ sumarPorColorYConcepto = conteo
+End Function
+
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/23.html b/templates/html_template/23.html
new file mode 100644
index 0000000..f19aeb4
--- /dev/null
+++ b/templates/html_template/23.html
@@ -0,0 +1,77 @@
+
+
+Function getMyIP() As String
+ Dim objWMI As Object
+ Dim objQuery As Object
+ Dim objQueryItem As Object
+ Dim vIpAddress As Variant
+ Dim res As String
+
+ On Error GoTo ErrorHandler
+
+ ' Crear objeto WMI
+ Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
+
+ ' Consultar WMI
+ Set objQuery = objWMI.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
+
+ res = ""
+
+ ' Recorrer todas las direcciones IP asignadas
+ For Each objQueryItem In objQuery
+ For Each vIpAddress In objQueryItem.IPAddress
+ res = res & "User IP - " & vIpAddress & vbCrLf
+ Next
+ Next
+
+ getMyIP = Trim(res)
+
+Cleanup:
+ ' Limpiar objetos
+ On Error Resume Next
+ Set objQueryItem = Nothing
+ Set objQuery = Nothing
+ Set objWMI = Nothing
+ On Error GoTo 0
+ Exit Function
+
+ErrorHandler:
+ ' Manejo de errores
+ res = "Error: " & Err.Description
+ getMyIP = res
+ Resume Cleanup
+
+End Function
+
+
+
+ Quiero exportar la información de mi carpeta de descargas, y quiero que el archivo se llame carpeta_descargas.
+
+
+
+
+ Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/24.html b/templates/html_template/24.html
new file mode 100644
index 0000000..48edcdf
--- /dev/null
+++ b/templates/html_template/24.html
@@ -0,0 +1,47 @@
+
+
+function exportDirectoryFilesTxt {
+ param(
+ [string]$fileName
+ )
+
+ # Asegurarse de que el archivo tenga la extensión .txt
+ $fileName = "$fileName.txt"
+
+ # Crear el archivo
+ New-Item -Path $fileName -ItemType File -Force
+
+ # Obtener el directorio actual
+ $curPath = $pwd
+
+ # Definir los encabezados
+ $headers = "File_Name|Extension_File|Date_Last_Write_Time|File_Path|MB_Size_File|Year|Month|Day|Hour|Minute|Second"
+ Set-Content -Path $fileName -Value $headers | Out-Null
+
+ # Obtener los archivos y añadir su información al archivo
+ Get-ChildItem -File -Recurse -Path $curPath | ForEach-Object {
+ $iterObj = $_.LastWriteTime
+ $fileSizeMB = [math]::Round((Get-Item -Path $_.FullName).Length / 1MB, 2) # Redondear a 2 decimales
+ $fileInfo = "$($_.Name)|$($_.Extension)|$($_.LastWriteTime)|$($_.FullName)|$fileSizeMB|$($iterObj.Year)|$($iterObj.Month)|$($iterObj.Day)|$($iterObj.Hour)|$($iterObj.Minute)|$($iterObj.Second)"
+ Add-Content -Path $fileName -Value $fileInfo | Out-Null
+ }
+
+ # Mover el archivo al escritorio (asegúrate de que $desktop esté definido)
+ $desktop = [Environment]::GetFolderPath("Desktop")
+ Move-Item -Path $fileName -Destination $desktop
+ Write-Host "Archivo guardado en la ruta: $desktop\$fileName"
+}
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/25.html b/templates/html_template/25.html
new file mode 100644
index 0000000..3b63714
--- /dev/null
+++ b/templates/html_template/25.html
@@ -0,0 +1,44 @@
+
+
+function CountFilesAndFolders {
+ param(
+ [string]$IsRecursive
+ )
+ $curP = pwd
+ if ($IsRecursive -eq "") {
+ Write-Host "El parametro -IsRecursive es obligatorio y solo acepta T= true o F=false, ejemplo de sitaxis:" -ForegroundColor Red
+ Write-Host "CountFilesAndFolders -IsRecursive T"
+ }
+ elseif (($IsRecursive -eq "T") -or ($IsRecursive -eq "F")) {
+ if ($IsRecursive -eq "T") {
+ $totalFiles = (Get-ChildItem -Path $curP -Recurse -File | Measure-Object).Count
+ $totalFolders = (Get-ChildItem -Path $curP -Recurse -Directory | Measure-Object).Count
+ Get-ChildItem -Path $curP -Recurse -File | group Extension -NoElement | sort Count -Descending
+ }
+ elseif ($IsRecursive -eq "F") {
+ $totalFiles = (Get-ChildItem -Path $curP -File | Measure-Object).Count
+ $totalFolders = (Get-ChildItem -Path $curP -Directory | Measure-Object).Count
+ Get-ChildItem -Path $curP -File | group Extension -NoElement | sort Count -Descending
+ }
+
+ Write-Host "Total files: " $totalFiles -ForegroundColor Green
+ Write-Host "Total folders:" $totalFolders -ForegroundColor Green
+ }
+ elseif ($IsRecursive -ne "T" -and $IsRecursive -ne "F") {
+ Write-Host "Verifica el parametro ingresado" -ForegroundColor Red
+ }
+}
+
+ Imaginemos que tenemos una carpeta con 32 archivos zip que queremos descomprimir y en la terminal ya estoy ubicado
+ en ese directorio, solo debo hacer el llamado de la función unzip:
+
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/26.html b/templates/html_template/26.html
new file mode 100644
index 0000000..8ab1e1c
--- /dev/null
+++ b/templates/html_template/26.html
@@ -0,0 +1,88 @@
+
+
+function unzip {
+ # https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.archive/compress-archive?view=powershell-7.2
+ $curP = $pwd
+ $Zips = Get-ChildItem -path $curP -filter "*.zip"
+ $Destination = $curP
+ $numFiles = (Get-ChildItem -Filter "*.zip" | Measure-Object).Count
+ if ($numFiles -eq 0) {
+ Write-Warning "No hay archivos zips para ser descomprimidos"
+ }
+ elseif ($numFiles -eq 1) {
+ Write-Host "Descomprimiendo: " $Zips.name -ForegroundColor Yellow
+ Expand-Archive $Zips.name -Force
+ Write-Host "Proceso finalizado " -ForegroundColor Green
+ }
+ elseif ($numFiles -gt 1) {
+ foreach ($_ in $Zips) {
+ $nRound = [math]::Round(((($Zips.IndexOf($_) + 1) / $numFiles) * 100), 2)
+ Write-Host "" ($Zips.IndexOf($_) + 1) " de " $numFiles " | " $nRound "% | Descomprimiendo: " $_.name -ForegroundColor Yellow
+ Expand-Archive $_ -Force
+ }
+ Write-Host "Proceso de descompresion finalizado exitosamente" -ForegroundColor Green
+ }
+}
+
+
Copiar código
+
+cd ~/.ssh
Copiar código
+
+ssh-keygen -t rsa -b 4096 -C "tu_correo_electronico@email.com"
+
+
+ Copiar código
+ cat ~/.ssh/id_rsa.pub
Copiar código
+ scb (cat ~\.ssh\id_rsa.pub)
Copiar código
+
+nano ~/.ssh/authorized_keys
Comentario adicional
+
+ Copiar código
+
+chmod 600 ~/.ssh/authorized_keys
Copiar código
+
+
+sudo su
Copiar código
+ adduser usuario_nuevo
Copiar código
+ sudo usermod -aG sudo usuario_nuevo
Copiar código
+ sudo deluser usuario_nuevo
Copiar código
+ sudo deluser --remove-home usuario_nuevo
Copiar código
+
+sudo apt install openssh-server -y
Copiar código
+
+systemctl status ssh
+
Copiar código
+
+sudo systemctl enable ssh
+
Copiar código
+
\ No newline at end of file
diff --git a/templates/html_template/29.html b/templates/html_template/29.html
new file mode 100644
index 0000000..1a3a0e9
--- /dev/null
+++ b/templates/html_template/29.html
@@ -0,0 +1,43 @@
+
+sudo ufw allow ssh
Copiar código
+
+sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
+
+ Copiar código
+
+sudo ufw allow 8080/tcp
+
+
Copiar código
+ sudo iptables-save
++ Este comando guarda la configuración actual de iptables para que se mantenga después de reiniciar el sistema: +
Copiar código
+ sudo ufw reload
++ Este comando recarga la configuración de UFW para aplicar cualquier cambio reciente: +
+ Yo aplico este método de crear variables de + entorno para almacenar datos sensibles en proyectos en desarrollo de los + cuales si compartes el proyecto en un repositorio público la información no sea visible. +
++ Para este ejemplo práctico vamos a crear una variable de entorno de tipo JSON muy sencilla donde la variable de + entorno se llamara 'usr_db' la cual tendra dos llaves, una será nombre y la otra será password: +
+ +{% set i %} +usr_db = { "nombre": "Saitama", "password": "OnePunchMan" } +{% endset %} +{% with codigo=i.strip(), isEditable="true" %} +{% include 'components/copy-code.html' %} +{% endwith %} + +
+ Una vez conociendo los datos que queremos que tenga nuestra variable de entorno lo que sigue es guardarla en el
+ sistema y para ello debemos abrir la consola oprimiendo la combinación de teclas Ctrl + Alt + T .
+ Una vez abierta la consola, debemos ir a home, así que ejecutamos el siguiente comando:
+
+ Editamos el archivo de configuración del usuario, para ello debemos hacerlo a través de sudo por lo que te será requerida tu contraseña. +
+ +{% set iii %} +sudo nano .bashrc +{% endset %} +{% with codigo=iii.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Una vez abierto el archivo en modo edición nos vamos al final del documento y añadimos lo siguiente: +
+ +{% set iv %} +export usuario='{"nombre":"Saitama", "password": "OnePunchMan"}' +{% endset %} +{% with codigo=iv.strip(), isEditable='true' %} +{% include 'components/copy-code.html' %} +{% endwith %} + +
+ Dentro del entorno de nano presionamos la combinación de teclas CTRL + s para guardar y luego CTRL + x
+ para salir del modo de edición.
Para reiniciar la configuración del usuario solo debes ejecutar el comando:
+
+ Una vez reiniciada la configuración del perfil del usuario podrás usar tu nueva variable de entorno. +
\ No newline at end of file diff --git a/templates/html_template/30.html b/templates/html_template/30.html new file mode 100644 index 0000000..50354c3 --- /dev/null +++ b/templates/html_template/30.html @@ -0,0 +1,50 @@ + ++ CRONTAB es una super herramienta que te ayudará a automatizar tareas en tu equipo Linux o en tu servidor casero. + En mi caso, lo uso para automatizar tareas como la actualización del sistema operativo, back-ups de base de datos, e + incluso un back-up de una partida de Minecraft. Para instalarlo, los pasos son muy sencillos: +
+Primero, verifica si está instalado CRON:
+ Copiar código
+dpkg -l | grep cron
+Si el comando no retorna información, deberás instalarlo y habilitarlo:
+ Copiar código
+sudo apt-get install cron && sudo systemctl enable cron
+En este punto, el servicio de cron debe indicar Active: active (running). + Ahora, solo queda automatizar tus tareas.
+ Copiar códigosystemctl status cron
+ Copiar códigosudo systemctl start cron
+ Copiar códigosudo service cron stop
+
+ + Para crear un Servidor DNS en tu red local vamos a usar una herramienta + sencilla y práctica llamada dnsmasq el cual nos + ayudará a conectarnos a los dispositivos de la red local sin necesidad de aprendernos + las IPs de los dispositivos, adicionalmente es muy importante que tanto tu servidor dns y todos los equipos a los que + deseamos acceder mediante dns + tengan asignada una ip estática de lo + contrario, no funcionará de forma permanente.. +
+ + + + Copiar código
+ # actualizar el sistema e instalar dnsmasq
+sudo apt-get update && sudo apt-get upgrade -y && sudo apt install dnsmasq -y
+
+
+ + Una vez instalado dnsmasq debemos modificar el archivo de configuración: +
+ + Copiar código
+ # modificar archivo de configuración de dnsmasq
+sudo nano /etc/dnsmasq.conf
+
+
+ + Dentro del archivo, nos desplazamos hasta el final del documento y añadiremos los siguientes registros: +
+ Copiar código
+ # añadir registros al final del documento
+interface=eth0 # Interfaz de red del equipo, puedes obtenerla con el comando [ip a] (puede ser wlan0 si usas WiFi), en este caso uso eth0
+bind-interfaces # Asegura que dnsmasq solo escuche en la interfaz especificada
+server=8.8.8.8 # Servidor DNS de respaldo (Google DNS u otro)
+domain-needed # Solo resuelve nombres de dominio completos
+bogus-priv # Bloquea consultas a direcciones privadas que no deberían salir de la red
+local=/mi-red.local/ # Dominio local personalizado
+expand-hosts # Expande nombres de host con el dominio especificado
+domain=mi-red.local # Dominio DNS local
+addn-hosts=/etc/hosts.dnsmasq # Archivo donde defines los nombres de host y sus IPs
+
+ + Creamos el archivo con los hosts personalizados para ello debemos conocer las ips de todos los dispositivos que + queremos acceder a través + de esta modalidad, considerando que en la configuración indicamos que los hosts iban a estar en la ruta + /etc/hosts.dnsmasq (addn-hosts=/etc/hosts.dnsmasq), + ejecutamos el siguiente comando: +
+ + Copiar código
+ # crear y editar el archivo con la lista de host e ips
+sudo nano /etc/hosts.dnsmasq
+
+
+ Una vez abierto el archivo añadimos la lista de ips de la red local y seguido, separado por un espacio, el nombre + de los hosts, ejemplo:
+ Copiar código
+ # crear y editar el archivo con la lista de ips y los nombres de host deseados
+192.168.1.1 server1
+192.168.1.2 server2
+192.168.1.3 server3
+192.168.1.4 server4
+192.168.1.5 server5
+
+
+ + Guardamos y cerramos el archivo, luego reiniciamos el servicio de dnsmasq: +
+ + Copiar código
+ # reiniciar dnsmasq
+sudo systemctl restart dnsmasq
+
+
+ En el equipo cliente donde usas alguna distribución de linux debes modificar el archivo resolv.conf, para ello + ejecutamos el comando:
+ Copiar código
+ # en cliente modificar archivo resolv.conf
+sudo nano /etc/resolv.conf
+
+
+ Al final del archivo añadimos lo siguiente:
+ Copiar código
+ # cliente conf resolv.conf
+nameserver 192.168.1.12 # ip local del servidor dns
+nameserver 8.8.8.8 # dns google
+nameserver 8.8.4.4 # dns google
+
+
+ + El archivo resolv.conf es un archivo que puede ser sobreescrito por el sistema por lo tanto debes de protegerlo de + escritura con el siguiente + comando: +
+ Copiar código
+ # comando para hacer inmutable el archivo resolv.conf
+sudo chattr +i /etc/resolv.conf
+
+
+ + En caso de que quieras volver a modificarlo es importante que primero lo vuelvas a hacer mutable con el comando: +
+ Copiar código
+ # comando para hacer mutable el archivo resolv.conf
+sudo chattr -i /etc/resolv.conf
+
+
+ + Finalmente para verificar que esta funcionando el servidor DNS lo que podemos hacer es un simple ping al server1 y + verificar que si hay + tráfico o en su defecto conectarnos mediante ssh ejemplo ssh usuario@server1 +
+ ++ Si tienes problemas para hacer inmutable el archivo te recomiendo que primero copies el contenido del archivo + resolv.conf y luego lo + elimines, lo vuelves a crear y finalmente pegarle el archivo e intenta nuevamente hacerlo inmutable, esto + seguramente lo resolverá: +
+ Copiar código
+ # moverse a la ruta etc donde esta el archivo de configuración
+cd /etc
+# copiar el contenido y hacer un respaldo del archivo de configuración, eliminar el archivo original de configuración
+sudo cat resolv.conf > backup_resolv.conf && sudo rm resolv.conf
+# tomar la información del archivo de respaldo para crear un nuevo archivo resolv.conf y asignarle una propiedad inmutable
+sudo cat backup_resolv.conf > resolv.conf && sudo chattr +i /etc/resolv.conf
+
+ + Si la maquina cliente es Windows deberás usar WSL y adicional a los pasos + anteriores de cliente, + deberas modificar el archivo wsl.conf mediante el comando: +
Copiar código
+ # modificar archivo wsl.conf
+sudo nano /etc/wsl.conf
+
+ Una vez abierto el archivo, al final del documento pegarás la siguiente información:
+ Copiar código
+[network]
+generateResolvConf = false
+nameserver=192.168.1.12 # IP del servidor DNS en este ejemplo
+
+
+
+ + Para poder subir cambios o descargar repositorios de nuestro servidor de control de versiones con Git (No host GitHub) + debemos primero haber creador el repositorio en nuestro servidor, para ello checa primero esa nota. +
++ Una vez creado el repositorio en nuestro servidor en nuestra maquina local podrémos hacer las siguientes + procedimientos: +
+ ++ Imaginemos que vamos a crear un nuevo proyecto llamado new_project, por lo tanto creamos la carpeta: +
+ Copiar código
+mkdir new_project; cd new_project
+ + Una vez dentro de la carpeta de nuestro nuevo proyecto debemos inicializar un repositorio Git: +
+ Copiar código
+# iniciar un entorno de git
+git init .
+
+ + Para vincular la carpeta del proyecto a nuestro servidor debemos ejecutar los siguientes comandos: +
+ Copiar código
+# vincular el proyecto a repositorio.
+git remote add origin nombre_usuario@ip_servidor_o_dns:/ruta/carpeta/repositorio/en/servidor
+# ejemplo: git remote add origin dave@192.162.1.18:/home/gitserver/repos/new_project
+
+ + El comando git remote add origin vincula nuestro proyecto local a un repositorio remoto. El alias + origin se usa para + referirse a este repositorio en comandos futuros como git push o git pull. +
++ El comando anterior debe funcionar tanto en redes locales como externas. Para conexiones externas, asegúrate de + abrir y + redirigir el puerto SSH (22) en tu router hacia la IP del servidor. Si tienes una IP dinámica, considera usar + servicios + como DuckDNS. +
++ Cabe mencionar que no es recomendable aperturar el puerto 22 de tu tu router ISP, pero en caso de que así lo + desees esos son + los pasos a seguir, lo más recomendable es usar una VPN como wireguard y ya sea que tu hagas la instalación o + compres un router que + sea compatible con algunas VPN. +
++ En caso de que hayas cambiado el puerto por defecto de escucha que es el 22 debes cambiar el comando de + vinculación a tu proyecto y especificar el puerto, el comando + puede ser aplicado tanto para redes locales y externas. +
+ Copiar código
+# comando para puerto de escucha modificado
+git remote add origin ssh://nombre_usuario@ip_publica_o_dns:puerto/ruta/carpeta/repositorio/en/servidor
+# ejemplo: ssh://dave@ip-casa-dns-sample.duckddns.org:2200/home/gitserver/repos/new_project
+
+ + Una vez hecho todos los pasos anterior ya puedes continuar con tu proyecto sin importar en el lenguaje de + programación en que vayas a + trabajar, guardar cambios con git add ., guardar cambios git commit -m "mensaje relacionado + a los cambios hechos" + y subirlos a tu servidor git push -u origin master. +
++ Adicional a lo anterior, tambien es importante que conozcas que puedes vincular un proyecto a más de un servidor + en caso de que quieras + redundancias para backups, para hacerlo el proceso es similar al anterior, ejemplo del comando: +
+ Copiar código
+git remote add server_1 dave1@192.168.16.10:/home/servergit1/new_project
+git remote add server_2 dave2@192.168.16.11:/home/servergit2/new_project
+
+ + Para hacer el envio de cambios es importante que hagas push por cada servidor, en este caso serían dos push, + ejemplo: +
+ Copiar código
+# Para enviar a servidor_1
+git push server_1 master
+
+# Para enviar a servidor_2
+git push server_2 master
+
+
+ + Si deseas desvincular el repositorio remoto configurado en tu máquina local, el procedimiento es muy sencillo. + Primero, verifica las conexiones actuales de tu repositorio mediante el siguiente comando: +
+ Copiar código
+# Listar los remotos configurados en el repositorio local
+git remote -v
+
+
+ + Este comando muestra las URL de los remotos configurados para operaciones de fetch (descarga) y + push (envío). + La salida será similar a la siguiente: +
+$ git remote -v
+origin dave@dns_server_git:/home/gitserver/repo/new_project (fetch)
+origin dave@dns_server_git:/home/gitserver/repo/new_project (push)
+
+
+ Alternativamente, puedes usar el comando git remote show origin
para obtener información más
+ detallada
+ sobre la configuración del remoto llamado origin
, incluyendo su URL y el estado actual de las
+ conexiones.
+
+ Una vez que hayas identificado el remoto que deseas eliminar, puedes desvincularlo usando el siguiente comando: +
+ Copiar código
+# Eliminar un remoto llamado 'origin'
+git remote remove origin
+
+
+ Después de ejecutar este comando, el repositorio local ya no estará vinculado al remoto eliminado.
+ No podrás realizar operaciones como git push
o git pull
hasta que configures una nueva
+ vinculación.
+ Sin embargo, los cambios realizados en tu repositorio local permanecerán intactos.
+
+ Si tienes múltiples remotos configurados, como se menciona en la sección "Vincular", asegúrate de especificar + correctamente el nombre del remoto que deseas eliminar. Por ejemplo: +
+ Copiar código
+# Eliminar un remoto llamado 'server_1'
+git remote remove server_1
+
+ + Clonar un repositorio es el proceso de crear una copia local de un repositorio remoto. Este procedimiento es + sencillo, + ya sea que trabajes en una red local o externa, siempre y cuando hayas realizado las configuraciones necesarias, + como + la apertura de puertos o la configuración de claves SSH. +
++ Para clonar un repositorio utilizando el puerto SSH predeterminado (22), usa el siguiente comando: +
+ Copiar código
+# Clonar repositorio con puerto predeterminado (22)
+git clone usuario@direccion_ip_servidor_o_dns:/ruta/carpeta/repositorio/en/servidor
+# Ejemplo: git clone dave@192.168.11.31:/home/gitserver/repos/new_project
+
+ + Si tu servidor está configurado para usar un puerto SSH diferente, debes especificarlo en el comando. + A continuación, te mostramos el formato y un ejemplo: +
+ Copiar código
+# Clonar repositorio con puerto modificado
+git clone ssh://usuario@direccion_ip_servidor_o_dns:puerto/ruta/carpeta/repositorio/en/servidor
+# Ejemplo: git clone ssh://dave@192.168.11.31:2200/home/gitserver/repos/new_project
+
+ + En caso de que no tengas una llave SSH te solicitará autenticación, solo ingresa la contraseña y podrás + clonar el repositorio, + puedes consultar mi nota de como crear una llave SSH. +
++ Primero debemos actualizar nuestro sistema + linux, una vez hecho eso, ya podemos iniciar con la instalación de Gitea: +
+ +1. Instalar dependencias
Primero, vamos a Instalar SQLite3 para poder manejar la configuración inicial y
+ en local.
Copiar código
+# es opcional ya que puedes usar otros gestores de bases de datos
+sudo apt install git sqlite3 -y
+
+2. Crear un usuario para Gitea
Es una buena práctica ejecutar Gitea con un usuario dedicado:
Copiar código
+# añadir un usuario ejemplo se llama gitea
+sudo adduser --system --group --home /home/gitea gitea
+
+3. Descargar Gitea
Descargamos la última versión de Gitea, en mi caso yo uso una Raspberry Pi 4, te
+ recomiendo primero conocer la arquitectura de tu maquina linux para saber que versión necesitas, para ello ejecuta el
+ comando:
+
Copiar código
+# En mi caso la salida del comando es: aarch64 lo que indica que es un procesador ARM de 64 bits.
+uname -m
+
+
+Para Raspberry Pi 64-bit:
+ Copiar código
+# esto solo aplica para descargar el binario compatible con la raspberry pi ARM64
+URL_VRSNS="https://api.github.com/repos/go-gitea/gitea/releases/latest"
+GITEA_VERSION=$(curl -s "$URL_VRSNS" | grep -Po '"tag_name": "\K.*?(?=")')
+VERSION=$(echo "$GITEA_VERSION" | sed 's/^v//')
+wget -O gitea https://github.com/go-gitea/gitea/releases/download/${GITEA_VERSION}/gitea-${VERSION}-linux-arm64
+
+Da permisos de ejecución:
+ Copiar código
+chmod +x gitea
+sudo mv gitea /usr/local/bin/
+
+4. Crear la estructura de directorios
Ahora, configura las carpetas necesarias para almacenar los datos y
+ configuraciones:
Copiar código
+# dependiendo del nombre del usuario que le diste en el punto dos debes reemplazarlo en gitea
+sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
+sudo chown -R gitea:gitea /var/lib/gitea
+sudo chmod -R 750 /var/lib/gitea
+sudo mkdir -p /etc/gitea
+sudo chown root:gitea /etc/gitea
+sudo chmod 770 /etc/gitea
+
+5. Crear el servicio de systemd
Para que Gitea se ejecute automáticamente, crea un servicio de systemd:
+
Copiar código
+sudo nano /etc/systemd/system/gitea.service
+Copia y pega el siguiente contenido:
+ Copiar código
+[Unit]
+Description=Gitea
+After=network.target
+
+[Service]
+RestartSec=2s
+Type=simple
+User=gitea
+Group=gitea
+WorkingDirectory=/var/lib/gitea
+ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
+Restart=always
+Environment=USER=gitea HOME=/home/gitea GITEA_WORK_DIR=/var/lib/gitea
+
+[Install]
+WantedBy=multi-user.target
+
+Guarda el archivo y sal (CTRL+S
, CTRL+X
, Enter
). Luego, habilita e inicia el
+ servicio:
Copiar código
+sudo systemctl daemon-reload
+sudo systemctl enable --now gitea
+
+Verifica que Gitea esté corriendo:
+ Copiar código
+sudo systemctl status gitea
+6. Configuración inicial de Gitea
Accede a la interfaz web en el navegador:
Copiar código
+http://IP-de-tu-equipo:3000
+
+ Cuando entres por primera vez al sitio tendrás que hacer la configuración inicial, los únicos
+ campos que yo modifico son:
+ "Tipo de base de datos": SQLite3
+ Usuario Configuración
+ SSH/Claves GPG
+ Le das clic en añadir una clave y le pegas tu llave pública SSH
+
+ En tu servidor de Gitea en la terminal deberás de ejecutar el siguiente comando: +
+ Copiar código
+sudo usermod -s /bin/bash gitea
+En una maquina diferente, de donde copiaste la llave SSH deberás ejecutar el siguiente comando para ver si gitea ya + esta funcionando:
+ Copiar código
+ssh -T gitea@ip-servidor-gitea
+
+Completa la configuración y tendrás Gitea listo para usar.
+ "Nombre del usuario": *lo dejo tal y como está, recuerda que debes considerar el punto dos de este manual"
+ "Contraseña": *Asignale la contraseña o al igual que en github puedes agregarle tu llave SSH*
+ "Título del sitio": *Pon el nombre que tu quieras*
+
Una vez que hayas hecho la configuración inicial, en tu servidor de Gitea deberás de iniciar sesión, ir a la ruta :
+
+ http://ip-del-equipo:3000/user/settings/keys
+
Para subir un proyecto a Apache HTTP Server que está hecho con Flask y VENV, debemos movernos mediante la terminal a + la ruta donde se almacenan los proyectos:
+ Copiar código
+cd /var/www/
+
+
+Clonamos el proyecto a desplegar
+ Copiar código
+# sudo git clone user_serv@ip.del.serv.git:[puerto_si_no_es_el_22]/ruta/al/repositorio
+sudo git clone usr1@192.160.11.29:/home/git_server/repos/ejemplo.com
+
+
++ Una vez clonado el repositorio, nos movemos a la carpeta ejemplo.com, creamos un entorno virtual (VENV) e instalamos + todas las dependencias listadas en requirements.txt (esto es una buena práctica). Todo lo anterior debe realizarse con + permisos de superusuario: +
+ Copiar código
+# Entramos en modo superusuario
+sudo su
+
+# Nos cambiamos al directorio del proyecto a desplegar
+cd /var/www/ejemplo.com
+
+# Iniciamos una instancia de VENV (entorno virtual)
+python3 -m venv .venv
+
+# Activamos el nuevo entorno virtual
+source .venv/bin/activate
+
+# Instalamos todas las dependencias necesarias
+pip install -r requirements.txt
+
+# Una vez instaladas las dependencias, podemos desactivar el entorno virtual con:
+deactivate
+
+# Salimos del modo superusuario
+exit
+
+
+ Dentro del proyecto, asegúrate de que exista un archivo con la extensión .wsgi, cuyo contenido debe ser similar al
+ siguiente, considera:
+
Copiar código
+# 1. sys: Se usa para manipular el entorno del sistema y agregar rutas a sys.path.
+import sys
+
+# 2. logging: Se usa para registrar eventos y errores, facilitando la depuración.
+import logging
+
+# 3. Ruta de Linux al proyecto Flask
+sys.path.insert(0, '/var/www/ejemplo.com')
+
+# 4. Ruta de Linux al entorno virtual (verifica la versión de Python en el servidor)
+sys.path.insert(0, '/var/www/ejemplo.com/.venv/lib/python3.11/site-packages')
+
+# 5. Configuración de logs
+logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
+
+# 6. Importamos la aplicación principal de Flask
+from main import app as application
+
+
++ Nos movemos al directorio de configuración de Apache: +
+ Copiar código
+cd /etc/apache2/sites-available/
+
+
++ Creamos el archivo de configuración con extensión .conf +
+ Copiar código
+# ejemplo
+sudo nano ejemplo.com.conf
+
+
++ Dentro del archivo debemos incluir una configuración similar a la siguiente. Consideraciones: +
Copiar código
+# Se recomienda NO usar el puerto 80 por seguridad.
+# Si decides usar otro puerto, asegúrate de abrirlo en el firewall.
+Listen 8084
+
+<VirtualHost *:8084>
+ ServerAdmin tu-email@email.com
+ ServerName ejemplo.com
+ ServerAlias ejemplo.com
+ DocumentRoot /var/www/ejemplo.com
+
+ WSGIDaemonProcess app-ejemplo user=www-data group=www-data threads=6 python-home=/var/www/ejemplo.com/.venv
+ WSGIScriptAlias / /var/www/ejemplo.com/ejemplo.com.wsgi
+
+ # dentro de tu proyecto debe existir la carpeta log para que dentro de esa se almacenen los logs
+ ErrorLog /var/www/ejemplo.com/log/error.log
+ CustomLog /var/www/ejemplo.com/log/access.log combined
+
+ <Directory /var/www/ejemplo.com>
+ WSGIProcessGroup app-ejemplo
+ WSGIApplicationGroup %{GLOBAL}
+ #Order deny,allow
+ Require all granted
+ </Directory>
+
+</VirtualHost>
+
+Para verificar la sintaxis del archivo de configuración, ejecuta:
+ Copiar código
+sudo apachectl configtest
+# si todo esta bien deberas ver el mensaje: Syntax OK
+
+
+Para aplicar los cambios, recarga el servicio de Apache:
+ Copiar código
+sudo systemctl reload apache2
+
+Finalmente, abre un navegador y coloca la IP del servidor de Apache. Si configuraste un puerto diferente al 80, debes + indicarlo:
+ Copiar código
+192.160.11.35:8084
+
+Si al recargar Apache aparecen errores o el sitio no carga en el navegador, revisa los logs de Apache o los del + proyecto:
+ Copiar código
+# Logs de Apache
+sudo journalctl -u apache2 --no-pager --lines=50
+
+# Logs del proyecto Flask
+cat /var/www/ejemplo.com/log/error.log
+
+El en repositorio de Git guarda los archivos de configuración .wsgi y .conf para que no los estes + creando cada vez que + despliegas cambios dentro del proyecto.
+A veces, en nuestro ambiente de pruebas, usamos variables de entorno en el front-end. Es común guardarlas en el + archivo `.bashrc` o en archivos `.env`. Si usas la segunda opción, siempre asegúrate de considerar el archivo + `.env` en `.gitignore` para evitar exponer información sensible y comprometer la seguridad de tu aplicación.
+En producción, cuando usamos Apache, debemos agregar las variables de entorno correctamente para que nuestra + aplicación las reconozca. Para hacerlo, sigue estos pasos:
+ +1. Editar el archivo de configuración de variables de entorno de Apache:
+ Copiar código sudo nano /etc/apache2/envvars
+
+2. Agregar las variables de entorno:
+Al final del archivo, agrega la variable con la siguiente estructura:
+ Copiar código
+# export nombre_variable='valor'
+export SALUDO="Hola mundo"
+
+3. Guardar y reiniciar Apache
+Guarda los cambios con `CTRL + S`, cierra el editor con `CTRL + X` y aplica los cambios reiniciando Apache:
+ Copiar código
+sudo systemctl restart apache2
+Una vez completados los pasos anteriores tu aplicación debe correr sin problemas, estas variables solo estarán + disponibles + para procesos manejados por Apache y no para sesiones de usuario en la terminal. +
+En tu proyecto de Flask en producción ya podrás usar la variable como normalmente la estabas usando, ejemplo:
+
+import os
+saludo = os.getenv("SALUDO")
+print(saludo) # Debería imprimir "Hola mundo"
+
\ No newline at end of file
diff --git a/templates/html_template/36.html b/templates/html_template/36.html
new file mode 100644
index 0000000..5d89e5a
--- /dev/null
+++ b/templates/html_template/36.html
@@ -0,0 +1,141 @@
+
+Para el manejo de caché en Apache, debemos seguir los siguientes pasos:
+1.- Habilitar los módulos de caché de Apache.
+ Copiar código
+sudo chown -R www-data:www-data /var/cache/apache2/mod_cache_disk
+sudo chmod -R 755 /var/cache/apache2/mod_cache_disk
+sudo apt-get install apache2-utils
+sudo a2enmod expires
+sudo a2enmod cache
+sudo a2enmod cache_disk
+sudo a2enmod headers
+sudo systemctl restart apache2
+
+
+2.- Configurar el caché en el disco:
Debemos movernos a la ruta donde están los archivos de configuración:
Copiar código
+cd /etc/apache2/sites-available/
+
+3.- Modificar el archivo de configuración del sitio, por ejemplo:
+ Copiar código
+sudo nano ejemplo.com.conf
+
+4.- Una vez en el modo de edición, veremos probablemente la configuración básica como esta:
+
+Listen 8084
+
+<VirtualHost *:8084>
+ ServerAdmin tu-email@email.com
+ ServerName ejemplo.com
+ ServerAlias ejemplo.com
+ DocumentRoot /var/www/ejemplo.com
+
+ WSGIDaemonProcess app-ejemplo user=www-data group=www-data threads=6 python-home=/var/www/ejemplo.com/.venv
+ WSGIScriptAlias / /var/www/ejemplo.com/ejemplo.com.wsgi
+
+ # dentro de tu proyecto debe existir la carpeta log para que dentro de esa se almacenen los logs
+ ErrorLog /var/www/ejemplo.com/log/error.log
+ CustomLog /var/www/ejemplo.com/log/access.log combined
+
+ <Directory /var/www/ejemplo.com>
+ WSGIProcessGroup app-ejemplo
+ WSGIApplicationGroup %{GLOBAL}
+ #Order deny,allow
+ Require all granted
+ </Directory>
+
+</VirtualHost>
+
+
+Dentro de la configuración, de preferencia después del cierre del tag </Directory>, agregaremos la + siguiente información:
+ + Copiar código
+# Habilitar caché para todas las solicitudes
+CacheEnable disk /
+
+# Configuración de caché
+<IfModule mod_cache_disk.c>
+ CacheRoot /var/cache/apache2/mod_cache_disk
+ CacheDirLevels 2
+ CacheDirLength 1
+ # [bytes] Tamaño máximo de archivo a almacenar en caché
+ CacheMaxFileSize 1000000
+ # CacheMinFileSize bytes
+ CacheMinFileSize 1
+ CacheIgnoreHeaders Set-Cookie
+ CacheIgnoreNoLastMod On
+
+ <FilesMatch "\.(jpg|jpeg|png|gif|css|js)$">
+ # Indica si el caché está funcionando
+ Header set X-Cache "HIT from Apache"
+ # Expiración por defecto (1 hora)
+ CacheDefaultExpire 3600
+ # Expiración máxima (1 día)
+ CacheMaxExpire 86400
+ CacheLastModifiedFactor 0.5
+ </FilesMatch>
+</IfModule>
+
+
+
+5.- El nuevo archivo de configuración debería de verse como el siguiente:
+ Copiar código
+Listen 8084
+
+<VirtualHost *:8084>
+ ServerAdmin tu-email@email.com
+ ServerName ejemplo.com
+ ServerAlias ejemplo.com
+ DocumentRoot /var/www/ejemplo.com
+
+ WSGIDaemonProcess app-ejemplo user=www-data group=www-data threads=6 python-home=/var/www/ejemplo.com/.venv
+ WSGIScriptAlias / /var/www/ejemplo.com/ejemplo.com.wsgi
+
+ # dentro de tu proyecto debe existir la carpeta log para que dentro de esa se almacenen los logs
+ ErrorLog /var/www/ejemplo.com/log/error.log
+ CustomLog /var/www/ejemplo.com/log/access.log combined
+
+ <Directory /var/www/ejemplo.com>
+ WSGIProcessGroup app-ejemplo
+ WSGIApplicationGroup %{GLOBAL}
+ #Order deny,allow
+ Require all granted
+ </Directory>
+
+ # INICIO MANEJO CACHE APACHE
+ # Habilitar caché para todas las solicitudes
+ CacheEnable disk /
+
+ # Configuración de caché
+ <IfModule mod_cache_disk.c>
+ CacheRoot /var/cache/apache2/mod_cache_disk
+ CacheDirLevels 2
+ CacheDirLength 1
+ # [bytes] Tamaño máximo de archivo a almacenar en caché
+ CacheMaxFileSize 1000000
+ # CacheMinFileSize bytes
+ CacheMinFileSize 1
+ CacheIgnoreHeaders Set-Cookie
+ CacheIgnoreNoLastMod On
+
+ # archivos en especifico:
+ <FilesMatch "\.(jpg|jpeg|png|gif|css|js)$">
+ # Indica si el caché está funcionando
+ Header set X-Cache "HIT from Apache"
+ # Expiración por defecto (1 hora)
+ CacheDefaultExpire 3600
+ # Expiración máxima (1 día)
+ CacheMaxExpire 86400
+ CacheLastModifiedFactor 0.5
+ </FilesMatch>
+ </IfModule>
+ # FINAL MANEJO CACHE APACHE
+
+</VirtualHost>
+
+
+
+6.- Para aplicar los cambios realizados en el archivo de configuración, debemos recargar Apache:
+ Copiar código
+sudo systemctl reload apache2
\ No newline at end of file
diff --git a/templates/html_template/37.html b/templates/html_template/37.html
new file mode 100644
index 0000000..7e26199
--- /dev/null
+++ b/templates/html_template/37.html
@@ -0,0 +1,158 @@
+
+Metabase es una herramienta de inteligencia empresarial (BI) de código abierto que permite visualizar y analizar + datos de manera sencilla y accesible. Su principal fortaleza radica en su facilidad de uso, ya que no requiere + conocimientos técnicos avanzados para crear dashboards, consultas y visualizaciones interactivas. A diferencia de + herramientas más complejas como Tableau o Power BI, Metabase se destaca por su simplicidad y rapidez de + implementación, lo que la hace ideal para equipos pequeños o medianos que buscan una solución ágil y económica. + Además, su naturaleza de código abierto permite personalizaciones y adaptaciones según las necesidades específicas de + cada organización. Su potencial reside en democratizar el acceso a los datos, permitiendo que usuarios no técnicos + exploren y tomen decisiones basadas en información en tiempo real.
+Para la instalación en un servidor Ubuntu, se deben seguir estos pasos:
+ +
+ 1. Actualizar el sistema e instalar Java
+ (requisito para Metabase):
+ Para ver las versiones disponibles, basta con ejecutar el comando:
+
Copiar código
+java -version
++ La salida de ese comando te enlistará las últimas versiones disponibles. Por ejemplo: +
dix@mb:~$ java -version
+Command 'java' not found, but can be installed with:
+sudo apt install default-jre # version 2:1.21-76, or
+sudo apt install openjdk-21-jre-headless # version 21.0.5~8ea-1
+sudo apt install openjdk-11-jre-headless # version 11.0.25~5ea-1ubuntu1
+sudo apt install openjdk-17-crac-jre-headless # version 17.0.13+0-0ubuntu2
+sudo apt install openjdk-17-jre-headless # version 17.0.12+7-2
+sudo apt install openjdk-21-crac-jre-headless # version 21.0.5+0-0ubuntu2
+sudo apt install openjdk-22-jre-headless # version 22.0.2+9-4
+sudo apt install openjdk-23-jre-headless # version 23+37-1
+sudo apt install openjdk-24-jre-headless # version 24~16ea-1
+sudo apt install openjdk-8-jre-headless # version 8u422-b05-1ubuntu1
+
Copiar código
+sudo apt install openjdk-24-jre-headless -y
+
++ Verificamos la versión instalada: +
+ Copiar código
+java -version
+
+
+ 2. Crear un usuario y carpeta para Metabase:
Por seguridad, es mejor ejecutar Metabase con un usuario sin
+ privilegios root:
+
Copiar código
+# crear un nuevo usuario llamado metabase
+sudo useradd -m -d /opt/metabase -s /bin/bash metabase
+
+# Opcional: Establece una contraseña para el usuario metabase
+# El sistema pedirá que ingreses una nueva contraseña para el usuario metabase.
+# Luego, te pedirá que confirmes la contraseña ingresándola nuevamente.
+# Si las dos entradas coinciden, la contraseña se actualizará y se almacenará de forma segura en el sistema.
+sudo passwd metabase
+
+# se utiliza para cambiar al usuario metabase en un sistema Linux, iniciando una sesión de shell como ese usuario.
+sudo su - metabase
+
++ 3. Crear un directorio para Metabase: +
+ Copiar código
+mkdir -p /opt/metabase && cd /opt/metabase
+
+
+ 4. Descargar el archivo .jar de Metabase:
Para ello, podemos consultar el repositorio en Github y ver cuál
+ es la versión más reciente. Para descargar el archivo desde la terminal, solo necesitamos ejecutar el comando wget y
+ el hipervínculo que aparece en la categoría Metabase Open Source con el concepto JAR download.
+
Copiar código
+wget https://downloads.metabase.com/v0.53.6.x/metabase.jar
+
+
+
+ 5. Ejecutar Metabase de forma manual:
Para verificar que todo está funcionando correctamente:
+
Copiar código
+java -jar /opt/metabase/metabase.jar
++ Veremos muchos logs en la terminal, pero después de unos 30 segundos aproximadamente, podremos ir a nuestro navegador + e ingresar la IP del servidor e indicar que queremos el puerto 3000 (puerto por defecto del servicio de Metabase). Por + ejemplo: +
+
+http://IP_DEL_SERVIDOR:3000
+
+Si ves los últimos logs en la terminal pero cuando vas al navegador no obtienes respuesta, entonces revisa que no + esté bloqueado el puerto 3000 por el firewall. Deberás salir del usuario Metabase y abrir el puerto con permisos de + superusuario.
++ En el caso de que veas el mensaje de bienvenida de Metabase en tu navegador, entonces todos los pasos ejecutados + anteriormente fueron + correctos. Así que interrumpiremos el servicio de Metabase para poder ejecutarlo en segundo plano y no tener que + hacerlo de forma manual. Seleccionamos la terminal donde se muestran los logs de Metabase y presionamos la combinación + de teclas CTRL + C para interrumpir el servicio. +
+ ++ 6. Salir del usuario metabase: +
+ Copiar código
+exit
+
+
+ 7. Configurar el servicio en segundo plano:
Mediante la edición del archivo metabase.service:
+
Copiar código
+sudo nano /etc/systemd/system/metabase.service
+Pegamos la siguiente configuración:
+ Copiar código
+[Unit]
+Description=Metabase
+After=network.target
+
+[Service]
+User=metabase
+ExecStart=/usr/bin/java -jar /opt/metabase/metabase.jar
+WorkingDirectory=/opt/metabase
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+
+
++ Guardamos (CTRL + S) y salimos (Ctrl + X). Luego, recargamos systemd y habilitamos el servicio: +
+ Copiar código
+sudo systemctl daemon-reload
+sudo systemctl enable metabase
+sudo systemctl start metabase
+
+
++ 8. Verificar que el servicio esté activo: +
+ Copiar código
+sudo systemctl status metabase
+
+
+En este punto, ya hemos finalizado la instalación y configurado el servicio en segundo plano. Ahora, el servicio + estará activo cada vez que el servidor esté encendido. Finalmente, solo queda que inicies sesión a través de tu + navegador web para añadir la configuración inicial de idioma, nombre, email, contraseña, conexiones a bases de datos + cómo PostgreSQL o MySQL, etc. +
\ No newline at end of file diff --git a/templates/html_template/38.html b/templates/html_template/38.html new file mode 100644 index 0000000..eeb854a --- /dev/null +++ b/templates/html_template/38.html @@ -0,0 +1,236 @@ + + + + + ++ Dominio de nuestra página web: Es el nombre que adquirimos a través de proveedores como + GoDaddy, Google Domains, Hostinger, entre otros. Este dominio será la dirección que + los usuarios utilizarán para acceder a nuestro sitio web. +
++ La IP pública: En muchos casos, la IP pública es dinámica, lo que significa que puede + cambiar con frecuencia. Esto puede ser un problema, ya que necesitamos una IP estática para garantizar la + accesibilidad constante de nuestros servicios. Para solucionar esto, podemos utilizar servicios como Duck DNS, que monitorea y actualiza automáticamente + la IP dinámica. Este servicio es especialmente útil para servicios como VPN, hosting web o conexiones SSH + (aunque este último no es recomendable por razones de seguridad). +
++ Configuración del router del ISP: En el router proporcionado por tu proveedor de + servicios de Internet (ISP), deberás abrir el puerto 80 (para este ejemplo). La configuración varía según + el modelo del router, pero generalmente debes buscar la opción de "Port Forwarding" o "Reenvío de + puertos". Allí, deberás agregar una regla que incluya: +
+ IP's estáticas de los servidores en la red local: Tanto los servidores web como el + balanceador de carga deben tener direcciones IP estáticas en la red local. Esto asegura que los + dispositivos siempre estén accesibles y que la configuración de red sea consistente. +
++ SSL: Adicional a los puntos anteriores, no es obligatorio pero por seguridad debes + considerar usar un servicio SSL ya sea que lo contrates con el proveedor del dominio o con Cloudflare que tiene una versión gratuita. +
++ Para este ejemplo consideraremos la siguiente información para la configuración: +
++ Una vez instalado HAProxy podemos revisar si el servicio está activo con el comando: +
+ +{% set i %} +systemctl status haproxy +{% endset %} +{% with codigo=i.strip(), isEditable="false" %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ La salida del comando debe ser algo similar a este: +
+ +{% set i %} +● haproxy.service - HAProxy Load Balancer + Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; preset: enabled) + Active: active (running) since Mon 2025-03-17 12:12:45 CST; 2 days ago + Docs: man:haproxy(1) + file:/usr/share/doc/haproxy/configuration.txt.gz + Main PID: 2643 (haproxy) + Tasks: 5 (limit: 8742) + CPU: 5min 30.311s + CGroup: /system.slice/haproxy.service + ├─2643 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock + └─2645 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock +{% endset %} +{% with btn=false, codigo=i.strip(), isEditable="false" %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Como podemos ver, HAProxy está activo, entonces podemos proceder a modificar el archivo de configuración con el editor + de nano y permisos de superusuario: +
+ +{% set ii %} +sudo nano /etc/haproxy/haproxy.cfg +{% endset %} +{% with codigo=ii.strip(), isEditable="false" %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Nos vamos hasta el final del archivo de configuración y añadimos la configuración del "frontend": +
+ +{% set iii %} +# frontend nombre_que_quieras +frontend https_frontend + # puerto que manejará el 80 + bind *:80 + # protocolo a usar + mode http + + # nombre de nuestro dominio: ejemplo-dom.com + # validador ejemplo-dom.com = is_ejemplo_dom_com (colocar el prefijo "is_", además los guiones medios y puntos se cambian a guiones bajos) + acl is_ejemplo_dom_com hdr(host) -i ejemplo-dom.com + # el nombre del backend puede ser el que tú quieras + use_backend ejemplo_dom_com if is_ejemplo_dom_com +{% endset %} +{% with codigo=iii.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Una vez configurado el frontend, continuamos en el mismo archivo y añadimos el "backend": +
+ +{% set iv %} +# backend nombre backend usado en la configuración del frontend +backend ejemplo_dom_com + # protocolo de balanceo de carga (puedes dejarlo o googlear otros protocolos) + balance roundrobin + # protocolo para sitios web + mode http + # enlistar las IPs de los servidores web o coloca la DNS de cada uno de los servidores en caso de usar un servidor DNS. + server server1 198.162.10.4:80 check + server server2 198.162.10.5:80 check + server server3 198.162.10.6:80 check + server server4 198.162.10.7:80 check + # server{1-4} puede ser el nombre que tú quieras, solo es una referencia para HAProxy + # 198.162.10.X:80 = indica que el servidor con esa IP tiene un servicio web activo en el puerto 80, en caso de no usar el 80 solo reemplaza ese valor + # check = valida que el servidor esté operando antes de redirigir el tráfico +{% endset %} +{% with codigo=iv.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Una vez configurado el frontend y el backend en el archivo de HAProxy, guardamos CTRL + S, cerramos CTRL + + X. Para validar que la sintaxis de la configuración sea correcta puedes usar el comando: +
+ +{% set v %} +sudo haproxy -c -f /etc/haproxy/haproxy.cfg +{% endset %} +{% with codigo=v.strip(), isEditable="false" %} +{% include 'components/copy-code.html' %} +{% endwith %} + +
+ Si todo está bien en términos de sintaxis, la salida del comando debe ser: Configuration file
+ is valid
+ Procedemos a reiniciar el servicio de HAProxy con el comando:
+
+ Listo, ahora podrás entrar a tu navegador web e ingresar el dominio ejemplo-dom.com. Tu proveedor de dominio
+ redirigirá a Duck DNS que tiene tu IP y mandará el tráfico a tu router ISP, este a su vez lo mandará a tu balanceador
+ de carga para finalmente redirigir el tráfico al servidor web
+ que esté con menos carga.
+ De forma práctica y simple, te recomiendo que en cada servidor web, en el HTML del sitio, en la página de inicio
+ coloques un comentario con el número de servidor, y desde el lado del navegador web refresques la página y veas cómo
+ cambia el número del servidor. Esto con la finalidad de saber si el balanceo de carga está funcionando, ejemplo diagrama de flujo:
+
+ Suponiendo que ya has creado la variable de entorno, ahora toca ver como leerla, ello el siguiente código de ejemplo: +
+ +{% set i %} +# la librería os nos ayudará a interactuar con las variables de entorno +import os +# la librería json nos ayudará a convertir la cadena de texto (str) a un formato JSON +import json + +# en seguimiento a mis notas de linux y de windows obtendremos la información de nuestra variable de entorno "usr_db" +usuario_env = os.getenv('usr_db') + +# Verifica si la variable de entorno existe +if usuario_env: + # si existe la variable de entorno la convertimos en formato JSON + usuario_json = json.loads(usuario_env) + # para este ejemplo solo imprimimos el valor de la variable + print(usuario_json) +else: + # en caso de que no exista que la consola nos imprima el siguiente texto + print("La variable de entorno 'usuario' no está definida.") +{% endset %} +{% with codigo=i.strip(), isEditable="true" %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Puedes ejecutar el código en un archivo con extensión .py o directamente en la terminal usando + el interprete de python como yo lo hago en este ejemplo: +
+
+ Para crear un repositorio de Git donde vamos a enviar
+ nuestros cambios, primero necesitamos instalar el programa con permisos
+ de superusuario (sudo
). Te pedirá tu contraseña, por lo que deberás proporcionarla; en caso de que no lo
+ hagas, no se
+ instalará:
+
+ Una vez instalado, debes moverte al directorio donde almacenarás tu repositorio. En mi caso, el repositorio lo
+ colocaré en home
.
+
+ Para este ejemplo, voy a crear una carpeta llamada repo_ejemplo
y me ubicaré dentro de ella:
+
+ Una vez dentro de la carpeta, debemos iniciar el repositorio ejecutando el siguiente comando:
+ git init --bare
.
+ Esta es una forma de configurar un repositorio Git centralizado y sin área de trabajo, que se utiliza típicamente para
+ facilitar la colaboración y el intercambio de código entre múltiples desarrolladores.
+
+ En caso de que no conozcas el nombre del usuario activo, deberás ejecutar el siguiente comando: +
+ +{% set v %} +whoami +{% endset %} +{% with codigo=v.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + +
+ Con los siguientes dos comandos, debes elevar los privilegios de la carpeta. Para ello, necesitaremos el nombre del
+ usuario obtenido con el comando anterior. En los comandos de abajo, deberás sustituir la palabra USER
por
+ tu
+ nombre de usuario.
+
Antes de instalar todas las herramientas recuerda que siempre es muy importante actualizar el sistema operativo, + para ello ejecuta los siguientes comandos:
+ +{% set i %}sudo apt update && sudo apt upgrade -y{% endset %} +{% with codigo=i.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +Apache Server es un software que nos ayudará a manejar todos los sitios web de nuestros servidores, en mi caso + integro Apache con ambientes virtuales de Python 3 y Flask, pero para esta nota lo unico que te enseñaré será a + instalarlo. Una vez abierta tu terminal ya sea en Ubuntu o en WLS, debes seguir los siguientes pasos:
+1.- Instalar el servidor de Apache que es la herramienta principal para hacer el hosting y manejo de peticiones por + sitio web:
+ +{% set ii %}sudo apt install apache2 -y{% endset %} +{% with codigo=ii.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +2.- Para poder integrar Python 3 (Flask) con Apache vamos a necesitar instalar el módulo WSGI de Apache para Python + 3.
+ +{% set iii %}sudo apt-get install libapache2-mod-wsgi-py3 -y{% endset %} +{% with codigo=iii.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +3.- Habilitar el módulo WSGI el cual es muy importante para poder leer los archivos de la aplicación de Flask:
+ +{% set iii %}sudo a2enmod wsgi{% endset %} +{% with codigo=iii.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +4.- Habilitar y activar Uncomplicated Firewall (UFW). UFW es una interfaz de usuario para iptables y está diseñado + para simplificar el proceso de administración de firewalls, haciendo más accesible la configuración de reglas de + firewall para los usuarios.
+ +{% set iv %}sudo ufw enable{% endset %} +{% with codigo=iv.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +5.- Hábilitar el puerto 80 del equipo para el tráfico de datos y poder acceder al sitio web desde otros equipos (NO + ES LO MISMO HABILITAR EL PUERTO 80 DEL EQUIPO QUE DEL ISP O ROUTER).
+ +{% set v %}sudo ufw allow 80{% endset %} +{% with codigo=v.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +6.- Una vez instalado el Apache Server (paso 1) podemos saber si esta activo el servidor ejecutando el comando:
+ +{% set vi %}sudo service apache2 status{% endset %} +{% with codigo=vi.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +6.1.- En caso de que la consola te de la respuesta "apache2 is not running":
+Lo que debes de hacer es levantar el servicio ejecutando el comando:
+ +{% set vii %}sudo service apache2 start{% endset %} +{% with codigo=vii.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +Una vez que el servicio este activo:
+Debemos conocer la ip del equipo, para ello ejecutamos el comando:
+ +{% set viii %}ifconfig{% endset %} +{% with codigo=viii.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +Del comando anterior tenemos que la ip de la interfaz "eth0", en la red local "inet" es la 172.30.29.141, por lo + tanto en tu navegador web ingresaras la ip y podras ver que tu servidor apache ya esta operando y listo para ser + modificado con tu sitio de interes.
+Otros comando básico sobre el servicio de apache:
+Reiniciar el sistema:
+ +{% set ix %}sudo service apache2 restart{% endset %} +{% with codigo=ix.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +Detener el servicio:
+ +{% set x %}sudo service apache2 stop{% endset %} +{% with codigo=x.strip() %}{% include 'components/copy-code.html' %}{% endwith %} \ No newline at end of file diff --git a/templates/html_template/7.html b/templates/html_template/7.html new file mode 100644 index 0000000..80e49ee --- /dev/null +++ b/templates/html_template/7.html @@ -0,0 +1,20 @@ + ++ En esta pequeña nota solo verémos la instalación, es muy sencilla, para proceder con la instalación ejecutamos el + comando de instalación dentro de la terminal: +
+ +{% set i %}sudo apt install haproxy -y{% endset %} +{% with codigo=i.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + +
+ Una vez instalado HAProxy puedes ver el archivo de configuración que está en la ruta:
+ /etc/haproxy/haproxy.cfg
+
+ Te recomiendo que antes de hacer alguna modificación al archivo primero realices una copia del mismo ya sea en una + carpeta de tu preferencia o en el directorio origen del archivo ejecutando el siguiente comando: +
+ +{% set i %}sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy_backup_usr.cfg{% endset %} +{% with codigo=i.strip() %}{% include 'components/copy-code.html' %}{% endwith %} \ No newline at end of file diff --git a/templates/html_template/8.html b/templates/html_template/8.html new file mode 100644 index 0000000..7862d4c --- /dev/null +++ b/templates/html_template/8.html @@ -0,0 +1,102 @@ + + + + +La instalación de PostgreSQL es muy sencilla, para ello debemos de abrir una terminal en el sistema.
+Comando de instalación en Linux:
+ + {% set i %}sudo apt install postgresql -y{% endset %} + {% with codigo=i.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + + +Comando de instalación en WSL:
+ + {% set ii %}sudo apt install postgresql postgresql-contrib -y{% endset %} + {% with codigo=ii.strip() %}{% include 'components/copy-code.html' %}{% endwith %} + + + Una vez instalado deberas saber que los archivos de configuración se guardan en la ruta:
+
/etc/postgresql/[version]/main/
+
+ Por seguridad asignale una contraseña al usuario postgres para ello debes ejecutar en la terminal el comando: +
+ +{% set iii %}sudo -u postgres psql{% endset %} +{% with codigo=iii.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + ++ Despues le asignamos la contraseña con el comando: +
+ +{% set iv %}ALTER USER postgres WITH PASSWORD 'la_contraseña_que_quieras';{% endset %} +{% with codigo=iv.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + + +Salimos de la terminal de postgresql con el comando:
+ +{% set v %}\q{% endset %} +{% with codigo=v.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + +Para saber si el servicio de postgresql esta activo puedes ejecutar el comando:
+ +{% set v %}sudo service postgresql status{% endset %} +{% with codigo=v.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + +Si el servicio esta inactivo se te mostrará la siguiente información:
+Para iniciar el servicio el comando es el siguiente:
+ +{% set vi %}sudo service postgresql start{% endset %} +{% with codigo=vi.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + +Para detener el servicio el comando es el siguiente:
+ +{% set vii %}sudo service postgresql start{% endset %} +{% with codigo=vii.strip() %} +{% include 'components/copy-code.html' %} +{% endwith %} + +Más documentación importante: +
+ + + \ No newline at end of file diff --git a/templates/html_template/9.html b/templates/html_template/9.html new file mode 100644 index 0000000..5cb4019 --- /dev/null +++ b/templates/html_template/9.html @@ -0,0 +1,92 @@ + ++ Para crear un usuario en PostgreSQL que pueda realizar operaciones CRUD en todas las tablas de una base de datos específica, sigue estos pasos: +
+ +1. Acceder a PostgreSQL como superusuario
Abrimos una terminal y accedemos a PostgreSQL:
2. Crear el usuario
Creamos un usuario con una contraseña:
3. Conceder acceso a la base de datos
Damos acceso al usuario para que pueda conectarse a la base de datos:
+
4. Otorgar permisos sobre el esquema public
Primero, nos conectamos a la base de datos y damos permisos
+ sobre el esquema:
5. Conceder permisos en tablas y secuencias existentes
Otorgamos permisos CRUD sobre todas las tablas y acceso a
+ secuencias existentes:
6. Conceder permisos para futuras tablas y secuencias
Para asegurarnos de que los objetos creados en el
+ futuro también sean accesibles por testusr:
7. Salir de psql
+ +{% set vii %} +\q +{% endset %} +{% with codigo=vii.strip(), isEditable="true" %} +{% include 'components/copy-code.html' %} +{% endwith %} + +8. Probar la conexión con el nuevo usuario
Antes de conectarnos, debemos conocer la IP del servidor de base
+ de datos. Si el servidor está en el mismo equipo, la IP será 127.0.0.1:
+ # psql -U testusr -d db_test -h localhost (te pedirá la contraseña por lo que deberás ingresarla)
+ psql -U testusr -d db_test -h 127.0.0.1
+
Portal estático, sitio hecho para la SICT en espera de ser integrado a la sección principal.
+ Sitio +Portal dinámico, aportación del gobierno mexicano al Proyecto Mesoamérica.
+ Sitio +Portal dinamico, sitio donde los beneficiarios de la conectividad generan sus reportes trimestrales.
+ Sitio +Portal dinámico que almacena la información de candidatos el área de reclutamiento y selección.
+ Sitio +Portal dinámico que muestra de forma sencilla tutoriales de gobierno.
+ Sitio +Consultora de RRHH especializada en reclutamiento, selección y evaluaciónes.
+ Sitio ++ {{ele[3]}} +
+