#!/usr/bin/env perl
#
# medalleroLondres2012P.pl
#
# Autor:
# Joaquín Ferrero
#
# Descripción:
# Actualización automática del medallero olímpico en Wikipedia
# para los Juegos Paralímpicos Londres 2012.
#
# Entrada: ninguna
# Salida: ninguna
#
# Historial:
# 2012.08.31 : Versión para Londres 2012 Paralímpicos
# 2012.07.31 : Versión para Londres 2012
# 2010.03.20 : Versión para Sudamericanos Medellin 2010
# 2010.03.13 : Versión para Vancouver 2010 Paralimpicos
# 2010.02.16 : Versión para Vancouver 2010
# 2008.09.07 : Versión inicial para Pekín 2008
#
### Bibliotecas -------------------------------------------------------------
use Modern::Perl 2012; # Programamos en Perl moderno
use autodie; # «Es mejor morir que regresar con deshonor» --proverbio Klingon
use utf8::all; # Activar todo el soporte para UTF-8. Realmente todo
use Mojo::UserAgent; # Un poco de mojo...
use MediaWiki::API; # Y mucha Wikipedia
### Configuración -----------------------------------------------------------
my $COUNTRY = 'GBR';
my $MEDALLERO_OFICIAL = 'http://www.london2012.com/paralympics/medals/medal-count/';
my $WIKIPEDIA_MEDALLERO = 'Anexo:Medallero de los Juegos Paralímpicos de Londres 2012';
my $WIKIPEDIA_TEST_PAGE = 'Wikipedia:Zona de pruebas/5';
my $WIKIPEDIA_USER_LOG = 'JoaquinFerrero';
my $WIKIPEDIA_USER_PAS = 'contraseña';
my $WIKIPEDIA_API_URL = 'http://es.wikipedia.org/w/api.php';
my $DEBUG = 0; #0 (sin avisos) o 1 (con avisos)
## Obtención de los resultados ----------------------------------------------
my $medallero_html;
for my $retry (0 .. 2) {
my $ua = Mojo::UserAgent->new(
name => 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:14.0) Mojolicious/2012 Wikipedia/es',
request_timeout => 5,
);
$medallero_html = $ua->get(
$MEDALLERO_OFICIAL,
{
'Accept' => 'text/html',
'Referer' => 'http://www.london2012.com/',
'Accept-Encoding' => 'none',
'DNT' => 1,
'Accept-Language' => 'es,es-es;q=0.8,en;q=0.5,en-us;q=0.3',
}
)->res->dom->find("div[id=lgc-main]")->[0];
last if defined $medallero_html;
sleep 30;
}
die "ERROR: No he podido leer la página del medallero oficial\n"
if not defined $medallero_html;
## Extracción de resultados -------------------------------------------------
my @tabla_medallero_oficial; # $tabla_medallero_oficial[$i] = [$posicion,$pais,@medallas,$total]
my %attr_to_pos = (
position => 0,
country => 1,
gold => 2,
silver => 3,
bronze => 4,
total => 5,
);
my @filas = $medallero_html->find("tr")->each;
for my $fila (@filas) {
next if $fila !~ /<td class="position/;
my @celdas = $fila->find("td")->each;
my @resultado_pais;
for my $celda (@celdas) {
my($clase)= $celda =~ /class="(\w+)/;
my $contenido = $celda->text;
if ($clase eq 'athleteInfo') { # código del país
$clase = 'country';
($contenido) = $celda =~ m{([^/]+?)\.png};
}
if (exists $attr_to_pos{$clase}) {
$resultado_pais[ $attr_to_pos{$clase} ] = $contenido;
}
}
push @tabla_medallero_oficial, [ @resultado_pais ] if @resultado_pais;
}
die "ERROR: No he leído la tabla del medallero oficial"
if ! @tabla_medallero_oficial;
## Conexión con Wikipedia ---------------------------------------------------
my $Wikipedia = MediaWiki::API->new({
api_url => $WIKIPEDIA_API_URL,
retries => 3,
retry_delay => 30,
});
$Wikipedia->login({
lgname => $WIKIPEDIA_USER_LOG,
lgpassword => $WIKIPEDIA_USER_PAS,
})
or die $Wikipedia->{error}->{code} . ': ' . $Wikipedia->{error}->{details};
## Medallero en formato wiki ------------------------------------------------
my @totales_medallero; # Almacena la suma de las medallas
my $se_ha_puesto_el_aviso = 0;
my $medallero_wiki = <<"EOF";
== Medallero ==
<!--
ATENCIÓN: La tabla se actualiza de forma automática cada 5 min. durante el periodo de los juegos.
CUALQUIER cambio realizado de forma manual se perderá.
AVISAR de incidencias a JoaquinFerrero.
--></noinclude>
{| {{Medallero|tipo = 1|ancho = 60%}}
EOF
foreach my $fila (@tabla_medallero_oficial) {
my @medallas = @{$fila}[2 .. 5]; # Desde Oro a total
map { $totales_medallero[$_-2] += $fila->[$_] } 2 .. 5; # Cálculo de los totales
if ($fila->[0] > 10 and ! $se_ha_puesto_el_aviso++) { # Poner nota de corte a los diez primeros clasificados
$medallero_wiki .= qq(<includeonly><!-- Para cerrar la tabla en el artículo principal -->|}</includeonly><noinclude>\n);
}
$medallero_wiki .= '|-'; # Nueva fila del medallero
$medallero_wiki .= '-bgcolor=ccccff' if $fila->[1] eq $COUNTRY; # País orgnizador
$medallero_wiki .= "\n"
. qq(|'''$fila->[0]'''\n)
. '|' . join(' || ', "{{BanderaPL|$fila->[1]|Londres 2012}}", @{$fila}[2 .. 5] ) . "\n"
;
}
# Totales y fin de la tabla
$medallero_wiki .= "|-\n" . join(' || ', '! colspan="2" | Total', @totales_medallero) . "\n|}";
$medallero_wiki .= '<noinclude>' if not $se_ha_puesto_el_aviso;
$medallero_wiki .= "\n\n";
## Actualización de la página del medallero ---------------------------------
my $pagina_wiki; # Contenido de la página wiki actual
my $pagina_antes_wiki; # Contenido de la página wiki anterior
my $titulo_pagina_wiki = $WIKIPEDIA_MEDALLERO; # $WIKIPEDIA_TEST_PAGE
my $pagina_wiki_ref = $Wikipedia->get_page({
title => $titulo_pagina_wiki,
});
die "ERROR: No conseguí la página del medallero\n"
if $pagina_wiki_ref->{missing};
$pagina_wiki = $pagina_antes_wiki = $pagina_wiki_ref->{'*'}; # Cómo es la página ahora
# Intentamos hacer un cambio
if ($pagina_wiki =~ s/^=+ Medallero =+.+?(?=^=)/$medallero_wiki/sm) {
if ($pagina_wiki ne $pagina_antes_wiki) { # Si hay realmente un cambio, la editamos
$Wikipedia->edit({
action => 'edit',
title => $titulo_pagina_wiki,
basetimestamp => $pagina_wiki_ref->{timestamp},
text => $pagina_wiki,
summary => 'Actualización automática del medallero',
})
or die $Wikipedia->{error}->{code} . ': ' . $Wikipedia->{error}->{details}
;
say 'Actualizado medallero' if $DEBUG;
}
else {
say 'No hay cambios' if $DEBUG;
}
}
else {
die 'ERROR: no encuentro la sección del medallero en la página';
}
__END__