Last active
May 28, 2020 00:24
-
-
Save danilomac/ef81ba112429c77de056dceb73439f64 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
''' | |
@author: Danilo ([[Usuário:Danilo.mac]]) | |
@licence: GNU Public Licence version 2 (GPLv2) | |
Script para avaliação automática de qualidade na Wikipédia lusófona, semelhante ao [[Módulo:Avaliação]] | |
Uso: | |
python qualidade.py <nome_do_arquivo> | |
O script lê o arquivo e interpreta cada linha como o título de um artigo, avalia a | |
qualidade e retorna o titulo com a qualidade. | |
Se o arquivo for um tsv, apenas a primeira coluna é interpretada como título e toda | |
linha é retornada com mais uma coluna com a qualidade | |
Opções: | |
-motivo Retorna o motivo da avaliação também | |
-revid Trata cada linha como o revision id da edição em vez de um título | |
-timestamp Trata a segunda linha do tsv como timestamp para avaliar a edição dessa data específica | |
''' | |
import re, json, sys, codecs | |
from urllib2 import urlopen | |
from urllib import quote | |
problemas = [u'artigo com problemas', u'artigo longo', u'artigo sobre direito com problemas', u'bsre', u'coi', | |
u'caracteres não-padrão', u'conflito interwiki', u'contextualizar2', u'conteúdo parcial', u'controverso', | |
u'corrigir', u'ctx2', u'curiosidades', u'direitos-autorais', u'disputa-bpv', u'divisão', u'em tradução', | |
u'expandir', u'expandir2', u'fusão', u'fusão com', u'fusão de', u'fusão vot', u'global', u'global/brasil', | |
u'global/lusofonia', u'global/portugal', u'hanzi', u'idioma estrangeiro', u'matrad', u'mtag', u'multitag', | |
u'má introdução', u'má tradução', u'não informado', u'não informado n', u'não-enc', u'não-enciclopédico', | |
u'não-enciclopédico2', u'parcial', u'parcialcontroverso', u'publicidade', u'rec', u'reciclagem', | |
u'reciclar-sobre', u'ren-pag', u'renomear página', u'revisão', u'revisão de tradução', u'revisão-sobre', | |
u's-fontes-bpv', u'sem cat', u'sem-fontes-bpv', u'sem-fontes-sobre', u'semimagem-arquitetura', | |
u'semimagem-sobre', u'separar', u'suspeito2', u'tradução de', u'vda2', u'wikificação'] | |
bpd = re.compile(ur'(?<={{).+?(?=\||\n|}})') # busca predefinições | |
bp = re.compile(ur'(?:^|\n\n|==\n)[^*\n].{100,}?(?=\n\n|\n==)') # busca parágrafos | |
br = re.compile(ur'{{[Rr]efer[eê]ncias|{{[Rr]ef-?section|{{[Rr]odapé referências|==.*?[Rr]eferências.*?==|{{[Rr]eflist') # busca seção de referências | |
bl = re.compile(ur'\[\[[^:]*?\]\]') # busca ligações internas | |
bs = re.compile(ur'(?s)\n== ?([^=\n}{]+?) ?==(.+?)(?=\n==[^=\n]|$)') # busca seções | |
bss = re.compile(ur'\n===[^=\n]+?===\n') # busca subseções | |
bref = re.compile(ur'<ref[^\n/]*?>.*?</ref>|<ref .+?/>', re.I|re.S) # busca notas de rodapé/referências | |
brefname = re.compile(ur'(?<=<ref name=).+?(?= />|/>| >|>)', re.I) | |
bi = re.compile(ur'\[\[(ficheiro|imagem?|file|arquivo):.*?(\||\]\])|{{imagem dupla\||\| ?imagem *=.*?\.[a-z]{3,4}', re.I) # busca imagens | |
excecoes = [u'Referências', u'Ver também', u'Notas', u'Notas e referências', u'Discografia', u'Galeria de imagens', | |
u'Referências gerais', u'Leitura adicional', u'Subdivisões', u'Leitura recomendada', u'Ligações externas', u'Bibliografia'] #exeções para seções | |
def avaliar(pagename, timestamp=False): | |
if timestamp: | |
pagename = quote(pagename.encode('utf-8'), safe='') | |
api = urlopen('https://pt.wikipedia.org/w/api.php?action=query&format=json&prop=revisions&titles=%s&rvprop=content&rvstart=%d&rvlimit=1' % (pagename, int(timestamp))) | |
elif re.match(r'r\d+', pagename): | |
api = urlopen('https://pt.wikipedia.org/w/api.php?action=query&format=json&prop=revisions&revids=%d&rvprop=content&rvlimit=1' % int(pagename[1:])) | |
else: | |
pagename = quote(pagename.encode('utf-8'), safe='') | |
api = urlopen('https://pt.wikipedia.org/w/api.php?action=query&format=json&prop=revisions&titles=%s&rvprop=content&rvlimit=1' % pagename) | |
try: | |
texto = json.loads(api.read())['query']['pages'].values()[0]['revisions'][0]['*'] | |
except: | |
return ('?', u'página não existe') | |
if len(texto) < 2000: | |
return (1, u'menos de 2000 bytes') | |
predefs = dict([(p.lower(), p) for p in bpd.findall(texto)]) | |
if u'artigo destacado' in predefs: | |
return (6, u'artigo destacado') | |
if u'artigo bom' in predefs: | |
return (5, u'artigo bom') | |
ref = br.search(texto) | |
if not ref and len(texto) < 8000: | |
return (1, u'menos de 8000 bytes e não tem referências') | |
paragrafos = bp.findall(bref.sub('', texto)) | |
wkf = [x for x in paragrafos if len(x) > 2504] | |
if wkf: | |
return (1, u'parágrafo muito grande (%d bytes): "%s..."' % (len(wkf[0]), wkf[0][0:23])) | |
wikilinks = bl.findall(texto) | |
if len(wikilinks) < 10: | |
return (1, u'menos de 10 ligações internas') | |
subp = filter(lambda x:x.find(u'. ') == -1, paragrafos) | |
if len(paragrafos) - (len(subp)/2) < 5: | |
return (1, u'menos de 5 parágrafos') | |
# Verificando parâmetros para qualidade 3: | |
secoes = bs.findall(texto) | |
subsec = bss.findall(texto) | |
#if len(secoes) + (len(subsec)/5) < 2: return (1, u'menos de 2 seções') | |
for predef in [u'mínimo', u'contexto', u'reciclagem', u'reciclar-sobre']: | |
if predef in predefs: | |
return (1, u'encontrado [[predefinição:%s]]' % predefs[predef]) | |
if not ref: | |
return (2, u'não tem seção de referências') | |
if len(texto) < 12000: | |
return (2, u'menos de 12000 bytes') | |
if len(wikilinks) < 30: | |
return (2, u'menos de 30 ligações internas') | |
if len(secoes) + (len(subsec)/5) < 3: | |
return (2, u'menos de 3 seções') | |
refs = bref.findall(texto) | |
refnames = brefname.findall(texto) | |
nrefs = len(refs) - len(refnames) + len(set(refnames)) | |
if nrefs < 5: | |
return (2, u'menos de 5 referências') | |
imagens = bi.findall(texto) | |
if len(imagens) < 1: | |
return (2, u'não tem imagem') | |
for predef in [u'esboço', u'wikificação', u'revisão', u'revisão-sobre']: | |
if predef in predefs: return (2, u'encontrado [[predefinição:%s]]' % predefs[predef]) | |
# Verificando parâmetros para qualidade 4: | |
if len(texto) < 20000: | |
return (3, u'menos de 20000 bytes') | |
if len(wikilinks) < 50: | |
return (3, u'menos de 50 ligações internas') | |
if len(secoes) + (len(subsec)/5) < 5: | |
return (3, u'menos de 5 seções') | |
if nrefs < 10: | |
return (3, u'menos de 10 referências') | |
if len(imagens) < 2: | |
return (3, u'só tem uma imagem') | |
for predef in problemas: | |
if predef in predefs: | |
return (3, u'encontrado [[predefinição:%s]]' % predefs[predef]) | |
for s in secoes: | |
if s[0] not in excecoes: | |
if not bref.search(s[1]) and len(bp.findall(s[1])) > 1: | |
return (3, u'não foram encontradas referências na seção "%s"' % s[0]) | |
# Nada encontrado: | |
return (4, u'indique para [[WP:EAD|EAD]] quando o artigo satisfizer os [[Wikipédia:O que é um artigo bom?|critérios de artigo bom]]') | |
if __name__ == '__main__': | |
args = sys.argv[1:] | |
mot = '-motivo' in args | |
revid = '-revid' in args | |
timestamp = '-timestamp' in args | |
arquivo = args[-1] | |
with codecs.open(arquivo, 'r', 'utf-8') as f: | |
for line in f: | |
line = line.strip('\r\n') | |
page = line.split('\t') | |
q = avaliar((revid and u'r' or u'') + page[0], timestamp and page[1]) | |
if mot: | |
print '%s\t%d\t%s' % (line, q[0], q[1]) | |
else: | |
print '%s\t%s' % (line, q[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment