Usuário:Danilo.bot/marcas.py: diferenças entre revisões

Origem: Wikipédia, a enciclopédia livre.
Conteúdo apagado Conteúdo adicionado
reformatando o código, adicionando comentários na função atualizar e não mais adicionando |rev= quando não houver avaliação humana (antes adicionava sempre)
→‎Código: refazendo a função atualizar, agora o comando -rmbot remove o parâmetro |bot= da marca, nos parâmetros passados para o robô "|" e ";" foram trocados para ",", e foram feitas outras alterações e correções
Linha 19: Linha 19:


-adicionar:TEMA Adiciona esse tema à marca se ele já não existir. Para mais de um
-adicionar:TEMA Adiciona esse tema à marca se ele já não existir. Para mais de um
tema use a barra vertical: TEMA1|TEMA2
tema use a barra vertical: TEMA1,TEMA2


-exceção:TEMA Só adiciona o tema se TEMA não estiver na marca.
-exceção:TEMA Só adiciona o tema se TEMA não estiver na marca.


-imp:TEMA:I Adiciona importância I para TEMA. Para mais de um tema separe
-imp:TEMA:I Adiciona importância I para TEMA. Para mais de um tema separe
com ";", exemplo: -imp:TEMA1:2;TEMA2:3
com ";", exemplo: -imp:TEMA1:2,TEMA2:3


-eimp:I Só adiciona a importância se a importância já não for I. Para mais
-eimp:I Só adiciona a importância se a importância já não for I. Para mais
Linha 38: Linha 38:
-comandos Exibe na tela todos os comandos disponíveis para especificar as páginas
-comandos Exibe na tela todos os comandos disponíveis para especificar as páginas
"""
"""
import re, time
import re
import pywikibot
import pywikibot
from pywikibot import pagegenerators
from pywikibot import pagegenerators
from datetime import date




Linha 143: Linha 142:
bimp = re.compile(u'importância ?= ?0?(\d)')
bimp = re.compile(u'importância ?= ?0?(\d)')
brev = re.compile(u'rev ?= ?\d{8}')
brev = re.compile(u'rev ?= ?\d{8}')
qs = [u'1', u'2', u'3', u'4', u'5', u'AB', u'6', u'AD']
qs = {u'1', u'2', u'3', u'4', u'5', u'AB', u'6', u'AD'}


def atualizar(page, q=False, ad=u'', ex=u'', imp=[]):
def atualizar(page, avalia=False, adicionar=[], excecoes=[], imp={}, eximp=[], rmbot=False):
if page.namespace() == 0:
if page.namespace() == 0:
page = page.toggleTalkPage()
page = page.toggleTalkPage()
elif page.namespace() != 1:
elif page.namespace() != 1:
return None
return None
try:
if page.exists():
texto = page.get()
texto = page.get()
except pywikibot.NoPage:
else:
texto = u''
texto = u''
rev = None
ad, ex = ad and ad.split(u'|'), ex and ex.split(u'|')
bot = False
adtema = []
temas = {}
qualidade = None

# Marca nova
# Marca nova
marca = bmarca.search(texto)
marca = bmarca.search(texto)
if marca:
if marca: # Tem marca nova
marca = [p for p in marca.group(1).split('|')]
marca = [p for p in marca.group(1).split('|')]
tema = None
n = 1
if len(marca) > 1: # Tem marca nova e ela tem parâmetros
for param in marca:
if param.startswith(u'rev='): # Tem |rev= na marca
rev = param
elif param.startswith(u'bot='): # Tem parâmetro |bot=
bot = param
elif u'=' not in param: # Não tem "=" no parâmetro
if n == 1: # Primeiro parâmetro é a qualidade
qualidade = param
elif n % 2 == 0: # Parâmetro par é tema
tema = param
else: # Parâmetro impor é importância
temas[tema] = param
tema = None
n += 1
if tema: # Último tema não tem importância
temas[tema] = u'?'
rmbot = rmbot and bot # Só considera que vai remover o |bot= se tiver
# Marcas antigas
# Marcas antigas
marcas = [[m[1]]+[m[3]] for m in bmarcas.findall(texto)]
marcas = [[m[1]]+[m[3]] for m in bmarcas.findall(texto)]
if marcas: # Tem marcas antigas
imarcas = [[m[0]] + bimp.findall(m[1]) for m in marcas] # Importâncias nas marcas antigas
for m in imarcas: # Pega os parâmetros das marcas antigas
if len(m) == 2:
temas[m[0]] = m[1]
else:
temas[m[0]] = u'?'
if not rev: # Não tem rev na marcas novas
rev = brev.search(str(marcas)) # Busca rev nas antigas
rev = rev and rev.group(0)
if not qualidade: # Não tem qualidade na marca nova
qmarcas = bqua.search(str(marcas)) # Busca qualidade em marcas antigas
if qmarcas:
qualidade = qmarcas.group(1) in (u'AB', u'AD') and {u'AB': u'5', u'AD': u'6'}[qmarcas.group(1)] or qmarcas.group(1)
# Adição de temas
if not filter(lambda t:t in excecoes, temas):
for ad in adicionar:
if ad not in temas:
temas[ad] = u'?'
adtema.append(ad)
# Adição de importância
imp = dict((tema, i) for tema, i in imp.items() if tema in temas and temas[tema] not in [i] + eximp)
for tema in imp:
temas[tema] = imp[tema]

# Verificações:
# Não tem marca antiga ou nova nem vai adicionar
# Não tem marca antiga ou nova nem vai adicionar
if not marcas and not marca and not ad and not imp:
if not marcas and not marca and not adtema:
if texto:
if texto:
pywikibot.output(u'Não foram encontradas marcas em ' + page.title())
pywikibot.output(u'Não foram encontradas marcas em ' + page.title())
Linha 168: Linha 218:
pywikibot.output(page.title() + u' não existe...')
pywikibot.output(page.title() + u' não existe...')
return None
return None
# Não tem marca antiga e tem nova e não vai avaliar e (não tem tema para adicionar ou tem um tema exceção)
# Não tem marca antiga e ( (tem nova mas não vai avaliar, adicionar tema, adicionar exceção ou remover bot) ou (não tem marca nova e não vai adicionar) )
elif not marcas and marca and not q and (not filter(lambda a:a not in marca, ad) or filter(lambda e:e in marca, ex)):
elif not marcas and ((marca and not avalia and not adtema and not imp and not rmbot) or (not marca and adtema)):
pywikibot.output(u'Não foram encontradas marcas para atualizar em ' + page.title())
pywikibot.output(u'Não foram encontradas marcas para atualizar em ' + page.title())
return None
return None
# Ou avalia ou remove o |bot=
if q: # Vai avaliar
if rmbot and avalia:
q = avaliar(page.toggleTalkPage())
pywikibot.output(u'Erro: ou avalia ou remove o parâmetro bot')
if marca: # Tem marca nova
qualidade = marca[0]
return None

elif marcas: # Tem marca antiga
if avalia: # Fazer avaliação robótica
qmarcas = bqua.findall(str(marcas)) # Qualidade em marcas antigas
bot = avaliar(page.toggleTalkPage())
if qmarcas:
if bot[0] > 4: # Avaliação automática retornou 5 ou 6
qualidade = qmarcas[0]
qualidade = str(bot[0]) # Avaliação automática 5 e 6 passam para o campo de avaliação humana
else:
qualidade = None
bot = None

else: # Não tem marca nova nem antiga
# Monta a nova marca
qualidade = None
if qualidade not in qs: # Qualidade não está em (1, 2, 3, 4, 5, 6, AB, AD)
nova = u'{{Marca de projeto|' + qualidade + (rev and u'|' + rev or u'') + u'|' + u'|'.join(t + u'|' + i for t, i in temas.items())
qualidade = u'?'
if bot and not rmbot:
# type(bot) == tuple é uma nova avaliação, type(bot) == unicode é uma avaliação antiga
if q and q[0] > 4: # Avaliação automática retornou 5 ou 6
nova += type(bot) == tuple and u'|bot=%d/{{subst:CURRENTYEAR}}{{subst:CURRENTMONTH}}{{subst:CURRENTDAY2}}' % bot[0] or u'|' + bot
qualidade = str(q[0]) # Avaliação automática 5 e 6 passam para o campo de avaliação humana
q = False
nova = u'{{marca de projeto|%s' % qualidade
rev = None
if marca and len(marca) > 1: # Tem marca nova e ela tem parâmetros
for i, p in enumerate(marca):
if p.startswith(u'rev='): # Parâmetro |rev=
rev = p
elif p.startswith(u'bot='): # Parâmetro |bot=
# Vai avaliar e não tem o parâmetro -forçar e já foi avaliado a menos de 6 meses
if q and not reav and p[6:] and date(int(p[6:10]), int(p[10:12]), int(p[12:14])).toordinal() + 182 > date.today().toordinal():
pywikibot.output(page.title() + u' foi avaliado por robô a menos de 6 meses, não foi reavaliado.')
return None
marca = filter(lambda x:u'=' not in x, marca) # Remove parâmetros com nome (|x=y)
if len(marca) % 2 == 0:
marca.append(u'?') # Adiciona |? se qualidade mais temas e importâncias der número impar (alguém esqueceu do |? no último tema)
for p in marca[1:]:
nova += u'|' + p # Monta uma nova marca com os parâmetros da anterior
if marcas: # Tem marcas antigas
imarcas = [[m[0]] + bimp.findall(m[1]) for m in marcas] # Importâncias nas marcas antigas
for m in imarcas: # Adiciona os parâmetros da marcas antigas na nova
if len(m) == 2:
nova += u'|' + m[0] + u'|' + m[1]
else:
nova += u'|' + m[0] + u'|?'
# Seria para adicionar um tema mas existe um tema exceção
if ad and filter(lambda e:e in nova.split(u'|'), ex):
ad = None
elif ad: # Vai adicionar um tema
ad = [a for a in ad.split(u'|') if not u'|' + a.lower() + u'|' in nova.lower()]
for m in ad: nova += u'|' + m + u'|?'
# Se vai avaliar adiciona a avaliação e data no parâmetro |bot=
if q:
nova += u'|bot=%d/{{subst:CURRENTYEAR}}{{subst:CURRENTMONTH}}{{subst:CURRENTDAY2}}' % q[0]
if not rev:
rev = brev.search(str(marcas))
if rev:
rev = rev.group(0)
if rev and qualidade != u'?': # Tem |rev= na marca e não tem avaliação humana
nova += u'|' + rev
nova += u'}}\n'
nova += u'}}\n'

impsum = {}
# Substitui marcas no texto
if imp: # Colocação de importância
for i in imp: # imp = {'tema1':'imp1', 'tema2':'imp2', ..., 'eimp': ['x', 'y', 'z']}
if i == 'eimp': # imp['eimp'] guarda as exceções
continue
iindex = nova.lower().find(i.strip().lower() + u'|') + len(i) + 1 # Posição da importância para esse tema na nova marca
if iindex > 20 and nova[iindex] not in imp['eimp']: # Encontrada a posição e a importância não é uma exceção
nova = nova[0:iindex] + imp[i].strip() + nova[iindex + 1:] # Nova importância
impsum[i] = imp[i] # guarda a importância para detalhar no sumário
if marcas: # Remove marcas antigas da página
if marcas: # Remove marcas antigas da página
texto = bmarcas.sub('', texto)
texto = bmarcas.sub('', texto)
Linha 244: Linha 248:
texto = re.sub(ur'{{[Aa]vançarDiscussão}}\n?', u'', texto) # Remove {{avanção discussão}} se tiver
texto = re.sub(ur'{{[Aa]vançarDiscussão}}\n?', u'', texto) # Remove {{avanção discussão}} se tiver
texto = re.sub(ur'^({{[Aa]vançarDiscussão}} ?\n?|.*?)', r'\1' + nova, texto) # Adiciona a marca no inicio ou depois de {{avançar discussão}}
texto = re.sub(ur'^({{[Aa]vançarDiscussão}} ?\n?|.*?)', r'\1' + nova, texto) # Adiciona a marca no inicio ou depois de {{avançar discussão}}

if type(q) == tuple: # Foi feita uma avaliação
if ad:
# Sumário da edição
if type(bot) == tuple: # Foi feita uma avaliação
sumario = u'Bot: adicioando marca "%s" e avaliando [[Wikipédia:Qualidade|qualidade]]: %d (%s)' % (ad[0], q[0], q[1])
if adtema:
sumario = u'Bot: adicioando marca{} {} e avaliando [[Wikipédia:Qualidade|qualidade]]: {} ({})'.format(len(adtema) > 1 and u's' or u'',
listar(adtema), bot[0], bot[1])
else:
else:
sumario = u'Bot: avaliando [[Wikipédia:Qualidade|qualidade]]: %d (%s)' % (q[0], q[1])
sumario = u'Bot: avaliando [[Wikipédia:Qualidade|qualidade]]: {} ({})'.format(bot[0], bot[1])
elif ad: # Não foi feita avaliação mas foi adicionado um tema
elif adtema: # Não foi feita avaliação mas foi adicionado um tema
if marcas:
if marcas:
sumario = u'Bot: adicionando marca "%s" e atualizando marca(s) de wikiprojeto(s)' % ad[0]
sumario = u'Bot: adicionando marca{0} {1} e atualizando marca{2} de wikiprojeto{2}'.format(len(adtema) > 1 and u's' or u'', listar(adtema),
len(marcas) > 1 and u's' or u'')
else:
else:
sumario = u'Bot: adicionando marca "%s"' % ad[0]
sumario = u'Bot: adicionando marca{} {}'.format(len(adtema) > 1 and u's' or u'', listar(adtema))
elif imp: # Não foi avaliado nem adicionado tema mas foi adicionada importância
elif imp: # Não foi avaliado nem adicionado tema mas foi adicionada importância
sumario = u'Bot: colocando importância em marca(s) de wikiprojeto(s)'
sumario = u'Bot: colocando importância em marca{0} de wikiprojeto{0}: {1}'.format(len(imp) > 1 and u's' or u'',
listar([u'importância {} para {}'.format(i, tema) for tema, i in imp.items()]))
else:
else:
sumario = u'Bot: atualizando marca(s) de wikiprojeto(s)'
sumario = u'Bot: atualizando marca{0} de wikiprojeto{0}'.format(len(temas) > 1 and u's' or u'')

if impsum: # Detalhar no sumário as importâncias adicionadas
for i in impsum:
sumario += u', importância %s para %s' % (impsum[i], i)
if simular: # Com o parâmetro -simular não salva
if simular: # Com o parâmetro -simular não salva
if page.exists():
if page.exists():
Linha 273: Linha 280:
return
return
return (nova, sumario)
return (nova, sumario)

def listar(itens):
lista = u''
n = len(itens) > 1 and len(itens) - 1 or 1
for i, item in enumerate(itens):
lista += (i == n and u' e ' or i > 0 and u', ' or u'') + item
return lista


simular, reav = False, False
simular, reav = False, False
Linha 278: Linha 292:
def main(*args):
def main(*args):
site = pywikibot.getSite()
site = pywikibot.getSite()
params = {}
av, predef, cat, subcat, ad, atu , ex, imp, eimp= False, None, None, u'', u'', None, u'', [], []
genFactory = pagegenerators.GeneratorFactory()
genFactory = pagegenerators.GeneratorFactory()
for arg in pywikibot.handleArgs(*args):
for arg in pywikibot.handleArgs(*args):
if arg.startswith(u'-predef'):
if arg == u'-avaliar':
pywikibot.output(u'A qualidade não é mais avaliada por robô na Wikipédia, para apenas ver a avaliação use -avaliar:"nome do artigo"')
predef = arg[8:]
if not predef:
return
predef = pywikibot.input(u'Qual predefinição?')
if predef:
if predef.find(u':') != -1:
predef = pywikibot.Page(site, predef)
else:
predef = pywikibot.Page(site, u'Predefinição:' + predef)
elif arg == u'-avaliar':
av = True
elif arg.startswith(u'-adicionar:'):
elif arg.startswith(u'-adicionar:'):
ad = arg[11:]
params['adicionar'] = [a.strip() for a in arg[11:].split(u',')]
elif arg.startswith(u'-avaliar:'):
elif arg.startswith(u'-avaliar:'):
qualidade = avaliar(pywikibot.Page(site, arg[9:]))
qualidade = avaliar(pywikibot.Page(site, arg[9:]))
Linha 299: Linha 305:
return
return
elif arg.startswith(u'-exceção:'):
elif arg.startswith(u'-exceção:'):
ex = arg[9:]
params['excecoes'] = [e.strip() for e in arg[9:].split(u':')]
elif arg.startswith(u'-imp:'):
elif arg.startswith(u'-imp:'):
imp = dict([i.split(u':') for i in arg[5:].split(u';')])
params['imp'] = dict([i.strip().split(u':', 1) for i in arg[5:].split(u',')])
elif arg.startswith(u'-eimp:'):
elif arg.startswith(u'-eimp:'):
eimp = arg[6:].split(u',')
params['eimp'] = arg[6:].split(u',')
elif arg.startswith(u'-rmbot'):
params['rmbot'] = True
elif arg == u'-simular':
elif arg == u'-simular':
global simular
global simular
simular = True
simular = True
elif arg == u'-forçar':
global reav
reav = True
elif arg == u'-comandos':
elif arg == u'-comandos':
pywikibot.output(pagegenerators.parameterHelp)
pywikibot.output(pagegenerators.parameterHelp)
Linha 316: Linha 321:
pywikibot.output(u'#Comando não encontrado: '+ arg)
pywikibot.output(u'#Comando não encontrado: '+ arg)
return
return
if imp:
imp['eimp'] = eimp
for page in pagegenerators.PreloadingGenerator(genFactory.getCombinedGenerator()):
for page in pagegenerators.PreloadingGenerator(genFactory.getCombinedGenerator()):
if not page.namespace() in [0, 1]:
if not page.namespace() in [0, 1]:
continue
continue
novo = atualizar(page, av, ad, ex, imp)
novo = atualizar(page, **params)
t = page.title()
t = page.title()
t = t[0:t.find(u':') + 1] + u'\03{lightblue}' + t[t.find(u':') + 1:] + u'\03{default}' # Cor
t = t[0:t.find(u':') + 1] + u'\03{lightblue}' + t[t.find(u':') + 1:] + u'\03{default}' # Cor

Revisão das 00h03min de 29 de junho de 2014

Ver também

Código

# -*- coding: utf-8  -*-
"""
@ Autor: [[Usuário:Danilo.mac]]
@ Licença de software: GNU General Public License 2.0 (GPLv2) e Creative Commons Attribution/Share-Alike (CC-BY-SA)

Utilize os seguntes comandos:

-avaliar:PÁGINA         Mostra uma avaliação com base nos parâmetros pré-estabelecidos.

-avaliar                Faz com que todas as qualidades sejam avaliadas.
                        Note que -avaliar e -avaliar: são dois comandos diferentes

-adicionar:TEMA         Adiciona esse tema à marca se ele já não existir. Para mais de um
                        tema use a barra vertical: TEMA1,TEMA2

-exceção:TEMA           Só adiciona o tema se TEMA não estiver na marca.

-imp:TEMA:I             Adiciona importância I para TEMA. Para mais de um tema separe
                        com ";", exemplo: -imp:TEMA1:2,TEMA2:3

-eimp:I                 Só adiciona a importância se a importância já não for I. Para mais
                        exceções separe com vírgula, exemplo: -eimp:3,4

-simular                Não salva a edição, apenas mostra o diff na tela.

-- Comandos para especificar as páginas que serão trabalhadas --

Este script utiliza a classe GeneratorFactory para especificar as páginas, veja a documentação
com a lista completa dos comandos no arquivo pagegenerators.py ou utilize o comando abaixo:

-comandos               Exibe na tela todos os comandos disponíveis para especificar as páginas
"""
import re
import pywikibot
from pywikibot import pagegenerators


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(page):
  try:
    texto = page.get()
  except pywikibot.IsRedirectPage:
    texto = page.getRedirectTarget().get()
  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) < 2:
    return (2, u'menos de 2 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) < 4:
    return (3, u'menos de 4 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]]')

bmarca = re.compile(u'{{[Mm]arca de projeto\|?([^\n}]*?)}}') #busca a marca
bmarcas = re.compile(u'{{(?:Predefinição:)?([Cc]lassificação/)?(([Áá]lbuns)|[^\n\|}]+?)(?(1)[|}]|(?(3)[|}]|/[Mm]arca))\|?([^\n}]*?)}}?\n?') # busca marcas antigas
bqua = re.compile(u'qualidade ?= ?0?(\d|A[BD])')
bimp = re.compile(u'importância ?= ?0?(\d)')
brev = re.compile(u'rev ?= ?\d{8}')
qs = {u'1', u'2', u'3', u'4', u'5', u'AB', u'6', u'AD'}

def atualizar(page, avalia=False, adicionar=[], excecoes=[], imp={}, eximp=[], rmbot=False):
  if page.namespace() == 0:
    page = page.toggleTalkPage()
  elif page.namespace() != 1:
    return None
  try:
    texto = page.get()
  except pywikibot.NoPage:
    texto = u''
  rev = None
  bot = False
  adtema = []
  temas = {}
  qualidade = None

  # Marca nova
  marca = bmarca.search(texto)
  if marca: # Tem marca nova
    marca = [p for p in marca.group(1).split('|')]
    tema = None
    n = 1
    if len(marca) > 1: # Tem marca nova e ela tem parâmetros
      for param in marca:
        if param.startswith(u'rev='): # Tem |rev= na marca
          rev = param
        elif param.startswith(u'bot='): # Tem parâmetro |bot=
          bot = param
        elif u'=' not in param: # Não tem "=" no parâmetro
          if n == 1: # Primeiro parâmetro é a qualidade
            qualidade = param
          elif n % 2 == 0: # Parâmetro par é tema
            tema = param
          else: # Parâmetro impor é importância
            temas[tema] = param
            tema = None
          n += 1
          if tema: # Último tema não tem importância
            temas[tema] = u'?'
  rmbot = rmbot and bot # Só considera que vai remover o |bot= se tiver
  # Marcas antigas
  marcas = [[m[1]]+[m[3]] for m in bmarcas.findall(texto)]
  if marcas: # Tem marcas antigas
    imarcas = [[m[0]] + bimp.findall(m[1]) for m in marcas] # Importâncias nas marcas antigas
    for m in imarcas: # Pega os parâmetros das marcas antigas
      if len(m) == 2:
        temas[m[0]] = m[1]
      else:
        temas[m[0]] = u'?'
    if not rev: # Não tem rev na marcas novas
      rev = brev.search(str(marcas)) # Busca rev nas antigas
      rev = rev and rev.group(0)
    if not qualidade: # Não tem qualidade na marca nova
      qmarcas = bqua.search(str(marcas)) # Busca qualidade em marcas antigas
      if qmarcas:
        qualidade = qmarcas.group(1) in (u'AB', u'AD') and {u'AB': u'5', u'AD': u'6'}[qmarcas.group(1)] or qmarcas.group(1)
  # Adição de temas
  if not filter(lambda t:t in excecoes, temas):
    for ad in adicionar:
      if ad not in temas:
	temas[ad] = u'?'
	adtema.append(ad)
  # Adição de importância
  imp = dict((tema, i) for tema, i in imp.items() if tema in temas and temas[tema] not in [i] + eximp)
  for tema in imp:
    temas[tema] = imp[tema]

  # Verificações:
  # Não tem marca antiga ou nova nem vai adicionar
  if not marcas and not marca and not adtema:
    if texto:
      pywikibot.output(u'Não foram encontradas marcas em ' + page.title())
    else:
      pywikibot.output(page.title() + u' não existe...')
    return None
  # Não tem marca antiga e ( (tem nova mas não vai avaliar, adicionar tema, adicionar exceção ou remover bot) ou (não tem marca nova e não vai adicionar) )
  elif not marcas and ((marca and not avalia and not adtema and not imp and not rmbot) or (not marca and adtema)):
    pywikibot.output(u'Não foram encontradas marcas para atualizar em ' + page.title())
    return None
  # Ou avalia ou remove o |bot=
  if rmbot and avalia:
    pywikibot.output(u'Erro: ou avalia ou remove o parâmetro bot')
    return None

  if avalia: # Fazer avaliação robótica
    bot = avaliar(page.toggleTalkPage())
    if bot[0] > 4: # Avaliação automática retornou 5 ou 6
      qualidade = str(bot[0]) # Avaliação automática 5 e 6 passam para o campo de avaliação humana
      bot = None

  # Monta a nova marca
  nova = u'{{Marca de projeto|' + qualidade + (rev and u'|' + rev or u'') + u'|' + u'|'.join(t + u'|' + i for t, i in temas.items())
  if bot and not rmbot:
    # type(bot) == tuple é uma nova avaliação, type(bot) == unicode é uma avaliação antiga
    nova += type(bot) == tuple and u'|bot=%d/{{subst:CURRENTYEAR}}{{subst:CURRENTMONTH}}{{subst:CURRENTDAY2}}' % bot[0] or u'|' + bot
  nova += u'}}\n'

  # Substitui marcas no texto
  if marcas: # Remove marcas antigas da página
    texto = bmarcas.sub('', texto)
  if marca: # Remove marcas novas da página
    texto = bmarca.sub('', texto)
  if texto.count(u'{{', 0, texto.find(u'\n==')) < 3: # Tem menos de 3 predefinições antes da primeira seção
    texto = re.sub(ur'{{[Aa]vançarDiscussão}}\n?', u'', texto) # Remove {{avanção discussão}} se tiver
  texto = re.sub(ur'^({{[Aa]vançarDiscussão}} ?\n?|.*?)', r'\1' + nova, texto) # Adiciona a marca no inicio ou depois de {{avançar discussão}}

  # Sumário da edição
  if type(bot) == tuple: # Foi feita uma avaliação
    if adtema:
      sumario = u'Bot: adicioando marca{} {} e avaliando [[Wikipédia:Qualidade|qualidade]]: {} ({})'.format(len(adtema) > 1 and u's' or u'',
        listar(adtema), bot[0], bot[1])
    else:
      sumario =  u'Bot: avaliando [[Wikipédia:Qualidade|qualidade]]: {} ({})'.format(bot[0], bot[1])
  elif adtema: # Não foi feita avaliação mas foi adicionado um tema
    if marcas:
      sumario =  u'Bot: adicionando marca{0} {1} e atualizando marca{2} de wikiprojeto{2}'.format(len(adtema) > 1 and u's' or u'', listar(adtema),
        len(marcas) > 1 and u's' or u'')
    else:
      sumario =  u'Bot: adicionando marca{} {}'.format(len(adtema) > 1 and u's' or u'', listar(adtema))
  elif imp: # Não foi avaliado nem adicionado tema mas foi adicionada importância
    sumario =  u'Bot: colocando importância em marca{0} de wikiprojeto{0}: {1}'.format(len(imp) > 1 and u's' or u'',
      listar([u'importância {} para {}'.format(i, tema) for tema, i in imp.items()]))
  else:
    sumario =  u'Bot: atualizando marca{0} de wikiprojeto{0}'.format(len(temas) > 1 and u's' or u'')

  if simular: # Com o parâmetro -simular não salva
    if page.exists():
      pywikibot.showDiff(page.get(), texto)
    else:
      pywikibot.output(u'Nova página:\n' + texto)
  else: # Salva o texto
    try:
      page.put(texto, comment=sumario)
    except pywikibot.LockedPage:
        pywikibot.output(u'\03{lightred}' + page.title() + u'está protegida!\03{default}')
        return
  return (nova, sumario)

def listar(itens):
  lista = u''
  n = len(itens) > 1 and len(itens) - 1 or 1
  for i, item in enumerate(itens):
    lista += (i == n and u' e ' or i > 0 and u', ' or u'') + item
  return lista

simular, reav = False, False

def main(*args):
  site = pywikibot.getSite()
  params = {}
  genFactory = pagegenerators.GeneratorFactory()
  for arg in pywikibot.handleArgs(*args):
    if arg == u'-avaliar':
      pywikibot.output(u'A qualidade não é mais avaliada por robô na Wikipédia, para apenas ver a avaliação use -avaliar:"nome do artigo"')
      return
    elif arg.startswith(u'-adicionar:'):
      params['adicionar'] = [a.strip() for a in arg[11:].split(u',')]
    elif arg.startswith(u'-avaliar:'):
      qualidade = avaliar(pywikibot.Page(site, arg[9:]))
      pywikibot.output(u'qualidade %d (%s)' % (qualidade[0], qualidade[1]))
      return
    elif arg.startswith(u'-exceção:'):
      params['excecoes'] = [e.strip() for e in arg[9:].split(u':')]
    elif arg.startswith(u'-imp:'):
      params['imp'] = dict([i.strip().split(u':', 1) for i in arg[5:].split(u',')])
    elif arg.startswith(u'-eimp:'):
      params['eimp'] = arg[6:].split(u',')
    elif arg.startswith(u'-rmbot'):
      params['rmbot'] = True
    elif arg == u'-simular':
      global simular
      simular = True
    elif arg == u'-comandos':
      pywikibot.output(pagegenerators.parameterHelp)
      return
    elif not genFactory.handleArg(arg):
      pywikibot.output(u'#Comando não encontrado: '+ arg)
      return
  for page in pagegenerators.PreloadingGenerator(genFactory.getCombinedGenerator()):
    if not page.namespace() in [0, 1]:
      continue
    novo = atualizar(page, **params)
    t = page.title()
    t = t[0:t.find(u':') + 1] + u'\03{lightblue}' + t[t.find(u':') + 1:] + u'\03{default}' # Cor
    if novo:
      pywikibot.output(t + u' -> ' + novo[1])


if __name__ == "__main__":
  try: main()
  finally: pywikibot.stopme()