dadadi blog

To content | To menu | To search

Thursday, July 1 2010

simplebox: a lightbox-like library for prototype

Still as part of my next project, and still wanting to move reusable code into autonomous projects, I wrote simplebox, a lightbox-like library: a javascript library to display modal elements in a web page.

There already exist a lot of modal javascript libraries, but I was looking for one that:

  1. worked with prototype
  2. does not need script.aculo.us
  3. works for random html content (not only images)
  4. was opensource

So, I wrote my own. You can see a basic example or check code at github.

Thursday, June 3 2010

conversion hexadécimal vers décimal en php

L'autre jour, j'avais besoin en php de vérifier qu'une valeur était bien un nombre hexadécimal, puis de le convertir en décimal. Pour convertir un hexadécimal en décimal, on peut utiliser la fonction hexdec. Mais, comme spécifié, elle ignorera tout caractère non-hexadécimal qu'elle rencontrera. Du coup, la chaîne 0xAMB est considérée comme 0xAB, et on ne peut pas savoir, avec hexdec, si la chaîne convertie est valide.

Pour réaliser cette validation, il y a, depuis la version 5.2 de php[1] , la fonction filter_var. Elle filtre une variable avec un filtre spécifique. En l'occurence, on peut utiliser le filtre FILTER_VALIDATE_INT avec le drapeau FILTER_FLAG_ALLOW_HEX. L'instruction suivante:

filter_var($input, FILTER_VALIDATE_INT, array( 'flags'   => FILTER_FLAG_ALLOW_HEX))

renverra false si la chaîne d'entrée n'était pas valide, ou bien, l'entier converti si elle était valide.

La fonction filter_var est très souple : elle permet d'utiliser un grand nombre de filtres. On peut par exemple tester si une chaîne est une adresse ip, une url, ou bien même une adresse email valide. Ainsi, l'instruction suivante :

filter_var($input, FILTER_VALIDATE_EMAIL);

permet de valider une adresse email. Pour les curieux, l'adresse est validée suivant une expression rationnelle inspirée de celle utilisée par HTML_QuickForm.

Notes

[1] Pour les versions antérieures, il semble qu'il existe une extension PECL

Thursday, May 27 2010

gisconverter.php: a kml <-> geojson <-> wkt converter

For my next personal project, I need to convert in php, geographic data between different formats. I need that, among other things to insert those data in postgis. Actually, postgis support a lot of data format as output formats, but quite few as input formats.

Instead of of integrating that to my main project, I decided to create a related autonomous project. So, I had to implement more features than strictly needed. But I think it's more profitable in the middle and long run.

  • This library is separated from my application. So it's more easy to test, debug and extend.
  • That allow other people to reuse it in their application more easily.
  • That allow me to reuse it in my future application with zero reintegration work.

So, here is gisconverter.php

gisconverter.php only work with php 5.3 (and probably higher). php 5.3 has a few nice new features. So, I decided to not care about backward compatibility. I use namespaces so I can include it in my project without having to care about name conflict. I also use late static binding. It allow to use class constants. Prior to php 5.3, it was not possible to use class constants in derived classes. I also use closure quite a lot (along with array_map). It saved me a couple of lines of code, but I could easily have done without.

I also used phpunit to test the library. It allowed me have a really efficient workflow. I first write the tests, then I implement a method, and when all tests pass, I known my method is bug free. The tricky part is to write the tests correctly, to test the code thoroughly without being redundant. Now, I'd like to use phpunit in my main application. It's is a full website with a database, so I've not yet understood how to use it.

Monday, May 17 2010

nouvelle version mineure de prvcat

prvcat, est un plugin dotclear pour avoir des catégories privées. Une nouvelle version vient de sortir. Elle ajoute un champ de confirmation de mot de passe lors de l'enregistrement des catégories privées. Cela permettra d'éviter de se tromper en rentrant le mot de passe.

Si vous avez des remarques ou des suggestions à propos de ce plugin, n'hésitez pas à me laisser m'en faire part dans les commentaires de ce blog, ou par email.

Sunday, May 16 2010

configuration d'une imprimante pixma 610 en réseau.

Nous avons plusieurs ordinateurs sous Ubuntu ou Debian, ainsi qu'un serveur également sous Debian. Nous avons une imprimante/scanner pixma 610, qui était reliée à un des ordinateurs. Nous avons décidé de brancher l'imprimante sur le serveur, et de le configurer en serveur d'impression afin de pouvoir imprimer depuis tous les ordinateurs.

La manipulation, sans être extrêmement complexe, n'est pas triviale. Je la pose donc par écrit, tout d'abord pour m'en souvenir si je dois un jour la refaire, d'autre part, parcequ'elle pourrait être utile à d'autres personne.

configuration de l'imprimante

Installation des drivers sur le serveur

La première étape consiste à branche l'imprimante sur le serveur, et à installer les drivers afin qu'elle soit reconnue par le serveur. Pour cela, il faut se rendre sur le site autrichien de canon. En effet, il semble, d'après plusieurs commentaires lus sur les forums ubuntu que ce soit le seul endroit où tous les paquets nécessaires soient disponibles. On trouve alors la page de téléchargement des drivers. Il faut prendre les 4 paquets: scangearmp-common, scangearmp-mp610series, cnijfilter-common et cnijfilter-mp610series. Par chance, il existe des paquets Debian. Mais malheureusement, à cause de quelques utilitaires, ils dépendent de librairies graphiques que je ne souhaitais pas installer sur mon serveur (libxi6, libxext6, gtk, pango, cairo, etc).

Sous debian, il est possible d'installer un paquet sans tenir compte des dépendances avec l'option --force-depends de dpkg, mais cette solution n'est pas pérenne car apt proposera ensuite systématiquement la désinstallation de ces paquets. Il est également possible, grâce à equivs, de faire croire au système qu'une librairie est installée, sans que ce ne soit le cas. Je ne souhaitais pas non plus utiliser cette solution, car si plus tard, je veux installer un paquet qui dépende d'une de ces librairies, le paquet s'installerait correctement sans me prévenir qu'il y a un problème. J'ai donc extrait les paquets avec dpkg -x et dpkg -e. Puis j'ai édité les fichiers DEBIAN/control pour supprimer les dépendances aux librairies graphiques, et pour finir j'ai reconstruit les paquets avec dpkg -b. Cette étape n'est pas obligatoire, il est possible, pour plus de simplicité, d'installer toutes les dépendances demandées par les paquets des drivers, mais je préférais la réaliser afin de garder mon serveur un peu plus propre.

J'ai ensuite installé les fichiers ppd destinés à améliorer la qualité d'impression sous linux. Une fois téléchargée l'archive, l'installation est simple et bien documentée dans le fichier README. Je n'ai pas testé l'imprimante avant l'installation de ces fichiers; je ne sais donc pas dans quelle mesure ils améliorent l'impression.

Installation et configuration de cups

Il faut maintenant installer le paquet cups sur le serveur. Il faut ensuite modifier la directive Listen du fichier /etc/cups/cupsd.conf afin de rendre accessible cups depuis l'extérieur. La directive correspondant à ma configuration était:

Listen 192.168.1.2:631

192.168.1.2 est l'adresse du serveur sur le réseau local. 631 est le port par défaut d'ipp. J'ai également du modifier le firewall du serveur pour laisser passer le trafic venant du réseau local sur le port 631.

J'ai ensuite défini les droits d'accès et d'administration au serveur. J'ai laissé l'accès normal sans authentification à partir du réseau local. J'ai mis en place l'authentification pour la partie administration. Il y a deux possibilités: soit laisser l'accès à des utilisateurs qui ont un compte unix sur le serveur, soit recourir à des utilisateurs virtuels. J'ai choisi cette dernière solution. J'ai donc installé le paquet cups-client pour pouvoir utiliser la commande lppasswd qui m'a permis de créer ces utilisateurs, et de leur attribuer un mot de passe.

Voici la portion de mon fichier /etc/cups/cupsd.conf qui définit les droits d'accès:


DefaultAuthType BasicDigest

<location>
Order allow,deny
Allow From 127.0.0.1
Allow From @LOCAL
</location>

<location /admin>
AuthType Default
Require valid-user
Order allow,deny
Allow From 127.0.0.1
Allow From @LOCAL
</location>
<location /admin/conf>
AuthType Default
Require valid-user
Order allow,deny
Allow From 127.0.0.1
Allow From @LOCAL
</location>

Maintenant que cups est installé, il faut configurer l'imprimante. J'ai ouvert un navigateur à l'adresse http://192.168.1.2:631/, et j'ai suivi la procédure indiquée pour installer et configurer l'imprimante, il n'y avait aucune difficulté. J'ai lancé une page de test de l'impression pour vérifier que tout fonctionnait correctement.

Il est à noter que l'accès à la partie administration de cups se fait par défaut en https.

configuration des clients

Une fois cups installé, le plus dur est fait, mais il faut encore configurer les clients pour qu'ils utilisent le serveur d'impression. Il m'a fallu ajouter dans le fichier ~/.cups/client.conf, les deux lignes suivantes:

Encryption IfRequested
ServerName 192.168.1.2

Pour l'impression en console, il faut utiliser la commande lpadmin -d pour définir l'imprimante par défaut. On peut alors utiliser la commande lp sans devoir spécifier l'imprimante à chaque fois. Il est également recommandé d'installer le paquet cups-bsd afin de disposer des commandes lpr, lpq, lprm, etc.

configuration du scanner

L'imprimante étant multifonctions, j'ai aussi configuré le scanner. J'ai installé le paquet sane-utils sur le serveur. Le démon saned peut être lancé soit en permanence, soit par inetd (comportement par défaut). Comme je voulais qu'il soit lancé en permanence, j'ai du lancer dpkg-reconfigure sane-utils pour demander ce comportement.

J'ai ensuite édité le fichier /etc/sane.d/saned.conf pour y ajouter la ligne 192.168.1.0/24 afin que saned réponde aux requêtes venant du réseau local. J'ai également dû charger le module nf_conntrack_sane, puis modifier le firewall du serveur pour laisser passer le trafic venant du réseau local sur le port 6566.

Enfin, sur les postes clients, j'ai modifié les fichiers /etc/sane.d/net.conf pour qu'ils contiennent la ligne suivante: 192.168.1.2 (l'adresse du serveur).

L'imprimante/scanner est enfin configurée pour être utilisée en réseau.

conclusion

Je suis assez content d'avoir réalisé cette opération. Auparavant, pour imprimer un fichier, je devais le mettre sur clé usb puis aller l'ouvrir sur l'ordinateur connecté à l'imprimante, ça va être beaucoup plus pratique maintenant.

Cela dit, j'ai trouvé l'installation des drivers laborieuse. Le fait de devoir se rendre sur le site autrichien pour trouver les bons fichiers est complètement ubuesque. Heureusement que j'ai trouvé cette information par hasard sur les forums ubuntu. D'autre part, j'aurais aimé que les utilitaires de canon soient dans des paquets à part, cela m'aurait évité de devoir extraire puis reconstruire les paquets. Je ne sais d'ailleurs pas à quoi servent ces outils, l'impression fonctionne sans que je n'ai eu à les utiliser. Enfin, les paquets ne sont disponibles que pour une architecture 32bits. Si mon serveur avait été en 64bits, l'opération aurait été encore plus compliquée.

Thursday, May 6 2010

OpenLayers class to draw and modify a path

To display a map on a webpage, you can often use directly the api of a commercial provider (such as cloudmade Web Maps Lite or google maps api). The other solution is to use OpenLayers, a free javascript library to display embed maps in a web document.

With OpenLayers, it's quite easy to draw a path on the map. But unfortunately, once a point has been added to the path, it's not possible to modify or delete it. This is possible with web maps lite, as can be seen in this distance calculator. I really like the ergonomy of the web maps lite path creator, and wanted to have something similar for OpenLayers.

So, I wrote ModifiablePath, a class to improve OpenLayers path creator. So, when creating a path with this handler, you can move, delete or even add new points. I've put a demo online, and code is available at github.

Thursday, April 29 2010

prvcat: des catégories privées pour dotclear

Pour un blog dotclear (pas celui-là, un autre), j'avais besoin de restreindre l'accès à certains billets. Dotclear propose cette fonctionnalité: il est possible de définir un mot de passe sur un billet. Néanmoins, c'est d'une part assez contraignant de rentrer le mot de passe pour chaque billet. D'autre part, le billet n'apparaît nulle part, il faut récupérer son url dans l'interface d'administration pour y avoir accès, et fournir les urls une à une aux personnes à qui l'on souhaite donner accès aux billets privés. Il existe aussi Mode privé, un plugin qui permet de rendre le blog complètement privé. Ce n'était pas non plus ce que je cherchais.

J'ai donc fini par écrire un plugin qui correspondait à mes attentes. Je vous présente donc prvcat, un plugin dotclear qui gère les catégories privées. On peut définir une (ou plusieurs) catégorie comme privée, et lui associer un mot de passe. Les billets appartenant à cette catégorie seront automatiquement protégés par le mot de passe. Les catégories privées sont listées sur la page d'accueil du blog, mais on ne peut accèder à leur contenu qu'après avoir renseigné le bon mot de passe. On a alors accès aux billets privés, ainsi qu'au flux rss de la catégorie.

Saturday, April 17 2010

New release for Show Your Places.

Today is time for a new Show Your Places release. Version 0.4 is now available.

SYP is a CMS to manage photos or pictures and displaying them on a map. It's slightly similar to what you get when showing photos with google maps, but it suits my needs more. First, I host my photos and my application myself, so (as long as I backup), it's more durable. Then, I don't have to adhere to painful google maps terms of use. That's actually the main reason I had to write syp: I wanted to show some photos on a map, and wanted my site to be private (password protected). It's not allowed to do that will google maps, so I had to find an alternative, and eventually wrote my own CMS. And also, it uses openstreetmap to display the map.

I hadn't worked on syp for 6 months, so it was time to move this project forward again. Yesterday, I added support for postgresql as a database backend. There was also some old committed but not released modifications. So now, syp is less a pain when you have many photos in same area. You can refer to changelog for more information.

As usual, you can get syp from syp main page, you can browse git repository, or you can try the demo or admin interface demo (login: admin; password: toto). Enjoy!

Thursday, April 1 2010

CSS History Hack corrigé

Grâce au (à cause du) sélecteur css visited, il est possible d'appliquer une propriété différente à un lien html qui a été visité. Cela peut donner une indication visuelle très intéressante lorsque par exemple les liens déjà visités sont d'une couleur différente. Par contre, cela donne aux sites webs, un moyen de connaître la liste des sites que l'utilisateur a visités, ou au moins de savoir lesquels il a visité parmi une liste d'adresses.

En javascript, la méthode getComputedStyle permet de récupérer des informations sur le style réellement appliqué à un élément. Si l'auteur du site déclare que les liens visités doivent être de couleur verte ou de taille 12px qu'il affiche une liste de liens (au besoin en les cachant plus ou moins grossièrement à l'utilisateur), il lui suffit d'utiliser la méthode getComputedStyle pour connaître la couleur ou la taille des liens et ainsi savoir lesquels ont été visités. Il est ainsi possible de tester un grand nombre de sites très rapidement. (démo)

Il est également possible d'utiliser cette technique sans javascript. Par exemple, en utilisant la propriété css background-image qui va afficher telle ou telle image distante pour chaque adresse visitée. Il suffit au site attaquant d'interpréter les logs du serveur web pour savoir quelles images ont été affichées et donc en déduire quels sites ont été visités. (démo).

Ce problème est connu depuis longtemps, au moins 8 ans, et aucune solution n'avait été apportée. Or, le problème vient d'être résolu par Mozilla. Tout d'abord, le comportement de getComputedStyle a été modifié afin de ne plus  retourner le vrai résultat pour les liens visités. D'autre part, on ne peut plus maintenant modifier que  la couleur des liens, et pas les autres propriétés.

Cette correction sera disponible dans les prochaines version de Firefox et permettra d'améliorer la protection de l'historique des utilisateurs, au moins dans Gecko pour l'instant. Elle ne permettra malheureusement pas de le protéger complètement. Il sera toujours possible par exemple d'afficher des images de différents sites et de mesurer le temps de chargement pour essayer de deviner si elles étaient dans le cache. D'autres moyens sont également envisageables. Néanmoins, ce type d'attaque devrait être rendue plus difficile à mettre en place, ce qui est déjà un progrès important.

vteplugin: improve your workflows by decreasing number of opened windows

When working on my computer, my two main applications are a webbrowser and a terminal. I'm constantly switching between those two windows, and therefore loosing some valuable time during the switch.

At first, I decided to improve my workflow by browsing the web from my terminal, but browsing experience in the console is slightly limited. I had still a strong motivation after lynx had prompted me 4 times if I wanted to store cookies when using a search engine, and didn't give up when I realized cookies were not stored on hard drive, but I decided to find another way when I could not log into this blog.

As it was difficult to use a webbrowser inside my terminal, I tried to run instead my terminal inside my webbrowser. Then I made vteplugin, a plugin to run a terminal inside a webbrowser tab.

screenshot of vteplugin inside midori

It works in Gecko (firefox, seamonkey, ...) and webkit-gtk (midori, uzbl, ...). I don't known if it works in webkit-qt (arora, ...). If you try it, I'd be happy to known the result. It does not work in opera. To install, you can download it from this blog or clone it from github. Then, extract it and run ./waf configure && ./waf build and, as root, ./waf install. Restart your browser, and open vteplugin.html file.

On the technical side, it's a npapi plugin using XEmbed Extension. It uses libvte to open a terminal in plugin window

Now, like web2.0 fanboys, I can have all my applications inside my browser, but all my data are still belong to me.

Post written with vim inside vteplugin inside iceweasel

Friday, March 26 2010

new geoclue release

geoclue 0.12 has been released last Thursday. Geoclue is a geoinformation library. It provides a way for applications to get geographical informations, such as user address or positions.

Geoclue has a really nice feature, the master provider. It means geoclue can handle multiple sources of geoinformations. For example, you can get your position with your gps device, or with OpenCellId, or with webservices that will associate your IP address with a location (such as hostip). Geoclue master provider is able to choose the source with the best accuracy.

Geoclue is used at least in Empathy to publish your location to your contacts, and in WebkitGtk to support html5 geolocation.

It's been the first release in nearly two years, and it's great to see that nice project moving forward again. In this release, Nominatim has been added as a provider for geocoding and reverse/geocoding. It means it's possible to use nominatim service to get the position for a given address, or the opposite. There have been also many bugfixes and code cleaning, including a bug I've helped to resolve that prevented master provider from being usable in some configurations.

During this realease cycle, I've also started working on a provider that would allow an user to enter it's location manually. While location aware software can be a really useful feature in some cases, it's also important that user can a have the choice to provide a fake or inaccurate location. This is already possible in Firefox with geolocater extension. Once I have finished this provider, it will be possible to have this privacy protection for all applications using geoclue library.

Tuesday, March 16 2010

Mosaic on linux

Sources of mosaic web browser are available at github. Mosaic is one of the first graphical browsers, and the first one to support images in html documents. It is often considered as the grandparent of modern web browsers.

Available sources compile fine on linux. This allowed me to install mosaic and browse the web for some time. Actually, I did not browse for a long time because most websites, including the most accessible ones display badly with pristine mosaic. But that was still fun.

this blog with mosaic


google with mosaic


wikipedia with mosaic



Saturday, March 13 2010

installation de weave minimal

Je me suis intéressé récemment au projet weave de mozilla. Il s'agit principalement d'une extension Firefox qui permet la synchronisation de données (historique, marque-pages, etc) entre différents postes de travail.

Ce type d'outil est très répandu, mais le premier intérêt de weave, c'est que les données sont chiffrées avant envoi au serveur; il lui est donc impossible de lire nos données, de les diffuser ou de les revendre. Le deuxième intérêt, c'est qu'en plus de proposer le service de synchronisation, Mozilla met à disposition, sous licence libre, le logiciel du serveur de synchronisation. Il devient ainsi facile de synchroniser des profils Firefox de manière totalement indépendante, c'est à dire sans dépendre d'un service que l'on ne maitrise pas.

Pour cela, j'ai d'abord commencé par créer mon sous-domaine weave.renevier.net et attendu que les dns soient mis à jour. Ensuite, j'ai téléchargé une copie du minimal server. À priori il existe une version plus complète et plus compliquée à installer, mais le minimal server est adapté à un usage domestique pour lequel les nouveaux utilisateurs sont ajoutés manuellement.

J'ai ensuite décompressé l'archive
tar zxf weave_minimal.tgz
puis j'ai déplacé le répertoire extrait dans le répertoire de mon choix
mv weave_minimal /var/http/
J'ai ensuite donné les droits en écriture à l'utilisateur qui fait tourner le serveur web, afin que la base de données sqlite puisse être crée puis mise à jour correctement.
chgrp -R /var/http/weave && chmod g+w /var/http/weave
Weave a besoin d'une installation de php qui supporte json, mbstring et sqlite, j'ai donc du installer, sur mon serveur en debian stable, le paquet php5-sqlite
J'ai ensuite configuré et redémarré le serveur web. J'utilise lighttpd, voici le contenu de mon fichier de configuration

server.modules += ( "mod_alias", "mod_redirect", "mod_auth" )

$HTTP["host"] =~ "^weave.renevier.net$" {

server.document-root = "/var/httpd/weave/"
alias.url = ("/weave" => "/var/httpd/weave/index.php")

$SERVER["socket"] == ":80" {
url.redirect = ( "^/(.*)" => "https://weave.renevier.net/$1" )
}

}

Pour que weave soit disponible en https, il faut créer un certificat. Idéalement, il faudrait le faire certifier par une autorité de certification, mais pour un usage personnel, un certificat auto-signé fait très bien l'affaire. Comme j'en avais déjà un, je n'ai pas eu à en recréer, je ne vais donc pas décrire cette étape, mais des bons tutoriels existent sur le web.

Ensuite, je me suis rendu avec mon navigateur à l'adresse https://weave.renevier.net/weave/1.0/blah/info/collection et mon navigateur m'a demandé login et mot de passe. On peut rentrer n'importe quoi, cette étape ne sert qu'à initialiser la base sqlite. Ensuite, le navigateur redemande en boucle login et mot de passe, c'est normal, il suffit juste de répondre une seule fois.

On peut maintenant créer les utilisateurs du service grâce au script create_user disponible dans le dossier weave: php create_user.

Il ne reste plus maintenant qu'à installer l'extension sur les postes de travail que l'on veut synchroniser. Avant d'installer l'extension, il m'a été nécessaire, vu que j'utilise un certificat autosigné, de visiter l'url https://weave.renevier.net/ afin d'ajouter une exception de sécurité pour chacun des postes que je vais synchroniser. Lors de la configuration de l'extension, j'ai du choisir l'option Use a custom server, et configurer l'url suivante: https://weave.renevier.net/weave/

Voila, weave est maintenant installé !

Sunday, March 7 2010

creating a midori extension.

Today, I created my first extension for midori browser. I wanted to have the current time in my statusbar, in way similar to what Statubar Clock does for Firefox.

Extensions for midori must be written in C language. An extension source file must implement a function extensions_init to be loaded. If the source file to be in extensions/ directory, midori build system will be aware of its existence and build it.

A MidoriExtension object must be created in extension_init. A callback must then be connected to it for signal "activate". When extension is activated, this callback will be called with a MidoriApp object as argument. With this object, it's possible to access the underlying windows, tabs, menus, webviews, and other objects extension may need to access. Extension must also connect a callback to deactivate in order to be able to clean up things if user wants to deactivate the extension.

In my extension, I needed to get the statusbar, add a label to it, and set a timeout to update with with current time. Display format can be configured in a config file. There is currently no UI for configuration; I still need to work on it.

You can take a look at a screenshot of midori with Stat'o'clock activated. You can also see the source code of stat'o'clock.

In the end, I think building a simple extension for midori is quite easy and fun if you known a bit of gtk. It will be even better if one day, midori extension can be written in other languages (python, lua, javascript ...). You can learn more by reading the midori extension tutorial.