Archives février 2010

« On se tient au courant ! »

| Aucun Commentaire | Aucun Trackback

Récemment, au détour de GitHub, j'ai vu un projet intéressant : growlme. Pour ceux qui ne connaissent pas Growl, il s'agit d'un système de notification non intrusif. Imaginez que vous lancez la gravure d'un DVD, et pendant ce temps-là vous en profitez pour travailler sur un article ou un billet de blog. Traditionnellement, les logiciels de gravure vous afficheront une petite fenêtre à la fin de la grave, interrompant ainsi ce que vous étiez en train de faire. Avec les systèmes de notification comme Growl, une fenêtre volante apparaîtra en haut à droite de l'écran signalant la fin de la gravure. Growl est uniquement disponible sur Mac1, mais il existe des systèmes équivalent sur Linux (libnotify entre autres).

growlme permet de lancer un programme en ligne de commande et d'être tenu au courant du résultat de son exécution via Growl. Comme il m'arrive souvent de lancer un processus assez long via la ligne de commande, et de m'atteler à d'autres tâches entre-temps, j'aimerais bien avoir l'équivalent sur mon Linux.

Le résultat n'est pas bien long et exploite Desktop::Notify, c'est-à-dire l'interface Perl à libnotify, IPC::Run pour lancer la commande, Getopt::Long pour traiter les paramètres en ligne de commande (notez l'usage de Getopt::Long::Configure('pass_through') pour conserver un @ARGV, ainsi que Sys::Hostname pour avoir le titre de la notification. Pour le reste, j'ai singé le programme originel.

#!/usr/bin/env perl

use strict;
use warnings;

use Desktop::Notify;
use IPC::Run qw( run );
use Getopt::Long;
use Sys::Hostname;

my $config = {
    message => 'Succeed!',
    fail    => 'FAILED',
    title   => hostname(),
};

Getopt::Long::Configure('pass_through');
GetOptions( $config, 'message=s', 'fail=s', 'title=s' );

if ( scalar(@ARGV) == 0 ) {
    die "$0: must provide a command to execute\n";
}
else {
    my $notify = Desktop::Notify->new();
    my $notification;

    eval { run \@ARGV };
    my $exitcode = $? >> 8;
    if ( $exitcode == 0 ) {
        $notification = $notify->create(
            summary => $config->{title},
            body    => $config->{message},
            timeout => 5000,
        );
    }
    else {
        $notification = $notify->create(
            summary => $config->{title},
            body    => $config->{fail},
            timeout => 5000,
        );
    }

    $notification->show();
    $notification->close();
}

J'ai créé un gist sur GitHub de cet outil.

Pearltrees

| 2 Commentaires | Aucun Trackback

Pearltrees

Suite à un commentaire sur son blog, @SebDeclercq a expliqué les raisons de son choix concernant Pearltrees. En résumé (et il me corrigera si j'ai mal compris) :

  1. besoin d'un outil permettant d'effectuer des sauvegardes de ces favoris ;
  2. cet outil devait être en ligne pour pouvoir être utilisé depuis plusieurs machines ;
  3. le système de classement proposé doit être efficace, et le classement visuel sous forme d'arbre rencontrait ses attentes.

De mon côté, je partage le besoin d'un système permettant de gérer mes favoris. J'ai utilisé pendant un temps Delicious, mais à un moment, j'ai abandonné l'habitude d'y déposer les ressources jugées intéressantes au profit d'un petit outil développé par mes soins. Dans sa réponse @SebDeclercq signale que son utilisation de Pearltrees passe essentiellement par l'extension Firefox. Je n'avais pas pris le temps de tester ce dernier. D'abord parce que mon navigateur principal est maintenant Chromium, et aussi par manque de temps. J'avais donc testé l'outil offert par Pearltrees, à savoir le bookmarklet, mais je n'en étais pas nécessairement content. Ce dernier déposait les perles (comprendre les URL que vous souhaitez conserver) dans un panier, et il vous restait encore à « ranger » ces perles. Et donc, devoir utiliser cette interface en Flash que je trouve particulièrement rebuttante1. Bref, dans ces conditions, il m'était difficile d'adopter Pearltrees dans ma boîte à outils.

Mais l'article de @SebDeclercq m'a obligé à revisiter l'outil, et donc, cette fois-ci j'ai pris le temps de lancer un Mozilla Firefox, et d'installer l'extension. Et j'ai donc pu comprendre pourquoi c'était un outil intéressant pour gérer ses favoris :

  • l'évidente intégration dans le navigateur ;
  • la mise à disposition d'un bouton vous permettant de choisir où placer votre perle, et donc, cela vous dispense de passer par le site, et donc d'éviter l'interface Flash ;
  • un bouton permettant de lancer votre Pearltrees.

Néanmoins, malgré tout, je ne pense pas inclure Pearltrees dans ma boîte à outil pour les raisons suivantes :

  • absence d'API à ce jour : de mon point de vue, c'est vraiment le plus gros point noir de cet outil. En effet, dans le web 2.0 qui est le nôtre, et dans le web 3.0 ou le web des données qui pointe le bout de son nez, la présence d'un API est essentielle2 ! Ainsi, si j'ai du mal avec l'interface Flash, la présence d'une API m'aurait permis de développer un interface en ligne de commande comme je les aime. Mais là, ce n'est pas avec l'export RDF que je vais aller bien loin3 puisque je dois me connecter pour réaliser cet exportation ;
  • les fonctionnalités de l'outil ne dépasse pas de beaucoup celle d'un Delicious. Bon, la structure arborescente est vraiment chouette, l'aspect visualisation est intéressante4, le fait de pouvoir « capturer » un pearltree est vraiment très sympathique, mais pour le reste, je crains de reproduire le même schéma qu'avec Delicious ;
  • à côté de cela, j'ai découvert dernièrement via un tweet de @MarioAsselin un outil plus en accord avec mes besoins : Diigo, je l'utilise depuis maintenant une semaine, et même si je dois encore améliorer mon workflow personnel de PKM afin de faire un peu de place à Diigo, j'ai peut-être trouvé une réponse adéquate à mes besoins.

Diigo

Alors, voici en bref les fonctionnalités qui m'ont séduit :

  1. présence d'une API ; bon, OK, elle n'est pas complète, mais elle permet déjà
    de récupérer les informations sur les favoris, et donc, à moi de jouer pour
    l'intégrer dans mes workflows personnels ; j'ai déjà jeté les premières pierres pour réaliser cette opération, mais je dois encore continuer
    (vivement le week-end !) ;
  2. existence d'une extension pour Chromium (et évidemment, une extension est
    également disponible pour Firefox, mais je n'ai pas encore pris le temps de
    la tester) ;
  3. possibilité d'annoter les pages lues ; ces annotations peuvent être
    récupérées via l'API et dans les fonctions d'export de l'outil ;
  4. plusieurs formats d'exportation (IE Bookmark, Netscape Bookmark, RSS, CSV et
    Delicious) ;
  5. Diigo crée un snapshot du lien sauvegardé, cela signifie donc que même si
    le lien n'est plus disponible, vous avez une version disponible dans votre
    bibliothèque Diigo
  6. possibilité de créer des liens privés ;
  7. possibilité de créer des listes, et ces dernières peuvent également être
    privées ;
  8. possibilité de créer des groupes, c'est un aspect communautaire
    supplémentaire par rapport à Delicious, utilisé entre autres par le groupe UQ de partage sur la techno pédagogie et sur les technologies ou les environnements numériques d'apprentissage.

Bref, intéressant, non ?

Conclusion

Bon, j'ai été long, mais je pense que le sujet en vaux la peine : comment garder une trace de ses lectures sur le web. Une réflexion de base pour des spécialistes de l'information, mais aussi, et de plus en plus pour M. Tout-le-monde qui doit faire preuve d'une littératie de plus en plus importante. Quant au choix de l'outil, il importe finalement peu pour autant que ce dernier réponde aux besoins de l'utilisateur. 

Et comme je suis pour une diversité maximale de l'écologie des outils et des
logiciels : longue vie à Pearltrees et à Diigo !!! 

Notes de bas de page:

1 les raisons en sont relativement simples :

  • je travaille sur des machines différentes, et une de ces machine est un Asus EeePC 1005HA, donc, un écran 10", ce qui rend l'interface Flash particulièrement irritante ;
  • même sur des écrans plus grands, je trouve cette interface terriblement lente ; je suis particulièrement peu patient avec les interfaces de logiciels, et j'aime que la limite soit ma capacité à exploiter le logiciel, dans le cas présent, je dois attendre l'interface, et cela m'irrite au plus au point, cette philosophie explique probablement mon addiction à la ligne de commande.

2 Il me reste évidemment la possibilité d'analyser le fonctionnement du bookmarklet et de l'extension pour savoir comment construire les requêtes, etc. Bref, du reverse engineering qui me prendra du temps, et me distraira d'autres projets ;

3 cet export RDF peut difficilement être qualifié de bonne nouvelle, je vous met au défi de faire quoi que ce soit avec ce fichier RDF. Cela signifie donc que vous pouvez exporter vos données ... mais aucun logiciel actuel n'est capable de manipuler le format en question. Cool. Un export CSV ou, mieux encore, tout autre format habituellement géré par les navigateurs aurait été le bienvenu !

4 cela me rappelle l'histoire de KartOO, qui a commencé par l'interface « carte » (une innovation pour un métamoteur) puis qui a fini par proposer le choix entre une interface « carte » et une interface plus classique. En espérant que l'histoire se termine mieux pour Pearltrees puisque qu'apparemment, KartOO, c'est fini !!

Dans le cadre d'un cours d'un cours de Gestion numérique des connaissances, je parle un peu d'information retrieval. Juste les bases, mais bon, cela me paraît important de savoir comment fonctionne un moteur de recherche, surtout pour de futurs spécialistes de l'information et de la documentation. Parmi ces bases, nous avons la manière dont un moteur de recherche perçoit le texte qu'il doit indexer. Si la théorie est facile à appréhender, cela ne m'empêche pas de rajouter une couche visuelle, et c'est pour cette raison que j'ai écrit un petit permettant d'illustrer cette phase de l'indexation.

Le script a été développé sur un temps de midi, un peu avant de donner le cours, et donc, je n'ai pas travaillé l'ergonomie et la mise en page de l'outil. Pour réaliser rapidement l'outil, j'ai utilisé les outils suivants :

Pour le reste, le code est assez simple :

#!/usr/bin/env perl

use strict;
use warnings;

package MyView::Templates;
use Template::Declare::Tags;
use base 'Template::Declare';

private template form => sub {
    my $self  = shift;
    my $title = shift;

    div {
        attr { style => 'margin: auto; size: 15%;', };
        form {
            attr {
                action => '/submit',
                method => 'POST',
            };
            textarea {
                attr {
                    cols  => '100',
                    rows  => '25',
                    name  => 'title',
                    style => 'float: left;',
                };
                $title;
            };
            input {
                attr {
                    name  => 'submit',
                    type  => 'submit',
                    value => 'Soumettre',
                    style => 'float: left;',
                };
            };
            input {
                attr {
                    name  => 'reset',
                    type  => 'reset',
                    value => 'Réinitialiser',
                    style => 'float: left;',
                };
            };
            div { attr { style => 'clear: both;' } };
        };
    };

};

template main => sub {
    my $self  = shift;
    my $title = shift;

    html {
        head {};
        body {
            show( 'form', $title );
        };
    };
};

private template data => sub {
    my $self   = shift;
    my $result = shift;

    div {
        attr { style => 'margin: auto; width: 40%' };
        h1 {
            "Résultat de l'analyse";
        };
    }
    div {
        ol {
            foreach my $word ( sort keys %$result ) {
                li { $word . " : " . $result->{$word} };
            }
        };
    };
};

template result => sub {
    my $self   = shift;
    my $title  = shift;
    my $result = shift;

    html {
        head {};
        body {
            show( 'form', $title );
            hr {};
            show( 'data', $result );
        };
    }
};

package MyWebServer;

use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);
use Text::ExtractWords qw(words_count);

use Template::Declare;
Template::Declare->init( dispatch_to => ['MyView::Templates'] );

my %dispatch = (
    '/'       => \&resp_homepage,
    '/submit' => \&resp_submit,
);

sub handle_request {
    my $self = shift;
    my $cgi  = shift;

    my $path    = $cgi->path_info();
    my $handler = $dispatch{$path};

    if ( ref($handler) eq "CODE" ) {
        print "HTTP/1.0 200 OK\r\n";
        $handler->($cgi);

    }
    else {
        print "HTTP/1.0 404 Not found\r\n";
        print $cgi->header( -charset => 'UTF-8' ),
          $cgi->start_html('Not found'),
          $cgi->h1('Not found'),
          $cgi->end_html;
    }
}

sub resp_homepage {
    my $cgi = shift;
    return if !ref $cgi;

    print $cgi->header( -charset => 'UTF-8' ), Template::Declare->show('main');
}

sub resp_submit {
    my $cgi = shift;
    return if !ref $cgi;

    my $title  = $cgi->param('title');
    my $result = {};
    words_count( $result, $title, {} );

    print $cgi->header( -charset => 'UTF-8' ),
      Template::Declare->show( 'result', $title, $result );
}

package main;

my $server = MyWebServer->new(9999);
$server->run();

J'ai créé un gist de cet outil sur Github, et je compte l'améliorer quand j'aurai un peu de temps.

Dernièrement sur la liste de diffusion perl4lib, une question a été posée concernant l'existence d'une solution permettant de diviser un fichier MARC trop gros en plusieurs fichiers plus petits.

Comme beaucoup d'utilisateurs de fichiers MARC, et de programmeurs manipulant des fichiers MARC, j'ai été confronté à ce problème et j'avais développé une petite solution rapide :

#!/usr/bin/env perl

use strict;
use warnings;

use MARC::File::USMARC;
use MARC::Record;

use Getopt::Long;

my $config = { output => 'input' };

GetOptions($config, 'input=s', 'chunk=s', 'output=s', 'max=s');

if (not exists $config->{input} and not exists $config->{chunk}) {
    die "Usage: $0 --input file --chunk size [--output file]\n";
} else {
    run($config->{input}, $config->{output}, $config->{chunk}, $config->{max});
    
}

sub run {
    my ($input, $output, $chunk, $max) = @_;

    my $marcfile = MARC::File::USMARC->in($input);
    
    my $fh = $output eq 'input' ? create_file($input) : create_file($output);
    my $cpt = 1;
        my $total = 0;
    while (my $record = $marcfile->next) {
        $total++;
        
        if (defined $max) {
            last if $total > $max;
        }
        if ($cpt++ > $chunk) {
            close $fh;
            $fh = $output eq 'input' ? create_file($input) : create_file($output);
            $cpt = 1;
        } 

        print $fh $record->as_usmarc;
    }   
    close $fh;
}

sub create_file {
    my ($output) = @_;
    my $cpt = 0;
    
    my $filename = sprintf('%s.%03d', $output, $cpt++);
    while (-e $filename) {
        $filename = sprintf('%s.%03d', $output, $cpt++);
    }

    open my $fh, '>', $filename;
    return $fh;
}

Cet outil est l'exemple même de solution qu'un bibliothécaire - documentaliste devrait être à même de programmer (pour autant qu'il souhaite programmer, bien entendu). L'algorithme employé est loin d'être compliqué (même si cela reste un bon exercice), et il s'agit d'une exploitation de modules existants (vive le CPAN !) pour lesquels il existe de la documentation. Bref, un bel exemple de paresse et de spécicialisation.

Néanmoins, une meilleure solution que ce marcsplit.pl est sans aucun doute l'utilisation de l'utilitaire yaz-marcdump comme l'indique Sébastien Hinderer. Voici quelques exemples :

  • yaz-marcdump -C 5000 export.mrc : cela créera des fichiers de 5000 notices dont le nom sera de la forme suivante : 0000001, 0000002, etc
  • yaz-marcdump -C 5000 -s export_by_5000- export.mrc : permettra de spécifier un préfixe aux fichiers créés, dans l'exemple, cela nous donnera des fichiers de la forme suivante : export_by_5000-0000001, export_by_5000-0000002, etc

À propos de cette archive

Cette page est une archive des notes de février 2010 listées de la plus récente à la plus ancienne.

décembre 2009 est l'archive précédente.

mars 2010 est l'archive suivante.

Retrouvez le contenu récent sur l'index principal ou allez dans les archives pour retrouver tout le contenu.

Pages

Powered by Movable Type 4.261