#!/usr/bin/env perl## medalleroMoscu2013.pl## Autor:# Joaquín Ferrero## Descripción:# Actualización automática de medalleros olímpicos en Wikipedia.## Entrada: ninguna# Salida: ninguna## Historial:# 2013.08.13 : 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 -------------------------------------------------------------useModern::Perl2013;# Programamos en Perl modernouseutf8::all;# Activar todo el soporte para UTF-8. Realmente todouseMojo::UserAgent;# Un poco de mojo...useMediaWiki::API;# Y mucha Wikipedia#use Data::Dumper;### Configuración -----------------------------------------------------------my$PAÍS_ANFITRIÓN='RUS';my$URL_MEDALLERO='http://www.iaaf.org/competitions/iaaf-world-championships/14th-iaaf-world-championships-4873/medaltable';my$WIKIPEDIA_PÁGINA_MEDALLERO='Campeonato Mundial de Atletismo de 2013';my$WIKIPEDIA_PÁGINA_TEST='Wikipedia:Zona de pruebas/5';my$WIKIPEDIA_USUARIO_LOGIN='user';my$WIKIPEDIA_USUARIO_PASSW='password';my$WIKIPEDIA_API_URL='http://es.wikipedia.org/w/api.php';my$DEBUG=1;# 0 o 1my$título_página_wiki=$WIKIPEDIA_PÁGINA_MEDALLERO;# $WIKIPEDIA_PÁGINA_TESTmy$medallero_wiki_cabeza=<<"EOF";== Medallero ==<!-- ATENCIÓN Esta tabla se actualiza de forma automática cada 15 min. durante el periodo de los juegos. CUALQUIER cambio realizado de forma manual se perderá. AVISAR de incidencias al usuario JoaquinFerrero.-->EOF### Fin de configuración ----------------------------------------------------## Obtención de los resultados ----------------------------------------------my$medallero_html;my$ua=Mojo::UserAgent->new(name=>'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:14.0) Mojolicious/2012 Wikipedia/es',request_timeout=>5,);formy$retry(1..3){# Tres intentos$medallero_html=$ua->get($URL_MEDALLERO,{})->res->dom->find("table.records-table")->[0];# CSS Selectorlastifdefined$medallero_html;say"Intento fallido $retry..."if$DEBUG;sleep30;}die"ERROR: No he podido leer la página del medallero oficial\n"ifnotdefined$medallero_html;## Extracción de resultados -------------------------------------------------my@tabla_medallero_oficial;# aquí guardamos el resultado de la extracciónmy@filas=$medallero_html->find("tr")->each;shift@filas;# la primera línea de la tabla no es interesantemy$posición=1;# Renumeración de las posicionesmy$posición_absoluta=1;# Posición real dentro del global de posicionesformy$fila(@filas){my$resultados;# resultados para un participantemy@celdas=$fila->find("td")->each;nextif@celdas!=6;$celdas[1]->children->first->attrs('src')=~ /(\w+)[.](?:gif|png)$/;# extraemos el código COI de la bandera$resultados->{'COI'}=uc$1;my@medallas;formy$celda(@celdas[2..5]){# resto de celdas de la fila: número de medallaspush@medallas,0+$celda->text;}$resultados->{'medallas'}=\@medallas;# ajustar posición según logros alcanzadosif(@tabla_medallero_oficial>0# solo a partir de la segunda filaand($tabla_medallero_oficial[-1]{'medallas'}[0]>$medallas[0]# Oroor$tabla_medallero_oficial[-1]{'medallas'}[1]>$medallas[1]# Plataor$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ónpush@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 Wikimy@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 tablamy$DCOL=' || ';formy$fila(@tabla_medallero_oficial){my@medallas=@{$fila->{'medallas'}};# Número de medallasmap{$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"{{$fila->{'COI'}}}",# país@medallas# medallas;$medallero_wiki.="\n";}# 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,})ordie$Wikipedia->{error}->{code}.': '.$Wikipedia->{error}->{details};## Actualización de la página del medallero ---------------------------------my$página_wiki;# Contenido de la página wiki actualmy$página_antes_wiki;# Contenido de la página wiki anteriormy$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áginaif($página_wiki=~s/^=+ Medallero =+.+?(?=^=)/$medallero_wiki/sm){if($página_wikine$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',})ordie$Wikipedia->{error}->{code}.': '.$Wikipedia->{error}->{details};say'Medallero actualizado'if$DEBUG;}else{# say 'No hay cambios' if $DEBUG;}}else{die'ERROR: no encuentro la sección del medallero en la página';}__END__