Usuario:JoaquinFerrero/MedalleroBaku2015
Apariencia
#!/usr/bin/env perl
# *- encode: utf8. tabs: 8 spaces. -*
#
# medalleroBaku2015.pl
#
# Autor:
# Joaquín Ferrero
#
# Descripción:
# Actualización automática de medalleros en Wikipedia.
#
# Entrada: ninguna
# Salida: ninguna
#
# Historial:
# 2015.06.13 : Versión Baku Europeos 2015
# 2014.03.07 : Versión Sochi Paralímpicos Invierno 2014
# 2014.02.08 : Versión Sochi Invierno 2014
# 2013.08.10 : Versión Moscú Atletismo 2013
# 2013.06.26 : Versión Mersin Mediterráneo 2013
# 2012.08.31 : Versión Londres Paralímpicos 2012
# 2012.07.31 : Versión Londres Verano 2012
# 2010.03.20 : Versión Medellin Sudamericanos 2010
# 2010.03.13 : Versión Vancouver Paralimpicos 2010
# 2010.02.16 : Versión Vancouver Invierno 2010
# 2008.09.07 : Versión Pekín Verano 2008
#
### Bibliotecas -------------------------------------------------------------
use v5.14.2;
use utf8::all; # Activar todo el soporte para UTF-8. Realmente todo
use MediaWiki::API; # Y mucha Wikipedia
use Mojo::UserAgent; # Un poco de mojo...
use Data::Dumper;
### Configuración -----------------------------------------------------------
my $PAÍS_ANFITRIÓN = 'AZE';
my $URL_MEDALLERO = 'http://www.baku2015.com/medals/index.html';
my $WIKIPEDIA_PÁGINA_MEDALLERO = 'Anexo:Medallero de los Juegos Europeos de Bakú 2015';
my $WIKIPEDIA_PÁGINA_TEST = 'Wikipedia:Zona de pruebas/5';
my $WIKIPEDIA_USUARIO_LOGIN = 'usuario';
my $WIKIPEDIA_USUARIO_PASSW = 'contraseña';
my $WIKIPEDIA_API_URL = 'http://es.wikipedia.org/eswiki/w/api.php';
my $título_página_wiki = $WIKIPEDIA_PÁGINA_MEDALLERO; # $WIKIPEDIA_PÁGINA_TEST
my $medallero_wiki_cabeza = <<'EOF';
== Medallero ==
<!--
_ _____ _____ _ _ ____ ___ __ _ _
/ \|_ _| ____| \ | |/ ___|_ _|/_/ | \ | |
/ _ \ | | | _| | \| | | | |/ _ \| \| |
/ ___ \| | | |___| |\ | |___ | | |_| | |\ |
/_/ \_\_| |_____|_| \_|\____|___\___/|_| \_|
Este medallero se actualiza de forma automática
cada 5 minutos durante el periodo de la competición.
Cualquier cambio realizado de forma manual se perderá.
Avisar de incidencias al usuario JoaquinFerrero.
--></noinclude>
EOF
my $medallero_wiki_aviso_corte = <<'EOP10';
<includeonly><!-- Para cerrar la tabla en el artículo principal -->|}</includeonly><noinclude><!--
Para que automáticamente se genere una lista de solo 10 países en el artículo principal, mover el tag "noinclude"
tras los 10 mejores países clasificados -->
EOP10
my $DEBUG = 0; # 0, 1 o 2
### Fin de configuración ----------------------------------------------------
## Obtención de los resultados ----------------------------------------------
my $ua = Mojo::UserAgent->new(
name => 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:14.0) Mojolicious/2015 Wikipedia/es',
request_timeout => 20,
);
my $medallero_html;
for my $retry (1 .. 3) { # Tres intentos
$medallero_html = $ua->get(
$URL_MEDALLERO,
{
}
)->res->dom->find("table#or-tbl-medal")->[0]; # CSS Selector
last if defined $medallero_html;
say "Intento fallido $retry..." if $DEBUG;
sleep 30;
}
die "ERROR: No he podido leer la página del medallero oficial\n"
if not defined $medallero_html;
## Datos de los países ------------------------------------------------------
my %países;
while (my $l = <DATA>) {
chomp $l;
# *{{bandera|AZE}} [[Azerbaiyán en los Juegos Europeos de Bakú 2015|Azerbaiyán]] <small>(AZE)</small> (289)
my @l = split " ", $l, 2;
my($id) = $l[0] =~ m/\|(.+?)\}/;
$l =~ s/ \(\d+\)$//;
$l =~ s/^\*//;
next if not $id;
$países{$id} = $l;
}
## Extracción de resultados -------------------------------------------------
my @tabla_medallero_oficial; # aquí guardamos el resultado de la extracción
my $posición = 1; # Renumeración de las posiciones
my $posición_absoluta = 1; # Posición real dentro del global de posiciones
for my $fila ($medallero_html->find("tr")->each) {
my $resultados; # resultados para un participante
my @celdas = map { $_->all_text } $fila->find("td")->each;
next if @celdas != 6;
$resultados->{'COI'} = $celdas[1]; # extraemos el código COI del país
my @medallas = map { 0 + $_ } @celdas[2..5]; # valores de las medallas (oro, plata, bronce, totales)
$resultados->{'medallas'} = \@medallas;
# ajustar posición según logros alcanzados
if ( @tabla_medallero_oficial > 0 # solo a partir de la segunda fila
and (
$tabla_medallero_oficial[-1]{'medallas'}[0] > $medallas[0] # Oro
or $tabla_medallero_oficial[-1]{'medallas'}[1] > $medallas[1] # Plata
or $tabla_medallero_oficial[-1]{'medallas'}[2] > $medallas[2] # Bronce
)
) {
$posición = $posición_absoluta; # sí: su posición es una más que el anterior
}
$resultados->{'posición'} = $posición; # guardamos nueva posición
push @tabla_medallero_oficial, $resultados; # nueva fila en el medallero
$posición_absoluta++;
}
die "ERROR: No he leído la tabla del medallero oficial"
if ! @tabla_medallero_oficial;
## Confección del Medallero en formato wiki ---------------------------------
my $medallero_wiki; # Medallero en formato Wiki
my @totales_medallero; # Almacena la suma de las medallas
# Cabecera de la tabla
$medallero_wiki = $medallero_wiki_cabeza;
$medallero_wiki .= "{{Leyenda|#CCCCFF|País organizador|border=solid 1px #AAA}}\n";
$medallero_wiki .= "{| {{Medallero|tipo=1|ancho=60%}}\n";
# Filas de la tabla
my $DCOL = ' || ';
my $n_fila = 1;
my $aviso_corte_puesto = 0;
for my $fila (@tabla_medallero_oficial) {
my @medallas = @{$fila->{'medallas'}}; # Número de medallas
last if $medallas[-1] == 0; # Paramos si no tiene medallas
map { $totales_medallero[$_] += $medallas[$_] } 0 .. 3; # Cálculo de los totales
$medallero_wiki .= '|-'; # Nueva fila
$medallero_wiki .= '-bgcolor=ccccff' if $fila->{'COI'} eq $PAÍS_ANFITRIÓN; # destaque
$medallero_wiki .= "\n";
$medallero_wiki .= '| '
. join $DCOL =>
"'''$fila->{'posición'}'''", # posición
"$países{$fila->{'COI'}}", # país
@medallas # medallas
;
$medallero_wiki .= "\n";
if ($n_fila == 10) {
$medallero_wiki .= $medallero_wiki_aviso_corte;
$aviso_corte_puesto = 1;
}
$n_fila++;
}
if (not $aviso_corte_puesto) {
$medallero_wiki .= $medallero_wiki_aviso_corte;
}
# Totales y fin de la tabla
$medallero_wiki .= "|-\n" . join($DCOL, '! colspan="2" | Total', @totales_medallero) . "\n|}";
$medallero_wiki .= "\n\n";
## Conexión con Wikipedia ---------------------------------------------------
my $Wikipedia = MediaWiki::API->new({
api_url => $WIKIPEDIA_API_URL,
retries => 3,
retry_delay => 30,
});
$Wikipedia->login({
lgname => $WIKIPEDIA_USUARIO_LOGIN,
lgpassword => $WIKIPEDIA_USUARIO_PASSW,
})
or die $Wikipedia->{error}->{code} . ': ' . $Wikipedia->{error}->{details};
## Actualización de la página del medallero ---------------------------------
my $página_wiki; # Contenido de la página wiki actual
my $página_antes_wiki; # Contenido de la página wiki anterior
my $página_wiki_ref = $Wikipedia->get_page({
title => $título_página_wiki,
});
die "ERROR: No conseguí la página del medallero\n"
if $página_wiki_ref->{missing};
$página_wiki = $página_antes_wiki = $página_wiki_ref->{'*'}; # Cómo es la página en este momento
# Editamos la página
if ($página_wiki =~ s/^=+ Medallero =+.+?(?=^=)/$medallero_wiki/sm) {
if ($página_wiki ne $página_antes_wiki) { # Si hay realmente un cambio, la editamos
$Wikipedia->edit({
action => 'edit',
text => $página_wiki,
title => $título_página_wiki,
basetimestamp => $página_wiki_ref->{timestamp},
summary => 'Actualización automática del medallero',
})
or die $Wikipedia->{error}->{code} . ': ' . $Wikipedia->{error}->{details}
;
say 'Medallero actualizado' if $DEBUG;
}
else {
say 'No hay cambios' if $DEBUG == 2;
}
}
else {
die 'ERROR: no encuentro la sección del medallero en la página';
}
__DATA__
*{{bandera|ALB}} [[Albania en los Juegos Europeos de Bakú 2015|Albania]] <small>(ALB)</small> (28)
*{{bandera|GER}} [[Alemania en los Juegos Europeos de Bakú 2015|Alemania]] <small>(GER)</small> (266)
*{{bandera|AND}} [[Andorra en los Juegos Europeos de Bakú 2015|Andorra]] <small>(AND)</small> (31)
*{{bandera|ARM}} [[Armenia en los Juegos Europeos de Bakú 2015|Armenia]] <small>(ARM)</small> (25)
*{{bandera|AUT}} [[Austria en los Juegos Europeos de Bakú 2015|Austria]] <small>(AUT)</small> (145)
*{{bandera|AZE}} [[Azerbaiyán en los Juegos Europeos de Bakú 2015|Azerbaiyán]] <small>(AZE)</small> (289)
*{{bandera|BLR}} [[Bielorrusia en los Juegos Europeos de Bakú 2015|Bielorrusia]] <small>(BLR)</small> (150)
*{{bandera|BEL}} [[Bélgica en los Juegos Europeos de Bakú 2015|Bélgica]] <small>(BEL)</small> (117)
*{{bandera|BIH}} [[Bosnia y Herzegovina en los Juegos Europeos de Bakú 2015|Bosnia y Herzegovina]] <small>(BIH)</small> (56)
*{{bandera|BUL}} [[Bulgaria en los Juegos Europeos de Bakú 2015|Bulgaria]] <small>(BUL)</small> (127)
*{{bandera|CRO}} [[Croacia en los Juegos Europeos de Bakú 2015|Croacia]] <small>(CRO)</small> (109)
*{{bandera|CYP}} [[Chipre en los Juegos Europeos de Bakú 2015|Chipre]] <small>(CYP)</small> (23)
*{{bandera|DEN}} [[Dinamarca en los Juegos Europeos de Bakú 2015|Dinamarca]] <small>(DEN)</small> (65)
*{{bandera|ESP}} [[España en los Juegos Europeos de Bakú 2015|España]] <small>(ESP)</small> (216)
*{{bandera|SVK}} [[Eslovaquia en los Juegos Europeos de Bakú 2015|Eslovaquia]] <small>(SVK)</small> (179)
*{{bandera|SLO}} [[Eslovenia en los Juegos Europeos de Bakú 2015|Eslovenia]] <small>(SLO)</small> (83)
*{{bandera|EST}} [[Estonia en los Juegos Europeos de Bakú 2015|Estonia]] <small>(EST)</small> (59)
*{{bandera|FIN}} [[Finlandia en los Juegos Europeos de Bakú 2015|Finlandia]] <small>(FIN)</small> (106)
*{{bandera|FRA}} [[Francia en los Juegos Europeos de Bakú 2015|Francia]] <small>(FRA)</small> (251)
*{{bandera|GEO}} [[Georgia en los Juegos Europeos de Bakú 2015|Georgia]] <small>(GEO)</small> (105)
*{{bandera|GRE}} [[Grecia en los Juegos Europeos de Bakú 2015|Grecia]] <small>(GRE)</small> (138)
*{{bandera|HUN}} [[Hungría en los Juegos Europeos de Bakú 2015|Hungría]] <small>(HUN)</small> (200)
*{{bandera|IRL}} [[Irlanda en los Juegos Europeos de Bakú 2015|Irlanda]] <small>(IRL)</small> (63)
*{{bandera|ISL}} [[Islandia en los Juegos Europeos de Bakú 2015|Islandia]] <small>(ISL)</small> (19)
*{{bandera|ISR}} [[Israel en los Juegos Europeos de Bakú 2015|Israel]] <small>(ISR)</small> (141)
*{{bandera|ITA}} [[Italia en los Juegos Europeos de Bakú 2015|Italia]] <small>(ITA)</small> (291)
*{{bandera|KOS}} [[Kosovo en los Juegos Europeos de Bakú 2015|Kosovo]] <small>(KOS)</small> (18)
*{{bandera|LAT}} [[Letonia en los Juegos Europeos de Bakú 2015|Letonia]] <small>(LAT)</small> (67)
*{{bandera|LIE}} [[Liechtenstein en los Juegos Europeos de Bakú 2015|Liechtenstein]] <small>(LIE)</small> (10)
*{{bandera|LTU}} [[Lituania en los Juegos Europeos de Bakú 2015|Lituania]] <small>(LTU)</small> (71)
*{{bandera|LUX}} [[Luxemburgo en los Juegos Europeos de Bakú 2015|Luxemburgo]] <small>(LUX)</small> (61)
*{{bandera|MLT}} [[Malta en los Juegos Europeos de Bakú 2015|Malta]] <small>(MLT)</small> (61)
*{{bandera|MDA}} [[Moldavia en los Juegos Europeos de Bakú 2015|Moldavia]] <small>(MDA)</small> (86)
*{{bandera|MON}} [[Mónaco en los Juegos Europeos de Bakú 2015|Mónaco]] <small>(MON)</small> (6)
*{{bandera|MNE}} [[Montenegro en los Juegos Europeos de Bakú 2015|Montenegro]] <small>(MNE)</small> (55)
*{{bandera|NOR}} [[Noruega en los Juegos Europeos de Bakú 2015|Noruega]] <small>(NOR)</small> (58)
*{{bandera|NED}} [[Países Bajos en los Juegos Europeos de Bakú 2015|Países Bajos]] <small>(NED)</small> (120)
*{{bandera|POL}} [[Polonia en los Juegos Europeos de Bakú 2015|Polonia]] <small>(POL)</small> (212)
*{{bandera|POR}} [[Portugal en los Juegos Europeos de Bakú 2015|Portugal]] <small>(POR)</small> (100)
*{{bandera|GBR}} [[Reino Unido en los Juegos Europeos de Bakú 2015|Reino Unido]] <small>(GBR)</small> (158)
*{{bandera|CZE}} [[República Checa en los Juegos Europeos de Bakú 2015|República Checa]] <small>(CZE)</small> (130)
*{{bandera|MKD}} [[República de Macedonia en los Juegos Europeos de Bakú 2015|República de Macedonia]] <small>(MKD)</small> (45)
*{{bandera|ROU}} [[Rumania en los Juegos Europeos de Bakú 2015|Rumania]] <small>(ROU)</small> (146)
*{{bandera|RUS}} [[Rusia en los Juegos Europeos de Bakú 2015|Rusia]] <small>(RUS)</small> (359)
*{{bandera|SMR}} [[San Marino en los Juegos Europeos de Bakú 2015|San Marino]] <small>(SMR)</small> (20)
*{{bandera|SRB}} [[Serbia en los Juegos Europeos de Bakú 2015|Serbia]] <small>(SRB)</small> (133)
*{{bandera|SWE}} [[Suecia en los Juegos Europeos de Bakú 2015|Suecia]] <small>(SWE)</small> (76)
*{{bandera|SUI}} [[Suiza en los Juegos Europeos de Bakú 2015|Suiza]] <small>(SUI)</small> (130)
*{{bandera|TUR}} [[Turquía en los Juegos Europeos de Bakú 2015|Turquía]] <small>(TUR)</small> (191)
*{{bandera|UKR}} [[Ucrania en los Juegos Europeos de Bakú 2015|Ucrania]] <small>(UKR)</small> (243)