Créer une application Perl autour de MySQL : Intégration avec Mojolicious, HTML::Tiny et HTML::FormHandler (3/3)

Magazine
Marque
GNU/Linux Magazine
Numéro
169
|
Mois de parution
mars 2014
|
Domaines


Résumé
Reprenons l'histoire du hacker à qui on a demandé de créer des pages web pour le suivi de la production logicielle de la société. Comme tout hacker qui se respecte, il préfère que la machine fasse son boulot à sa place. Pour ce faire, il a mis en place une base de données MySQL, un ORM (DBIx:Class). Reste maintenant à fournir un serveur web pour exploiter les données de cette base.

Body

Petit rappel des épisodes précédents : notre hacker favori a expliqué comment mettre en place dans une base de données MySQL les tables et relations qui assureront la persistance des données de production. Puis, comment lire et écrire ces données avec DBIx:Class. Le code SQL de la structure de la base et le petit script contenant les exemples d'accès à la base sont disponibles dans un dépôt git [GITHUBADOD].

1. Exploitation des données

Maintenant que nous savons écrire des données dans la base, nous allons voir comment récupérer ces données pour les afficher dans des pages HTML avec Mojolicious::Lite. Ce module fournit une infrastructure « légère » de serveur web. Ceci permet de tester rapidement les pages produites avec le mini-serveur de Mojolicious. Comme ce module a été décrit précédemment [GLMF138], les explications sur Mojolicious seront rapides.

1.1 Mise en place d'un micro serveur avec Mojolicious

Pour démarrer plus facilement, on va créer un petit script avec Mojolicious::Lite qui sera chargé de lire les informations de la base de données. On verra plus tard comment mettre à jour ces données.

La commande suivante va créer un embryon de ce script :

$ mojo generate lite_app rapport.pl
$ cat rapport.pl
#!/usr/bin/env perl
use Mojolicious::Lite;
# Documentation browser under "/perldoc"
plugin ‘PODRenderer’;
get ‘/’ => sub {
my $self = shift;
$self->render(‘index’);
};
app->start;
__DATA__
@@ index.html.ep
% layout ‘default’;
% title ‘Welcome’;
Welcome to the Mojolicious real-time web framework!

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head><title><%= title %></title></head>
<body><%= content %></body>
</html>

En résumé, la première partie de ce script déclare comment traiter la route / avec le template index. Celui-ci est décrit dans le script après la ligne __DATA__. Si ce résumé vous laisse perplexe, je vous invite à lire [GLMF138].

Pour tester le résultat, lancez le mini-démon :

$ ./rapport.pl daemon
[Fri Jun 1 16:24:43 2012] [info] Listening at "http://*:3000".
Server available at http://127.0.0.1:3000.

Et passez l'URL indiquée à votre butineur favori. Vous y verrez affichée une petite page d'accueil Mojolicious. En bonus, grâce au plugin Podrenderer, vous pouvez afficher des pages de doc de Perl sous l'URL http://localhost:3000/perldoc/. Par exemple, http://localhost:3000/perldoc/perlre.

Vous pouvez aussi lancer le script avec :

$ morbo rapport.pl daemon

morbo surveille les modifications du fichier rapport.pl et va le recharger si nécessaire. C'est très pratique dans les phases de développement.

2. Extraction et formatage des informations de la base

Revenons-en à nos produits. On a d'abord besoin d'afficher la liste de produits disponibles sous forme de table générée à partir du contenu de la base de données. Cette section va détailler la construction du script Mojolicious.

2.1 Utilisation des templates Mojolicious pour la liste des produits

D'abord, il faut se connecter à la base :

use Mojolicious::Lite;
use Integ::Schema ;
my $schema = Integ::Schema->connect(
‘DBI:mysql:database=Integ;host=localhost;port=3306’,
‘integ_user’, ‘’, { RaiseError => 1 }
);

Ensuite, on gère la route / pour que l'URL http://localhost:3000 renvoie la liste des produits. render va utiliser le template product_list pour générer le code HTML. Le reste des paramètres est un ensemble de clés-valeurs utilisables dans le template :

get ‘/’ => sub {
my $self = shift;
$self->render(product_list => rs => $schema-> resultset(‘Product’) );
};

Cette dernière ligne démarre effectivement le daemon :

app->start;

Avec Mojolicious::Lite, les templates sont situés dans la section data (après la balise __DATA__). La syntaxe du template est détaillée dans [GLMF138]. En résumé :

- Les balises <% ... %> et les lignes commençant par % sont du code Perl ;

- Les balises <%= ... %> sont du code Perl dont la sortie est injectée dans le template, après une transformation pour le rendre moins lisible, mais compatible avec XML (e.g. > est changé en &gt;) ;

- les balises <%== ... %> sont du code Perl dont la sortie est injectée verbatim dans le template. Ce qui est indispensable si le code Perl génère lui-même du HTML.

Le code suivant (en zone DATA) va utiliser le « layout » défini par la commande mojo generate et renvoyer une page HTML contenant un tableau avec les listes des produits disponibles.

__DATA__
@@ product_list.html.ep
% layout ‘default’ ;
% title ‘Product list’ ;
<h1>Produits</h1>
<table>
<tr>
<th>Produit</th>
<th>Home page</th>
</tr>
% while (my $product = $rs->next) {
% my $name = $product-> name ;
<tr>
<td><a href="<%==$name%>"><%== $name %></td>
<td><a href="<%== $product->home_page%>">home page</td>
</tr>
% }
</table>

Notez que la première URL du tableau est construite sous la forme <nom_du_produit>. Il faudra définir une route dans le script Mojolicious pour répondre à cette adresse.

Pour tester, il faut relancer le mini-serveur (sauf si morbo s'en charge) et recharger la page web. Et là, horreur, cette page est moche : les informations sont là, mais en noir sur fond blanc.

Pour remédier à cette faute de goût, il suffit d'ajouter une feuille de styles dans le « layout » :

@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link href="/css/my_style.css" rel="stylesheet" />
</head>
<body><%= content %></body>
</html>

Plutôt que d'ajouter une route dans la section DATA, on peut placer le fichier CSS dans le répertoire public/css, Mojolicious::Lite saura aller le chercher à cet endroit.

2.2 Mais c'était quoi cette horreur ?

Vous aurez sans doute remarqué que le template product_list.html.ep du paragraphe précédent n'est pas forcément agréable à lire : c'est un pot-pourri indigeste de balises HTML et de balises de template, persillé avec du code Perl.

C'est une limite des templates : quelques variables Perl de-ci de-là ne posent pas de problème, mais ça devient illisible dès que le traitement métier devient important par rapport au texte.

La philosophie de Perl étant d'avoir plus d'une façon de faire une chose [TIMTOWTDI], on va utiliser pour les autres routes une façon alternative. Tous ces traitements complexes seront écrits principalement avec du code Perl et le code HTML sera généré avec le module qui va bien. Par exemple, le module HTML::Tiny.

2.3 Une petite digression sur HTML::Tiny

HTML::Tiny est un module bien pratique pour générer de l'HTML. Il fournit une méthode pour chaque balise HTML. Chaque méthode renverra une liste ou une chaîne, selon le contexte.

Par exemple, on peut avoir :

my $h = HTML::Tiny->new;
my $html_text = ‘’;
$html_text .= $h->h1(‘Une petite digression...’) ;

Les attributs d'une balise peuvent être passés dans un hash ref :

$html_text .= $h->div({class => ‘perl_module’},’HTML::Tiny’ ) ;

Chaque paramètre va générer une balise :

say $h->td(qw/foo bar baz/) ;
# <td>foo</td><td>bar</td><td>baz</td>

On peut aussi avoir une balise pour une liste en passant une référence :

my @chanson = map {"$_ km à pied, ça use, ça use... "} qw/un deux trois/ ;

my @li_en_vrac = $h->li( @chanson ) ;

say $h->ul( \@li_en_vrac ) ;

Ce qui donne, après reformatage manuel :

<ul>

<li>un km à pied, ça use, ça use... </li>

<li>deux km à pied, ça use, ça use... </li>

<li>trois km à pied, ça use, ça use... </li>

</ul>

Si une balise n'est pas implémentée dans HTML::Tiny, la méthode tag devra être utilisée :

say $h->tag('titi', qw/foo bar baz/),"\n";'

# <titi>foo</titi><titi>bar</titi><titi>baz</titi>

2.4 Générer la liste des versions

Le principe est le même que pour générer la liste de produits. Plutôt que d'utiliser les templates Mojolicious pour écrire la table, on va utiliser HTML::Tiny.

Tout d'abord, on crée un objet HTML::Tiny une fois pour toutes et on déclare la route. Celle-ci est un peu plus compliquée, car elle contient le nom du produit sous la forme :name.

my $h = HTML::Tiny->new;

get '/:name' => sub {

my $self = shift;

my $p_rs = $schema -> resultset('Product');

On récupère le nom du produit avec la méthode param et on recherche dans la base de données les infos pour les récupérer dans un objet Schema::Product :

my $n = $self->param('name') ;

my $p_obj = $p_rs->search({name => $n }) ->single ;

Et on construit le tableau HTML en faisant une itération sur les objets Schema::ProductVersion renvoyés par $p_obj->product_versions->all :

my @rows ;

foreach my $version_obj ($p_obj->product_versions->all) {

my $version_as_string = $version_obj->version ;

Le lien vers la page dédiée à la version est créé avec la méthode a. Cette URL sera de la forme /<nom_du_produit>/<version> :

my $v_link = $h->a({href => $version_as_string }, $version_as_string) ;

Les lignes du tableau sont créées avec :

my @data = $h->td( $v_link , $version_obj->date->ymd ) ;

push @rows, $h->tr( \@data ) ;

}

Et enfin, on passe le tableau HTML sous forme de string au template version_list :

$self->render ( version_list => rows => join("\n",@rows), name => $n ) ;

} ;

Comme tout le boulot est fait avec HTML::Tiny, le template version_list devient beaucoup plus simple :

@@ version_list.html.ep

% layout 'default' ;

% title 'Product version list' ;

<h1>Versions du produit <%== $name %></h1>

<table>

<tr>

<th>Version</th>

<th>Date</th>

</tr>

<%== $rows %>

</table>

Le script correspondant est disponible sur mon dépôt git [GITHUBADOD] sous rapport.pl.

3. Modification des données avec Mojolicious

Pour assurer le suivi de la qualification du produit, on va ajouter un formulaire web pour pouvoir modifier facilement le statut d'une version d'un produit. Pour cet article, ce statut est directement tiré des pratiques Debian, soit « unstable », « testing » ou « unstable ».

Le but est de créer un formulaire qui permettra de modifier le statut d'une version de produit.

D'abord, il faut une route pour lister les versions d'un produit. Chaque version contient un lien qui pointe vers une page d'édition. Cette route se contente de récupérer l'objet produit de la base pour le passer au template :

get '/:name' => sub {

my $self = shift;

# on récupère l'objet dans la base

my $p_obj = $schema

-> resultset('Product')

-> find({name => $self->stash('name')}) ,

# et on le passe au template

$self->render (

template => 'mojo_prod_v_list',

p => $p_obj

) ;

} ;

Le template en question est assez simple :

@@mojo_prod_v_list.html.ep

% layout 'default' ;

% title 'Product versions' ;

<h1>Versions of product <%== $p->name %></h1>

<ul>

% foreach my $r ($p->product_versions) {

% my $v = $r->version ;

<li><a href="<%== $p->name.'/'.$v %>"><%== $v %></a>

% }

</ul>

Ensuite, on crée la route pour éditer une version du produit. Comme le numéro de version contient un ., il faut utiliser #version au lieu de :version. Les boutons sont construits ici pour simplifier le traitement en Perl dans le template :

get '/:name/#version' => sub {

my $self = shift;

On récupère l'objet version du produit dans la base :

my $pv = $schema->resultset('Product')

-> find({name => $self->stash('name')})

-> product_versions

-> find ({version => $self->stash('version')}) ;

Ensuite, on crée les boutons radio actifs avec cette séquence un peu lourde (où $h est un objet HTML::Tiny). L'attribut check est calculé à la volée pour que le bouton affiche la valeur courante dans la base :

my @radio_items = map {

$h->label($_)

. $h->input({

type => "radio",

name => "v_status",

value => "$_",

($_ eq $pv->status) ? ( checked => 'checked') : ()

});

} qw/unstable testing stable/ ;

Enfin, on envoie le HTML pré-mâché au template :

$self->render (

template => 'mojo_template_mod',

radio_b => \@radio_items,

pv => $pv ,

) ;

};

Le template associé contient un formulaire. Pour se simplifier la vie, le bouton de sauvegarde va construire une URL avec l'id de la version plutôt qu'avec le couple « nom/version » :

@@mojo_template_mod.html.ep

% layout 'default' ;

% title 'Product status' ;

<h1>Product <%== $pv->product->name %> version <%== $pv->version %></h1>

<form name="save_data"

action="/product_version_data_save/<%= $pv->id %>"

method="post">

status :

<%== join("\n", @$radio_b) ; %>

<input type="submit"

name="save-product-version"

value="Save"/>

</form>

Et on obtient ce résultat, certes moche, mais fonctionnel :

prod_mod_with_template

Une fois le bouton « Save » pressé, le navigateur va envoyer une requête POST vers le serveur Mojolicious. Pour que cette requête puisse fonctionner, il faut la route associée.

Celle-ci va récupérer l'objet correspondant à la version modifiée et sauver le paramètre modifié dans la base.

post 'product_version_data_save/:vid' => sub {

my $self = shift ;

my $v_obj = $integ_schema

-> resultset('ProductVersion')

-> find({ id => $self->stash('vid')}) ;

# on extrait l'information des paramètres du POST

my $value = $self->param('v_status') ;

# on sauve dans l'objet version

$v_obj->status($value) ;

# enfin, on envoie la donnée dans la base

$v_obj->update ;

# le gros du boulot est fait, il reste à informer l'utilisateur

$self->render(

'product_version_save_done',

p => $v_obj->product,

v => $v_obj->version

);

} ;

Voici son template :

@@ product_version_save_done.html.ep

%title 'product '.$p->name . ' saved ' ;

%layout 'redirect', redirect_url => '/' ;

<p>Product <%= $p->name %> version <%== $v %> was saved</p>

<p><a href="/">go back to product list</a></p>

Au moins, ça fonctionne. Mais le code est déjà assez compliqué et les données ne sont pas vérifiées avant d'être envoyées dans la base (modify-a-la-mojo.pl dans [GITHUBADOD]).

Pour des formulaires plus compliqués que des boutons radio, il faut en plus s'assurer que les valeurs rentrées par l'utilisateur soient cohérentes. On peut toujours ajouter du code de validation dans les contrôleurs (c'est-à-dire dans les procédures associées aux routes), mais le mélange de la validation avec la génération des formulaires va compliquer la maintenance. L'idéal serait de pouvoir séparer la validation de la gestion des templates et des données.

Ben, justement, c'est ce que proposent les modules HTML::FormHandler et HTML::FormHandler::Model::DBIC.

4. Modification des données avec HTML::FormHandler

HTML::FormHandler est un module impressionnant qui permet de créer un formulaire HTML avec une déclaration de classe Perl en format Moose (ou presque). Cette classe est utilisée par HTML::FormHandler pour :

- Créer les formulaires HTML,

- Traiter et valider les paramètres envoyés par l'utilisateur avec une requête POST,

- Sauvegarder ces valeurs dans une base de données si HTML::FormHandler::Model::DBIC est aussi utilisé.

Je vous propose de faire un formulaire comprenant la fonction précédente (modification du statut) et l'ajout d'un log (pour montrer comment déclarer un champ avec une validation).

Tout d'abord, il faut créer une classe par formulaire. Cette classe doit utiliser HTML::FormHandler::Moose au lieu de Moose. Ça permet de déclarer les champs du formulaire avec has_field. Elle doit aussi hériter (déclaration avec extends) de HTML::FormHandler::Model::DBIC pour créer un formulaire dédié à une table de base de données. Comme cette classe va être incluse dans le fichier avec les routes de Mojolicious::Lite, on va l'englober entre deux accolades :

{

package ProductVersionForm;

use HTML::FormHandler::Moose;

extends 'HTML::FormHandler::Model::DBIC';

use namespace::autoclean;

Il faut ensuite déclarer quelle table va être utilisée pour sauvegarder les valeurs du formulaire. Il ne faut pas oublier le +, car cet attribut surcharge celui de la classe HTML::FormHandler.

has '+item_class' => ( default => 'ProductVersion' );

Ensuite, on peut déclarer les champs du formulaire.

status est un champ à plusieurs valeurs possibles (type select), où une seule valeur doit être choisie. Le plus simple est d'en faire un ensemble de boutons de type radio avec widget RadioGroup. Les informations passées avec options sont utilisées telles quelles dans la balise input. Chaque statut possible doit avoir une déclaration label et value pour que le champ soit affiché correctement.

has_field 'status' => (

type => 'Select',

widget => 'RadioGroup',

options => [

map { { label => $_ , value => $_ } ;} qw/unstable testing stable/

],

);

Maintenant, on va s'occuper du champ log. Pour emb^W inciter les utilisateurs à motiver le changement de statut, on rend le champ obligatoire avec required. Le paramètre apply permet de déclarer des contraintes de validation arbitraire (voire farfelues dans cet exemple). apply spécifie une condition à appliquer (une « subref » qui renvoie vrai ou faux) et un message d'erreur.

has_field 'log' => (

# utiliser TextArea pour une zone d'édition plus grande

type => 'Text',

required => 1,

apply => [

{

check => \&whatever,

message => 'whatever rule was not satisfied'

}

]

);

sub whatever {

my ( $value, $field ) = @_;

return $value =~ /whatever/ ? 1 : 0 ; # ok, c'est idiot

}

Enfin, le dernier champ spécifie l'indispensable bouton pour envoyer le formulaire :

has_field 'submit' => ( type => 'Submit', value => 'Save' );

Ces 2 dernières lignes sont des optimisations de performance :

__PACKAGE__->meta->make_immutable;

no HTML::FormHandler::Moose;

}

Maintenant, il faut revoir les contrôleurs. Les seuls qui changent sont ceux des routes /:name/#version et /product_version_data_save/:vid. Voici la première route qui va générer le formulaire :

get '/:name/#version' => sub {

my $self = shift;

my $product_version = $integ_schema

->resultset('Product')

->find( { name => $self->stash('name') } )

->product_versions

->find( { version => $self->stash('version') } );

my $form = ProductVersionForm->new(

action => "/product_version_data_save/".$product_version->id,

item => $product_version,

) ;

$self->render(

template => 'formhandler_template_mod',

my_form => $form ,

pv => $pv,

);

};

Il faut d'abord trouver dans la base l'objet version de produit (stocké dans $product_version) pour pouvoir afficher les valeurs courantes dans le formulaire. L'objet $form contient une instance de l'objet HTML::FormHandler. Le paramètre action spécifie où envoyer la requête POST. Le paramètre item doit contenir l'objet qui représente une ligne (« row ») dans la table ProductVersion. Enfin, l'appel à render utilise le template suivant :

@@formhandler_template_mod.html.ep

% layout 'default' ;

% title 'Product status' ;

<h1>Product <%== $pv->product->name %> version <%== $pv->version %></h1>

<%== $my_form->render%>

Celui-ci est très simple : il suffit d'appeler la méthode render sur l'objet formulaire pour créer tout le code HTML et produire cette page :

prod_mod_with_formhandler

Et voici le contrôleur pour sauver les données :

post '/product_version_data_save/:vid' => sub {

my $self = shift;

my $form = ProductVersionForm->new;

# ne pas oublier de traiter les paramètres

$form->process(

schema => $integ_schema ,

item_id => $self->stash('vid') ,

params => $self->req->params->to_hash

) ;

if ($form->has_errors) {

return $self->render(text => join("\n", $form->errors )) ;

}

$self->render(

'product_version_save_done',

);

};

Il faut aussi recréer l'objet HTML::FormHandler formulaire (dans $form). L'appel à process contient le schéma et l'id de l'objet version de produit passé en paramètre du POST. HTML::FormHandler n'a pas besoin de plus pour savoir comment sauver les autres paramètres du POST contenus dans $self-req->params>. Le template appelé est très simple :

@@ product_version_save_done.html.ep

%title 'product saved ' ;

%layout 'redirect', redirect_url => '/' ;

<p>Product status was saved</p>

<p><a href="/">go back to product list</a></p>

Ce qui renvoie sur la page principale du serveur.

Ce web serveur est disponible dans modify-a-la-formhandler.pl sur le dépôt git [GITHUBADOD].

Conclusion

Nous voici arrivés à la fin de la trilogie. Vous avez le minimum pour pouvoir créer une petite application web avec une base de données relationnelle. N'hésitez pas à utiliser les codes sur le dépôt git [GITHUBADOD], ceux-ci sont disponibles en licence Artistic ou GPL-1+.

Dans votre projet, vous vous rendrez compte que ces articles ne montrent que le sommet de l'iceberg. Les modules DBIX::Class, Mojolicious et HTML::FormHandler ont beaucoup plus de possibilités. Il faudrait, non pas 3 articles pour les couvrir, mais 3 volumes. Heureusement, ces modules ont tous une documentation très complète sur CPAN. N'hésitez pas à la consulter !

Remerciements

Les Mongueurs de Perl pour leur accueil et la relecture de cet article.

Liens

[GLMF138] « Développement web en Perl avec Mojolicious » GNU/Linux Magazine n°138
[TIMTOWTDI] http://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it
[GITHUBADOD] https://github.com/dod38fr/glmf-article-dbix-class-web


Sur le même sujet

Python « moderne » : comment coder en Python en 2020 ?

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
110
|
Mois de parution
septembre 2020
|
Domaines
Résumé

Le langage Python évolue progressivement, version après version et de nouvelles fonctionnalités voient le jour et changent la manière dont le langage peut être appréhendé.Au-delà de la curiosité que ces changements provoquent, ils sont des révolutions silencieuses ayant un impact réel sur le style de codage.

Zéro SQLi malgré les développeurs

Magazine
Marque
MISC
Numéro
111
|
Mois de parution
septembre 2020
|
Domaines
Résumé

Nous proposons une méthode pour effectuer des requêtes SQL qui garantit l'invulnérabilité aux injections SQL, y compris lorsqu'elle est utilisée par un développeur pressé ou incompétent, contrairement aux requêtes paramétrées. Basée sur l'utilisation d'arbres de syntaxe abstraite, elle permet facilement de construire des requêtes dynamiques et est plus facile à mettre en œuvre qu'un ORM. Nous proposons une bibliothèque Java implémentant nos idées, mais la méthode peut s'appliquer à d'autres langages de programmation et d'autres types de requêtes.

Les outils pour les développeurs Python

Magazine
Marque
GNU/Linux Magazine
HS n°
Numéro
110
|
Mois de parution
septembre 2020
|
Domaines
Résumé

Pouvoir déboguer son code en toutes circonstances, le tester à chaque amélioration, suivre son utilisation et son bon fonctionnement et être capable d’en optimiser les points faibles.Ce sont des enjeux importants que tous les développeurs connaissent. Voici les outils pour y parvenir.

Comment arrêter un ordinateur sans crise de nerfs ?

Magazine
Marque
GNU/Linux Magazine
Numéro
240
|
Mois de parution
septembre 2020
|
Domaines
Résumé

Quoi de plus normal qu'un enfant qui joue ? Le problème n'est pas pendant qu'il joue, c'est plutôt au moment de l'arrêt : que l'on ait accordé 1 h ou 2 h, cela se termine toujours par des cris « J'ai à peine fait 2 parties ! Ça fait même pas 10 mn que je joue ! ». La solution : ne plus intervenir directement !

Par le même auteur

Créer une application Perl autour de MySQL : Intégration avec Mojolicious, HTML::Tiny et HTML::FormHandler (3/3)

Magazine
Marque
GNU/Linux Magazine
Numéro
169
|
Mois de parution
mars 2014
|
Domaines
Résumé
Reprenons l'histoire du hacker à qui on a demandé de créer des pages web pour le suivi de la production logicielle de la société. Comme tout hacker qui se respecte, il préfère que la machine fasse son boulot à sa place. Pour ce faire, il a mis en place une base de données MySQL, un ORM (DBIx:Class). Reste maintenant à fournir un serveur web pour exploiter les données de cette base.

Créer une application Perl autour de MySQL : DBIx::Class (2/3)

Magazine
Marque
GNU/Linux Magazine
Numéro
168
|
Mois de parution
février 2014
|
Domaines
Résumé

Reprenons l'histoire du hacker à qui on a demandé de créer des pages web pour le suivi de la production logicielle de la société. Comme tout hacker qui se respecte, il préfère que la machine fasse son boulot à sa place. Pour ce faire, il a mis en place une base de données MySQL. Reste maintenant à utiliser Perl et DBIx::Class pour accéder aux données de cette base.

P... de proxy, le retour

Magazine
Marque
GNU/Linux Magazine
Numéro
152
|
Mois de parution
septembre 2012
|
Domaines
Résumé
L'article « P... de proxy» a expliqué comment utiliser tinyproxy pour se simplifier la vie sur un ordinateur nomade. Cette suite (c'est la mode au cinéma) va expliquer comment étendre la solution proposée pour gérer d'autres proxys (genre proxy-cache pour serveur de paquets) et surtout faire une commutation automatique de proxy pour atteindre le Saint-Graal des hackers : la machine s'occupe de tout et moi de rien :-)

Config::Model - Créer un éditeur graphique de configuration avec Perl (2e partie)

Magazine
Marque
GNU/Linux Magazine
Numéro
120
|
Mois de parution
octobre 2009
|
Résumé
Dans un article précédant [GLMF], nous avons vu comment créer la partie graphique d'un éditeur de configuration en précisant la structure et les contraintes des données du fichier /etc/ssh/sshd_config. Config::Model va utiliser cette structure (le modèle de la configuration de sshd_config) pour générer l'interface graphique. Mais il reste à pouvoir charger les données du fichier et les ré-écrire. Nous allons voir dans cette deuxième partie comment utiliser l'API de Config::Model pour lire et écrire les données de sshd_config.

Config::Model – Créer un éditeur graphique de configuration avec Perl (1ère partie)

Magazine
Marque
GNU/Linux Magazine
Numéro
117
|
Mois de parution
juin 2009
|
Résumé
La configuration d'une application est très souvent le premier obstacle que doit franchir un utilisateur avant de pouvoir utiliser une application. Le plus souvent, l'utilisateur est dirigé vers un fichier qu'il doit éditer avec « son éditeur favori ». Peu d'applications proposent une interface plus conviviale. Pour combler cette lacune, cet article décrit comment créer un éditeur de configuration d'une manière simple et maintenable. Dans la première partie de cet article, nous allons spécifier le modèle de sshd_config, c'est-à-dire sa structure et ses contraintes. Ce modèle permettra à Config::Model de générer l'interface graphique. Nous verrons dans une seconde partie comment lire et écrire les données de sshd_config pour les charger dans l'interface.