RIDITLETEUR - PHP - Notes perso sur xpath

xpath est une façon d'extraire des données d'un document xml plus logique que le parsing par une regex.

Malgré tout l'amûûûr que   j'ai pour les regex

En gros, on retrouve un contenu grâce au chemin dans le DOM qui y conduit.

📘 Ressources

Est-il vrai qu’il est désormais interdit de se balader avec un Opinel ou un Laguiole ? – Libération

Sont considérés comme des couteaux-poignards, d’après la définition qu’en font les douanes, les objets qui remplissent cinq critères cumulatifs : «Lame solidaire de la poignée ou équipée d’un système permettant de la rendre solidaire du manche [un dispositif de verrouillage, ndlr] ; à double tranchant sur toute la longueur ou tout au moins à la pointe ; d’une longueur supérieure à 15 centimètres ; d’une épaisseur au moins égale à 4 millimètres ; à poignée comportant une garde». Les couteaux de poche ne cochent pas tous l’ensemble de ces cases. L’Opinel numéro 8, le plus répandu, est doté d’une lame longue de 8,5 centimètres et épaisse de 2,5 millimètres. Les Laguiole et couteaux suisses ne sont pas pourvus d’un système de verrouillage maintenant la lame en position ouverte.

Astuce: Fusionner les fichiers vidéos d'un dossier avec ffmpeg en une ligne

Si jamais vous avez besoin de fusionner toutes les vidéos d'un dossier comme par exemple, je sais pas mais des épisodes de Kaamelott qui ont été distribués par épisode, voilà de quoi le faire en deux commandes sous linux:

Bouton droit dans le dossier et Ouvrir dans un terminal puis:

find -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" \) | sort | awk '{print "file " $0}' > liste.txt

puis

ffmpeg -f concat -safe 0 -i liste.txt -c copy sortie.mp4

La première commande crée un fichier contenant tous les fichiers vidéos du dossier ordonnés par ordre alphabétique et précédés de «file »

La seconde fournit cette liste à ffmpeg qui se charge de générer un fichier vidéo avec...

Bien entendu, on peut enchaîner les deux commandes en une seule ligne:

find -type f \( -name "*.mp4" -o -name "*.avi" -o -name "*.mkv" \) | sort | awk '{print "file " $0}' > liste.txt && ffmpeg -f concat -safe 0 -i liste.txt -c copy sortie.mp4

Cela va de soi, je présuppose que ffmpeg est installé sur votre ordi, sinon sudo apt-get install ffmpeg

EDIT (wink JerryWham )

Histoire d'automatiser un peu le tout, on peut en faire un script pour Nemo ou Caja sous linux :

1. créer un fichier txt contenant le script:


#!/bin/bash

find -type f ( -name ".mp4" -o -name ".avi" -o -name "*.mkv" ) | sort | awk '{print "file " $0}' > liste.txt && ffmpeg -f concat -safe 0 -i liste.txt -c copy sortie.mp4

2. Coller le fichier dans le dossier script:

  • Pour Nemo : ~/.local/share/nemo/scripts
  • Pour Caja : ~/.config/caja/scripts

3. Rendre exécutable

En ouvrant un terminal dans ce dossier et en faisant un piti :


~/.config/caja/scripts$ chmod +x *

4. Utiliser le nouveau script !

Capture du 2024-06-14 09-50-58.webp

Pense-bête installation de Linux Mint 21.3

Ma version à jour de la page de Timo et de Sebsauvage

Update de la distro

sudo apt update && sudo aptitude safe-upgrade

Install des derniers kernels

Capture du 2023-08-07 14-45-17.png

Capture du 2023-08-07 14-45-44.png

Installer les pilotes

Install des logiciels & environnements

sudo apt-get install apache2 php libapache2-mod-php php-json php-zip php-gd php-sqlite3 php-curl php-mbstring php-xml php-imagick sqlitebrowser gparted filezilla python3 sublime-text vlc kdeconnect syncthing gimp default-jre lutris

Signal desktop


wget -O- https://updates.signal.org/desktop/apt/keys.asc | gpg --dearmor > signal-desktop-keyring.gpg
cat signal-desktop-keyring.gpg | sudo tee /usr/share/keyrings/signal-desktop-keyring.gpg > /dev/null

echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/signal-desktop-keyring.gpg] https://updates.signal.org/desktop/apt xenial main' |\
  sudo tee /etc/apt/sources.list.d/signal-xenial.list

sudo apt update && sudo apt install signal-desktop

Désinstaller logiciels inutiles

sudo apt purge hexchat hexchat-common libespeak1 libsonic0 libspeechd2 python3-speechd speech-dispatcher speech-dispatcher-audio-plugins gnome-orca mate-screensaver mate-screensaver-common brltty mono-runtime-common avahi-daemon xscreensaver-data-extra xscreensaver-data xscreensaver-gl-extra xscreensaver-gl java-common icedtea-netx-common pix pix-data onboard timeshift 

configurer PHP

éditer php.ini

Le fichier se trouve dans /etc/php/NUMERO DE VERSION PHP/apache2/php.ini. Soit on l'ouvre via le terminal, soit on utilise l'éditeur de son choix.

On édite les lignes suivantes:

post_max_size = 20M
upload_max_filesize = 1000M
error_reporting = -1
display_errors = On
zend.multibyte = On

Pour limiter le nombre de processus de php, on ajoute à la fin

<IfModule mpm_prefork_module>
    StartServers          2
    MinSpareServers       1
    MaxSpareServers       3
    MaxClients           12
    MaxRequestsPerChild   3
</IfModule>

Déplacer www de var vers Home

mkdir ~/www && mkdir ~/www/html && sudo chmod 777 ~/www && sudo mv /var/www /var/www_old && sudo ln -s ~/www /var/www

fin

Puis, on relance le serveur: sudo service apache2 restart

Réglages divers

  • Activer les canaux Européens pour le wifi : sudo iw reg set FR
  • Résoudre le problème de décalage de l'heure en dual boot: timedatectl set-local-rtc 1 # mettez 0 pour la remettre sur UTC
  • Raccourcis claviers:
    • windows+E pour lancer caja: dans raccourcis clavier, chercher «dossier personnel» et redéfinir le raccourci
    • redéfinir la capture d'écran pour avoir le menu sa ns faire de capture direct: dans raccourcis clavier, créer un nouveau raccourci, dans la commande tapermate-screenshot --interactive (pour mate ou gnome-screenshot --interactive pour cinnamon) puis ré assigner le raccourci prtScr.
  • en cas de souci avec la touche verr maj:
    • sudo apt install numlockx
    • Centre de contrôle > Fenêtre de connexion > Options, cocher Activer NumLock.
  • sur portable, pour allonger l'autonomie: sudo apt install tlp

Note pour plus tard - The Zen of Python | Python.org

  • Préfère :
    • la beauté à la laideur,
    • l'explicite à l'implicite,
    • le simple au complexe
    • et le complexe au compliqué,
    • le déroulé à l'imbriqué,
    • l'aéré au compact.
  • Prends en compte la lisibilité.
  • Les cas particuliers ne le sont jamais assez pour violer les règles.
  • Mais, à la pureté, privilégie l'aspect pratique.
  • Ne passe pas les erreurs sous silence,
  • ... ou bâillonne-les explicitement.
  • Face à l'ambiguïté, à deviner ne te laisse pas aller.
  • Sache qu'il ne devrait [y] avoir qu'une et une seule façon de procéder,
  • même si, de prime abord, elle n'est pas évidente, à moins d'être Néerlandais.
  • Mieux vaut maintenant que jamais.
  • Cependant jamais est souvent mieux qu'immédiatement.
  • Si l'implémentation s'explique difficilement, c'est une mauvaise idée.
  • Si l'implémentation s'explique aisément, c'est peut-être une bonne idée.
  • Les espaces de nommage ! Sacrée bonne idée ! Faisons plus de trucs comme ça.
  • Texte d'origine

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Complex is better than complicated.
  • Flat is better than nested.
  • Sparse is better than dense.
  • Readability counts.
  • Special cases aren't special enough to break the rules.
  • Although practicality beats purity.
  • Errors should never pass silently.
  • Unless explicitly silenced.
  • In the face of ambiguity, refuse the temptation to guess.
  • There should be one-- and preferably only one --obvious way to do it.
  • Although that way may not be obvious at first unless you're Dutch.
  • Now is better than never.
  • Although never is often better than -right- now.
  • If the implementation is hard to explain, it's a bad idea.
  • If the implementation is easy to explain, it may be a good idea.
  • Notes perso JS : usage de fetch()

    Je me note ici pour une prochaine fois parce que fetch n'est pas forcément très intuitif...

    2 façons d'utiliser fetch :

    la plus tendance et élégante : en enchaînant les then()

    fetch("index.php", { method: 'POST', body: formData })
      .then((response)=>{
            // on attend l'arrivée de la réponse et on la traite
            return response.text(); // ou response.json();
      })
      .then((text)=>{
             // on attend la fin du traitement de la réponse  et on en traite le contenu
           console.log(text);
      });

    la plus lisible (?) : avec async et await

    En gros, on crée une fonction asynchrone pour pouvoir utiliser les await.

    const fetchAPI = async(URL) => {
        const response = await fetch(URL);  // on attend l'arrivée de la réponse 
        const data = await response.json();  // on attend la fin du traitement de la réponse
        console.log(data)
    }
    fetchAPI("https://jsonplaceholder.typicode.com/todos/1")

    Conciliateur de justice | Service-public.fr

    Oh ! Bon à savoir, ça: un médiateur gratuit qui permet de régler les conflits à l'amiable:

    Compétent pour

    • Problèmes de voisinage (bornage, droit de passage, mur mitoyen)
    • Différends entre propriétaires et locataires ou entre locataires
    • Différends relatifs à un contrat de travail
    • Litiges de la consommation
    • Litiges entre commerçants
    • Litiges en matière de droit rural
    • Litiges en matière prud'homale

    On peut trouver le conciliateur le plus proche là: http://www.conciliateurs.fr/Trouver-une-permanence

    Via https://shaarli.mydjey.eu/shaare/67xoyw

    A (more) Modern CSS Reset - Andy Bell

    De côté pour plus tard... Une reset.css plus moderne... Je me contentais du box-sizing depuis son avènement.

    Les explications associées sont intéressantes.

    /* Box sizing rules */
    *,
    *::before,
    *::after {
      box-sizing: border-box;
    }
    
    /* Prevent font size inflation */
    html {
      -moz-text-size-adjust: none;
      -webkit-text-size-adjust: none;
      text-size-adjust: none;
    }
    
    /* Remove default margin in favour of better control in authored CSS */
    body, h1, h2, h3, h4, p,
    figure, blockquote, dl, dd {
      margin: 0;
    }
    
    /* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
    ul[role='list'],
    ol[role='list'] {
      list-style: none;
    }
    
    /* Set core body defaults */
    body {
      min-height: 100vh;
      line-height: 1.5;
    }
    
    /* Set shorter line heights on headings and interactive elements */
    h1, h2, h3, h4,
    button, input, label {
      line-height: 1.1;
    }
    
    /* Balance text wrapping on headings */
    h1, h2,
    h3, h4 {
      text-wrap: balance;
    }
    
    /* A elements that don't have a class get default styles */
    a:not([class]) {
      text-decoration-skip-ink: auto;
      color: currentColor;
    }
    
    /* Make images easier to work with */
    img,
    picture {
      max-width: 100%;
      display: block;
    }
    
    /* Inherit fonts for inputs and buttons */
    input, button,
    textarea, select {
      font: inherit;
    }
    
    /* Make sure textareas without a rows attribute are not tiny */
    textarea:not([rows]) {
      min-height: 10em;
    }
    
    /* Anything that has been anchored to should have extra scroll margin */
    :target {
      scroll-margin-block: 5ex;
    }
    Via https://links.kalvn.net/shaare/McJg3Q

    PHP - Notes perso sur Imagick 2 - ImagickDraw... si on dessinait ?

    Deuxième épisode de mes notes perso sur la bibliothèque Image magic pour évoquer la classe ImagickDraw qui, comme son nom l'indique, permet de dessiner avec Imagick. ( 1er épisode )

    On va se limiter à des usages basiques parce que la lecture du sommaire suffit à imaginer des possibilités certes alléchantes mais totalement hors de propos en ce qui me concerne (courbes de bézier etc)

    Spoiler: c'est nettement moins intuitif et simple que pour le traitement d'image... l'écart entre Imagick et GD dans le domaine du tracé n'est plus si évident: ça mériterait de faire un classe pour simplifier tout ça... ( /me se jette sur son bujo pour griffonner spasmodiquement)

    Préambule

    Cette classe crée un objet servant d'instructions à appliquer ensuite à un objet Imagick.

    On partira du principe que vous avez fait des instances des classes comme suit:

    $im=new Imagick(); # l'image dans laquelle vous allez appliquer l'objet ImagickDraw
    $draw=new ImagikDraw();

    Ajouter un texte

    Fixer les caractéristiques

    • $draw->setFont(fonte); : sélectionne la fonte à utiliser
    • $draw->setFontSize(taille); : définit la taille en pixels
    • $draw->setFillColor(couleur);: définit la couleur de fond (normalement, couleur est un objet ImagickPixel, voir 1er épisode mais on peut passer une chaîne au format de couleur CSS )
    • $draw->setTextAlignment(alignement); : une des constantes d'alignement imagick::ALIGN_LEFT imagick::ALIGN_CENTER Imagick::ALIGN_RIGHT
    • $draw->setGravity(Imagick::GRAVITY_CENTER); centre le texte dans sa boîte (horizontal et vertical)
    • $draw->setTextDecoration(decoration): une des constantes de décoration imagick::DECORATION_UNDERLINE imagick::DECORATION_OVERLINE imagick::DECORATION_LINETROUGH et bien d'autres (comme du... bruit ?!).
    • $draw->setTextAntialias(true);: ajouter de l'antialias
    • l'espacement :
      • entre les mots : $draw->setTextInterwordSpacing(taille)
      • entre les lignes : $draw->setTextInterlineSpacing(taille)

    Tracer le texte

    • $draw->annotation(x,y,texte) : trace un texte dans la police sélectionnée
    • $im->annotateImage( $draw, 0, 0, 0, $fontName ); : ajoute le texte à l'image.

    Obtenir des infos utiles

  • obtenir la liste des polices disponibles: $im->queryFonts($pattern = "*") 🆒 on peut filtrer avec une pattern à la façon de glob().
  • obtenir les infos fixées par setXXX : getXXX ... ainsi on a getFont(), getFontSize() etc...
  • obtenir les dimensions de la boîte de texte: $im->queryFontMetrics($draw, text); on récupère un tableau comme ci-dessous
  • 
    Array
    (
        [characterWidth] => 9
        [characterHeight] => 9
        [ascender] => 9 # la taille au-dessus de la baseline
        [descender] => -2 # la taille sous la baseline
        [textWidth] => 71
        [textHeight] => 10
        [maxHorizontalAdvance] => 12
        [boundingBox] => Array
            (
                [x1] => 0
                [y1] => -2
                [x2] => 6.890625
                [y2] => 7
            )
        [originX] => 70
        [originY] => 0
    )
    

    Dessiner des formes

    Fixer les caractéristiques

    • opacité du trait : $draw->setStrokeOpacity(0-1);
    • couleur du trait : $draw->setStrokeColor(couleur);
    • épaisseur du trait : $draw->setStrokewidth(nb);
    • type de trait : $draw->setStrokeDashArray() Le motif semble être plein de possibilités car on peut le définir très spécifiquement et même utiliser une image comme motif (->setStrokePatternURL)
    • couleur de remplissage : $draw->setFillColor(couleur);

    Formes

    • cercle : $draw->circle ($x, $y, $x + $r, $y);
    • ellipse : $draw->ellipse($ox,$oy,$rx,$ry,$start,$end);
    • point : $draw->point ($x, $y);
    • polygone : $draw->polygon ($tableau_de_coordonnées); : array( 'x' => 3, 'y' => 4 ), array( 'x' => 2, 'y' => 6 )
    • ligne brisée : $draw->polyline ($tableau_de_coordonnées); : array( 'x' => 3, 'y' => 4 ), array( 'x' => 2, 'y' => 6 )
    • rectangle : $draw->rectangle ($x, $y, $x2, $y2); )
    • rectangle arrondi: $draw->roundRectangle ($x, $y, $x2, $y2,$rayonx,$rayony);

    Exemple

    Pour écrire un texte dans une image:

    
    $text='pipo et mollo';
    $im=new Imagick();
    $draw=new ImagickDraw();
    //var_dump($im->queryFonts('*'));exit;
    $draw->setFont( 'Courier' );
    $draw->setFontSize( 20 );
    $draw->setFillColor( 'black' );
    $draw->setTextAntialias(true);
    $metrics = $im->queryFontMetrics($draw, $text);
    $draw->annotation(0,$metrics['ascender'],$text);
    $im->newImage( 300, 20, 'lightblue');
    $im->drawImage($draw);
    $im->setImageFormat( 'png' );
    header('Content-type: image/jpeg');
    exit($im);  
    
    ce qui donne cette image
    index2.png
    C'est pas ouf...

    Il serait intéressant de pousser les tests mais là, j'ai pas le temps...

    Peut-être reprendrais-je des trucs existant avec tout ça ( scriptopic, RoR, Stamp mematic etc etc.)

    Et c'est là que Bronco prit  conscience de la quantité de   merdes affligeantes qu'il avait  codées sur un coup de tête  à la va-comme-je-te-pousse   et qu'il avait infligées à tous...

    PHP - Notes perso sur Imagick, un résumé de pourquoi je vire GD à coups de pompes dans l'oignon.

    Allez, pour une fois, j'ai un peu de temps devant moi, je vais éplucher un peu la lib Image magick dont je parlais il n'y a guère...

    La base

    charger UNE image

    Simple: pas besoin de plusieurs fonctions selon le format, il suffit de $images = new Imagick('image.jpg');

    charger DES images (et là c'est fort)

    Même pas nécessaire de passer par un foreach, on fournit le tableau des fichiers voire directement un glob: $images = new Imagick(glob('images/*.JPG'));

    Sauver une image

    $im->writeImage('image.jpg');

    Faire une miniature

    Si on laisse une dimension à 0, les proportions sont conservées (quand tu vois la merde que c'est avec GD !) $image->thumbnailImage(100, 0);

    Output une image

    header('Content-type: image/jpeg');
    $image = new Imagick('image.jpg');
    # ici on effectue un traitement puis on sort le résultat
    echo $image;

    Récupération d'infos sur les images

    • taille $im->getImageWidth() $im->getImageHeight()
    • format $im->getImageFormat()

    création d'une nouvelle image

    $im->NewImage(largeur,hauteur,couleur de fond);

    création d'une couleur

    Comme pour GD, il faut créer un objet couleur dans les traitements d'image, mais c'est plus simple qu'avec GD (et plus complet): il suffit de passer une couleur selon les normes CSS. Du coup, la transparence n'est pas gérée par une connerie de paramètre «alpha» mais simplement par ... rgba()... 💖

    $couleur=new ImagickPixel("white");
    $couleur=new ImagickPixel("#FFF");
    $couleur=new ImagickPixel('rgb(255,255,200)');
    $couleur=new ImagickPixel('rgba(255,255,200,0.5)');

    🆒 ⮕ Ça peut paraître compliqué, mais en fait, dans les fonctions où on est sensé utiliser ImagickPixel, je me suis aperçu qu'on pouvait tout simplement passer une string contenant la couleur css... elles se démerdent seules. 😍

    Traitements

    Ajouts

    • de bordure ->borderImage(couleur,largeur bords verticaux, largeur bords horizontaux): $im->borderImage(new ImagickPixel("white"), 5, 5);
    • de texte :
    • de stéganographie (cacher un filigrane dans une image) ->steganoImage():

    Modification de couleurs

    • sepia ->sepiaToneImage(force) : une valeur raisonnable est 80 (sic)
    • solarisation ->solarizeImage(force)
    • négatif ->negateImage(gris): $im->negateImage(0);
    • niveaux
      • $im->normalizeImage();
      • $im->autoLevelImage();
    • gamma ->gammaImage(niveau) : $im->gammaImage(5);
    • contraste $im->contrastImage(niveau)
    • luminosité et contraste $im->brightnessContrastImage(niveau luminosite, niveau contraste);
    • égalisation $im->equalizeImage()
    • coloriser ->colorizeImage(couleur,opacite) : $im->colorizeImage("red",0.5); 🤬 pas réussi à l'utiliser pour ce test...

    Modification de taille et d'orientation

    • redimensionner :
      • ->resizeImage(largeur,hauteur, filtre, flou) : $i->resizeImage(250,0,Imagick::FILTER_POINT,0);
      • ->scaleImage(largeur,hauteur): pas encore compris la différence avec la précédente
      • recadrer ->cropImage(largeur,hauteur,x,y): $im->cropImage(200,200,50,50);
      • 💖 créer une miniature à la taille donnée en recadrant l'image autour du centre ->cropThumbnailImage(largeur,hauteur)
    • retourner :
      • $im->flipImage() pour retourner horizontalement
      • $im->flopImage() pour retourner verticalement
    • pivoter ->rotateimage(color, $angle): $im->rotateImage(new ImagickPixel('#00000000'), 75);

    Modifications de qualité

    • modification d'opacité ->setImageOpacity(0-1) : $im->->setImageOpacity(0.3);
    • netteté ->sharpenImage(rayon, deviation,canal):
    • amélioration ->enhanceImage()
    • flou :
      • flou tout court ->blurImage(rayon, décalage): $im->blurImage(5,2);
      • gaussien ->gaussianBlurImage(rayon, deviation) : $im->gaussianBlurImage(5,2);
      • de mouvement ->motionBlurImage(rayon,deviation,angle) : $im->motionBlurImage(5,5,45);
    • réduction du nombre de couleurs ->posterizeImage(nb de couleurs, 0/1) :$im->posterizeImage(5,0);
    • ajout de bruit ->addNoiseImage(type) : `$im->addNoiseImage(imagick::NOISE_GAUSSIAN ); voir les constantes de type de bruit

    Modification d'aspect et déformations

    • aspect crayon $im->sketchImage(rayon, deviation, angle);
    • aspect fusain $im ->charcoalImage(rayon, deviation);
    • aspect emboss ->shadeImage(gris, angle, hauteur):
      • $im->->shadeImage(1, 90, 2); # emboss + image grisée
      • $im->shadeImage(0, 90,2) # emboss sur l'image d'origine (couleur)
    • peinture à l'huile ->oilPaintImage(rayon) : $im->oilPaintImage(5);
    • détection de bords ->edgeImage(rayon) : $im->edgeImage(5);
    • vagues ->waves(amplitude,longueur): $im->waveImage( 10, 10);
    • déformation ->distortImage(methode, arguments[],0) : voir les constantes de déformation

    interactions d'images

    Conclusion

    Image Magick me semble particulièrement bien nommée tant les possibilités sont énormes et la simplicité d'utilisation étonnante: on sent une volonté de se simplifier la vie lors de l'utilisation... c'est juste beau.

    Je voulais mettre une image de chaque effet dans les descriptions mais:

    1. ça prenait une place de ouf
    2. je préfère reprendre certaines de mes applis/api avec imagick
    3. j'ai plus le temps, les autres arrivent
    4. j'ai la flemme.

    [EDIT] En fait, j'ai fait une page de test même si tout n'est pas concluant : http://test.warriordudimanche.net/imagick/

    Outils gratuits en ligne de traitement d'image automatique (et de video et de son) MAJ

    📋 Note pour plus tard

    Image

    Vidéo et son

    Générateur

    Bionic Reading API Documentation (bionic-reading-bionic-reading-default) | RapidAPI

    Tiens, il existe une API qui permet de transformer du texte en Bionic Reading, cette technique améliorant la lecture en mettant en gras le début du mot. Je m'interrogeais justement sur la pertinence d'implémenter ça sur mon appli de documents en espagnol pour les élèves éprouvant des difficultés de lecture...

    Bon, il faudra que je fasse une couche d'interface afin que les données des élèves ne transitent pas vers le site de l'API, comme pour celle de synthèse vocale... mais rien de trop ardu.

    A creuser.

    Fil RSS des articles
    Caching time 0.004393 s