Petite mise à jour pour mon script findfeed qui sert à trouver le flux RSS d'un site s'il existe...
Je le reprends de temps à autres quand je tombe sur un site qui échappe aux regex de recherche
Il y a un petit bookmarklet: un clic dessus quand on est sur un site et hop, on récup l'url du flux...
Dans cette version, j'ai également remis à jour la récup pour une chaîne youtube.
Si vous souhaitez améliorer la détection, il suffit d'ajouter ou modifier le tableau $regexes au début du script (ajouter des règles ou les modifier.)
Note au passage
Certains sites peuvent bloquer findfeed parce qu'il ne fait pas une requête «normale» comme celle d'un visiteur lambada C'est le cas d'OVH par exemple, qui bloque l'accès à maximevende.org alors que ce dernier a bien un flux RSS dans son header quand on y accède normalement.
En ajoutant un USER_AGENT à ma fonction CURL , ça semble avoir résolu le problème
O2switch va bientôt fermer la beta de son offre nextcloud pour ouvrir l'offre définitive. La betaversion leur a permis de voir ce qu'il fallait améliorer... et dans le lot, il y avait la supression de la possibilité d'installer des applis comme on veut.
Or, le gestionnaire de mots de passe, qui m'allait pas trop mal, disparaît dans la nouvelle version.
Je me suis donc mis à une petite appli destinée à sauver les identifiants pour le cas où on les aurait perdus/oubliés etc.
Comme beaucoup d'autres, elle est basée sur Helium, mon framework perso, ce qui explique de j'ai pu coder Yavero en deux jours de mon temps libre (LOL)
Ce que je voulais
Une appli qui me permette d'ajouter, supprimer et d'éditer des identifiants simplement,
qui puisse importer et exporter les identifiants de et vers firefox (en CSV) ( wink @sebsauvage)
qui gère plusieurs comptes pour que toute la famille puisse ajouter les siens de son côté
aussi sûre que possible (pas de stockage en clair, bien sûr, pas de visibilité d'un compte sur l'autre, difficultés pour trouver le fichier BDD sur le serveur...)
Ce que je ne cherche pas
Une appli qui gère les mots de passe dans le navigateur pour autocompléter les formulaires etc...
J'en veux j'en veux !
Alors, bon, c'est pas que je veux pas partager, hein, vous me connaissez... toutefois, ce qui peut coincer, c'est qu'Helium, la base de cette appli, est toujours en cours de débugage... genre, j'ai créé et modifié des trucs sur le framework pendant le dev de cette appli... Si je partage, c'est à vos risques et périls et sans service après partage ... Donc pour le moment, pas de diffusion large en mode openbar mais si les copaines se sentent en mal de conjonctivite,...
Captures
La vue de la liste: on peut filtrer l'affichage en temps réel et les mots de passe se révèlent au survol (clic pour copier)
Un click sur édit permet d'éditer... Le bouton suppr permet de supprimer les éléments sélectionnés.
L'édition d'un identifiant.
L'exportation permet de sélectionner les identifiants qu'on veut mettre dans le fichier CSV
On sélectionne le fichier à importer...
Si on importe depuis firefox, c'est simple
Puis ensuite les identifiants que l'on souhaite importer dans la base...
Si on importe depuis une autre appli (comme nextcloud par exemple), Yavero propose d'attribuer les colonnes de données à chaque catégorie d'info attendue: ID, login, mot de passe etc...
La gestion des profils. Le premier profil créé est le superadmin (le seul à avoir accès à cette page)
Le code
Yavero utilise sqlite et aucune lib tierce (même pour le JS, c'est mon mini framework.)
les icônes viennent de fontello (je sais c'est caca pour l'accessibilité... DSL)
Les identifiants sont stockés et restitués en fonction de l'utilisateur connecté.
les mots de passe sont chiffrés dans la BDD
le nom de fichier de la base de données est randomisé
(Au passage, un llavero c'est un porte-clés en espagnol )
Bon, vu les tournures que prennent les choses et la shitstorm qui nous attend, voici un petit plugin pour ajouter facilement un canari de censure à votre pluXML.
Pour rappel, le canari de censure est une image que l'on laisse tant qu'on n'a pas subi de pression éditoriale ou de menaces... Si c'est le cas, on retire l'image et tout le monde comprend le message sans que l'auteur n'ait besoin de courir un risque supplémentaire en publiant un billet d'explication.
Donc: canary
Ce plugin ajoute donc une icône de canari (merci nounproject ) sur le site sans qu'il soit nécessaire d'éditer quoi que ce soit ou de s'y connaître en programmation. On active le plugin, on le configure et voilà.
La configuration permet de :
choisir la taille et le positionnement de l'icône,
choisir le texte de la balise title,
afficher ou ne pas afficher le canari.
Dans les options de positionnement, on a les quatre coins, l'endroit où le hook est appelé ou le footer (dans ce cas pas besoin d'ajouter le hook dans le code.)
A propos du hook, on peut placer l'image dans les templates avec
Après avoir commis BadGit, j'ai récidivé cet aprème avec Avatrine... qui génère un avatar sous forme de lettrine à fond de couleur.
Mais pourquoi me direz-vous ?
Parce que :
j'ai trouvé ça joli quand je l'ai vu je ne sais plus où
j'aime bien faire joujou avec Imagick
je fais ce que je veux
Les paramètres
str: la chaîne
[color]: la couleur de fond (calculée par défaut avec un hash de la chaîne)
[sz]: la taille, 128 par défaut
Pour faire simple
En gros, vous lui passez une chaîne de caractères, genre un pseudo par exemple, et il crée une image avec la première lettre du pseudo sur un fond dont la couleur dépend de la chaîne. Et il fait une rotation de 30° (valeur totalement empirique trouvée au doigt mouillé) sur la lettre pour que ce soit plus joli.
Des exemples
?str=Bronco
?str=Bronco&color=red
?str=Bronco&color=blue&sz=256
?str=Jerrywham&sz=256
?str=Sammyfisher&sz=256
Conclusion
Je sais que j'ai déjà fait des générateurs d'avatars...
( voir sur la page d'API https://api.warriordudimanche.net ROR et Avatomic )
avatar (Ror)
avatomic
et que celui-ci ne servira probablement pas plus que les autres mais bon... c'est cadeau quand même !
Comme je ne suis pas chez moi, je profite du fait d'avoir plus de temps pour picorer les videos de Grafikart, toujours aussi pertinentes et compréhensibles. Je me note donc ici quelques astuces intéressantes...
Comme l'URI ne sera pas complexe, on utilise $_SERVER['REQUEST_URI'] pour déterminer une page à charger à la place d'une variable $_GET un peu moche et sans passer par de l'URLrewriting...
On passerait de ça serveur.com/index.php.p=contact
if ($_GET['p']==='contact'){
require('contact.php');
}
à server.com/contact
if ($_SERVER['REQUEST_URI']==='/contact'){
require('contact.php');
}
A intégrer dans mon Helium pour la récup de la page demandée ?
Plus complexe : plusieurs variables $_GET
Il utilise une classe routeur ce qui me donne envie d'essayer d'en faire une simplifiée moi-même afin de pouvoir faire par exemple:
$routeur->toGet('page/user'); pour récupérer dans la variable $_GET les infos de l'URI serveur.com/contact/bronco
👍 glopglop : c'est élégant et propre, on peut injecter les données extraites de l'URI dans la variable $_GET afin d'éviter de modifier trop profondément la logique d'une appli existante.
👎 pasgloppasglop : avec ce système, les infos doivent absolument être dans l'ordre attendu ce que n'impose pas l'usage de $_GET
Histoire de bosser un peu sur l'utilisation d'Imagick (pour lequel je m'étais fait des notes ici 12) j'ai essayé de faire une petite «api» de génération de badges simple.
Objectifs
Un script qui permet de faire des badges à une ou plusieurs parties,
gestion de la taille de police et de la police,
gestion des couleurs,
gestion d'icônes
Résultat
On peut appeler l'api directement en précisant les variables suivantes:
txt: le texte; s'il y a plusieurs parties, on les sépare par un |. exemple ?txt=trop beau|pas vrai
backcolor: la couleur de fond; on peut préciser la couleur de chaque partie en les séparant par | aussi. La notation se fait comme en css (sauf pour le # qu'il faut omettre) ```F00|red|rgba(255,0,0,0.5)
textcolor: pareil pour le texte. Par défaut, badgit va choisir le blanc ou le noir afin de maintenir le meilleur contraste.
fontsize: la taille de police
font: une des fontes installées. Je n'en ai mis que deux pour le moment mais on peut utiliser «courier» par exemple.
icon: le nom d'une icône de iconeleon (j'ai d'ailleurs ajouté une option pour copier le nom en question depuis l'api d'icônes.)
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écorationimagick::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);
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()
🆒 ⮕ pour fixer le format de l'image, c'est juste $im->setImageFormat('png'); ! 😍
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()... 💖
🆒 ⮕ Ç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. 😍
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:
ça prenait une place de ouf
je préfère reprendre certaines de mes applis/api avec imagick
Après avoir fait goofi puis Getlib j'ai codé vite fait une petite «api» destinée à ramener en local n'importe quelle ressource distante... «quelle différence avec getlib ?» allez-vous me demander sur un ton narquois à propos de la cruauté duquel je tairais scrupuleusement tout commentaire.
J'ai eu envie de faire ça car j'en avais assez de passer par le combo
bouton droit sur une ressource ➜ télécharger ➜ envoyer sur mon site ➜ faire un lien ou une img
Du coup, il suffit d'ajouter l'adresse de l'api à l'url vers la ressource distante...
Donc http://insta.com/image.jpg devient par exemple http://api.warriordudimanche.net/fetchit?url=http://insta.com/image.jpg
Fetchit va récupérer la ressource en local et vous servir cette version au lieu de la distante. Comme d'hab' si cette ressource a déjà été récupérée elle n'est pas re téléchargée.
Le deuxième effet kiskool (paye ta réf de vieux) c'est que du coup, comme getlib, ça permet de récupérer toute lib en local et être plus RGPD friendly.
lien vers une ressource distante : <a href="http:www.distantserver.com/file.pdf"> Link to distant file</a> ➜ <a href="http://api.url.com?url=http:www.distantserver.com/pic.png"> Link to distant file</a>
utiliser une lib hébergée sur un CDN distant : <script src="http:www.distantnastyserver.com/lib.js"></script> ➜ <script src="http://api.url.com?url=http:www.distantnastyserver.com/lib.js"></script>
Con figue ?
Afin d'éviter que votre server ne se retrouve floodé par des fichiers vidéos 8K à 60 gigots l'unité, il y a une limite de taille configurée dans la constante SIZE_LIMIT, fixée par défaut à 10 Mo.
Le code ?! c'est... le code.
Ceux qui aiment farfouiller verront que cette fois, j'ai fait une classe fetchit_class.php qui se charge de tout. Son fonctionnement est tellement simple que je me fissure même pas le joufflu à vous le détailler, démerdez-vous.
License
Comme d'hab', c'est cadeau... Utilisez, partagez, modifiez... juste respectez la Dont be a dick licence
Il y a quelques jours, j'ai vu passer un article sur le contenu idéal d'un Readme ( https://warriordudimanche.net/article1840/6448d4a15a710 ) et en partageant le lien sur mastodon, on a émis l'idée de coder un assistant de génération qui permette de faire ça simplement...
Nicolas Delsaux* m'a alors passé quelques exemples d'applis déjà réalisées et - pour autant que j'ai pu en juger avec un test rapide - très bien foutues et très complètes:
le malheur était déjà en train de se produire: impossible d'empêcher mon cerveau de travailler en background façon «à la volette»
Du coup, si je voulais pouvoir faire autre chose, il fallait d'abord vider ma tête de ce «projet» LOL.
Voici donc ReadmeToaster
L'objectif est de pouvoir faire un readme rapidement, de pouvoir modifier «simplement» les éléments du contenu (ordre ou items), de pouvoir ajouter des captures d'écran, sélectionner une license...
La capture d'écran parle d'elle-même: on peut même choisir de générer des fichiers séparés pour certaines parties (Roadmap, Changelog...)
Configuration
La configuration des items se fait via le fichier config/patrs.json qui contient les objets, leur type (select/text/textarea etc), leur titre/label, leur placeholder, leur attribut name etc.
"Name":{
"type":"text",
"title":"The project name",
"name":"name",
"placeholder":"ReadmeToaster",
"class":"name",
"required":"required"
},
"Description":{
"type":"textarea",
"title":"A short description (what's the project's purpose ?)",
"name":"description",
"placeholder":"A tiny webapp to create normalised readme files",
"class":"description"
},
"Installation":{
"type":"textarea",
"title":"How to install or deploy ?",
"name":"installation",
"placeholder":"Just copy the folder onto your server and that's it... Noooo, I'm kidding !",
"class":"install"
},
"Contribute":{
"type":"textarea",
"name":"contribute",
"placeholder":"* translations,n* bug finding",
"class":"text",
"title":"Explain how to contribute"
},
"Contribute in a separated file":{
"type":"checkbox",
"name":"contribute_separate",
"title":"Put contribute in a separate file",
"placeholder":"",
"class":"",
"value":"contribute_text"
},
On peut ainsi facilement ajouter, modifier ou déplacer des items dans le frontend sans mettre les doigts dans le code. Si on peut pouvoir séparer un contenu dans un fichier à part, on colle un item checkbox dont le nom est ITEM_separate.
Le fichier généré sera un zip contenant tous les fichiers, y compris les éventuelles captures d'écran fournies.
Si après une MAJ vers linux mint 21.1 apache ne démarre plus et fait une erreur du genre
apache2: Syntax error on line 146 of /etc/apache2/apache2.conf: Syntax error on line 3 of /etc/apache2/mods-enabled/php7.4.load: Cannot load /usr/lib/apache2/modules/libphp7.4.so into server: /usr/lib/apache2/modules/libphp7.4.so: cannot open shared object file: No such file or directory
on peut rattraper le coup en désactivant php7.4 au profit de 8.1:
Tiens... et si je faisais un bot pour poster une citation par jour tirée des passages de romans que j'ai sélectionnés et stockés su ma Kobo ?!
C'est par ces mots que j'ai commencé à galérer... comme quoi, il suffit d'une idée à la con pour se lancer dans tout un merdier pourtant parfaitement facultatif ...
Le postulat de départ
Je veux qu'un BOT mastodon poste une citation de mes bookmarks de liseuse DONC il faut récupérer ces passages bookmarkés.
Donc, il faut trouver le fichier de base de donnée.
Puis il faut extraire les données intéressantes.
Puis utiliser ces données dans un BOT qui sera appelé une fois par jour.
Étape 1: trouver et comprendre les données sur la KoBo
En fouillant un peu, on trouve un fichier sqlite (JOIE) dont le chemin est .kobo/KoboReader.sqlite
Un passage par DBBrowser pour SQlite permet de jeter un oeil sur la structure des données.
Idéalement, il me faut deux informations: la citation et le titre du bouquin dont elle est extraite.
En fait les titres se trouvent dans la table content et les annotations dans la table Bookmark
Je pourrais utiliser Calibre et chercher un moyen de faire un export complet de ces deux données uniquement. Pas sûr que ça marche. Ou alors faire un export via le DBexplorer pis me retaper le truc à chaque export...
Étape 2 : extraire les données et les préparer pour le Bot
En vieux programmeur qui bricole, je vois là un prétexte pour coder une petite appli en python qui se chargera de l'extraction.
Mon problème, c'est que je me sers des notes de la Kobo pour retenir des passages intéressants mais aussi, parfois, pour noter vite fait un mot de vocabulaire espagnol que je ne connaissais pas et dont je veux conserver la traduction. Mais ces mots de vocabulaire ne sont pas des citations: il faudrait donc les virer à la main à chaque fois. C'est chiant.
L'appli devra donc permettre de filtrer les citations avant de générer un fichier exploitable par le bot.
Pour faire court
J'ai fait l'appli en question: elle permet donc de récupérer les données, filtrer en fonction de la longueur de la citation ou du fait qu'elle est ou pas accompagnée d'une note personnelle...
On peut formater les données selon plusieurs modèles (HTML, Json, Markdown, TXT brut, BOT) voire même créer son propre format (genre %title:«%quote» )
Étape 3 : coder un bot en PHP afin de l'appeler par la suite avec un CRONJob.
Rien d'extraordinaire ici: je fais un script qui parse le fichier obtenu à l'étape précédente, tire une citation au hasard et la poste sur le compte Masto du Bot.
Le point le plus intéressant du bouzin est plutôt la fonction servant à poster sur un compte mastodon:
Étape 4: Créer une appli Mastodon pour avoir un jeton d'utilisation
Aller sur le compte mastodon en question, puis dans les préférences.
Cliquer sur «developpement» puis «Nouvelle application».
Remplir le formulaire simplissime puis valider. Cliquez ensuite sur le nom de votre application dans la nouvelle page et copiez votre jeton d’accès. C'est celui-ci qu'il faut coller dans le script PHP (dans la constante TOKEN)
Étape 5 : Définir un Cronjob
Direction le panneau de config de votre hébergement, rubrique cronjob.
Sur Cpanel c'est là :
Définissez la fréquence (pour moi une fois par jour) et l'heure (8:00).
Ensuite, il faut définir la commande qui va appeler le script du BOT: wget fera l'affaire...
L'option -q pour quiet et -O /dev/null pour éviter d'avoir un fichier de sortie qui se crée à la racine.
Fin
Une fois tout ça terminé, j'ai bien un bot qui poste une citation à 8:00 tous les jours.
Bon, elles ne seront pas toujours bien formatées vu que la sélection de texte sur liseuse c'est un peu touchy... mais c'était plus pour apprendre à le faire qu'autre chose...