curl cert apache2 2.2

Grand fan de l’initiative letsencrypt (https://letsencrypt.org/) dont parle souvent l’EFF (https://www.eff.org/) (je suis membre), j’ai eu des problèmes avec la vérification des certificats générés par ce service sur un serveur avec une installation un peu ancienne. curl et LWP me refusaient en raison de problèmes de certificats.
https://community.letsencrypt.org/t/certificate-verification-errors-when-using-curl/105335 a attiré mon attention sur le fait qu’il me manquait la ligne, à priori propre à apache 2,2 suivante, à adapter au bon domaine, dans ma config apache:
SSLCertificateChainFile /etc/letsencrypt/live/privatestash.org/chain.pem


Une fois en place, plus besoin de bypass de la vérification des certificats dans LWP (use IO::Socket::SSL; $ua->ssl_opts( SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, verify_hostname =>0);) et plus besoin des mêmes options dans curl (-k), ce qui est bien plus satisfaisant.

Le truc bizarre est que les browsers ne pâtissaient pas de ce point.


curl cert apache2 2.2

Samesite cookies & rails & clueless monkey patch

Une vieille application Ruby on Rails 3. C’était par tourisme de dev et j’aime bien, malgré les particularités de ruby (typage et scope) . Des browsers qui commencent à se plaindre du mauvais voir du manque d’attribut same site sur les cookies (dans mon cas des cookies de session).

https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Set-Cookie/SameSite

Je commence par bien flipper. Entre toutes les versions de rails, des heures de recherche, j’étais presque résolu à monkey-patcher les libraires mais, étant bien incapable de localiser où frapper, je commençais à désespérer.

Le site étant service par un apache2 sous mod_passenger, la lumière la plus évidente m’est enfin apparue. J’installe et j’active le mod headers d’apache2 puis je rajoute ce segment dans la section qui vas bien de la config apache du site en question:

<ifmodule mod_headers.c>
Header always edit Set-Cookie (.*) "$1; SameSite=strict"
</ifmodule> 

Je redémarre mon apache et mon firefox ne se plaint plus. Magique !!


Samesite cookies & rails & clueless monkey patch

NoUTF8MB4

Dans un job d’indexation de données externes, essentiellement RSS mais aussi tweets (cf poste précédent), je me suis retrouvé bien en difficulté d’encodage, collation et stockage dans une base de contenus avec des emojis. J’avais pourtant passé la table d’utf8 à utf8mb4 mais cela ne marchait pas (peut-être un bug dans DBI mais je pense pas car j’ai déjà réussi ailleurs). Après pas mal de recherches, j’ai eu l’idée de ce patch qui a pour objet de garder les emojis sous forme d’entités hautes tout en conservant le texte en bas (les entitiés nommées) de l’unicode en direct.

$s = encode_entities($s);
(@entits) = $s =~ /(&.*?;)/g;
foreach $entit (@entits) {
  $deco = encode('utf-8',decode_entities($entit));
  $s =~ s/$entit/$deco/g unless($entit =~ /&#x/);
}

Plus qu’à décoder pour injection dans solR, ou conserver tel quel lors de l’inclusion dans le HTML. Petit hack qui évite bien des tracas.


NoUTF8MB4

twittRSS.cgi

J’en avais besoin, voici mon script qui utilise l’API Twitter pour générer des flux RSS. Assez simple, le plus chiant est sans doute d’obtenir les credentials et le token. Le plus long (mais simple) est d’installer le module Net::Twitter depuis le CPAN.

#!/usr/bin/perl

use CGI;
use XML::RSS;
use Net::Twitter;
use HTML::Entities;
my $twt = Net::Twitter->new(
  traits => [qw/API::RESTv1_1/],
  consumer_key => VOTRE_CLEF_DEVELOPPEUR,
  consumer_secret => VOTRE_MOT_DE_PASSE_DEVELOPPEUR,
  access_token => TOKEN_APPLICATION,
  access_token_secret => MOT_DE_PASSE_DU_TOKEN
);
$cgi = new CGI();
if ($login = $cgi->param('login')) {
  eval {
    my $statuses = $twt->user_timeline({ count => 64, screen_name => $login });
    $rss = XML::RSS->new (version => '2.0');
    $rss->channel(
      title => "Tweets de $login",
      link => "https://twitter.com/$login");
    foreach $status (@$statuses) {
      $rss->add_item(
        title => decode_entities($status->{text}),
        link => "https://twitter.com/$login/status/".$status->{id};
    }
  };
  if($@) {
    print "Content-type: text/plain\n\nProblem because: $@\n";
  } else {
    print "Content-type: application/rss+xml\n\n".$rss->as_string;
  }
} else {
  print "Content-type: text/plain\n\nWho can you trust ?";
}

A vos quotas, prêts, partez !


twittRSS.cgi

Perl Image::ExifTool

Je le mets ici car j’ai un peu trimé pour trouver les infos nécessaires.

ExifTool marche parfaitement mais ne pas oublier d’aller voir sur https://metacpan.org/pod/Image::ExifTool#DESCRIPTION que le type d’accès qu’offre le module en fonction du type fichier que vous visez (par example MP3 en lecture, PDF en compl<et).

#!/usr/bin/perl
use Image::ExifTool;
$exifTool = new Image::ExifTool;
$exifTool->ExtractInfo($ARGV[0]);
if ($ARGV[2]) {
$val = $exifTool->GetValue($ARGV[1],'ValueConv');
if (ref $val eq 'ARRAY') {
@values = split(/,\s*/g,$ARGV[2]);
$exifTool->SetNewValue($ARGV[1] => \@values, { Replace=>1, AddValue => 2 });
} else {
$exifTool->SetNewValue($ARGV[1],[$ARGV[2]]);
}
$exifTool->WriteInfo($ARGV[0]);
}
$exifTool->ExtractInfo($ARGV[0]);
foreach $tag (grep { !($_ =~ /\s(1)$/) } sort $exifTool->GetFoundTags()) {
$tt = $tag;
$tt .= ' (1)' if (grep { $_ eq $tt.' (1)'} $exifTool->GetFoundTags());
printf("%-21s : %s\n",$tag,$exifTool->GetValue($tt));
}

Notes: https://exiftool.org/ExifTool.html


Perl Image::ExifTool

Regex Article

Ici

$ra = ‘\s*(?:(([Aa][Nn][Nn][Ee][Xx][Ee]\s[A-Za-z0-9]+)?|([Tt][Aa][Bb][Ll][Ee][Aa][Uu]\s*[Nn]?°?\s?[A-Z0-9]*\s?)?)|\*?[LRDAO]*\.?\s?\**\.?\s?\d+(\-\d+)*\-?\s?[A-Z]*)(\s?(?:tricies|bis|ter|quater|quinquies|sexies|septies|octies|nonies|unvicies|quinquies|novovicies|tertricies|terdecies|duotricies|untrecies|quatertricies|decies|undecies|duodecies|terdecies|quaterdecies|quindecies|sexdecies|septdecies|octodecies|novodecies|vicies|unvecies|duovicies|tervecies|quatervicies|quinvicies|sexvicies|septvicies|octovicies|tervicies)?\s?[A-Z0-9\-]*\s?(?:bis|ter|quater|quinquies|sexies|septies)?\s?[A-Z0-9\-]*\-?\d?)?’;

Taux de réussite: 99.61 % au jour d’aujourd’hui

Bilan: 140.804 articles qui correspondent sur un total de 141.504

.

On examine ensuite la liste des matchs par ordre de longueur décroissante, on évalue au besoin la distance entre chaque match et le nom du code, et on confronte alors les résultats avec des tables de correspondances numéro:identifiant legifrance, …


Regex Article

Big Code ?

Je crois que j’en ai eu assez d’entendre des politiques et autres commentateurs dire que le code du travail trop gros et que sa modification est urgente. Au delà des arguments politiques, j’aimerais mettre quelques chiffres ici, suite à mon expérience sur ces données (http://codes.droit.org) et bientôt une application iOS et des web-services.

Si je regarde le poids des PDFs que je génère pour chaque codes (droit positif + articles liés), je constate que les plus lourds sont :

  • sante_publique.pdf (35412646)
  • rural_peche_maritime.pdf (30630860)
  • securite_sociale.pdf (30238979)
  • travail.pdf (28924689)
  • impots.pdf (23586049)

En nombre d’articles, c’est différent:

  • sante_publique (11845)
  • travail (1123)
  • rural_peche_maritime (9413)
  • securite_sociale (7538)
  • commerce (6679)

Enfin, si on se contente d’observer le nombre de liens, on obtient:

  • sante_publique 19001
  • securite_sociale 17364
  • rural_peche_maritime 14501
  • travail 13442
  • monetaire_financier 11899

Bref, le code du travail n’est ni le plus lourd, ni le plus long.

Je vous épargne mes commentaires politiques.

Big Code ?

Waveform

Il n’échappera à personne que je fais par ailleurs de la musique et que je la publie sur un de mes sites (http://habett.net). Pour avoir par ailleurs mis de la musique sur soundcloud j’observe que les formes d’ondes sont bien utiles pour comprendre et apprécier la structure du morceau. Reste que les waveforms de soundcloud sont extrêmement peu parlantes. J’ignore leur algorithme mais il est vraiment lénifiant et donne un résultat tellement peu expressif que je me suis très rapidement dit que je pouvais faire beaucoup mieux.

L’outil pour y procédé vas être un script bash avec quelques dépendances : sox, gnuplot et imagemagick. Le paramètre est le nom du fichier .wav à traiter sans son extension. Vous pouvez observer que je fais en fait deux waveforms que je combine à la fin dans  un composite, pour obtenir un représentation différentielles des fréquences utilisées par la musique en question, waveform plus sombre pour les basses et claire pour les aigus dominants.

#!/bin/sh

WAV=${1%.wav}
sox "$WAV" /tmp/test.wav lowpass 500

sox /tmp/test.wav --rate 1k /tmp/test.dat

rm /tmp/test.wav

grep -v '^;' /tmp/test.dat >/tmp/test.clean

perl -pe 's/.*/0 1 1\n0.0001 -1 -1/ if $. == 1' /tmp/test.clean > /tmp/test.norm

rm /tmp/test.dat

rm /tmp/test.clean

CMD="set terminal png transparent size 6400,1600; set noxtics;set tmarg 0;set bmarg 0;set lmarg 0;set rmarg 0;set noytics; set noborder;set nogrid;set nokey;set output '/tmp/test.png';plot '/tmp/test.norm' with impulses notitle lt -1"

 echo $CMD | gnuplot

rm /tmp/test.norm

convert /tmp/test.png -scale 1600x400 "$1.low.png"

rm /tmp/test.png

sox "$WAV" /tmp/test.wav highpass 300

sox /tmp/test.wav --rate 1k /tmp/test.dat

rm /tmp/test.wav

grep -v '^;' /tmp/test.dat >/tmp/test.clean

perl -pe 's/.*/0 1 1\n0.0001 -1 -1/ if $. == 1' /tmp/test.clean > /tmp/test.norm

rm /tmp/test.dat

rm /tmp/test.clean

echo $CMD | gnuplot

rm /tmp/test.norm

convert /tmp/test.png -negate -scale 1600x400 "$1.high.png"

rm /tmp/test.png

composite -compose difference "$1.low.png" "$1.high.png" "$1.png"

rm "$1.low.png"

rm "$1.high.png"

 

Waveform