De Inciclopedia
#!/usr/bin/python
# -*- coding: utf-8 -*-
#En caso de que falle la escritura cuando ha finalizado, los datos se guardan en estadisticas.txt
#Un intento cutre para conseguir las estadísticas de las páginas, debería funcionar para cualquier familia
# pero habría que quitar o adaptar la lista de OtraWikis
#Todo está manual porque hay que hacerlo a través de api.php y Special:Statistics?action=raw
#pyWikipediabot lo hace a través de las páginas y wikia tiene el límite hasta 1000 en la página de [[special:longpages]]
#La verdad es que para lo único que uso Pywikipediabot es para obtener el listado de lenguajes y escribir en la página
#Para páginas largas: http://inciclopedia.wikia.com/api.php?action=query&list=allpages&aplimit=500&apminsize=1000&format=phpfm
#php es la forma más compacta (phpfm para verlo en el explorador), lo hace de 500 en 500 porque solo los sysops pueden 5000
#ATENCION: USO EXCESIVO DE BLOQUES TRY...EXCEPT XD XD XD XD XD XD
from __future__ import division
import re
import codecs
import wikipedia
from urllib import urlopen, quote
OtrasWikis = {
"Inciclopedia": ["es", "inciclopedia.wikia.com", "/index.php", "/api.php"],
"Frikipedia": ["fk", "www.frikipedia.es", "/index.php", "/api.php"],
"Wikipediars": ["wprs", "www.wikipediars.com", "/index.php", "/api.php"],
"Jugopedia": ["jp", "jugopedia.foobar.cl/~jugopedia", "/index.php", "/api.php"]
}
class BasicBot:
def __init__(self):
self.TotalArticulos = 0
self.TotalFicheros = 0
self.TotalPaginas = 0
self.TotalEdiciones = 0
self.TotalUsuarios = 0
self.TotalActivos = 0
self.TotalAdministradores = 0
self.ArticulosActual = 0 # Para guardar temporalmente el número de artículos de la wiki que estamos recorriendo
self.AnadirOtrasWikis = True
self.site = wikipedia.getSite()
self.texto = ""
def run(self):
# Pone el sumario
wikipedia.setAction(u"Actualizando estadísticas")
self.treat()
def _EscribirCabecera(self):
self.texto += u"{| {{tablabonita|alineación=col1cen|text-align:right; font-size: 90%;}}\n"
self.texto += u"|-\n!|Leng<br />\n!|Edic<br />\n!|Pág<br />\n!|Ed/Pg<br />\n!|Art<br />\n!|%<br />\n!|Fich<br />\n"
self.texto += u"!|Fch/Art<br />\n!|Usu<br />\n!|Act<br />\n!|Adm<br />\n"
self.texto += u"!|>64k<br />\n!|%<br />\n!|>32kb<br />\n!|%<br />\n!|>16kb<br />\n!|%<br />\n"
self.texto += u"!|>8k<br />\n!|%<br />\n!|>4kb<br />\n!|%<br />\n"
def _EscribirTotales(self):
self.texto += u"\n{| {{tablabonita|alineación=|text-align: center;}}\n"
self.texto += u"|-\n!|Lenguaje\n!|Ediciones\n!|Páginas\n!|Artículos\n!|Ficheros\n!|Usuarios\n!|Activos\n!|Administradores\n"
self.texto += u"|-\n||TOTAL\n"
self.texto += u"||%d\n" % (self.TotalEdiciones)
self.texto += u"||%d\n" % (self.TotalPaginas)
self.texto += u"||%d\n" % (self.TotalArticulos)
self.texto += u"||%d\n" % (self.TotalFicheros)
self.texto += u"||%d\n" % (self.TotalUsuarios)
self.texto += u"||%d\n" % (self.TotalActivos)
self.texto += u"||%d\n" % (self.TotalAdministradores)
self.texto += u"|}\n----\n"
def _LeerEstadisticas(self, URLBase, Path):
# Expresiones regulares para extraer los datos
# Expresion1 incluye "activesers" mientras que Expresion2 no
# He hecho un montón de pruebas para unirlas poniendo (?:activeusers=(?P<activeusers>.*);)? pero no rula
Expresion1 = r"total=(?P<total>.*);good=(?P<good>.*);views=(?P<views>.*);edits=(?P<edits>.*);users=(?P<users>.*);activeusers=(?P<activeusers>.*);admins=(?P<admins>.*);images=(?P<images>.*);jobs=(?P<jobs>.*)"
Expresion2 = r"total=(?P<total>.*);good=(?P<good>.*);views=(?P<views>.*);edits=(?P<edits>.*);users=(?P<users>.*);admins=(?P<admins>.*);images=(?P<images>.*);jobs=(?P<jobs>.*)"
try:
Estadisticas = urlopen(u'http://%s%s?title=Special:Statistics&action=raw' %
(URLBase, Path)).read()
except:
return False
wikipedia.output(Estadisticas)
# Probamos con Expresion1 (con Activeusers)
param = re.search(Expresion1, Estadisticas)
try:
Articulos = int(param.group('good'))
except: # Probamos sin activeusers
param = re.search(Expresion2, Estadisticas)
try:
Articulos = int(param.group('good'))
except: # Ops, algo falló
return False
self.ArticulosActual = Articulos
Ediciones = int(param.group('edits'))
Paginas = int(param.group('total'))
Ficheros = int(param.group('images'))
Admin = int(param.group('admins'))
Usuarios = int(param.group('users'))
try:
Activos = int(param.group('activeusers'))
except:
Activos = 0
# Escribimos los datos
self.texto += u"||%d\n" % (Ediciones)
self.texto += u"||%d\n" % (Paginas)
temp = u"||%3.2f\n" % (Ediciones / Paginas)
self.texto += temp.replace(".", ",")
self.texto += u"||%d\n" % (Articulos)
temp = u"||%3.2f\n" % (Articulos * 100 / Paginas)
self.texto += temp.replace(".", ",")
self.texto += u"||%d\n" % (Ficheros)
temp = u"||%3.2f\n" % (Ficheros / Articulos)
self.texto += temp.replace(".", ",")
self.texto += u"||%d\n" % (Usuarios)
self.texto += u"||%d\n" % (Activos)
self.texto += u"||%d\n" % (Admin)
# Actualizamos acumuladores
self.TotalArticulos += Articulos
self.TotalFicheros += Ficheros
self.TotalPaginas += Paginas
self.TotalEdiciones += Ediciones
self.TotalUsuarios += Usuarios
self.TotalActivos += Activos
self.TotalAdministradores += Admin
return True
def _LeerPaginasLargas(self, URLBase, APIPath):
# Un poco cutre hacerlo de esta forma...
# Habría que mejorarlo mucho
Expresion1 = r"\"apfrom\";s:[0-9]*:\"(?P<sig>.*)\";\}\}s:"
Expresion2 = r"\"allpages\";a:(?P<paginas>.*):\{[i\}]"
for i in [65535, 32767, 16383, 8191, 4095]:
# for i in [8191]:
wikipedia.output(u"Buscando páginas de más de %d bytes" % i)
Contador = 0
try:
Estadisticas = urlopen(u'http://%s%s?action=query&list=allpages&aplimit=500&apminsize=%d&format=php' %
(URLBase, APIPath, i)).read()
except:
return False
Fin = False
while not Fin:
param = re.search(Expresion1, Estadisticas)
try:
Siguiente = quote(param.group(u"sig"))
wikipedia.output(u"Leido hasta: %s" % Siguiente)
try:
Estadisticas = urlopen(u'http://%s%s?action=query&list=allpages&aplimit=500&apminsize=%d&format=php&apfrom=%s' %
(URLBase, APIPath, i, Siguiente)).read()
except:
return False
Contador += 500
except:
try:
param = re.search(Expresion2, Estadisticas)
Contador += int(param.group(u"paginas"))
except:
return False
Fin = True
self.texto += u"||%d\n" % (Contador)
temp = u"||%3.2f\n" % (Contador * 100 / self.ArticulosActual )
self.texto += temp.replace(".", ",")
wikipedia.output(u"--> %d páginas encontradas" % Contador);
return True
def treat(self):
self._EscribirCabecera()
# Datos de las wikis Uncyclopedia
for i in self.site.languages():
# for i in ["es"]:
self.ArticulosActual = 0
wikipedia.output(u"\n>>> \03{yellow}%s\03{default} - \03{lightpurple}%s\03{default} <<<" %
(i, self.site.family.langs[i]))
wikipedia.output(u'http://%s%s?title=Special:Statistics&action=raw' %
(self.site.family.langs[i], self.site.family.path(i)))
# Nueva fila para la wiki
self.texto += u"|-\n||[[:%s:]]\n" % i
if not self._LeerEstadisticas(self.site.family.langs[i], self.site.family.path(i)):
self.texto += u"||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n" #Fila vacía
wikipedia.output(u'ERROR -> Al acceder a [[special:Statistics]]')
continue
if not self._LeerPaginasLargas(self.site.family.langs[i], self.site.family.apipath(i)):
# self.texto += u"||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n" #Fila vacía
wikipedia.output(u'ERROR -> Al acceder al API')
#Cerramos tabla
self.texto += u"\n|}\n"
# Escribimos los totales
self._EscribirTotales()
# Ahora lo hacemos con las wikis listadas al principio
if self.AnadirOtrasWikis:
self.TotalArticulos = 0
self.TotalFicheros = 0
self.TotalPaginas = 0
self.TotalEdiciones = 0
self.TotalUsuarios = 0
self.TotalActivos = 0
self.TotalAdministradores = 0
self.ArticulosActual = 0
self._EscribirCabecera()
for i in OtrasWikis:
self.ArticulosActual = 0
wikipedia.output(u"\n>>> \03{yellow}%s\03{default} - \03{lightpurple}%s\03{default} <<<" %
(i, OtrasWikis[i][1]))
wikipedia.output(u'http://%s%s?title=Special:Statistics&action=raw' %
(OtrasWikis[i][1], OtrasWikis[i][2]))
# Nueva fila para la wiki
self.texto += u"|-\n||[[%s|%s]]\n" % (i, OtrasWikis[i][0])
if not self._LeerEstadisticas(OtrasWikis[i][1], OtrasWikis[i][2]):
self.texto += u"||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n" #Fila vacía
wikipedia.output(u'ERROR -> Al acceder a [[special:Statistics]]')
continue
if not self._LeerPaginasLargas(OtrasWikis[i][1], OtrasWikis[i][3]):
self.texto += u"||\n||\n||\n||\n||\n||\n||\n||\n||\n||\n" #Fila vacía
wikipedia.output(u'ERROR -> Al acceder al API')
self.texto += u"|}\n"
self._EscribirTotales()
self.texto += u"===Leyenda===\n"
self.texto += u";Leng\n"
self.texto += u":Lenguaje de la wiki\n"
self.texto += u";Edic\n"
self.texto += u":Número total de ediciones\n"
self.texto += u";Pág\n"
self.texto += u":Número total de páginas creadas\n"
self.texto += u";Ed/Pg\n"
self.texto += u":Ediciones por página\n"
self.texto += u";Art\n"
self.texto += u":Número de artículos (En el espacio principal, con un enlace y no se que otra restricción)\n"
self.texto += u";%\n"
self.texto += u":Porcentaje de artículos sobre el total de páginas\n"
self.texto += u";Fich\n"
self.texto += u":Número de ficheros (imágenes, sonidos, etc) subidos a la wiki\n"
self.texto += u";Fch/Art\n"
self.texto += u":Número de ficheros por artículos (es decir, más o menos el número de imágenes en cada artículo)\n"
self.texto += u";Usu\n"
self.texto += u":Número de usuarios\n"
self.texto += u";Act\n"
self.texto += u":Número de usuarios activos (solo lo implementa una wiki...)\n"
self.texto += u";Adm\n"
self.texto += u":Número de administradores\n"
self.texto += u";>64kb, %\n"
self.texto += u":Artículos de más de 64kb y su porcentaje sobre el total\n"
self.texto += u";>32kb, %\n"
self.texto += u":Artículos de más de 32kb y su porcentaje sobre el total\n"
self.texto += u";>16kb, %\n"
self.texto += u":Artículos de más de 16kb y su porcentaje sobre el total\n"
self.texto += u";>8k, %\n"
self.texto += u":Artículos de más de 8kb y su porcentaje sobre el total\n"
self.texto += u";>4kb, %\n"
self.texto += u":Artículos de más de 4kb y su porcentaje sobre el total\n"
self.texto += u"===Notas===\n"
self.texto += u"La tabla ya no la hago a mano, he hecho un bot con el pywikipediabot. "
self.texto += u"Así me evito tener que estar haciéndolo a mano y las posibles fallos que puda tener\n\n"
self.texto += u"El kB está comparado como lo es informáticamente, es decir: 65.536B, 32.768B, 16.384B,"
self.texto += u"8.192B y 4096B respectivamente.\n\n"
self.texto += u"Las que no tienen nada de nada... Será que está mal configurada en el bot o "
self.texto += u"que ha dado error al intentar acceder\n\n"
self.texto += u"Aquellas en las que no se tienen los tamaños de los artículos s que no tienen activado"
self.texto += u"el api.php (Tiene que escribir <code>$wgEnableAPI=true;</code> en "
self.texto += u"LocalSettings.php y solo lo pueden hacer quien tenga acceso al servidor donde esté instalada\n\n"
self.texto += u";Para las de Wikia\n"
self.texto += u"*El número de usuarios son el total de toda Wikia\n"
fichero = codecs.open('estadisticas.txt', mode='w', errors='strict', encoding='utf-8', buffering=1)
fichero.write(self.texto)
fichero.close
page=wikipedia.Page(self.site, u"User:Chixpy/Estadistitis")
try:
page.put(self.texto)
except wikipedia.LockedPage:
wikipedia.output(u"Página bloqueada: %s" % page.aslink())
except wikipedia.EditConflict:
wikipedia.output(u'Conflicto de edición: %s' % (page.title()))
except wikipedia.SpamfilterError, error:
wikipedia.output(u'Puto filtro anti-spam: %s - %s' % (page.title(), error.url))
def main():
bot = BasicBot()
bot.run()
if __name__ == "__main__":
try:
main()
finally:
wikipedia.stopme()