Interfaces gráficas en Perl: Como embellecer a un camello
Publicado por josevnz 4 Junio 2006 en General, How To's, Perl, Software Libre / Abierto, XML, linux. english • español
En mi blog escribí hace tiempo un articulo que mostraba como bajarse todas las imagenes públicas de una persona en Flickr utilizando Perl y Java, todo eso usando el API de Flick. Para refrescar la memoria les coloco aquí lo que hize con el módulo 'Flickr::API'; Si no lo tiene y utiliza Linux, entonces utilice CPAN para montarlo: perl -MCPAN -e 'install Flickr::API':
-
Running make install
-
Installing /usr/lib/perl5/site_perl/5.8.6/Flickr/API.pm
-
Installing /usr/lib/perl5/site_perl/5.8.6/Flickr/API/Response.pm
-
Installing /usr/lib/perl5/site_perl/5.8.6/Flickr/API/Request.pm
-
Installing /usr/share/man/man3/Flickr::API.3pm
-
Installing /usr/share/man/man3/Flickr::API::Response.3pm
-
Installing /usr/share/man/man3/Flickr::API::Request.3pm
-
Writing /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/Flickr/API/.packlist
-
Appending installation info to /usr/lib/perl5/5.8.6/i386-linux-thread-multi/perllocal.pod
-
/usr/bin/make install -- OK
El código erá muy sencillo, sólo le pasabas como parametros la clave de Flickr y el usuario de el cual te quieras bajar las fotos y listo:
-
#!/usr/bin/perl
-
use strict;
-
use Flickr::API;
-
use Data::Dumper;
-
use LWP::UserAgent;
-
-
# Put your Flickr key here:
-
use constant API_KEY => 'xxx';
-
use constant PER_PAGE => 500;
-
use constant PAGE => 1;
-
use constant DEBUG => 0;
-
-
die "[ERROR]: Please provide the user ID!";
-
} else {
-
}
-
my $api = new Flickr::API({
-
'key' => API_KEY}
-
);
-
my $ua = LWP::UserAgent->new;
-
# Get the user NSID first
-
my $response = $api->execute_method(
-
'flickr.people.findByUsername', {
-
'username' => $ARGV[0]
-
});
-
if (! $response->{success}) {
-
}
-
# Parse the tree and get the NSID
-
my %tree = %{$response->{tree}};
-
# Cheat with 'print Dumper($tree);' to get the value I want right away
-
my $id = $tree{children}->[1]->{attributes}->{nsid};
-
if (DEBUG) {
-
}
-
# Get now the list of public photos
-
$response = $api->execute_method(
-
'flickr.photos.search', {
-
'user_id' => $id
-
});
-
%tree = %{$response->{tree}};
-
# Get the photo information. For that we get a more manageable structure
-
my @subtree = @{$tree{children}->[1]->{children}};
-
if (DEBUG) {
-
}
-
foreach my $ref (@subtree) {
-
my $attributes = $$ref{attributes};
-
# Construct the URL like this:
-
# http://photos{server-id}.flickr.com/{id}_{secret}_o.(jpg|gif|png)
-
my $url = "http://photos" .
-
$$attributes{'server'} .
-
".flickr.com/" .
-
$$attributes{'id'} .
-
"_" .
-
$$attributes{'secret'} .
-
"_o.jpg";
-
$ua->mirror(
-
$url,
-
$$attributes{'id'} . "_" . $$attributes{'secret'} . "_o.jpg"
-
);
-
if ($response->is_success) {
-
printf "OK\n";
-
} else {
-
printf "ERROR\n";
-
}
-
-
}
-
__END__
-
-
=head1 NAME
-
-
DownloadPictures.plx - A program that downloads all the public pictures for
-
a given user, from Flickr.com
-
-
=head1 DESCRIPTION
-
-
This program uses the API as described in 'http://www.flickr.com/services/api/',
-
and uses the Perl module Flickr::API (http://search.cpan.org/~iamcal/Flickr-API/).
-
-
How to use:
-
-
./DownloadPublicPictures.plx <flickr user name>
-
-
=head1 AUTHOR
-
-
Jose Vicente Nunez Zuleta
-
-
=head1 BLOG
-
-
El Angel Negro - http://elangelnegro.blogspot.com
-
-
=head1 LICENSE
-
-
GPL
-
-
=cut
El script es sencillo, fácil de usar y feo :). El script trabaja más o menos así:
-
Getting list of public pictures for 'josevnz'
-
Downloading: Picture -> http://photos48.flickr.com/154791207_7f1c2cb3e5_o.jpg...OK
-
Downloading: bombones 005 -> http://photos55.flickr.com/151559225_c38baad4ff_o.jpg...OK
-
Downloading: bombones 004 -> http://photos49.flickr.com/151558983_8bcec2dcc1_o.jpg...OK
-
Downloading: bombones 003 -> http://photos47.flickr.com/151558718_5d7be20c4d_o.jpg...OK
-
Downloading: bombones 002 -> http://photos52.flickr.com/151558495_4445aab3d2_o.jpg...OK
-
Downloading: bombones 001 -> http://photos44.flickr.com/151558324_d362c91b31_o.jpg...OK
-
Downloading: backup index -> http://photos52.flickr.com/145892133_f3da092eaa_o.jpg...OK
-
Downloading: Stop -> http://photos49.flickr.com/141706199_5189a46d1e_o.jpg...OK
-
Downloading: Cross -> http://photos46.flickr.com/141706096_af843c443c_o.jpg...OK
Seria mejor tener un script que mostrara los resultados en una ventana aparte, así que para reusar el código escrito en Perl usamos Perl Tk.
NOTA: Si usted utiliza Fedora 4 entonces puede instalar Perl TK de la siguiente manera (como root):
-
[root@localhost ~]# yum install perl-Tk
-
Setting up Install Process
-
Setting up repositories
-
livna 100% |=========================| 951 B 00:00
-
updates-released 100% |=========================| 951 B 00:00
El código completo que hace el truco es el siguiente:
-
#!/usr/bin/perl
-
use strict;
-
use Flickr::API;
-
use Data::Dumper;
-
use LWP::UserAgent;
-
use Tk;
-
use Tk::ProgressBar;
-
use Tk::ROText;
-
use Tk::Balloon;
-
use Tk::DialogBox;
-
-
# Put your Flickr key here:
-
use constant API_KEY => 'xxxx';
-
use constant PER_PAGE => 500;
-
use constant PAGE => 1;
-
use constant DEBUG => 0;
-
-
my $flickrId;
-
my $percent_done;
-
-
printf "Starting application...\n";
-
my $mainWindow = MainWindow->new(-title => 'KodeGeek.com: Download Flickr public pictures');
-
$mainWindow->geometry('+500+300');
-
# Create a simple menu
-
my $menu = $mainWindow->Frame()->pack(-side => 'top', -fill => 'x');
-
my $filemenu = $menu->Menubutton(
-
-text => 'File',
-
-underline => 0
-
)->pack(-side => 'left');
-
$filemenu->command(
-
-label => 'Quit',
-
-underline => 0,
-
-accelerator => 'Meta+Q',
-
-command => \&quit
-
);
-
my $frame = $mainWindow->Frame()->pack(-side => 'bottom', -fill => 'both');
-
# Create the main window contents. Use more frames to align the components
-
my $topFrame = $frame->Frame()->pack(-side => 'top', -fill => 'both');
-
my $label = $topFrame->Label(
-
-text => 'Flickr user ID'
-
)->pack(-side => "left")->pack();
-
my $text = $topFrame->Entry(
-
-textvariable => \$flickrId
-
)->pack(-side => "right", -fill => "x", -expand => 'x')->pack();
-
my $bText = $mainWindow->Balloon();
-
$bText->attach($text,-balloonmsg => "Please, type the Flickr ID with public photos");
-
my $textArea = $frame->Scrolled(
-
'ROText',
-
-width => 60,
-
-height => 30
-
)->pack(-side => "bottom", -fill => "y")->pack();
-
my $download = $frame->Button(
-
-text => 'Download pictures',
-
-command => [\&getPhotos, \$flickrId, $mainWindow, $textArea, $text]
-
)->pack(-side => "bottom", -fill => "x")->pack(-padx=>15, -pady=>15);
-
my $dBaloom = $mainWindow->Balloon();
-
$dBaloom->attach($download,-balloonmsg => "Click here to download the photos!");
-
-
MainLoop();
-
-
# Quit the app
-
sub quit() {
-
$mainWindow->destroy();
-
printf "Exiting application...\n";
-
exit;
-
}
-
-
# Get the public photos from Flickr
-
sub getPhotos {
-
my $id = ${$_[0]};
-
my $mainWindow = $_[1];
-
my $textArea = $_[2];
-
-
$mainWindow->update();
-
my $api = new Flickr::API({
-
'key' => API_KEY}
-
);
-
my $ua = LWP::UserAgent->new;
-
# Get the user NSID first
-
my $response = $api->execute_method(
-
'flickr.people.findByUsername', {
-
'username' => $id
-
});
-
if (! $response->{success}) {
-
}
-
$download->configure(-state => 'disabled');
-
$filemenu->configure(-state => 'disabled');
-
$text->configure(-state => 'disabled');
-
$text->delete('1.0', 'end');
-
# Parse the tree and get the NSID
-
my %tree = %{$response->{tree}};
-
# Cheat with 'print Dumper($tree);' to get the value I want right away
-
my $id = $tree{children}->[1]->{attributes}->{nsid};
-
if (DEBUG) {
-
}
-
# Get now the list of public photos
-
$response = $api->execute_method(
-
'flickr.photos.search', {
-
'user_id' => $id
-
});
-
%tree = %{$response->{tree}};
-
# Get the photo information. For that we get a more manageable structure
-
my @subtree = @{$tree{children}->[1]->{children}};
-
if (DEBUG) {
-
}
-
my $position = 0;
-
-
# Collect the real list of URL to download:
-
my %urlList = ();
-
# Get the list of photos
-
$textArea->insert('end', "Getting list of photos from Flickr\n");
-
$mainWindow->update();
-
foreach my $ref (@subtree) {
-
my $attributes = $$ref{attributes};
-
# Construct the URL like this:
-
# http://photos{server-id}.flickr.com/{id}_{secret}_o.(jpg|gif|png)
-
my $url = "http://photos" .
-
$$attributes{'server'} .
-
".flickr.com/" .
-
$$attributes{'id'} .
-
"_" .
-
$$attributes{'secret'} .
-
"_o.jpg";
-
$urlList{$url}->{DEST} = $$attributes{'id'} . "_" . $$attributes{'secret'} . "_o.jpg";
-
$urlList{$url}->{TITLE} = $$attributes{'title'};
-
} # end for-each
-
$mainWindow->update();
-
$ua->mirror($url, $urlList{$url}->{DEST});
-
if ($response->is_success) {
-
} else {
-
}
-
$mainWindow->update();
-
}
-
$filemenu->configure(-state => 'normal');
-
$download->configure(-state => 'normal');
-
$text->configure(-state => 'normal');
-
}
-
-
__END__
-
-
=head1 NAME
-
-
flickr_download_public_pic.pl - A program that downloads all the public pictures for
-
a given user, from Flickr.com
-
-
=head1 DESCRIPTION
-
-
This program uses the API as described in 'http://www.flickr.com/services/api/',
-
and uses the Perl module Flickr::API (http://search.cpan.org/~iamcal/Flickr-API/).
-
-
=head1 AUTHOR
-
-
Jose Vicente Nunez Zuleta
-
-
=head1 BLOG
-
-
KodeGeek - http://kodegeek.com
-
-
=head1 LICENSE
-
-
GPL
-
-
=cut
Algunas cosas interesantes:
- La función que hacia la llamada a Flickr::API fué re-escrita para recibir información acerca de los componentes gráficos que hay que actualizar. No es la mejor práctica, pero hace el trabajo y mantiene el código simple
- Note como llamamos a la función '$mainWindow->update()'. La idea es actualizar los componentes gráficos cada vez que hay un cambio.
- La lista de componentes gráficos es bastante completa. Pueden darle un vistazo en el sitio de CPAN. Sin embargo la documentación realmente apesta.
- Perl TK y Java Swing son muy similares; En Perl Tk podemos controlar la ubicación de los componentes usando un layout manager como pack() (o grid el cual no mostré en el ejemplo).
- El manejo de eventos se hace utilizando callbacks (-command, -textvariable)
Finalmente los dejo con unos articulos interesantes sobre el tema, los cuales espero despertarán aún más su curiosidad:
- Introducción a Perl TK
- Otro articulo, muestra un sistema de pago
- El sitio oficial de Perl Tk/
- Tutorial acerca de como utilizar "widgets", con buenos ejemplos
Por cierto, se puede bajar el código fuente desde acá.
0 Respuestas a “Interfaces gráficas en Perl: Como embellecer a un camello”
Por favor Espera
Añade un Comentario