Blog Tinux Net

tinux

author_description

  • Publicado en

    Archivo index.php:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Autocomplete by MRoblesDev</title>
    
        <style type="text/css">
            ul {
                list-style-type: none;
                width: 300px;
                height: auto;
                position: absolute;
                margin-top: 10px;
                margin-left: 10px;
            }
    
            li {
                background-color: #EEEEEE;
                border-top: 1px solid #9e9e9e;
                padding: 5px;
                width: 100%;
                float: left;
                cursor: pointer;
            }
        </style>
    </head>
    
    <body>
        <h3>Autocomplete</h3>
    
        <form action="" method="post" autocomplete="off">
            <div>
                <label for="campo">Buscar:</label>
                <input type="text" name="campo" id="campo">
    
                <ul id="lista"></ul>
            </div>
        </form>
    
        <script src="js/peticiones.js"></script>
    </body>
    
    </html>
    

    Archivo .env para los datos de acceso de la database. Se puede crear un directoro inc para su inclusion:
    database.env

    <?php
    
    class Database
    {
        private $hostname = "localhost";
        private $database = "database";
        private $username = "user";
        private $password = "password";
        private $charset = "utf8";
    
        /**
         * Se conecta a la base de datos y devuelve un objeto PDO. (PHP Data Objects) 
         * 
         * @return La conexión a la base de datos.
         */
        function conectar()
        {
            try {
                $conexion = "mysql:host=" . $this->hostname . ";dbname=" . $this->database . ";charset=" . $this->charset;
                $options = [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_EMULATE_PREPARES => false,
                ];
    
                $pdo = new PDO($conexion, $this->username, $this->password, $options);
    
                return $pdo;
            } catch (PDOException $e) {
                echo 'Error conexion: ' . $e->getMessage();
                exit;
            }
        }
    }
    

    El archivo de funciones de codigo de php:

    <?php
    
    require 'database.php';
    
    $con = new Database();
    $pdo = $con->conectar();
    
    $campo = $_POST["campo"];
    
    $sql = "SELECT cp, asentamiento FROM codigos_postales WHERE cp LIKE ? OR asentamiento LIKE ? ORDER BY cp ASC LIMIT 0, 10";
    $query = $pdo->prepare($sql);
    $query->execute([$campo . '%', $campo . '%']);
    
    $html = "";
    
    while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
        $html .= "<li onclick=\"mostrar('" . $row["cp"] . "')\">" . $row["cp"] . " - " . $row["asentamiento"] . "</li>";
    }
    
    echo json_encode($html, JSON_UNESCAPED_UNICODE);
    

    Archivo de sql para inyectar en la base de datos para hacer las pruebas:

    Pongo el enolace, ya que es muy extenso:

    Database SQl Archive

  • Publicado en

    Estos son los principales Meta Tags de OpenGraph. Son los principales para que aparezcan cuando se comparte por Whtasapp , Telegram o Signal.

    <meta name='og:title' content='Tinux Net'>
    <meta name='og:type' content='image'>
    <meta name='og:url' content='http://www.imdb.com/title/tt0117500/'>
    <meta name='og:image' content='http://ia.media-imdb.com/rock.jpg'>
    <meta name='og:site_name' content='IMDb'>
    <meta name='og:description' content='Tinux Net, En la red desde 1997 ..'>
    

    Y si hay video recomendable poner.

    <meta property='og:video:type' content='application/x-shockwave-flash'>
    <meta property='og:video' content='http://example.com/html5.mp4'>
    <meta property='og:video:type' content='video/mp4'>
    <meta property='og:video:height' content='640'> 
    <meta property='og:video:width' content='385'>
    <meta property='og:video' content='http://example.com/fallback.vid'>
    <meta property='og:video:type' content='text/html'>
    
  • Publicado en

    index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Simple AJAX - GET REQUEST</title>
      </head>
      <body>
    
        <button onclick="sendRequest()">
    

    Hace la llamada a la funcion javascript del archivo script.js

          Send Ajax Request
        </button>
    
        <div id="container"></div>
    <script src="script.js" type="text/javascript"></script>
      </body>
    </html>
    

    script.js:

    function sendRequest() {
    

    Creamos el Objeto que va a recibir los datos a través de AJAX

        var theObject = new XMLHttpRequest();
    

    Verificamos que se ha enviado una petición

        theObject.open('POST', 'backend.php', true);
    

    Indicamos que tipo de cabecera se ha enviado a través del navegador

        theObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    

    Vemos en cual es el State o Estado

        theObject.onreadystatechange = function() {
          if(theObject.readyState === 4 & theObject.status === 200) {
    

    Si el Estado es Ok =200 y Enviado procedemos a insertar en el div con id container el Texto del Objeto

            document.getElementById('container').innerHTML = theObject.responseText;
          }
        }
    

    Y lo enviamos

        theObject.send('username=Fazt&password=secret');
      }
    

    Y el fichero que se ejecutara en el Backend: backend.php:

    <?php
    
    if(isset($_POST)) {
      echo $_POST['username'];
      echo '<br>';
      echo $_POST['password'];
    }
    
      #echo 'Working!';
    
    ?>
    
  • Publicado en

    Autocompletar un formulario con PHP, Javascript y MySQL

    Creamos 3 archivos: index.html, default.css y default.js

    Invocamos el css en la etiqueta con

    <link rel=""steelshhet" href="default.css">
    

    y el script de javascritp antes del final del </body>

    <script src="default.js"></script>
    

    En body del html

    <form action ="#" autocomplete=off" method="POST"> // Para que se limpie el input de varios valores anteriores 
         <div class="autocompletar">
             <input type="text" name=tipo-mascota" id="tipo-mascota" placeholder="Elige tu tipo de mascota">
         </div>
     </form>
    

    Aplicamos estilos en default.css

    body{
    font-famuly: Arial, sans-serif;
    }
    
    form{
    margin: 50px auto;
    widt: 500px;
    }
    
    .autocompletar{
    position: relative:
    display: inline-block;
    }
    strong {
    color: black;
    }
    
    
    #tipo-mascota{
    background-color #eee;
    border: none;
    border-radius: 30px;
    font-size: 1.7em;
    padding: 10px 25px;
    outline: none;
    width: 500px;
    }
    

    El estilo de salida de la lista de autocompletado

    .lista-autocompletar-items{
    color: ccc:
    position: abolute
    border: 1px solid #d4d4d4:
    border-bottom: none;
    z-index: 99;
    
    top: 100%;
    left: 20px;
    right: 0;
    width: 93%;
    }
    

    Utilizaremos el mismo identificador anterior pero le incorporaremos una capa.

    .lista-autocompletar-items div{
    padding: 10px;
    cursor: pointer;
    çbackground-color: #fff;
    border-bottom: 1px solid #d4d4d4;
    }
    

    y incorporaremos una capa para el hover:

           .lista-autocompletar-items div:hover{
    background-color: dogedeblue;
    }
    
    .autocompletar-active{
    backgound-color: doggerblue;
    color: #a1caff;
    }
    
    
    .autocompletar-active strong{
    
    color: white:
    }
    

    Una vez definido tambien el CSS vamos con el javascript default.js

    autocompletar(['perro','gato', 'pez','paloma','conejo']);
    
    function autocompletar(arreglo){
    const inputMascota =  document.querrySelector('#tipo-mascota');
    let indexFocus = -1;
    
    inputMadscota.addEventListener('input', function() {
    const tipomascota = this.value;
    if(!tipoMascota) return false;
    
    // Crear Lista de sugerencias
    cons divList = document.createElement('div');
    divList.setAttribute('id', this.id + );
    divList.setAttrribute('class');
    
    )
    });
    
    inputMascota.addEventListerner('keydown', function() {
    
    }
    
  • Publicado en

    Autocompletado Input

    Un sencillo input para un formulario.

    input.html:

    La clase del div es para poner los colores del background , la posicion general del div y su tipo de letra,

    Los estilos style.css:

    body {
      background-color: blue;
      font-family: sans-serif;
    }
    
    .autocomplete {
      display: flex;
      flex-direction: column;
      min-height: 100vh;
      align-items: center;
      justify-content: top;
      padding-top: 100px;
    }
    
    input {
      font-size: 2em;
      width: 300px;
    }
    
    .autocomplete-results {
      display: none; // Se indica None, para que no se muestre, luego con el javascript lo habilitaremos
      width: 300px;
      margin-top: -2px;
      font-size: 1.3em;
      color: #eee;
      list-style: none;
      margin: 0;
      padding: 0;
    }
    
      .autocomplete-results li {
        margin: 0;
        padding: 0;
        padding: 10px 0 10px 10px;
        border-right: 2px solid #eee;
        border-bottom: 2px solid #eee;
        border-left: 2px solid #eee;
      }
    
      .autocomplete-results li:hover {
        background-color: #eee;
        color: blue;
        cursor: pointer;
      }
    

    Y ahora el javascript: script.js:

    let input = document.querySelector("input");
    let autocomplete_results = document.getElementById('autocomplete-results');
    
    input.addEventListener('keyup',  (event) =>  {
      autocomplete_results.style.display = 'block';
      let key = event.target.value;
    
      console.log(key)
    
      if(key.length > 0) {
        search(key);
      }
      else {
        build_list();
      }
    })
    
    const search = (key) => {
      fetch(`https://restcountries.eu/rest/v2/name/${key}?fields=name`)
      .then(res => res.json())
      .then(data => {
        if(Array.isArray(data)) {
          build_list(data.map(item => {
            return item.name
          }))
        }
      })
    }
    
    const build_list = (items) => {
      console.log('elems', items)
    
      if(items === undefined) {
        items = [];
      }
    
      autocomplete_results.innerHTML = '';
    
      items.slice(0,10).map(item =>  {
        autocomplete_results.innerHTML += `<li>${item}</li>`;
                          })
    }
    
    document
      .getElementById("autocomplete-results")
      .addEventListener("click", e => {
        if (e.target && e.target.nodeName == "LI") {
    
          input.value = e.target.innerHTML;
          build_list()
        }
      });
    
  • Publicado en

    Instalacion

    npm create vite@latest
    

    Pero tambien se puede crear el proyecto directamente con

    # npm 7+, extra double-dash is needed:
    npm create vite@latest vite-project -- --template react
    

    Crea el Directorio vite-project Luego :

    cd vite-project
    npm install
    npm run dev
    

    Nos lanzara un script y el puerto abierto para el renderizado. VITE v5.3.3 ready in 180 ms

    ➜ Local: http://localhost:5173/
    ➜ Network: use --host to expose
    ➜ press h + enter to show help

    press r + enter to restart the server
    press u + enter to show server url
    press o + enter to open in browser
    press c + enter to clear console
    press q + enter to quit

  • Publicado en

    WLS

    Dependiendo la version de Windows, puede ya estar instalado wls o bien hay que descargarsela desde microsoft: Podemos ver la version de windows: Tecla Windows Logo + R, teclear winver

    Si tecelamos wsl.es y no esta, tendremos que instalar con la version antigua.

    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    

    y habilitar el Servicio de la Maquina Virtual:

    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    

    Nota: para la instalacion es necesario Inicializar un PowerShell como administrador Si ya esta y podemos teclear wsl pasamos al siguiente paso. Ver las distribuciones disponible

    wls --list --online
    

    Teniendo un resultado parecido a este: A continuación, se muestra una lista de las distribuciones válidas que se pueden instalar. Instalar con 'wsl --install -d <Distribución>'.

    NAME FRIENDLY NAME
    Ubuntu Ubuntu
    Debian Debian GNU/Linux
    kali-linux Kali Linux Rolling
    Ubuntu-18.04 Ubuntu 18.04 LTS
    Ubuntu-20.04 Ubuntu 20.04 LTS
    Ubuntu-22.04 Ubuntu 22.04 LTS
    Ubuntu-24.04 Ubuntu 24.04 LTS
    OracleLinux_7_9 Oracle Linux 7.9
    OracleLinux_8_7 Oracle Linux 8.7
    OracleLinux_9_1 Oracle Linux 9.1
    openSUSE-Leap-15.5 openSUSE Leap 15.5
    SUSE-Linux-Enterprise-Server-15-SP4 SUSE Linux Enterprise Server 15 SP4
    SUSE-Linux-Enterprise-15-SP5 SUSE Linux Enterprise 15 SP5
    openSUSE-Tumbleweed openSUSE Tumbleweed

    wsl --install -d openSUSE-Leap-15.5 
    

    Y ya es una instalacion de linux

    openSUSE-Leap-15.5

    Para entornos de trabajo estables, es preferible una distribucion solida y que solo haya sido probada y dada de alta como estable.

    wsl --install -d openSUSE-Leap-15.5 
    

    Una vez instalado, lo actualizamos con

    sudo zypper update
    

    salimos con exit.

    Y para entrar, lo podemos hacer de tres manera WindowsKey +R -> wsl y enter En buscar wsl. O desde un shell de PowewShell: wls

    Ya una vez entraso el el Subsistema, podemos instalar softwarde linux como si estubieramos en linux. Ejemplo para instalar rsync :

    sudo zypper install rsync
    
  • Publicado en

    WLS

    Dependiendo la version de Windows, puede ya estar instalado wls o bien hay que descargarsela desde microsoft: Podemos ver la version de windows: Tecla Windows Logo + R, teclear winver

    Si tecelamos wsl.es y no esta, tendremos que instalar con la version antigua.

    dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
    

    y habilitar el Servicio de la Maquina Virtual:

    dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    

    Nota: para la instalacion es necesario Inicializar un PowerShell como administrador Si ya esta y podemos teclear wsl pasamos al siguiente paso. Ver las distribuciones disponible

    wls --list --online
    

    Teniendo un resultado parecido a este: A continuación, se muestra una lista de las distribuciones válidas que se pueden instalar. Instalar con 'wsl --install -d <Distribución>'.

    NAME FRIENDLY NAME Ubuntu Ubuntu Debian Debian GNU/Linux kali-linux Kali Linux Rolling Ubuntu-18.04 Ubuntu 18.04 LTS Ubuntu-20.04 Ubuntu 20.04 LTS Ubuntu-22.04 Ubuntu 22.04 LTS Ubuntu-24.04 Ubuntu 24.04 LTS OracleLinux_7_9 Oracle Linux 7.9 OracleLinux_8_7 Oracle Linux 8.7 OracleLinux_9_1 Oracle Linux 9.1 openSUSE-Leap-15.5 openSUSE Leap 15.5 SUSE-Linux-Enterprise-Server-15-SP4 SUSE Linux Enterprise Server 15 SP4 SUSE-Linux-Enterprise-15-SP5 SUSE Linux Enterprise 15 SP5 openSUSE-Tumbleweed openSUSE Tumbleweed

    wsl --install -d openSUSE-Leap-15.5 
    

    Y ya es una instalacion de linux

    openSUSE-Leap-15.5

    Para entornos de trabajo estables, es preferible una distribucion solida y que solo haya sido probada y dada de alta como estable.

    wsl --install -d openSUSE-Leap-15.5 
    

    Una vez instalado, salimos con exit.

    Y para entrar, lo podemos hacer de tres manera WindowsKey +R -> wsl y enter En buscar wsl. O desde un shell de PowewShell: wls

  • Publicado en

    Rsync: Copias Incrementales

    El desarrollo de esta script es para hacer copias de seguridad que ademas cada cierto tiempo haga una copia completa y guarde un numero especifico de completas, eliminando las mas antiguas., pero también hacer como git en control de versiones pero sin ramificaciones.

    0.- Creamos una variable del path que queremos hacer la copia de seguridad. printenv para ver variables printenv HOME devuelve el path home

    1.- Creamos un directorio para la copia de seguridad:

    mkdir /mnt/backup
    

    dentro de ella creamos la main para la copia maestra

    mkdir /mnt/backup/main
    

    y otra para las incrementales

    mkdir /mnt/backup/incrementals
    

    2.- Utilizaremos varios parámetros de rsync para hacer una copia de seguridad distinta. Usa el comando rsync con las siguientes opciones clave:

    • -a: modo de archivo, preserva enlaces simbólicos, permisos, propietario, grupo, etc.
    • -b: hace una copia de seguridad de los archivos antes de actualizarlos.
    • --backup-dir: especifica el directorio donde se almacenarán las versiones anteriores de los archivos.
    • -u: actualiza solo archivos que han cambiado.
    • --delete: elimina archivos en el destino que ya no existen en el origen.
    • --exclude Los directorios o archivos que no queremos que se hagan copia de seguridad como por ejemplo los .git o los modules. Recomendable es crear un archivo de ficheros y/o directorios de exclusión exclude.txt Hay que tener cuidado con este Tip: si la ruta de destino no existe, rsync, la creará si tiene permisos, si se omite la barra al final del directorio «/», rsync, copiará el directorio de origen dentro del directorio de destino.

    Preparando el directorio para las incrementales:

    mkdir $(date +'%Y-%m-%d:%H%M')
    

    Comando date para generar el directorio con la fecha y la hora como versión. Luego inyectar al comando mkdir para crear con la fecha: Quedaría algo parecido a: 2024-07-05:0914

    Para respaldar el origen de la copia de seguridad. Podemos utilizar una variable para guardar la extensión del archivo y del directorio:

    dateincr=$(date +'%Y-%m-%d:%H%M')
    

    Para respaldar el directorio /home/origen/ al directorio /mnt/backup/ y almacenar versiones anteriores en un subdirectorio con la fecha:

    rsync -ab --backup-dir=/mnt/backup/`date + %F%H%M`
     -u --delete
     --exclude=/mnt/backup/ /home/origen/
     /mnt/backup/incrementales/
    

    Script final en zsh:

    #!/bin/zsh
    # 
    # Black        0;30     Dark Gray     1;30
    # Red          0;31     Light Red     1;31
    # Green        0;32     Light Green   1;32
    # Brown/Orange 0;33     Yellow        1;33
    # Blue         0;34     Light Blue    1;34
    # Purple       0;35     Light Purple  1;35
    # Cyan         0;36     Light Cyan    1;36
    # Light Gray   0;37     White         1;37
    
    # Regular Colors
    Black='\033[0;30m'        # Black
    Red='\033[0;31m'          # Red
    Green='\033[0;32m'        # Green
    Yellow='\033[0;33m'       # Yellow
    Blue='\033[0;34m'         # Blue
    Purple='\033[0;35m'       # Purple
    Cyan='\033[0;36m'         # Cyan
    White='\033[0;37m'        # White
    Orange='\033[1;33m'     #Yellow        1;33
    
    clear
    BackupSource=$(printenv PWD)/Source/;
    BackupMain=$(printenv PWD)/main/;
    BackupIncrementals=$(printenv PWD)/incrementals/;
    BackupDateIncrementals=$(date +'%Y-%m-%d:%H%M')
    
    echo "La mecaniva de este script es la siguiente:";
    echo "Del archivo Fuente (Source) hace previamente una copia inicial de diferencianasnteriores al archivo de incrementales de los archivos que se han detectado como Modificado ";
    echo "Luego hace una actualizacion el archivo main con los nuevos cambios que se han detectado en el Source";
    echo "la primera copia se denomina Full Backup";
    
    echo '***************************************************';
    echo '*                                                 *';
    echo '*                                                 *';
    echo "*     ${Green} Sistema de copia de Seguridad Incremental ${White}   *";
    echo '*                                                 *';
    echo "*    ${Purple}El directorio Origen:                        *";
    echo "*     ${Cyan}$BackupSource            *";
    echo '*                                                 *';
    echo '*                                                 *';
    echo '*    El directorio Main:                          *';
    echo "*     $BackupMain              *";
    echo '*                                                 *';
    echo '*                                                 *';
    echo '*    El directorio de Incrementales:              *';
    echo "*     ${Orange}$BackupIncrementals      *";
    echo '*                                                 *';
    echo '*                                                 *';
    echo '***************************************************';
    
    echo 'Archivos en el directrio Fuente';
    eza --color $BackupSource
    echo 'Archivos en la Copia Main del Backup';
    eza --color $BackupMain;
    echo '______________________________________________________';
    echo '\n';
    echo 'Variable de generacion del la version de la Incremental';
    echo 'BackupDateIncrementals: '$BackupDateIncrementals;
    echo '\n';
    echo 'Ejemplo de posible script hecho con la devolucion de variables:';
    echo 'Crea el directorio para la Incremental:'
    mkdir $BackupIncrementals/Backup-$BackupDateIncrementals;
    rsync -avhb --delete --backup-dir=$BackupIncrementals/Backup-$BackupDateIncrementals $BackupSource $BackupMain;
    # rsync -avhb --delete --backup-dir=/ruta/destino/copia_$(date +%d%m%Y%H%M) /ruta/origen/ /ruta/destino/ 
    echo '\n';
    echo 'Listado de directorio creados'
    eza -al $BackupIncrementals;
    
    echo 
    echo '***************************************************';
    echo '*                                                 *';
    echo '*                                                 *';
    echo '*                                                 *';
    echo "*    ${Purple}Ficheros en Origen:                 *";
    echo "*     ${Cyan}$BackupSource                       *";
    echo "*      $(eza $BackupSource)                        *"; 
    echo '*                                                 *';
    echo '*                                                 *';
    echo '*    Ficheros en la main del Backup:              *';
    echo "*     $(eza  $BackupMain)                         *";
    echo '*                                                 *';
    echo '*                                                 *';
    echo '*    Los ficheros Incrementados:              *';
    echo "* $(eza $BackupIncrementals"Backup"-$BackupDateIncrementals )                  *";
    echo '*                                                 *';
    echo '*                                                 *';
    echo '***********************