#!/usr/bin/perl
# *- encode: utf8. tabs: 4 spaces. -*
#
# medalleroVancouver2010.pl
#
# Autor:
# Joaquín Ferrero
#
# Descripción:
# Actualización automática del medallero olímpico en Wikipedia para los Juegos Olímpicos de Vancouver 2010.
#
# La conexión entre la página oficial y la información de Wikipedia se realiza con los códigos de país que
# el COI asigna a cada uno: http://es.wikipedia.org/wiki/C%C3%B3digos_nacionales_del_COI
#
# Entrada: ninguna
# Salida: ninguna
#
# Historial:
# 2010.02.16 : Versión para Vancouver 2010
# 2008.09.07 : Versión inicial para Pekín 2008
#
## Bibliotecas
use common::sense; # Siempre hay que tener sentido común
use LWP::Simple;
use MediaWiki::API;
## Constantes
my $MEDALLERO_OFICIAL = 'http://www.vancouver2010.com/olympic-medals/';
my $WIKIPEDIA_VANCOUVER2010 = 'Juegos Olímpicos de Vancouver 2010';
my $WIKIPEDIA_MEDALLERO_VANCOUVER2010 = 'Anexo:Medallero de los Juegos Olímpicos de Vancouver 2010';
my $WIKIPEDIA_TEST_PAGE = 'Wikipedia:Zona de pruebas';
my $AVISO = qq(<includeonly><!-- Para cerrar la tabla en el artículo principal -->|}</includeonly><noinclude><!--
Para que automáticamente se genere una lista de sólo 10 países en el artículo principal, mover el tag "noinclude"
tras los 10 mejores países clasificados -->\n);
## Variables
my %paises; # $paises{SVK} = "{{BanderaOL|Eslovaquia|SVK|ed=Vancouver 2010}}"
my $medallero_oficial; # Resultados del medallero desde el sitio oficial
my @tabla_medallero_oficial; # $tabla_medallero_oficial[$i] = [$posicion,$pais,@medallas,$total]
my $wiki_medallero; # Tabla del medallero en formato wiki
my @totales_medallero; # Almacena la suma de las medallas
my $wiki_pagina; # Contenido de la página en formato wiki
## Configuración
my $DEBUG = 1; # 1: Dar información extra en la salida estándar. 0: No
my $wikipedia_resultado = $WIKIPEDIA_MEDALLERO_VANCOUVER2010; # Para hacer pruebas, cambiar esta variable a $WIKIPEDIA_TEST_PAGE
# En producción, cambiarla por $WIKIPEDIA_MEDALLERO_VANCOUVER2010
## Conexión con Wikipedia
my $mw = MediaWiki::API->new({
api_url => 'http://es.wikipedia.org/w/api.php',
retries => 3,
retry_delay => 30,
});
$mw->login({
lgname => 'JoaquinFerrero',
lgpassword => 'contraseña',
})
or die $mw->{error}->{code} . ': ' . $mw->{error}->{details};
## Obtención de la lista de los países participantes
while (my $l = <DATA>) { # Primero, desde la sección DATA
chomp $l;
my ($id, $valor) = split " ", $l, 2;
$paises{$id} = $valor;
}
if (!%paises) { # Si no hay DATA, entonces desde la propia página web de Wikipedia
$wiki_pagina = $mw->get_page({ title => $WIKIPEDIA_VANCOUVER2010 })->{'*'};
# Buscamos las banderas de los participantes
while ($wiki_pagina =~ /BanderaOL\|(.+?)\|(...)\|(ed=.*?)\}/simog) {
$paises{$2} = "{{BanderaOL|$1|$2|$3}}";
}
die "ERROR: la página de los Juegos no es correcta\n" if ! %paises;
# Modificación del programa, en la sección DATA
open my $yo_mismo, q[>>], $0 or die "ERROR: No puede añadir a $0\n";
binmode $yo_mismo, ':utf8';
while(my($p,$v) = each %paises) {
say $yo_mismo "$p $v";
}
close $yo_mismo;
say 'Actualizado el programa medallero.pl' if $DEBUG;
}
die "ERROR: no tengo una lista correcta de países\n" if ! %paises;
## Página con los resultados oficiales
$medallero_oficial = get($MEDALLERO_OFICIAL);
die "ERROR: No conseguí los resultados de medallas\n" if not $medallero_oficial;
my ($seccion_medallas) = $medallero_oficial =~ m{<div class="dataTable medalDataTable medalCount">(.*?)</div>}smio;
while($seccion_medallas =~ m{<tr .*? > (.*?) </tr>}smigox) {
my $datos = $1;
my($pais) = $datos =~ /<td class="c2".*? flag(...)"/io;
my($oro) = $datos =~ /<td class="c3">(\d+)/io;
my($plata) = $datos =~ /<td class="c4">(\d+)/io;
my($bronze) = $datos =~ /<td class="c5">(\d+)/io;
if ($paises{$pais}) {
$pais = $paises{$pais};
push @tabla_medallero_oficial, [ $pais, $oro, $plata, $bronze, $oro+$plata+$bronze ];
}
elsif ($pais) {
say "ERROR: No tengo código para el país [$pais]:\n$datos";
}
}
die "ERROR: No he leído medallero oficial" if ! @tabla_medallero_oficial;
# Ordenación según el número de medallas oro, plata y bronce
@tabla_medallero_oficial
= sort {
$b->[1] <=> $a->[1] # Oro
||
$b->[2] <=> $a->[2] # Plata
||
$b->[3] <=> $a->[3] # Bronze
||
$a->[0] cmp $b->[0] # Nombre del país
}
@tabla_medallero_oficial
;
# Inserción del número de posición
my $cuenta_filas;
my $cuenta_posicion;
my $anterior_pais_medallero = '';
for my $pais_ref (@tabla_medallero_oficial) {
$cuenta_filas++;
my $pais_medallero = join ',', @{ $pais_ref }[1..4]; # Vemos el aspecto de las medallas
if ($pais_medallero ne $anterior_pais_medallero) { # Si el medallero del país es distinto del anterior país
$cuenta_posicion = $cuenta_filas; # actualizamos el contador de posición al de las filas
}
unshift @{$pais_ref}, $cuenta_posicion; # agregamos la posición en
# la primera posición de la información de cada país
$anterior_pais_medallero = $pais_medallero;
}
## Medallero en formato wiki
$wiki_medallero = <<"EOF";
== Medallero ==
</noinclude><!--
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á.
-->{| {{Medallero|style=text-align:right;}}
EOF
my $se_ha_puesto_el_aviso = 0;
foreach my $fila (@tabla_medallero_oficial) {
if ($fila->[0] > 10 and ! $se_ha_puesto_el_aviso++) { # Poner nota de corte a los diez primeros clasificados
$wiki_medallero .= $AVISO;
}
$wiki_medallero # Cada $fila del medallero
.= "|-\n"
. "|'''$fila->[0]'''\n"
. join( q{||align=center|}, "|align=left|$fila->[1]", @{$fila}[2 .. 5] )
. "\n"
;
map { $totales_medallero[$_-2] += $fila->[$_] } 2 .. 5; # Cálculo de los totales
}
# Totales y fin de la tabla
$wiki_medallero
.= qq(|-class="sortbottom"\n)
. join('||align=center|', "!colspan=2| '''Total'''", @totales_medallero) . "\n|}"
;
if (not $se_ha_puesto_el_aviso) {
$wiki_medallero .= '<noinclude>';
}
$wiki_medallero .= "\n\n";
## Actualización de la página del medallero
my $wiki_pagina_ref = $mw->get_page({ title => $wikipedia_resultado });
die "ERROR: No conseguí la página del medallero\n" if $wiki_pagina_ref->{missing};
my $wiki_pagina_antes = $wiki_pagina = $wiki_pagina_ref->{'*'}; # Cómo es la página ahora
# Hacemos la actualización
if ($wiki_pagina =~ s/^== Medallero ==.+?(?=^==)/$wiki_medallero/sm) {
if ($wiki_pagina ne $wiki_pagina_antes) { # Si hay realmente un cambio la editamos
$mw->edit({
action => 'edit',
title => $wikipedia_resultado,
basetimestamp => $wiki_pagina_ref->{timestamp},
text => $wiki_pagina,
summary => 'Actualización automática del medallero',
})
or die $mw->{error}->{code} . ': ' . $mw->{error}->{details}
;
say 'Actualizado medallero' if $DEBUG;
}
}
## Datos fijos
# Si se limpia esta sección, la próxima ejecución del programa lo rellenará con la lista de los países participantes,
# extraída de la página de los Juegos en Wikipedia.
__DATA__
IRI {{BanderaOL|Irán|IRI|ed=Vancouver 2010}}
BUL {{BanderaOL|Bulgaria|BUL|ed=Vancouver 2010}}
ISR {{BanderaOL|Israel|ISR|ed=Vancouver 2010}}
NZL {{BanderaOL|Nueva Zelanda|NZL|ed=Vancouver 2010}}
BIH {{BanderaOL|Bosnia y Herzegovina|BIH|ed=Vancouver 2010}}
SUI {{BanderaOL|Suiza|SUI|ed=Vancouver 2010}}
NEP {{BanderaOL|Nepal|NEP|ed=Vancouver 2010}}
ROU {{BanderaOL|Rumania|ROU|ed=Vancouver 2010}}
MGL {{BanderaOL|Mongolia|MGL|ed=Vancouver 2010}}
RUS {{BanderaOL|Rusia|RUS|ed=Vancouver 2010}}
UZB {{BanderaOL|Uzbekistán|UZB|ed=Vancouver 2010}}
LAT {{BanderaOL|Letonia|LAT|ed=Vancouver 2010}}
ALB {{BanderaOL|Albania|ALB|ed=Vancouver 2010}}
DEN {{BanderaOL|Dinamarca|DEN|ed=Vancouver 2010}}
BEL {{BanderaOL|Bélgica|BEL|ed=Vancouver 2010}}
TPE {{BanderaOL|China Taipei|TPE|ed=Vancouver 2010}}
ARM {{BanderaOL|Armenia|ARM|ed=Vancouver 2010}}
AUT {{BanderaOL|Austria|AUT|ed=Vancouver 2010}}
PRK {{BanderaOL|Corea del Norte|PRK|ed=Vancouver 2010}}
MKD {{BanderaOL|Macedonia|MKD|ed=Vancouver 2010}}
CAN {{BanderaOL|Canadá|CAN|ed=Vancouver 2010}}
POL {{BanderaOL|Polonia|POL|ed=Vancouver 2010}}
LIE {{BanderaOL|Liechtenstein|LIE|ed=Vancouver 2010}}
COL {{BanderaOL|Colombia|COL|ed=Vancouver 2010}}
SVK {{BanderaOL|Eslovaquia|SVK|ed=Vancouver 2010}}
GRE {{BanderaOL|Grecia|GRE|ed=Vancouver 2010}}
ETH {{BanderaOL|Etiopía|ETH|ed=Vancouver 2010}}
SMR {{BanderaOL|San Marino|SMR|ed=Vancouver 2010}}
BLR {{BanderaOL|Bielorrusia|BLR|ed=Vancouver 2010}}
ITA {{BanderaOL|Italia|ITA|ed=Vancouver 2010}}
LTU {{BanderaOL|Lituania|LTU|ed=Vancouver 2010}}
CHI {{BanderaOL|Chile|CHI|ed=Vancouver 2010}}
FIN {{BanderaOL|Finlandia|FIN|ed=Vancouver 2010}}
TUR {{BanderaOL|Turquía|TUR|ed=Vancouver 2010}}
FRA {{BanderaOL|Francia|FRA|ed=Vancouver 2010}}
BRA {{BanderaOL|Brasil|BRA|ed=Vancouver 2010}}
ISL {{BanderaOL|Islandia|ISL|ed=Vancouver 2010}}
SWE {{BanderaOL|Suecia|SWE|ed=Vancouver 2010}}
HUN {{BanderaOL|Hungría|HUN|ed=Vancouver 2010}}
EST {{BanderaOL|Estonia|EST|ed=Vancouver 2010}}
MEX {{BanderaOL|México|MEX|ed=Vancouver 2010}}
LIB {{BanderaOL|Líbano|LIB|ed=Vancouver 2010}}
IND {{BanderaOL|India|IND|ed=Vancouver 2010}}
CRO {{BanderaOL|Croacia|CRO|ed=Vancouver 2010}}
JPN {{BanderaOL|Japón|JPN|ed=Vancouver 2010}}
POR {{BanderaOL|Portugal|POR|ed=Vancouver 2010}}
TJK {{BanderaOL|Tayikistán|TJK|ed=Vancouver 2010}}
GEO {{BanderaOL|Georgia|GEO|ed=Vancouver 2010}}
CHN {{BanderaOL|China|CHN|ed=Vancouver 2010}}
CYP {{BanderaOL|Chipre|CYP|ed=Vancouver 2010}}
PAK {{BanderaOL|Pakistán|PAK|ed=Vancouver 2010}}
MNE {{BanderaOL|Montenegro|MNE|ed=Vancouver 2010}}
SRB {{BanderaOL|Serbia|SRB|ed=Vancouver 2010}}
NOR {{BanderaOL|Noruega|NOR|ed=Vancouver 2010}}
MAR {{BanderaOL|Marruecos|MAR|ed=Vancouver 2010}}
ESP {{BanderaOL|España|ESP|ed=Vancouver 2010}}
CAY {{BanderaOL|Islas Caimán|CAY|ed=Vancouver 2010}}
BER {{BanderaOL|Bermudas|BER|ed=Vancouver 2010}}
KOR {{BanderaOL|Corea del Sur|KOR|ed=Vancouver 2010}}
AND {{BanderaOL|Andorra|AND|ed=Vancouver 2010}}
MDA {{BanderaOL|Moldavia|MDA|ed=Vancouver 2010}}
SLO {{BanderaOL|Eslovenia|SLO|ed=Vancouver 2010}}
KAZ {{BanderaOL|Kazajistán|KAZ|ed=Vancouver 2010}}
GER {{BanderaOL|Alemania|GER|ed=Vancouver 2010}}
RSA {{BanderaOL|Sudáfrica|RSA|ed=Vancouver 2010}}
MON {{BanderaOL|Mónaco|MON|ed=Vancouver 2010}}
GBR {{BanderaOL|Reino Unido|GBR|ed=Vancouver 2010}}
JAM {{BanderaOL|Jamaica|JAM|ed=Vancouver 2010}}
UKR {{BanderaOL|Ucrania|UKR|ed=Vancouver 2010}}
AUS {{BanderaOL|Australia|AUS|ed=Vancouver 2010}}
PER {{BanderaOL|Perú|PER|ed=Vancouver 2010}}
USA {{BanderaOL|Estados Unidos|USA|ed=Vancouver 2010}}
SEN {{BanderaOL|Senegal|SEN|ed=Vancouver 2010}}
AZE {{BanderaOL|Azerbaiyán|AZE|ed=Vancouver 2010}}
GHA {{BanderaOL|Ghana|GHA|ed=Vancouver 2010}}
ARG {{BanderaOL|Argentina|ARG|ed=Vancouver 2010}}
CZE {{BanderaOL|República Checa|CZE|ed=Vancouver 2010}}
IRL {{BanderaOL|Irlanda|IRL|ed=Vancouver 2010}}
NED {{BanderaOL|Países Bajos|NED|ed=Vancouver 2010}}
ALG {{BanderaOL|Argelia|ALG|ed=Vancouver 2010}}
KGZ {{BanderaOL|Kirguistán|KGZ|ed=Vancouver 2010}}
HKG {{BanderaOL|Hong Kong|HKG|ed=Vancouver 2010}}