DeepPDF URL

Encore à propos des PDFs. Besoin d’ouvrir dans un browser avec des fonctions en plus. Il y a le basique pour les destinations données "url/fichier.pdf#nom", et aussi le « url/fichier.pdf#page=21 » qui sont assez standards. (A noter que pdfinfo -dests fichier.pdf permet d’automatiser la recherche des destinations nommées dans un PDF.

Dans le contexte d’un moteur de recherche, je voulais aller plus loin avec « url/fichier.pdf#search=emprise » et cela fonctionne bien avec Firefox et mais pas sur chrome et ses dérivés. J’ai fini par comprendre que c’était lié au composant utilisé par ces browsers. Ouf, il suffit d’installer un add-on qui se base sur PDF.js, comme nativement avec Firefox, comme PDF Viewer. Pas encore trouvé de solution pour Safari

Youpi : https://codes.droit.org/PDF/Code%20civil.pdf#search=emprise

A noter que PDF.js tel que dans Firefox (ou DiversChromes avec le viewer en question) permet des choses interdites par d’autres contextes. Ainsi, car PDF.js est un citoyen libre, il me sert à redistiller des fichiers en contournant les blocages tels que l’interdiction d’imprimer: Au lieu de faire des screenshots (ou des copier/coller avec Word !!!) pour pouvoir distribuer un fichier librement, il suffit de l’ouvrir dans un lecteur basé sur PDF.js puis de l’imprimer aux format PDF pour le redistiller de manière libérale.Et hop.

UniteThePages

Besoin de réunir des PDFs en un seul, pas vraiment compliqué avec pdfunite. Excellent. Dans mon cas, besoin un peu plus sophistiqué car besoin d’introduire des signets afin d’avoir un document plus agréable à consulter, d’où ce script.

Script en perl mais dépendances pour manipuler les fichiers PDF, à savoir pdfinfo, pdfunite (brew install Doppler sur Mac et apt install poppler-utils sur linux) et enfin ghostscript. Pas besoin de modules perl spécifiques.

#/usr/bin/perl
open(STRU,'>','merger.txt');
$cursor = 1;
foreach $af (@ARGV) {
if(-e $af) {
$ninfo = pdfinfo "$af";
my %inf;
foreach $lee (split(/\n/g,$ninfo)) {
if($lee =~ /^(.?)\:[\s\t]+(\w.)/) {
$inf{$1} = $2;
}
}
$tito = $inf{'Title'};
$tito = $af unless($tito);
if($inf{'Pages'} =~ /\d+/) {
print STRU "[/Page $cursor /Title ($tito) /OUT pdfmark\n";
$cursor += $inf{'Pages'};
}
}
}
close(STRU);
$units = join(' ',map { "\"$_\"" } @ARGV);
pdfunite $units merger.pdf;
print gs -sDEVICE=pdfwrite -q -dBATCH -dNOPAUSE -sOutputFile=Merged.pdf -dPDFSETTINGS=/prepress merger.txt -f merger.pdf;

unlink('merger.txt');
unlink('merger.pdf');

Simple et efficace. Peace.

400 on ip rangers

J’ai mon serveur privé à domicile, adressé avec un dyndns (à vrai dire, un clone car depuis le rachat c’était payant). Pas de soucis mais je voulais restreindre le trafic de bots qui scannent des IP par rayons entiers.

ServerName jesus.dyndns.org
StrictHostCheck ON

Avec ces deux lignes au tout début de ma config apache, je dis à mon serveur de ne répondre que quand il est appelé par son petit nom mais pas quand s’adresse à lui avec son IP (qui est en plus dépendante de ce que me donne mon FAI).

Résultat éclatant, trafic divisé par 10, presque plus de scanners.

Peace

Gospelled in MP3 under spotlight

Je fais de la musique depuis longtemps, sous licence creative commons CC(by). Pour obtenir un public plus large, je diffuse gratuitement depuis mon site et j’essaye d’être sur un maximum de services, et pour être suivi, j’ai mis en place une page podcasts toute simple et utilisée.

L’autre jour je suis allé sur Apple Podcasts Connect (https://podcastsconnect.apple.com) pour y constater que les stats ne sont pas disponibles alors que mon serveur vois bien plein de requêtes avec comme user agent « iTMS ». Bref, passons. Je vois en moyenne de 100 à 500 episodes par jour, écoutés au travers du podcast.

Parlant avec des utilisateurs de Spotify, je me dis qu’il doit y avoir un moyen d’être présent là aussi. Spotify est un gros player, ils acceptent les podcasts et j’ai cru comprendre qu’ils diffusaient de la musique. Gros potentiel pour moi.

Je me diffuse moi-même. Je vais sur Spotify for Creators, je crée un compte, j’indique l’URL de mon feed (http://habett.net/tracks.rss) et, alors que tout se passe bien jusqu’au bout, je finis par être inondé de messages « An episode of your podcast has been removed » !!!

En détail, chaque message indique que tel épisode est jugé comme non conforme à leur « content policy »:

Spotify for Creators supports the distribution of audio and video podcasts. Content that appears to be exclusively or primarily music is automatically taken down.

Si je comprends bien, de la musique, des podcasts, mais surtout pas le mélange des deux. Le pain, le beure mais surtout pas la tartine gratuite. J’imagine qu’ils font cela pour forcer les créateurs à passer par un organisme de gestion et/ou se blinder sur les questions de droits d’auteur en se déchargeant sur des opérateurs tiers. Techniquement, je ne vois aucune explication. Bref, cela ne vas pas avec les tout petits diffuseurs autonomes.

? Sprite ou Vecteur

Interfaces graphiques oldschool (90s), GUI tout en sprites/bitmaps. Simple, efficace, binaire. Ensuite les vecteurs sont apparus à droite à gauche, essentiellement pour le texte typographique. Sur mon Acorn, on pouvait activer un mode antialiasing pour le texte et les résultats étaient non seulement magnifiques, mais aussi gracieux en très grandes tailles. A l’époque, les images en format vectoriel étaient très appréciées car réutilisables, souples et légères.

Quand le NeXT est apparu, le truc qui m’avait le plus impressioné, en plus de son boîtier cubique noir et de sa gestion du multitâche, était son mode d’affichage. Le mobilier des fenêtres, et surtout les icônes, sublimes, étaient en vectoriel (display postscript). Bref, un format issu du monde de l’impression, appliqué à une lignée (imaginée) de systèmes d’exploitation pour s’accommoder d’un futur dans lequel nous sommes arrivés.

Si plus personne ne discute réellement le fait que la typographie numérique soit basée sur des vecteurs, le reste de l’environnement est resté bitmap dans des proportions totalitaires. A l’époque où l’on est capable de faire du ray-tracing en temp réel, on reste bloqué avec des images non vectorielles. Si on regarde dans Xcode, il est demandé de fournir des logos et images en plusieurs définitions là ou un seul fichier vectoriel pourrait suffire. Ce futur est bien décevant.

Si je prend Pages.app, le mini traitement de texte sur Mac, on peut monter la taille des caractères très haut, 1000pt. A cette taille, le tracé (issu de vecteurs) reste parfaitement harmonieux.

Mon problème du jour, est exprimé par l’implémentation des emojis. Prenez un emoji et affichez-le dans une très grande taille, vous verrez surgir un infect mélange de pixel et de flou. Dès 256pt, la perte de qualité est gênante. Les émojis ne sont des caractères que fonctionnellement. Quel héritage triste Apple a-t-il hérité de NeXT ? LibreOffice sous Linux présente ce même problème, MSWord aussi j’imagine.

Ou aurait pu avoir des Emojis vectoriels, techniquement tout était prêt. Mais non, on a droit, puisque c’est en partie le problème à mon avis, à un mélange idiot. Imaginer un monde en vectoriel, adapté du jour au lendemain aux affichages sub-pixels intégré. Imaginez ce monde. La formalisation unicode est sans doute une très grande occasion manquée, emojis et autres aussi.

?

Chaque plateforme a son emojiset et la complexification du développement de cet eco-système est telle que c’est perdu. A l’époque des écrans 4K et plus, on en reste là. On fait transiter de gros fichiers plein de pixels inutiles et d’une qualité discutable. Zut pour les SVG/XML ? Fuck pour les PDFs sans graphiques bitmap/photos inclus ? Un fichier vectoriel peut encapsuler des bitmaps si vraiment il y a besoin mais la réciproque n’est pas vraie.

Peut-être que nous sommes dans un autre type de monde ? pixels/vecteurs/fractales ? Je ne sais pas. En attendant, on fait du ravaudage et on perds du temps.

Je voulais conclure sur l’ascii-art et Figlet, les logiciels de vectorisation, les IA qui génèrent des photos alors qu’elles figurent des vecteurs, mais il est trop tard. Trop tard. Désolé.

Hankode

J’ai longtemps trainé autour d’une solution, passant par des modules hasardeux et des manoeuvres try {} et aujourd’hui j’en arrive à ce point pour négocier les encodages variés, car même si l’UTF-8 est maintenant dominant, le notepad.exe n’enregistre toujours pas par défaut ainsi.

C’est presque un haïku:

open(T,'<','Any.txt') or die($!);
binmode(T);
$l = <T>;
close(T);
if(length($l) == length(decode('utf-8',$l))) {
$l = encode('utf-8',$l);
}
print $l;

Le binmode ne sert à rien mais c’est pour montrer l’intention.

Enfin, avec HTML::Entities

$l = encode('utf-8',decode_entities(decode('utf-8',$l)));

My Ranker

J’adore SolR mais certaines choses sont plus compliquées à faire. Je voulais me faire un algorithme de ranking personnel basé sur la pertinence (de base) et sur une valeur numérique (karma ou date par exemple), ainsi que donner plus d’importance à certains champs. Ainsi, sur mon SolrR 8, cela se formule comme ça (je ne mets ici que les paramètres différents d’une utilisation) :

defType=edismax

&q=remix test

&sort=product($qq,karma)+desc

&qq={!edismax v="remix test" qf="title^20 description^2 author^10 "}

J’aurais aimé mettre dans qq, v=$q au lieu de répéter la requête mais j’ai l’impression que ce n’est pas valable. En tout cas mon ranking est alors bien meilleur.

Enfin, pour ce qui est mettre un bonus aux documents les plus récents, toujours en edismax, j’ajoute: &bf=sqrt(sqrt(ms(dated))). Il est pertinent d’ajuster la fonction ms avec une origine temporelle du décompte: ms(mydatefield, 2000-01-01T00:00:00Z)

Who’s in here ?

Je suis pas parano mais j’aime bien surveiller un peu ce qui se passe à l’intérieur de mon Ubuntu Desktop perso. J’ai donc mis dans mon .bashrc

if [ $(who | wc -l) -gt 1 ]; then
notify-send -t 3000 "Someone else logged in as me"
fi

Simple et pratique. J’aurais pu faire un grep pour filtrer les connexions externes uniquement mais j’aime bien comme ça. Avant je mettais directement notify-send mais cela perturbait l’Ubuntu car le .bashrc était lu avant la session graphique. Je mets aussi dans mon conky.conf une ligne pour surveiller aussi:

${font Lato:light:size=22}Who =$color ${user_number}locals ${font}

On s’amuse comme on peut.

No Return (mails)

Je gère pour un site des envois d’e-mails personnalisés en masse. J’envoyais mais, au bout d’un certain temps, j’en ai eu mare de recevoir, par exemple, les messages d’absence en retour.

Au final, j’ai ajouté à ces messages des headers qui font le job, globalement car certains serveurs me résistent de par leur implémentation.

'X-Auto-Response-Suppress:' => 'OOF, DR, RN, NRN, AutoReply'
'Auto-Submitted:' => 'auto-generated'

C’est assez élégant et fonctionnel.

Deep structure JSON

J’aime bien le JSON mais je dois avouer que quand il s’agit de traiter des structures plus profondes (au delà des tables et des listes, et surtout les cas où la profondeur est variable (exemple: JORF), je suis assez démuni alors que je n’ai pas du tout ce problème avec du XML où il est facile de naviguer entre enfants et parents, etc.

J’avais fais des essais avec JSON::XPath et autres mais la syntaxe me dépasse car j’y vois des tonnes de confusions avec le XPath du XML (notamment à propos de la notion de. parent). Plutôt que de me prendre la tête , je me suis mis à chercher un convertisseur JSON vers XML.

Trouvé ici : https://stackoverflow.com/questions/17398601/how-to-create-xml-from-json-string-in-perl

use JSON::Any;
use XML::Simple;

my $convertor = JSON::Any->new();
my $data = $convertor->decode($json);
my $xml = XMLout($data);

J’adore!