sábado, 7 de febrero de 2026

FreeCAD (IV): Translaciones y rotaciones (se requiere mejorar la interfaz del usuario!!!).

1. Introducción

Esta parte es muy cutre. Hay 2 tipos de traslaciones/rotaciones: Transform y Placement

2. Transform

Esta herramienta parece ser poco precisa ....

Sobre el menu de "arbol" de la izquierda donde están las piezas de hace click con el botón derecho sobre la pieza a mover/rotar  y se selecciona "Transformar".



Si se quiere tener unos mínimos de precisión se procederá:

  1. Indicar el incremento de la traslación (en una dirección).
  2. Con el ratón sobre el cuadrado verde, se procede a trasladar dicho cuadrado podo a poco hasta que la pieza haga un salto hasta la posición deseada. Si el traslado es pequeño, debemos ampliar la escala para poder controlar.
  3. Se procede igual en otra dirección perpendicular.
  4. Para giros, se indica el incremento de rotación y con el ratón sobre el círculo verde ejercemos la rotación poco a poco hasta que salte al ángulo deseado.
  5. Pero tenemos un problema, y con eso se demuestra lo cutre que es todavía. NO SE PUEDE DESPLAZAR EL CENTRO DE ROTACIÓN. Normalmente está en el punto (0,0)
  6. Solución "chapucera". Si el centro de rotación no se puede mover, se tendrá que mover la pieza hasta que el centro de rotación este en la posición que nos intereses, y se rota la pieza. A continuación se deja la pieza donde estaba.

3. Placement

Para poder utilizar esta herramienta, hay que hacer :
  1. Click izquierdo sobre la pieza en el menú de árbol de la izquierda.
  2. Aparece abajo una "grid" con alguna propiedades de la pieza, entre ellas está el nombre (para comprobar que es la pieza correcta) y otra que se llama "placement" que es la que nos interesa. Y hacemos doble-click en los valores de Placement y aparece un botón con 3 puntitos: 



  3. Apretamos el botón de los 3 puntitos y ya nos pide información sobre translaciones y rotaciones








FreeCAD (III) Guardar documento, piezas y exportar.

1. Guardar el documento (proyecto)

El documento puede contener varia piezas 

Se guarda con Archivo -> Guardar (o Guardar como)

Y se guarda con la extendión própia ".FCStd"

No se debe guardar con estas extensiones:

Extensión Motivo
.STEP Se piede historial, sketches, parámetros
.STL Se pierde todo menos la malla
.DXF, .DWG  Solo para 2D


2. Guardar solo una pieza

  1. Abrir el documento original 
  2. Hacer click sobre el cuerpo (Body) de la pieza del menu de arbol de la derecha y hacer Control-C de copiar y nos indica que se copiará de la pieza



  3. Menu Archivo - Nuevo (Crea un documento "sin nombre")
  4. Hacer click sobre el documento nuevo y Control-V de pegar y ya se ha copiado la pieza y ahora se guarda ese documento nuevo con una sola pieza



  5. Ahora se guarda el documento que ha recibido el copiado. (Sin nombre2)


    3. Copiar una pieza a otro documento.

    Tal como hemos visto se abren tanto el documento original como el que va a recibir la copia y se procede como el punto anterior con Cntl-C sobre la pieza a copiar y Cntl-V sobre el documento que va a recibir la pieza





    FreeCAD (II) Agujeros y roscas

    1. Crear agujeros con rosca

    Los pasos a seguir son

    1. Marcar el cuerpo activo. En la pestaña Modelo, aparece una vista de árbol con las piezas creadas. a pieza activa o cuerpo activo se muestra en verde. Para seleccionar otra pieza, nos situamos en el cusor sobre ella y damos click derecho y "Cuerpo Activo"



    2. Marcar la cara donde va el agujero, vasta hacer click sobre ella y apretar el icono de crear sketch



    3. En el sketch (boceto, croquis,..) se dibujan una o varias circunferencias, solo importa el centro de las mismas. El radio no sirve para nada. Los centros de esas circunferencias son las que definen el centro del taladro. TODAS las circunferencias dibujadas van a ser taladradas con el MISMO DIAMETRO. Y se cierra el boceto con el botón Close


    Se le da al icono de "Hole" 


    Hay que indicar bien los parámetros de la operación"Hole":

    • En Perfil si aparece "Nada", será un agujero sin rosca, pero si seleccionamos "Perfil regular métrico ISO" da opciones para definir el roscado
    • Se elige la métrica, profundidad y los tipos de roscado (por defecto mano derecha).
    • NO se debe elegir rosca modelada, pues el diseño geométrico de la rosca aparece en el dibujo y hace demasiado largo el fichero. Pero la información sobre el roscado debería aparecer en "metadatos". La opción "actualizar vista de rosca" permite ver el roscado solo si se ha aceptado la opción no deseable anterior.
    • Se puede elegir avellanado, y la forma de la punta del final del taladro.
    Se le da al botón OK y ya tenemos la operació hecha.



    2. Crear agujeros sin rosca

    Se puede proceder de la misma forma (Herramienta "Hole") pero en Perfil se selecciona "Nada".

    Pero también se puede hacer igual pero eligiendo la herramienta "Vaciado" sobre cada circunferencia, con ello se respeta el diámetro de cada una.






    lunes, 3 de noviembre de 2025

    WEBPROPv2 (XVII). Tareas de manternimiento (II). Clave SSH. Scripts de mantenimiento (copiar ficheros, arrancar servicios etc)

    1. Clave ssh

    1.1 Creación de una clave ssh para conectarnos al servidor remoto

    Primeramente crearemos una carpeta (aunque no esnecesario). Utilizaremsos el tipo ed25519.  

    Se le dará el nombre que queramos en este caso "srv01_ssh_key" y opcionalmente se puede añadir un comentario que se añadirá dicho comentario al final en el fichero de la clave pública. El comentario es: "Clave Srv01"


    mkdir -p /home/myuser/keys
    
    ssh-keygen -t ed25519 -f /home/myuser/keys/srv01_ssh_key -C "Clave Srv01"
    

    Se creará una clave privada (srv01_ssh_key) y una clave pública (srv01_ssh_key.pub). Hay que tener cuidado de no compartir la clave privada.

    Durante el proceso te pide una contraseña, que debes guardar

    1.2. Uso de la clave ssh

    Cada vez que ejecutemos un comando por ejemplo

    ssh -i /home/myuser/keys/srv01_ssh_key usuario@servidor.com

    Nos pedirá la contraseña.

    Si queremos conservar la contraseña en memoria en cada conexión :

    eval "$(ssh-agent -s)"
    ssh-add /home/myuser/keys/srv01_ssh_key
    


    1.3. Copiar la clave pública al servidor remoto

    Se puede copiar utilizando ssh-copy-id o cat + ssh

    # Si se dispone de ssh-copu-id
    ssh-copy-id -i /home/myuser/keys/srv01_ssh_key usuario_remoto@IP_REMOTA
    
    #Sinó
    cat /home/myuser/keys/srv01_ssh_key | ssh usuario_remoto@IP_REMOTA "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
    


    1.4. Ejecutar en el servidor remoto

    Podemos ejecutar ssh, scp o rsync usando esta clave:

    # 1. ssh
    ssh -i /home/myuser/keys/srv01_ssh_key usuario_remoto@IP_REMOTA
    
    # 2. scp
    scp -i /home/myuser/keys/srv01_ssh_key archivo usuario_remoto@IP_REMOTA:/ruta/
    
    # 3. rsync
    rsync -e "ssh -i /home/myuser/keys/srv01_ssh_key" ...
    

    1.5. Configurar ~/.ssh/config con alias y ruta de la clave par acceder al servidor remoto

    Así podemos evitar usar la opción -i. Veamos el fichero ~/.ssh/config:

    # Read more about SSH config files: https://linux.die.net/man/5/ssh_config
    
    # Servidor GLI i ara té la web de l'Ajuntament
    Host srv01
        HostName IP_REMOTA
        User usuario_remoto
        IdentityFile /home/myuser/keys/srv01_ssh_key
        IdentitiesOnly yes
        Port 22
    

    Y ahora ejecutando

    ssh IP_REMOTA 

    nos pediará la contraseña de la clave privada y entramos


    2. Script de borrar (mover) logs y arrancar servicios remotos. Se ejecuta directamente sobre el servidor remoto

    Queremos poder ejecutar los comandos mv, systemctl stop y systemctl restart remotamente, cosa que nos pide que lo hagamos con sudo. Para que no nos pida la contraseña de "sudo" ejecutamos:

    sudo visudo

    y metemos esta línea

    usuario_remoto ALL=(ALL) NOPASSWD: /bin/mv, /bin/systemctl stop *, /bin/systemctl restart *
    


    Con esto ya no nos pedirá la contraseña en estos 3 comandos para el usuario en cuestión.

    Después de mucho preguntar al chatgpt, me ha dado muchos problemas el intentar parar servicios remotos. Es por ello que he decidido entrar en una sesión remota y ejecutar directamente esta shell que llama a las demas (una para parar los servicios, otra para mover los logs y otra para rearrancar los servicios)

    Ahora, aunque lo ejecutemos en el servidor remot directamente no nos pedirá la contraseña de sudo.

    2.1 script de llamada a las demás


    SERV.00.sh

    #!/bin/bash
    
    # 1. Obtenemos la ruta de la carpeta donde está el script
    DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    
    # 2. Lista de scripts a ejecutar
    scripts=(
      "SERV01.Pas1.parar_serveis.sh"
      "SERV02.Pas2.copiar_y_borrar_logs.07.sh"
      "SERV03.Pas3.arrancar_serveis.01.sh"
    )
    
    # 3. Ejecución de lso scripts
    for s in "${scripts[@]}"; do
      path="$DIR/$s"
      if [[ -f "$path" ]]; then
        echo "Ejecutando $s..."
        bash "$path" || { echo "Error en $s"; exit 1; }
      else
        echo "No encontrado: $path"
      fi
    done
    

    2.2 script de parada de los servicios


    SERV01.Pas1.parar_serveis.sh
     
    #!/bin/bash
    
    # ==============================================================================
    # CONFIGURACIÓN
    # ==============================================================================
    
    # Lista de patrones de búsqueda (expresiones regulares)
    PATRONES_BUSQUEDA="(openr|python_)" 
    
    # ==============================================================================
    # PROCESO PRINCIPAL
    # ==============================================================================
    
    echo "--- Buscando y rearrancando servicios que coincidan con $PATRONES_BUSQUEDA ---"
    echo "--------------------------------------------------------------------------"
    
    # 1. Obtener la lista de servicios activos que coinciden con los patrones.
    SERVICIOS=$(systemctl list-unit-files --type=service | grep -E "$PATRONES_BUSQUEDA" | awk '{print $1}')
    
    # 2. Iterar sobre la lista de servicios y reiniciarlos.
    if [ -z "$SERVICIOS" ]; then
        echo "ℹ️ No se encontraron servicios activos que comiencen por 'openr' o 'python_'."
    else
        for SERVICIO in $SERVICIOS; do
            echo "➡️ Parando servicio: $SERVICIO"
            
            # Ejecutar el comando de reinicio. Se usa 'sudo' porque 'systemctl restart'
            # requiere permisos de superusuario para la mayoría de los servicios.
            sudo systemctl stop "$SERVICIO"
            
            # 3. Verificar el estado (opcional, pero recomendado)
            if [ $? -eq 0 ]; then
                echo "   ✅ $SERVICIO parado con éxito."
            else
                echo "   ❌ Fallo al parar $SERVICIO. Verifique los logs (journalctl)."
            fi
        done
    fi
    
    echo "--------------------------------------------------------------------------"
    echo "--- Proceso completado ---"
    

    2.3 script de traslado de ficheros logs 


    SERV02.Pas2.copiar_y_borrar_logs.07.sh
     
    #!/bin/bash
    
    #################################
    # DEFINICION DE PARAMETROS
    # Ruta al fichero de configuración (puedes modificarla)
    #################################
    # a. Configuración de openresty
    FICHERO="/usr/local/openresty/nginx/conf/nginx.conf"
    
    # b. Define your service name pattern (optional)
    SERVICES_BEGIN_WITH='^(openr|python_)'
    
    # c. destino de los logs al copiarse
    DESTINO="/home/informatica/mylogs"
    #========================================
    #  Función: copiar_con_fecha
    #  Mueve un fichero al destino, añadiendo timestamp antes de la extensión
    #========================================
    
    
    
    mover_fichero_con_fecha() {
        local fichero="$1"
        #local destino="/home/informatica/mylogs"
    
        # Verificar si existe el fichero
        if [[ ! -f "$fichero" ]]; then
            echo "❌ No existe el fichero: $fichero"
            return 1
        fi
    
        # Crear destino si no existe
        mkdir -p "$DESTINO"
    
        # Obtener nombre base y extensión
        local nombre_base
        nombre_base=$(basename "$fichero")
        local nombre_sin_ext="${nombre_base%.*}"
        local extension="${nombre_base##*.}"
    
        # Si no tiene extensión
        if [[ "$nombre_sin_ext" == "$nombre_base" ]]; then
            extension=""
        fi
    
        # Fecha y hora actual
        local timestamp
        timestamp=$(date +"%Y%m%d_%H%M%S")
    
        # Crear nuevo nombre con timestamp
        local nuevo_nombre
        if [[ -n "$extension" ]]; then
            nuevo_nombre="${nombre_sin_ext}_${timestamp}.${extension}"
        else
            nuevo_nombre="${nombre_sin_ext}_${timestamp}"
        fi
    
        # Mover el fichero (usar sudo si no hay permisos)
        if [[ -w "$(dirname "$fichero")" ]]; then
            mv "$fichero" "$DESTINO/$nuevo_nombre"
        else
            echo "Using sudo to move $fichero"
            sudo mv "$fichero" "$DESTINO/$nuevo_nombre"
        fi
    
        echo "✅ Movido a: $DESTINO/$nuevo_nombre"
    }
    
    
    
    #========================================
    #1. Buscamos los logs de openresty
    #========================================
    # Ruta al fichero de configuración (puedes modificarla)
    #FICHERO="/usr/local/openresty/nginx/conf/nginx.conf"
    
    # Verificar si el fichero existe
    if [[ ! -f "$FICHERO" ]]; then
        echo "❌ El fichero no existe: $FICHERO"
        exit 1
    fi
    
    # Buscar la línea que contiene "error_log /usr/" y extraer la palabra con "/usr/"
    all_log_paths=$(grep "error_log /usr/" "$FICHERO" | grep -oE '[^[:space:]]*/usr/[^[:space:];]*')
    all_log_paths+=$'\n'"${all_log_paths/error.log/access.log}"
    
    echo "$all_log_paths"
    
    #==================================================================
    #2. Añdimos los logs de los servicios que comienzan por "python_"
    #==================================================================
    
    # Define your service name pattern (optional)
    #SERVICES_BEGIN_WITH='^(openr|python_)'
    
    # Iterate over matching services
    for service in $(systemctl list-unit-files --type=service | awk '{print $1}' | grep -E "$SERVICES_BEGIN_WITH"); do
        echo "Service: $service"
    
        # Extract relevant lines
        current_logs=$(systemctl cat "$service" 2>/dev/null | \
                       grep -E '(StandardOutput|StandardError|SyslogIdentifier)' )
    
        if [ -n "$current_logs" ]; then
            echo "Current_logs: $current_logs"
    
    		for log_file in $current_logs; do
    			# Append only the extracted values (after ":")
    			#echo "log_file: $log_file"
    			all_log_paths+=$'\n'"${log_file#*:}"
    		done	
        fi
    
        #echo "Journal logs: journalctl -u $service"
        #echo "---"
    done
    
    echo "$all_log_paths"
    
    
    #==================================================================
    #3.Movemos los ficheros a la carpeta $DESTINO
    #==================================================================
    for fichero in $all_log_paths; do if [[ -n "$fichero" && -e "$fichero" ]]; then #if [[ -w "$fichero" ]]; then # rm -f "$fichero" #else # echo "Using sudo to remove $fichero" # sudo rm -f "$fichero" mover_fichero_con_fecha "$fichero" else echo "File not found or variable empty: $fichero" fi done

    2.4 script para rearrancar los servicios


    SERV03.Pas3.arrancar_serveis.01.sh

    #!/bin/bash
    
    # ==============================================================================
    # CONFIGURACIÓN
    # ==============================================================================
    
    # Lista de patrones de búsqueda (expresiones regulares)
    PATRONES_BUSQUEDA="(openr|python_)" 
    
    # ==============================================================================
    # PROCESO PRINCIPAL
    # ==============================================================================
    
    echo "--- Buscando y rearrancando servicios que coincidan con $PATRONES_BUSQUEDA ---"
    echo "--------------------------------------------------------------------------"
    
    # 1. Obtener la lista de servicios activos que coinciden con los patrones.
    SERVICIOS=$(systemctl list-unit-files --type=service | grep -E "$PATRONES_BUSQUEDA" | awk '{print $1}')
    echo "$SERVICIOS"
    # 2. Iterar sobre la lista de servicios y reiniciarlos.
    if [ -z "$SERVICIOS" ]; then
        echo "ℹ️ No se encontraron servicios activos que comiencen por 'openr' o 'python_'."
    else
        for SERVICIO in $SERVICIOS; do
            echo "➡️ Rearrancando servicio: $SERVICIO"
            
            # Ejecutar el comando de reinicio. Se usa 'sudo' porque 'systemctl restart'
            # requiere permisos de superusuario para la mayoría de los servicios.
            sudo systemctl restart "$SERVICIO"
            
            # 3. Verificar el estado (opcional, pero recomendado)
            if [ $? -eq 0 ]; then
                echo "   ✅ $SERVICIO rearrancado con éxito."
            else
                echo "   ❌ Fallo al rearrancar $SERVICIO. Verifique los logs (journalctl)."
            fi
        done
    fi
    
    echo "--------------------------------------------------------------------------"
    echo "--- Proceso completado ---"
    



    3. Script que se ejecuta en cliente para copiar los programas al servidor

    Hay que tener en cuenta que para poder ejecutar este script tenemos que entrar en sudo visudo y asegurarnos que tiene la línea del usuario para que no pida la contraseña en el comando mv.

    CLI00.TOT.Copiar_a_WEBPROP.sh

    #!/usr/bin/env bash
    # ============================================================
    # Copiar TODAS las subcarpetas de un directorio al servidor remoto 192.168.28.16
    # EXCEPTO algunas, usando usuario, contraseña e IP (sin clave SSH)
    # ============================================================
    
    # Uso:
    # ./Copiar_a_WEBPROP.sh /carpeta/local /ruta/remota IP usuario contraseña "carpeta1 carpeta2 ..." [puerto]
    # Ejemplo:
    # ./copiar_subcarpetas_excluyendo.sh /home/eduard/proyectos /home/juan/backups 192.168.1.100 juan MiPass123 "temp logs node_modules" 22
    
    LOCAL_DIR="/home/ximo/MyPython/versio.02/softprop"
    REMOTE_DIR="/home/informatica/eduApps/softprop"
    REMOTE_IP="192.XXX.XXX.XXX"
    REMOTE_USER="miusuario"
    REMOTE_PASS="mipassword"
    EXCLUDE_LIST=".pytest_cache .vscode 01_provetes utilitats_varies"    # lista separada por espacios
    REMOTE_PORT="${7:-22}"
    
    
    # Definimos una función para copiar entre carpetas remotas
    # ==========================================
    # FUNCION PARA COPIAR FICHEROS ENTRE CARPETAS REMOTAS
    # ==========================================
    copiar_remoto() {
        local origen="$1"
        local destino="$2"
    
        echo "➡️  Copiando en remoto: $origen$destino"
    
        # Ejecuta copia remota vía SSH
        #sshpass -p "$REMOTE_PASS" ssh -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" \
        #    "sudo cp -f \"$origen\" \"$destino\" && echo '✅ Copiado: $destino' || echo '❌ Error copiando $origen'"
    
    	sshpass -p "$REMOTE_PASS" ssh -T "$REMOTE_USER@$REMOTE_IP" "sudo cp -f \"$origen\" \"$destino\" && echo '✅ Copiado: $destino' || echo '❌ Error copiando $origen'"
    }
    
    
    
    
    # Verifica parámetros
    #if [[ -z "$LOCAL_DIR" || -z "$REMOTE_DIR" || -z "$REMOTE_IP" || -z "$REMOTE_USER" || -z "$REMOTE_PASS" ]]; then
    #    echo "Uso: $0 /carpeta/local /ruta/remota IP usuario contraseña \"excluir1 excluir2 ...\" [puerto]"
    #    exit 1
    #fi
    
    # Comprueba dependencias
    for cmd in sshpass rsync; do
        if ! command -v $cmd >/dev/null 2>&1; then
            echo "Instalando $cmd..."
            sudo apt update && sudo apt install -y $cmd
        fi
    done
    
    # Construye lista de exclusiones para rsync
    EXCLUDE_ARGS=()
    if [[ -n "$EXCLUDE_LIST" ]]; then
        for folder in $EXCLUDE_LIST; do
            EXCLUDE_ARGS+=(--exclude="$folder/")
        done
    fi
    
    echo "🚀 Iniciando copia desde $LOCAL_DIR$REMOTE_USER@$REMOTE_IP:$REMOTE_DIR"
    echo "Excluyendo: $EXCLUDE_LIST"
    echo "==========================================================="
    
    # Copia todas las subcarpetas excepto las excluidas
    sshpass -p "$REMOTE_PASS" rsync -avz --progress \
        -e "ssh -p $REMOTE_PORT -o StrictHostKeyChecking=no" \
        "${EXCLUDE_ARGS[@]}" \
        "$LOCAL_DIR/" "${REMOTE_USER}@${REMOTE_IP}:$REMOTE_DIR"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Copia completada correctamente."
    else
        echo "❌ Error al copiar carpetas."
        exit 2
    fi
    
    
    # Ahora copiamos los ficheros a su lugar:
    EXPORTACIO="$REMOTE_DIR/_exportacio"
    copiar_remoto "$EXPORTACIO/authentication/xmopenresty.py" \
                  "$REMOTE_DIR/authentication/xmopenresty.py"
    
    copiar_remoto "$EXPORTACIO/menus/mnu_main.py" \
                  "$REMOTE_DIR/menus/mnu_main.py"
    
    copiar_remoto "$EXPORTACIO/openresty/v04/nginx.conf" \
                  "/usr/local/openresty/nginx/conf/nginx.conf"
    
    echo "✅ Todas las copias han finalizado."
    




    martes, 28 de octubre de 2025

    WEBPROPv2 (XVI). Solución de errores(3). Un registro de Osticket (id=769) da error al mostrarse. HTMX problem

    1. Causa del problema

    htmx cuando hace un post, si el elemento que lo realiza está dentro de un form entonces envia todos los datos del form en el request dentro de una estructura "FormData"

    Si el form tiene muchso datos y pasamos for nginx (openresty), entonces hacemos un "overflow" del caché del mismo.

    ChatGPT y Claude plantean soluciones QUE NO FUNCIONAN que es añadirle algunos de estos parámetros al htmx (aplicados a un botón o un anchor):

    form = 'none' 
    hx-include="none" 
    hx-include="[data-include='never']"

    Al final utilizando Claude lo que se hace es realizar un fetch, para simplificar creamos una función para utilizarla igual:

    /**
     * Fetch data from the given endpoint and update the target element with the response HTML.
     * @param {*} endpoint 
     * @param {*} data 
     * @param {*} targetSelector 
     * @returns 
     */
    async function fetchAndUpdate(endpoint, data, targetSelector) {
    	console.log("executing fetchAndUpdate with:", endpoint, JSON.stringify(data), targetSelector);
        try {
            const response = await fetch(endpoint, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(data)
            });
            
            const html = await response.text();
            const target = document.querySelector(targetSelector);
            
            if (target) {
                target.innerHTML = html;
            } else {
                console.warn(`Target element "${targetSelector}" not found`);
            }
            
            return html;
        } catch (error) {
            console.error('Fetch error:', error);
            throw error;
        }
    }
    

    y luego la llamamos así:

    // ✅ Define the "value" property
      set value(newValue) {
        
    	const tab_id= sessionStorage.getItem("id_tab");
            const mydata= { sql_id: newValue, my_id: this._parentId, tab_id: tab_id || "" };		
    	fetchAndUpdate( this.url, mydata, this.target );
      }
    



    martes, 21 de octubre de 2025

    WEBPROPv2 (XV). Actualizando versiones.

    1. Comprobaciones previas:

    a. Copiar programas desde el ordenador de desarrollo al de producción

    Para ello utilizaremos el FileZilla (también sepuede utilizar ssh)

    Se deberán copiar todos los ficheros y carpetas de la carpeta softprop de desarrollo excepto las carpetas:

    • .pythest_cache
    • .vscode
    • __pycache__
    • _provetes
    • camel2snake
    • venv_softprop
    • zz_copies_seg_zip
    Si se hubiera tocado parte de la configuración de openresty como nginx.conf,algún modulo lua, certificados etcentonces se copiará:
    • openresty/v04/* a /usr/local/openresty/nginx/conf/

    b. Copiar y revisar el contenido de _exportacio

    Ahora hay que comprobar que las rutas a los servidores y entorno virtual python sean correctas en las versiones que hemos copiado y modificado adecuadamente en _exportació

    1. En autentication/xmopenresty.py verifcar que está activa la parte remota y el entorno virtual remoto:

    #!/home//informatica/eduApps/softprop/venv_softprop/bin/python3
    
    #????????###################################################
    # CANVIAR LOCAL:
    #my_host = "192.168.XX.XX"
    #my_port = 5001
    #------------------------------
    # CANVIAR REMOT:
    my_host = "192.168.YY.YY"
    my_port = 5001
    ####################################################
    

    2. En menus/menu_main.py verificar lo mismo

    #!/home/informatica/eduApps/softprop/venv_softprop/bin/python3
    
    #????????###################################################
    # CANVIAR LOCAL:
    #my_host = "edu.poblacion.es"
    #my_port = 5000
    #------------------------------
    # CANVIAR REMOT:
    my_host = "proves.poblacion.es"
    my_port = 5000
    ####################################################
    

    Y en openresty/v04/nginx.conf verificar:

    http {
        #????????============================================================================
    	# CANVIAR LOCAL: 
    	# --- Constants defined with map
        #map "" $MY_SERVER        { default 192.168.10.5; }
        #map "" $MY_SERVER_NAME   { default edu.tavernes.es; }
        #map "" $MY_AUTH_URL      { default https://192.168.10.5:5001/auth; }
        #map "" $MY_CONF_PATH     { default /usr/local/openresty/nginx/conf; }
        #map "" $SESSION_EXPIRATION { default 3600; }  # 1 hour
    	# Creamos una bateria de servidores para softprop con un solo servidor
        #upstream softpropsrv {
    	#	server 192.168.10.5:5000;
    	#	keepalive 32; # NOU 2025-10-6 (2)
        #}   
    	#-----------------------------------------
    	#  CANVIAR REMOT!
    	# --- Constants defined with map
        map "" $MY_SERVER        { default 192.168.YY.YY; }
        map "" $MY_SERVER_NAME   { default proves.localidad.es; }
        map "" $MY_AUTH_URL      { default https://192.168.YY.YY:5001/auth; }
        map "" $MY_CONF_PATH     { default /usr/local/openresty/nginx/conf; }
        map "" $SESSION_EXPIRATION { default 3600; }  # 1 hour
    	# Creamos una bateria de servidores para softprop con un solo servidor
        upstream softpropsrv {
    		server 192.168.YY.YY:5000;
    		keepalive 32; # NOU 2025-10-6 (2)
        }   
    	# fi: CANVIAR
    	#============================================================================
    	
    

    Y se copiara desde el servidor de desarrollo al de producción
    • _exportacio/authentication/xmopenresty.py a authentication/xmopenresty.py
    • _exportacio/menus/menu_main.py a menuis/menu_main.py
    • _exportacio/openresty/v04/nginx.conf a /usr/local/openresty/nginx/conf/nginx.conf
    Si ppor algun motivo los ficheros de servicios se hubieran perdido, en _exportacio/services se encuentran dichos ficheros

    c. Rearrancar los siguientes servicios:

    1. openresty
    2. python_menus_mnu_main_py.service
    3. python_authentication_xmopenresty_py.service
    Se muestran los comandos para rearrancar cada uno de ellos:

    sudo systemctl restart openresty
    sudo systemctl restart python_menus_mnu_main_py.service
    sudo systemctl restart python_authentication_xmopenresty_py.service

    Para ver el estado de cada uno uy ver si estń arrancados se ejecutará esta orden:

    systemctl list-units --type=service | grep -E 'openresty|python'

    Si no estuvieran definidos estos servicios, se consultará a esta entrada.