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 )
Tiens, je ne connaissais pas l'event auxclick de javascript: il permet de tester l'appui sur tout autre bouton de la souris que le gauche... event.pointerType contiendra le type de pointeur (mouse, pen, touch, etc.)
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
En bossant sur l'appli que j'utilise pour mes cours, j'ai voulu ajouter un accès rapide à un document en tapant le début du nom de dossier dans un input alimenté par une datalist.
Bien entendu, je veux éviter de devoir passer du clavier à la souris plusieurs fois : tape un bout du nom, clique pour sélectionner, appuie sur entrée pour valider...
Donc, il faudrait que la sélection et l'ouverture du document se fasse:
quand je tape un bout de nom et que j'appuie sur entrée (il ira chercher le premier de la liste)
quand je tape le début, que j'utilise les flèches pour aller chercher celui que je veux et que j'appuie sur entrée,
quand je tape le début et que je clique sur le nom du document qui m'intéresse.
Et là, c'est le drame
En effet, autant on peut capturer un évènement sur un input, autant ce n'est pas possible sur les option ou le datalist
Donc, il faut gruger et agissant sur les events de l'input.
Je mets ici ma solution actuelle (c'est le code que j'utilise avec mon framework js perso parce que j'ai la flemme de changer ):
<input type="text" placeholder="accès rapide à un document" list="docs_list" id="input_docs_list">
<datalist id="docs_list">
\\ici les option qui vont bien
</datalist>
<script type="text/javascript">
on('keydown','#input_docs_list',function(e){ // ça, c'est mon VanillaJS
if(e.keyCode==13||!e.key){
// si on a appuyé sur entrée ou que l'évènement n'est pas déclenché par une touche (donc, c'est la souris)
window.location.replace("?"+e.target.value);
}
});
on('input','#input_docs_list',function(e){
// celui-ci est pour firefox
if(e.inputType=='insertReplacementText'){
window.location.replace("?"+e.data);
}
})
</script>
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.)
Depuis que mon grand est en fac d'info, on a un nouveau sujet de conversation et j'ai ENFIN un interlocuteur dans le domaine à la maison !
Du coup, il arrive le weekend avec les TP qu'il a eus pendant la semaine et me pose des questions sur les difficultés qu'il a.
En ce moment, il commence PHP et CSS/HTML...
Du coup, aujourd'hui, il travaillait sur la page de login pour le projet final, une todolist en PHP+HTML+CSS sans JS.
Il voulait faire des labels flottants parce qu'il avait vu que c'était joli... Comme il découvre le monde merveilleux du frontend, on s'y est mis à deux et on a improvisé un petit cours.
Il a appris les subtilités du ciblage, les pseudo éléments, l'usage de :not() et :has()...
En gros, on veut que le label soit dans l'input, comme un placeholder, lorsque il est vide mais que le label reprenne une place normale lorsque l'utilisateur clique dans l'input pour le remplir.
Pour ça, j'ai créé un label contenant un span avec le texte et l'input correspondant:
À ce stade, quand l'utilisateur clique dans l'input, le label glisse vers le haut pour sortir de l'input.
Toutefois, le problème c'est que lorsque l'input perd le focus, le label revient à l'intérieur même si l'input a été complété... et les deux textes se chevauchent hideusement...
La logique voudrait qu'on cible alors le span du label contenant un input vide, genre avec input[value=""] ... sauf que ça ne marche pas car le fait de remplir un input ne modifie pas l'attribut value de la balise input...
Heureusement, on peut gruger...
Puisqu'on ne peut pas cibler un changement de l'attribut value, on peut cibler... le placeholder ! Enfin... styler en fonction de la visibilité du placeholder...
Ainsi, en utilisant :placeholder-shown, on peut ajouter une règle de ciblage au CSS précédent:
Et là, les plus observateurs d'entre-vous - qui se demandaient avec une angoisse et un mépris non dissimulés pourquoi j'avais collé un placeholder=" " dans mon HTML - comprennent l'astuce: si le placeholder est visible, c'est que l'input est vide...
Et ça marche, tout est supporté dans la plupart des navigateurs. En plus, c'est léger, ne demande pas une structure HTML alambiquée ou des règles CSS à la mords-moi le zboub...
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")
J'implémente toute une nouvelle rubrique et de nouveaux items afin de couvrir le spectre de l'expression orale de façon simple en ajoutant une sorte de labo de langue simplifié.En gros, je veux que le gamin puisse travailler à l'écoute de mots modèles mais également qu'il puisse s'enregistrer et se réécouter simplement et quelque soit le support...
Les frontend qui me lisent voient de suite où ça va couiller (merci les copaines)
Et oui, j'ai codé un truc qui fonctionne très bien, relativement propre et simple, facile à utiliser... sous Firefox, opera, vivaldi, chromium et sous Android.
Hélas, ma solution utilise l'API MediaRecorder qui semble présenter des difficultés sous certains navigateurs, vous devinez lesquels...
J'ai testé sur safari (enfin epiphany passque j'ai pas d'apple sous la pogne, tu te doutes...) et ça refuse de fonctionner, vu que MediaRecorder y est bloqué pour nôôôtre saicuritay...
J'ai ensuite testé sur Edge avec mon portable et ça n'a pas fonctionné... toutefois, quand j'ai installé le deb d'Edge sur mon linux ⬇⬇⬇ ...
...là, ça a fonctionné... Mais si ça marche, ça doit venir de Linux et pas de Edge (mauvaise foi inside )
Donc en gros, on revient à des soucis de compatibilité avec le nouvel IE ?! (ouelcome to aoueur fanne tasse tique taïme meuchine !)
Pourtant, canIuse me dit que ça devrait fonctionner, même sous Safari:
Bon, avec le navigateur à la pomme, il y a bien une manip à faire dans la configuration avancée pour les devs qui pourrait débloquer la situation mais je me vois mal demander ça à des élèves qui éprouvent déjà des difficultés non négligeables à discerner la barre d'adresse ou qui peinent - la sueur au front - à taper une majuscule sans passer par la touche de verrouillage...
Donc, là, pour le moment, rien à faire dans l'immédiat pour utiliser simplement MediaRecorder avec safari ou Edge... j'ai donc opté pour une «solution» temporaire: en cas d'absence de l'API, j'ajoute une classe spécifique et je disable les recorders de la page, puis j'affiche un message d'avertissement avec des liens vers des navigateurs compatibles (firefox et forks en tête)...
Après, j'ai bien trouvé un polyfill qui pourrait faire le job ( https://github.com/ai/audio-recorder-polyfill ) mais je ne l'ai pas testé, c'est un peu lourd à installer et pis... c'est pas moi qui l'ai fait...
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
Tout le monde connaît les licences libres habituelles mais il y en a de moins connues et - souvent - moins compliquées à comprendre : petit florilège...
Littéralement, la Licence Démerdez-vous... Je vous laisse la lire tranquilou pour vous faire une idée: toute tentative de résumé serait une trahison du texte original
«Cette Licence» se réfère à la version 1 de la «Demerden Sie Sich License» (le texte original en français).
«Démerder», se réfère au sens de se «débrouiller». A aucun moment «cette Licence» ne vous demandera de vous enduire (vous ou votre œuvre) d'excréments humains (ni même animal).
«Œuvre» est aussi appelée «travail» (quelques fois, l'extension «de sagouin» peut lui être apposée), «programme» ou tout autre terme relatif à ce qui a été effectué. Ainsi, une «documentation» ou un «manuel» peut être considéré comme une œuvre.
«Auteur» signifie que la personne (ou groupe de personnes), qui utilise «cette Licence», se lave complètement les mains de la façon dont vous utiliserez son œuvre.
L'«Auteur» peut-être considéré comme irresponsable et il incombe à l'utilisateur en priorité de se «démerder» par lui même.
Les licences les plus WTF
La D&R
The Death and Repudiation License
This software may not be used directly by any living being.
En gros, l'usage à toute personne vivante est formellement interdit.
Conditions très exotiques pour cette licence qui régule drastiquement la redistribution des copies du code:
à chaque 1000ème copie distribuée au moins la moitié des employés ou personnes affiliées doit écouter «the chicken dance» de Werner Thomas
à chaque 20000ème copie distribuée, une personne affiliée doit exécuter la Chicken dance dans une vidéo
il est formellement interdit à tout employé ou personne affiliée de prononcer le mot «gazorninplat» en public tant que dure la distribution du produit.
If someone says "stop" or goes limp — or taps out — the project is over.
Only two developers to a project.
One project at a time.
No shirts, no shoes.
Projects will go on as long as they have to.
If this is your first time reading the FIGHT CLUB LICENSE, you HAVE to license your next project under the FIGHT CLUB LICENSE.
La OGPITAL
The Offendo General Pain In The Ass License
L'auteur de toute modification doit redistribuer le travail modifié par un moyen plus contraignant et difficile que celui par lequel il a acquis le code original.
Pour faire court, c'est pas un bug c'est une fonctionnalité...
Bugs in the licensed work are features, to be cherished, documented, and developed upon.
Modified works must not include known bugs.
Where identified, modified works' bugs shall be fixed.
Authors and maintainers of the licensed work reserve the right to pull bug fixes from modified or derivative works without compensation, recognition, or any other reference to the authors of the bug fix.
Une licence qui autorise tout avec pour seule condition de ne pas être un connard (a dick)... l'auteur fournit une liste non exhaustive de ce qu'il appelle être un connard:
se contenter de copier et de changer le nom
vendre une version non modifiée sans produire le moindre travail
Faire des modifications afin d'implémenter du contenu dangereux
Faire de l'argent avec et devenir riche sans même soutenir l'auteur
Vous voulez partager un logiciel ou un code en interdisant toute exploitation commerciale capitaliste et libérale ? Cette licence permet de restreindre l'usage et l'exploitation à certains types d'utilisateurs:
une personne privée travaillant pour elle-même
une organisation à but non lucratif
une organisation à but éducatif
une organisation visant les profits partagés pour tous ses membres
si l'utilisateur est une organisation alors tous les travailleurs sont propriétaires et inversement.
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