a3nm's blog

plint -- a French poetry validator

— updated

English version

Version française ci-dessous.

I'm constantly annoyed by French poetry which sort-of rhymes but does not respect metric constraints (and don't get me started on rhyme genres), so I wrote a tool to validate French poetry against metric, rhyme and rhyme genre constraints, which is called plint for lack of a better name.

The code is available so you can run it on your server (or use a CLI or an experimental IRC interface). It uses haspirater as well as a small tool to infer the end phonemes of a word called frhyme (and itself based on Lexique.

Of course, formal constraints are not the only important thing in poetry and you're welcome to deviate from them if you do so willingly. This tool is mostly designed for people who think they're following the rules.

Version française

English version above.

Je suis souvent confronté à de la poésie qui rime plus ou moins mais qui ne respecte aucune contrainte métrique (et ne parlons pas des rimes féminines et masculines), donc j'ai écrit un outil pour vérifier automatiquement les poèmes (pour la métrique, la rime et le genre des rimes). Il s'appelle plint.

Le code est disponible, donc vous pouvez le faire tourner sur votre propre serveur, ou utiliser une interface en ligne de commande ou une interface IRC expérimentale. Il utilise haspirater ainsi qu'un petit outil pour inférer les quelques derniers phonèmes d'un vers qui s'appelle frhyme (utilisant lui-même Lexique).

Bien sûr, la poésie, ce n'est pas que le respect des contraintes formelles, et il peut être raisonnable de s'en écarter à condition de le faire délibérément. Cet outil s'adresse surtout aux gens qui pensent suivre les règles classiques.

RATP, informatique et libertés

— updated

Summary in English

This post isn't of much interest unless you live in France, so I'll write it in French. The gist is that a French law allows you to ask for a copy of the personal data that a company has about you, that I contacted the Paris public transporation agency to request mine, and that I got an actual reply.

L'histoire, en français

Dans les tramways et bus RATP, on peut observer une affiche se terminant par les paragraphes suivants :

Différents sujets évoqués sur cette affiche font l'objet d'un traitement automatisé. (Conformément à la loi 78-17 du 6 janvier 1978 relative à l'informatique, aux fichiers et aux libertés, toute personne peut obtenir communication des données à caractère personnel la concernant et, le cas échéant, exercer son droit de rectification).

Le droit d'accès peut s'exercer auprès du correspondant Informatique et Libertés de la RATP, soit par courrier électronique à cil-ratpNOSPAM@ratp.net, soit par correspondance à l'adresse suivante : RATP - Service de la Direction Générale LAC JV27 - 13, rue Jules Vallès - 75547 Paris

Toute demande doit être accompagnée d'une copie d'une pièce d'identité.

Cette mention légale est fréquente, mais la possibilité d'exercer le droit d'accès par courriel l'est moins. Aussi, curieux de savoir si ça fonctionnait vraiment, j'ai envoyé à tout hasard à l'adresse susmentionnée, le soir du vendredi 27 janvier, le courriel suivant, auquel était joint un scan de mon passeport :

Sujet: Accès aux données à caractère personnel Imagin'R xxxxxxxx

Bonjour,

En application de la loi 78-17 du 6 janvier 1978 relative à l'informatique, aux
fichiers et aux libertés, je souhaiterais exercer mon droit d'accès aux données
à caractère personnel me concernant. En conséquence, je vous prie de me
transmettre une copie de toutes les informations personnelles enregistrées pour
ma carte Imagin'R numéro xxxxxxxx (notamment le relevé des validations
effectuées). Une copie de pièce d'identité est jointe à ce message.

Bien cordialement,

-- 
Antoine Amarilli

J'ai eu la surprise de recevoir, le 30 janvier, une réponse de la RATP :

Pour répondre à votre demande, je vous transmets ci-joints :

- la fiche client des informations de votre passe NAVIGO et du contrat Imagine'R
étudiant qui lui est associé

- le cumul des validations de ce passe effectuées en entrée ou en sortie de
nos réseaux ferrés au cours de ce mois (Janvier 2012)  et du mois précédent
(Décembre 2011). Les données de cumul journalier sont conservées pendant ce
maximum de 2 mois à seule fin de vérification de la fiabilité des passes NAVIGO.
Nous ne conservons ni les heures ni les lieux de passage.

Le cumul des validations est un document PDF créé à partir de Microsoft Word. Il se borne effectivement à une indication du nombre de passages pour les dates des mois de décembre et janvier. La fiche client est un document PDF un peu plus intéressant contenant toutes sortes d'informations dont :

  • Le code Hexaclé de l'adresse postale indiquée par le client. Je ne connaissais même pas l'existence de ce code, mais il semble assez difficile d'obtenir le sien par ailleurs vu que la base de données Hexaclé n'est pas gratuite...
  • Des indications de si vous acceptez ou non la pub : "Opt-in source", "Opt-in console", "Stop pub source" et "Stop pub console", ainsi que de plus énigmatiques "Demande de non regroupement" et "Déduplication à tort".
  • Toutes sortes d'information sur vos passes : numéro de lot, numéro de version, etc.
  • Des événements concernant le rechargement de passes Navigo. L'historique remonte assez loin, mais je n'en vois qu'un par passe, donc il doit en manquer et il se pourrait que ce soit juste la création des passes.

Je reste assez surpris d'avoir effectivement obtenu ces données de la RATP. Quelques remarques en conclusion :

Peu d'informations.
La RATP ne garde (ou ne prétend garder) que peu d'informations. J'espérais obtenir le relevé des dates, heures et lieux de validation du passe Navigo sur une durée arbitrairement longue. À moins qu'on m'ait menti, je suis assez agréablement surpris de voir que la RATP prend effectivement la peine d'effacer les informations.
Exploitation régulière
Évidemment, plutôt qu'une communication ponctuelle, je préférerais que la RATP m'envoie ces informations au fur et à mesure qu'elles se construisent (pour conserver la liste de toutes mes validations de Navigo), et si possible dans un format facile à traiter (CSV, SQL...). J'ai répondu à leur message pour les interroger à ce sujet et on m'a répondu que le format PDF satisfaisait les obligations de la loi 78-17, qu'il n'était pas prévu de transmettre de manière régulière ces données, et qu'une demande tous les deux mois pourrait être considérée comme abusive du fait de son caractère répétitif (ce qui est effectivement conforme à la loi en question, article 39, paragraphe II).
Sécurité
L'authentification des demandes par la RATP s'appuie exclusivement sur la fourniture d'une copie de pièce d'identité. Il y a là confusion entre l'identification d'une personne (désigner un individu de façon non-ambiguë) et l'authentification d'une demande (garantir que c'est bien la personne concernée qui effectue la demande). Une copie de pièce d'identité, si elle n'est pas falsifiée, permet d'identifier la personne, mais ne certifie pas qu'elle a autorisé la demande : certaines personnes tierces disposent d'un scan de mon passeport et pourraient obtenir de la RATP mes informations personnelles (incluant le numéro de téléphone, l'adresse, et des informations agrégées donnant cependant une idée de ma présence ou non en région parisienne...) en se faisant passer pour moi. À mon avis, il serait déjà préférable que la RATP vérifie qu'elle transmet bien les informations à l'adresse de courriel indiquée sur la fiche client (ce qui n'a pas été fait dans mon cas, puisque j'ai effectué la demande depuis une autre adresse). J'ai adressé ces suggestions à la RATP, qui n'y a pas apporté de réponse.

htmlrebase -- relative link resolution in HTML according to a given base URL

— updated

I found this code lying around, so I'm dumping it here in case someone needs it. It takes an HTML file on standard input and a URL as a command-line argument and produces the HTML file on standard output where all relative links have been resolved according to the given base URL.

#!/usr/bin/env python

"""Resolve relative links in an HTML blob according to a base"""

from BeautifulSoup import BeautifulSoup
import sys
import urlparse

# source: http://stackoverflow.com/q/2725156/414272
# TODO: "These aren't necessarily simple URLs ..."
targets = [
    ('a', 'href'), ('applet', 'codebase'), ('area', 'href'), ('base', 'href'),
    ('blockquote', 'cite'), ('body', 'background'), ('del', 'cite'),
    ('form', 'action'), ('frame', 'longdesc'), ('frame', 'src'),
    ('head', 'profile'), ('iframe', 'longdesc'), ('iframe', 'src'),
    ('img', 'longdesc'), ('img', 'src'), ('img', 'usemap'), ('input', 'src'),
    ('input', 'usemap'), ('ins', 'cite'), ('link', 'href'),
    ('object', 'classid'), ('object', 'codebase'), ('object', 'data'),
    ('object', 'usemap'), ('q', 'cite'), ('script', 'src'), ('audio', 'src'),
    ('button', 'formaction'), ('command', 'icon'), ('embed', 'src'),
    ('html', 'manifest'), ('input', 'formaction'), ('source', 'src'),
    ('video', 'poster'), ('video', 'src'),
]

def rebase_one(base, url):
    """Rebase one url according to base"""

    parsed = urlparse.urlparse(url)
    if parsed.scheme == parsed.netloc == '':
        return urlparse.urljoin(base, url)
    else:
        return url

def rebase(base, data):
    """Rebase the HTML blob data according to base"""

    soup = BeautifulSoup(data)

    for (tag, attr) in targets:
        for link in soup.findAll(tag):
            try:
                url = link[attr]
            except KeyError:
                pass
            else:
                link[attr] = rebase_one(base, url)
    return unicode(soup)


if __name__ == '__main__':
    try:
        base = sys.argv[1]
    except IndexError:
        print >> sys.stderr, "Usage: %s BASEURL" % sys.argv[0]
        sys.exit(1)

    data = sys.stdin.read()
    print rebase(base, data)

Ambiguous verbal forms in French

— updated

This list is incomplete! You should see the new list instead! Cette liste est incomplète! Regardez plutôt la nouvelle liste!

English explanations

Added "méprise" and "méprises", thanks to Erik McDonald.

In this post, I present a list of French verbal forms which are ambiguous because they can be derived from different infinitives (always two). To determine which are those derivations (infinitive, mode, tense, person), you can use french-deconjugator from Verbiste. This (hopefully complete) list has been computed using Lexique. See also my list of non-homophonous homographs in French and my list of French words without rhymes.

Explications en français

Ajout de "méprise" et "méprises", merci à Erik McDonald.

Ce post présente une liste de formes verbales du français qui sont ambiguës car elles peuvent être dérivées de plusieurs infinitifs différents (toujours exactement deux). Pour déterminer quelles sont les dérivations possibles (infinitif, mode, temps, personne), vous pouvez utiliser french-deconjugator de Verbiste. Cette liste que j'espère exhaustive a été calculée avec Lexique. Voir aussi ma liste d'homographes non-homophones en français (en anglais) et ma liste de mots français sans rimes.

The list / la liste

Random notes on the Hercules eCafe EX

— updated

I happened to stumble upon an interesting offer for the Hercules eCafe EX (163 EUR including shipping fees), and I couldn't resist and bought one. (I have to admit that I did hesitate with "ordinary" netbooks which offer more decent performance for only 40 EUR more, but I was tempted by the exoticism of an ARM architecture.)

Looking back at this, the most important point about the machine is: a strange glitch means that a few keypresses are lost every 30 seconds or so. This doesn't sound like much, but it's enough to make typing on the device very annoying, which means I've never used it seriously for anything; it's really a pity, because the device could conceivably be useful for a lot of things otherwise (though the impossibility of running a Web browser is a bit limiting, and the fact that you're stuck with a fork of the kernel at a specific version, and to certain binary variants of software to get hardware video acceleration, is a problem for sustainability). I've tried out several ways to investigate the problem, including recompiling the kernel with additional debug, disabling all USB power saving options, etc.; nothing shows up in dmesg whenever the keypresses start getting ignored... A possibility would be to replace the built-in keyboard with an USB one, but this would not be trivial. I'm a bit out of ideas with this machine, really.

The eCafe looks more or less like an ordinary netbook on the outside (though the design is a bit weird), but it pretty different inside because it uses an ARM processor (and a flash chip for storage). This means no mechanical parts at all (and no ventilation, no heat vents even) and ridiculously high battery life (roughly over 12 hours, though I should really benchmark it) but ridiculously bad performance.

The documentation available about the device online is sparse and there aren't that many people using it, so I thought I'd post some random notes about it in case someone wants to know more about the beast. I'm still discovering the thing, so there are many questions here and not many answers, but here you go.

Non-removable battery
There is no way to remove or change the battery. There is, however, a switch to physically disconnect the battery from the device if you don't want to use it.
SIM port
There is a port to plug a SIM card. I have no idea what it's supposed to be used for, or if it's connected to anything.
SD-card reader
Yes, the thing really has two sd-card readers: one external on the right side, and one internal reachable from under the device.
DIP switch
The device is advertised as having a "DIP switch" to boot a different operating system. You can find more info about that in this PDF. What the switch does is instruct the computer to search for an U-Boot installation at a specific position on an SD-card in the external reader. Might be fun.
BIOS
The device has no proper BIOS, it uses U-Boot. I'm not exactly sure how good this is: the boot is not especially fast, and the U-Boot part seems to take some time (though it's hard to tell because of all the nice annoying splash screens which hide what is really going on). From the PDF mentioned above, it seems as if U-Boot is requesting a DHCP lease to do a TFTP boot, which might take a lot of time, but this is just a guess. I'd have to try with my own U-Boot setup.
ACPI
The device has no real ACPI support but seems to use custom stuff instead. The battery status can be queried through /sys/devices/platform/imx-i2c.0/i2c-0/0-000b/power_supply/BAT0/
Suspend
The device has pretty good suspend to RAM with pm-suspend. Resume really takes 4 seconds, as advertised. The stability of this is unclear.
Light sensor
The device seems to have a light sensor. I don't know yet how you can query it.
Backlight
The backlight brightness can be controlled via /sys/devices/platform/pwm-backlight.0/backlight/pwm-backlight.0/, all the way from full power to no LCD backlighting.
Special keys
There are a few special keys, which all generate X events. On the keyboard: XF86Sleep, XF86MonBrightnessUp, XF86MonBrightnessDown, XF86AudioMute, XF86AudioLowerVolume, XF86AudioRaiseVolume, and keycode 248. On the right side with LED effects: XF68AudioPrev, XF86AudioNext, XF86AudioPlay, XF86AudioStop. It's nice that you can remap those to whatever you want, especially the four on the right side that can be reached even when the lid is closed. I still have to find a creative use for this.
Numlock and Capslock leds
Yes, there are some, which is pretty rare nowadays.
Keyboard feel
The keyboard feel is slightly hard but pretty nice. However, there is a really annoying glitch: some keypresses seem to be lost occasionally. I still have to debug this. It occurs both in ttys and when using X, so either it's the kernel or it's a hardware problem.
Wifi chip
It is driven with the non-standard rt3070 module. It seems related to similar models with good kernel support, but I'm not really sure. It seems pretty limited: for instance, changing the MAC address (SIOCSIFHWADDR) is not supported. Once again, hopefully there's a way to make this work.
Kernel limitations
The provided kernel isn't compiled with much stuff. For instance, LUKS, iodine and openvpn don't work.
Performance
Performance is horrendously bad. /proc/cpuinfo says the processor is an "ARMv7 Processor rev 5 (v7l)". Using Firefox on a reasonably simple HTML page is already pretty unpleasant. However, it's a nice ssh client (or text-entry station), except for the keyboard glitch.
Shipped OS
The shipped OS is a customized Ubuntu with a crappy netbook interface and custom repositories from Hercules without much stuff inside. The interface is probably simple enough to be used by anyone (except that it's so slow...) but it' not really good for a power user. It is possible to add the Ubuntu Netbook Remix Lucid Lynx repos and install the applications you want, though installing their kernel will not work.
Multimedia acceleration
Hardware acceleration for multimedia decoding is available though a proprietary modified version of gstreamer. It really makes a difference, ie. you can read a video with these extensions but not without. I'm not sure yet about how versatile this can be.
Toolchain
There is some documentation and code available though I didn't try to play with it yet. I did; you can rebuild the bootloader and kernel (it isn't entirely straightforward), but you're stuck with the provided kernel version, which includes some changes that would apparently not be trivial to port to a newer kernel...
Available memory
The machine is supposed to have 512 MB of RAM, but /proc/meminfo only reports 416680 kB MemTotal. Maybe this memory is reserved for something (video acceleration?), or maybe the kernel doesn't detect it correctly? or maybe the hardware just doesn't match the spec?