Diferencia entre revisiones de «Trabajo:Mejora de la wiki de ELP/Bots»

De FdIwiki ELP
Saltar a: navegación, buscar
(página con el código de los bots)
 
(Eliminado el código y puesto en GitHub, aclaraciones)
 
Línea 1: Línea 1:
 
{{#breadcrumb: Trabajo:Mejora de la wiki de ELP}}
 
{{#breadcrumb: Trabajo:Mejora de la wiki de ELP}}
  
En esta página se muestra el código de los bots desarrollados y utilizados para el trabajo.
+
En esta se explica la labor de los diferentes bots desarrollados y utilizados para el trabajo.
  
Los bots escritos en C# requieren la infraestructura de [http://dotnetwikibot.sourceforge.net/ DotNetWikiBot] (GPLv2). Los bots escritos en Python necesitan  [https://www.mediawiki.org/wiki/PWB Pywikibot].
+
Su código, liberado bajo licencia [http://www.gnu.org/licenses/gpl-3.0.txt GPLv3], se puede encontrar en [https://github.com/ningit/wikielp-bots GitHub].
 
+
Para ejecutar los bots escritos en Python se necesita que el archivo ''<tt>user-config.py</tt>'', con la información de la wiki y el usuario, esté accesible en el directorio donde se ejecute. El nombre de usuario se puede omitir si no se van a realizar cambios, en caso contrario la contraseña se solicitará por consola. Un ejemplo de archivo:
+
 
+
<pre>
+
family_files['welp'] = 'http://wikis.fdi.ucm.es/ELP/api.php'
+
 
+
family='welp'
+
mylang = 'welp'
+
 
+
usernames['welp']['*'] = u'usuario'
+
</pre>
+
 
+
El código de los bots está liberado licencia [http://www.gnu.org/licenses/gpl-3.0.txt GPLv3].
+
  
 
== Categorización de trabajos ==
 
== Categorización de trabajos ==
Línea 22: Línea 9:
 
Asocia los trabajos a su curso académico de acuerdo a las fechas en las que fueron creados. Por ejemplo, [[:Categoría:Curso 2014-2015]] y [[:Categoría:Curso 2015-2016]].
 
Asocia los trabajos a su curso académico de acuerdo a las fechas en las que fueron creados. Por ejemplo, [[:Categoría:Curso 2014-2015]] y [[:Categoría:Curso 2015-2016]].
  
<pre>
+
'''Código:''' [https://github.com/ningit/wikielp-bots/blob/master/Categorizador.cs Categorizador.cs] (C# con [http://dotnetwikibot.sourceforge.net/ DotNetWikiBot]).
using System;
+
using System.Text;
+
using System.Collections.Generic;
+
using System.Text.RegularExpressions;
+
 
+
using DotNetWikiBot;
+
 
+
/**
+
* Clase auxiliar válida para distintos bot que operen sobre la wiki de ELP.
+
*/
+
class BotELP : Bot
+
{
+
 
+
/**
+
* Registra al bot en la wiki.
+
*
+
* Pide nombre de usuario y contraseña por consola.
+
*
+
* @returns En caso de error devuelve {@code null}.
+
*/
+
public static Site iniciar()
+
{
+
// Pide nombre de usuario y contraseña
+
 
+
Console.Write("Nombre usuario: ");
+
string usu = Console.ReadLine();
+
Console.Write("Contraseña: ");
+
string cña = ReadPassword();
+
Console.WriteLine();
+
 
+
try {
+
Site welp = new Site("http://wikis.fdi.ucm.es/ELP/", usu, cña);
+
 
+
return welp;
+
}
+
catch (WikiBotException wbe) {
+
Console.Error.WriteLine(wbe.Message);
+
 
+
return null;
+
}
+
}
+
 
+
/**
+
* Lee distintas opciones en la línea de comandos.
+
* -v para modo verboso
+
* -d para depuración (simulación, no se escriben cambios)
+
*/
+
public static void leerOpciones(string[] ops)
+
{
+
if (Array.Exists(ops, "-v".Equals))
+
DisableSilenceMode();
+
else
+
EnableSilenceMode();
+
 
+
simulado = Array.Exists(ops, "-d".Equals);
+
}
+
 
+
/**
+
* Lee una contraseña desde la consola.
+
*/
+
public static string ReadPassword()
+
{
+
StringBuilder pwd = new StringBuilder();
+
 
+
while (true)
+
{
+
ConsoleKeyInfo c = Console.ReadKey(true);
+
 
+
if (c.Key == ConsoleKey.Enter)
+
{
+
break;
+
}
+
else if (c.Key == ConsoleKey.Backspace)
+
                {
+
if (pwd.Length > 0)
+
{
+
pwd.Remove(pwd.Length - 1, 1);
+
Console.Write("\b \b");
+
}
+
}
+
else
+
{
+
pwd.Append(c.KeyChar);
+
Console.Write("*");
+
}
+
}
+
 
+
return pwd.ToString();
+
}
+
 
+
/**
+
* Indica si el bot escribe cambios en la wiki o únicamente lo simula.
+
*
+
* Útil para depuración.
+
*/
+
protected static bool simulado = false;
+
}
+
 
+
/**
+
* Categoriza los trabajos de la wiki de ELP según el curso académico.
+
*/
+
class Categorizador : BotELP
+
{
+
public static int Main()
+
{
+
 
+
// Se registra en la página y configura el bot
+
Site welp = iniciar();
+
 
+
leerOpciones(Environment.GetCommandLineArgs());
+
 
+
if (welp == null)
+
return 1;
+
 
+
// Cuenta del número de ediciones
+
int cuenta = 0;
+
 
+
// Obtiene todos los trabajos (de momento en el espacio de nombre Principal)
+
PageList todas = new PageList(welp);
+
 
+
todas.FillFromAllPages("Trabajo:", 0, false, Int32.MaxValue, "Trabajo;");
+
 
+
foreach (Page pag in todas)
+
{
+
pag.Load();
+
 
+
// Si ya hay indicación de curso no hace nada
+
List<string> cats = pag.GetCategories();
+
 
+
if (cats.Exists(patronCCurso.IsMatch))
+
continue;
+
 
+
// Para averiguar el curso obtiene la fecha de la
+
// primera edición
+
PageList hist = new PageList(welp);
+
 
+
hist.FillFromPageHistory(pag.title, Int32.MaxValue);
+
 
+
DateTime fc = hist[hist.Count()-1].timestamp;
+
 
+
// Distingue en base a ella el curso
+
int año = fc.Year;
+
 
+
// Si es antes del 29 de septiembre (aprox) es que es
+
// del curso que empieza en el año anterior
+
if (fc.Month < 9 || fc.Month == 9 && fc.Day < 29)
+
año--;
+
 
+
string curso = "Curso " + año + "-" + (año + 1);
+
 
+
// Muestra información por consola
+
Console.Error.WriteLine("«" + pag.title + "» creado en " + fc + " => " + curso);
+
 
+
cuenta++;
+
 
+
if (!simulado) {
+
pag.AddToCategory(curso);
+
 
+
pag.Save("bot: categorización de trabajos por curso", true);
+
}
+
}
+
 
+
// Resumen de las operaciones
+
Console.Error.WriteLine("El bot " + (simulado ? "hubiera realizado " : "realizó ") + cuenta + " ediciones.");
+
 
+
return 0;
+
}
+
 
+
/**
+
* Patrón en el que encajan las categorías de curso académico.
+
*/
+
private static Regex patronCCurso = new Regex("^Categoría:Curso \\d+-\\d+$", RegexOptions.Compiled);
+
}
+
</pre>
+
  
 
== Enlaces rotos ==
 
== Enlaces rotos ==
Línea 202: Línea 15:
 
Revisa todas las páginas de la wiki en busca de enlaces rotos, tanto internos como externos. El tiempo de acceso a enlaces externos se limita a 10 segundos. Tarda en ejecutarse debido al gran número de peticiones web que realiza y a que revisa todas las páginas de la wiki. Podría mejorarse atendiendo sólo a los cambios recientes con [https://pywikibot.readthedocs.org/en/latest/pywikibot/#pywikibot.site.APISite.recentchanges APISite.recentchanges].
 
Revisa todas las páginas de la wiki en busca de enlaces rotos, tanto internos como externos. El tiempo de acceso a enlaces externos se limita a 10 segundos. Tarda en ejecutarse debido al gran número de peticiones web que realiza y a que revisa todas las páginas de la wiki. Podría mejorarse atendiendo sólo a los cambios recientes con [https://pywikibot.readthedocs.org/en/latest/pywikibot/#pywikibot.site.APISite.recentchanges APISite.recentchanges].
  
No efectúa cambios sobre la wiki.
+
No efectúa cambios sobre la wiki. Como resultado proporciona una lista de enlaces rotos que se han revisado manualmente. Los internos han servido para poblar la lista de [[FdIwiki_ELP:Artículos_solicitados|artículos solicitados]] o han sido corregidos en caso de contener errores. Los externos se han corregido manualmente en algunos casos.
 
+
<pre>
+
#!/usr/bin/python3
+
#
+
# Bot para generar listas de enlaces rotos (internos y externos)
+
#
+
# Require pywikibot: https://www.mediawiki.org/wiki/Manual:Pywikibot
+
 
+
import pywikibot
+
import urllib.request
+
import sys
+
 
+
# Establece la conexión
+
site = pywikibot.Site()
+
 
+
# Explora toda las páginas
+
todas = site.allpages()
+
 
+
for pag in todas :
+
 
+
# Explora los enlaces internos de cada página en busca
+
# de páginas para completar
+
 
+
enls = pag.linkedPages()
+
 
+
for p in enls :
+
if not p.exists() :
+
print('No existe la página:', p.title())
+
 
+
# Explora los enlaces externos de cada página en busca
+
# de enlaces rotos
+
 
+
enls = pag.extlinks();
+
 
+
for url in enls :
+
print('Procesando', url, file=sys.stderr)
+
 
+
try :
+
# Se podrían hacer peticiones HEAD por eficiencia
+
res = urllib.request.urlopen(url, timeout=10)
+
  
except Exception as e :
+
'''Código:''' [https://github.com/ningit/wikielp-bots/blob/master/enlaces-rotos.py enlaces-rotos.py] (Python con [https://www.mediawiki.org/wiki/PWB Pywikibot]).
print('Problema con el enlace', url, 'en', pag.title(), '::', e)
+
</pre>
+
  
 
[[Categoría:Curso 2015-2016]]
 
[[Categoría:Curso 2015-2016]]

Última revisión de 20:47 18 ene 2016

En esta se explica la labor de los diferentes bots desarrollados y utilizados para el trabajo.

Su código, liberado bajo licencia GPLv3, se puede encontrar en GitHub.

Categorización de trabajos

Asocia los trabajos a su curso académico de acuerdo a las fechas en las que fueron creados. Por ejemplo, Categoría:Curso 2014-2015 y Categoría:Curso 2015-2016.

Código: Categorizador.cs (C# con DotNetWikiBot).

Enlaces rotos

Revisa todas las páginas de la wiki en busca de enlaces rotos, tanto internos como externos. El tiempo de acceso a enlaces externos se limita a 10 segundos. Tarda en ejecutarse debido al gran número de peticiones web que realiza y a que revisa todas las páginas de la wiki. Podría mejorarse atendiendo sólo a los cambios recientes con APISite.recentchanges.

No efectúa cambios sobre la wiki. Como resultado proporciona una lista de enlaces rotos que se han revisado manualmente. Los internos han servido para poblar la lista de artículos solicitados o han sido corregidos en caso de contener errores. Los externos se han corregido manualmente en algunos casos.

Código: enlaces-rotos.py (Python con Pywikibot).