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

Open Game

J’étais à une conférence où il était question entre autre d’Open Access et Démocratie.

J’ai été marqué par plusieurs choses. Par exemple dans l’opposition vis à vis des éditeurs privés (concentrations, prix abusif, opacité, …) plusieurs personnes semblaient rêver d’interventions de l’Etat afin de garantir un accès démocratique. Plusieurs fois l’intervention du secteur public semble vécue comme la panacée. Sur le fond je trouve aussi que sur de telles questions l’intervention de l’Etat est plus que légitime et pourrait aller encore plus loin de par ses prérogatives. Reste que vu l’évolution du paysage politique, je ne pense malheureusement pas que l’intervention de l’Etat soit l’ultime remède car certains prétendants au pouvoir (et pas les plus mal placés (( entretiennent apparemment de gros fantasmes de privatisations.

Le rempart cela semble être la publication de code open source permettant de traiter les données. Si tel service est privatisé ou absorbé par un méchant éditeur du secteur privé, au moins on sauve l’infrastructure logicielle de traitement. Ce raisonnement doit être modéré par les interrogations sur l’Open Source au sens logiciel. Pour ma part je relis très très rarement le code d’autres personnes. Peut-être suis-je une loup des steppes/circuits mais je vois rarement mes confrères proches évoquer ce  type d’activité non productrice à court terme.

Vu de l’extérieur code is code, il sera relu et tout ira bien.

Mon point principal, en tant que programmeur en perl, javascript, xml et/ou swift, c’est que le langage dans lequel sont développés ces projets est un enjeu majeur. Il suffit de peu d’observations pour se rendre compte que le public qui s’exprime en assembleur, C++, python ou dotnet sont très différents. Il y a une part d’idéologie sous-jacent, un constat générationnel et sociologique. C’est pourtant bien occulté au grand public. Pour un certain nombre de personnes plus proches du milieu vas vous tenir le raisonnement que pour tel type de job il n’y a pas à tergiverser quand au choix de l’outil qui doit s’imposer par lui même. Je n’y crois pas. Comme on dit souvent entre perlistes, « there’s more than one way to do it ».

J’y crois d’autant moins que j’ai connu professionnellement des cas où la décision du choix du langage incombe à la hiérarchie non technique. Je suis pour le pluralisme, je pratique certains langages mais j’en ignore bien d’autres. Je n’ai pas envie d’imposer mes choix, au mieux convaincre, et encore. J’aurai pu apprendre php il y a quelques années mais cela me révulse, j’aurai pu me mettre au python mais je trouve le code inélégant, et je suis trop jeune pour avoir un background en assembleur. Paysage d’autant plus compliqué avec l’explosion du nombre de librairies et fameworks, il y en a pour tous les goûts.

Code is not code. Ce n’est pas un tour de babel mais une ville avec ses quartiers et ses ghettos, sa politique et sa sociologie.

Open Game