Usuário:Danilo.bot/marcas.py
Documentação
Descrição
Script para atualização de marcas de projeto.
Uso
O código deve ser salvo na pasta /script da versão core do pywikibot. Para usá-lo deve estar na pasta anterior (pasta raiz do pywikibot) e digitar no console (Linux) ou DOS (Windows) "python pwb.py marcas parâmetros
".
O script faz as seguintes atualizações:
- Se houver marcas antigas na página de discussão ele coloca na marca nova. Essa atualização é feita independente dos parâmetros passados ao script.
- Adiciona temas se ainda não existir na marca nova ou em uma antiga. Use o parâmetro
-adicionar:"tema1, tema2"
. - Remove temas. Use o parâmetro
-remover:"tema1, tema2"
. - Adiciona importância a um tema. Use o parâmetro
-imp:"tema1:importância, tema2:importância"
e para exceções (ex: não adicionar 3 se já tiver importância 4) use-eimp:importância,importância
. - Remove o parâmetro
|bot=
da marca se houver. Isso só é feito automaticamente quando é feita uma das alterações acima ou quando é usado o parâmetro-rmbot
para forçar a remoção quando nenhuma outra alteração é feita. - Remove o parâmetro
rev
quando não existe avaliação humana. Isso só é feito automaticamente quando é feita uma das alterações acima.
Geradores
O script aceita todos geradores do pagegenerators, com duas mudanças:
- As páginas são automaticamente convertidas para páginas de discussão, então mesmo se o gerador listar artigos o script irá verificar as discussões dos artigos.
- Apenas páginas do domínio Discussão e Anexo Discussão são verificadas, então serão desconsideradas as páginas que não estiverem nesses dois domínios ou nos respectivos domínios de conteúdo.
Exemplos de utilização
Atualiza todas as marcas antigas nas páginas que trancluem a Predefinição:Capital/Marca:
python pwb.py marcas -transcludes:"Predefinição:Capital/Marca"
Adiciona o tema Física na marca na Discussão:Teorema de Norton e faz outras correções aplicáveis:
python pwb.py marcas -page:"Teorema de Norton" -adicionar:Física
Remove o parâmetro |bot= na marca na Discussão:Alumínio mesmo se não houver outra alteração a ser feita:
python pwb.py marcas -page:"Alumínio" -rmbot
Ver também
Código
editar# -*- 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:
-adicionar:TEMA Adiciona esse tema à marca se ele já não existir. Para mais de um
tema use vírgula: TEMA1,TEMA2
-remover:TEMA Remove esse tema se tiver na marca. Para mais de um tema use
vírgula: 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 vírgula, 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.
-rmbot Força a remoção do parâmetro |bot= mesmo quando não existe outra
alteração a fazer. Sem o -rmbot o parâmetro bot é removido desde que
haja outra alteração a fazer.
-- 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
from collections import OrderedDict
import pywikibot
from pywikibot import pagegenerators
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?') # 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'}
predefs = {u'Projeto-Pokémon': u'Pokémon', u'Wikipédia:PTV/Marca': u'Televisão', u'Anti-Vandalismo': u'Antivandalismo', u'catolicismo_diálogo': u'Catolicismo',
u'Wikipedia:Projetos/Ferrovipédia/ArtigoMembro': u'Ferrovipédia', u'Países/ArtigoMembro': u'Países', u'Wikipedia:Projetos/Televisão/Marca': u'Televisão',
u'Wikipedia:Projetos/Harry Potter/Marca': u'Harry Potter', u'Wikipedia:Projetos/Cidades do Mundo/Portugal/Marca': u'Localidades de Portugal',
u'ProjetoLGBT': u'LGBT', u'projetobd': u'Banda Desenhada', u'Canções': u'Canções', u'canções': u'Canções', u'Wikipedia:Projetos/Cinema/Marca': u'Cinema',
u'Wikipédia:Projetos/Subdivisões do Brasil/Artigo membro': u'Subdivisões do Brasil', u'Wikipedia:Projetos/Cidades do Mundo/Dinamarca/marca': u'Dinamarca',
u'WikiProjecto Escolares e universitários': u'Escolares e universitários', u'Wikipedia:Projetos/Cidades do Mundo/Espanha/Marca': u'Espanha',
u'WikiProjecto Discografias': u'Discografias', u'Projetobd': u'Banda Desenhada', u'álbuns': u'Álbuns', u'Música/Marca': u'Música', u'Ferrovipédia/Marca': u'Ferrovipédia', u'Cinema/Marca': u'Cinema', u'Games/Marca': u'Games'}
bmarcas2 = re.compile(u'{{ *(?:Predefinição:)? *(%s)\|?([^}]*?)}}?\n?' % u'|'.join(p for p in predefs)) # busca marcas antigas fora de padrão
stemas = {u'Filme': u'Cinema', u'Empresa': u'Empresas', u'Biografia': u'Biografias', u'Político': u'Políticos', u'Capital': u'Capitais',
u'Hisória e sociedade': u'História', u'Telenovela': u'Telenovelas', u'Freguesias de Portugal': u'Localidades de Portugal'}
def atualizar(page, adicionar=[], remover=[], excecoes=[], imp={}, eximp=[], rmbot=False):
if page.namespace() not in {1, 103}:
return None
try:
texto = page.get()
except pywikibot.NoPage:
texto = u''
rev = None
bot = False
adtema = []
rmtema = []
temas = OrderedDict()
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 impar é importância
temas[tema in stemas and stemas[tema] or tema] = param or u'?'
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)] + [(predefs[m[0]], m[1]) for m in bmarcas2.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 m[0] in temas and temas[m[0]] != u'?':
continue # Importância definida na marca nova tem prioridade
elif len(m) == 2:
temas[m[0] in stemas and stemas[m[0]] or m[0]] = m[1]
else:
temas[m[0] in stemas and stemas[m[0]] or 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)
qualidade = qualidade in qs and qualidade or u'?'
if not rev and qualidade and qualidade != u'?':
# Buscar no histórico
history = page.fullVersionHistory()
marcaSemData = bmarca.search(texto)
if not marcaSemData:
marcaSemData = re.compile(u'qualidade *= *' + qualidade).search(texto)
if marcaSemData:
marcaSemData = marcaSemData.group(0)
revision = history[0]
for r in history:
if marcaSemData in r[3]:
revision = r
else:
break
rev = u'rev=' + revision[1].totimestampformat()[0:8]
if rev and qualidade == u'?':
rev = None # Só mantém rev se tiver avaliação humana
# Adição de temas
if not set(excecoes) & set(temas):
for ad in adicionar:
if ad not in temas:
temas[ad] = u'?'
adtema.append(ad)
# Remoção de temas
for rm in remover:
if rm in temas:
del temas[rm]
rmtema.append(rm)
# 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]
# Substituição de temas
temas = [(t in stemas and stemas[t] or t, i) for t, i in temas.items()]
# 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 adicionar ou remover tema ou remover bot) ou (não tem marca nova e não vai adicionar) )
elif not marcas and ((marca and not adtema and not rmtema and not imp and not rmbot) or (not marca and not adtema)):
pywikibot.output(u'Não foram encontradas marcas para atualizar em ' + page.title())
return None
# Monta a nova marca
imps = {'1', '2', '3', '4'}
nova = u'{{Marca de projeto|' + qualidade + (rev and u'|' + rev or u'') + u'|' + u'|'.join(t + u'|' + (i in imps and i or u'?') for t, i in temas) + u'}}\n'
# Substitui marcas no texto
if marcas: # Remove marcas antigas da página
texto = bmarcas.sub('', bmarcas2.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
sumario = []
if rmtema:
sumario.append(u'removendo marca{} {}'.format(len(rmtema) > 1 and u's' or u'', listar(rmtema)))
if adtema:
sumario.append(u'adicioando marca{} {}'.format(len(adtema) > 1 and u's' or u'', listar(adtema)))
if marcas:
sumario.append(u'[[WP:Projetos/Padronização/Marcas|atualizando marca{}]]'.format(len(marcas) > 1 and u's' or u''))
if imp:
sumario.append(u'colocando importância em marca{}: {}'.format(len(imp) > 1 and u's' or u'',
listar([u'{} para {}'.format(i, tema) for tema, i in imp.items()])))
if sumario:
sumario = u'Robô: ' + listar(sumario)
else:
sumario = u'Robô: 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()
limit = 0
for arg in pywikibot.handleArgs(*args):
if arg.startswith(u'-avaliar'):
pywikibot.output(u'A qualidade não é mais avaliada por robô na Wikipédia')
return
elif arg.startswith(u'-adicionar:'):
params['adicionar'] = [a.strip() for a in arg[11:].split(u',')]
elif arg.startswith(u'-remover:'):
params['remover'] = [a.strip() for a in arg[9:].split(u',')]
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.startswith(u'-simular'):
global simular
simular = True
limit = int(arg[8:] or 0)
elif arg == u'-comandos':
pywikibot.output(pagegenerators.parameterHelp)
return
elif not genFactory.handleArg(arg):
pywikibot.output(u'#Comando não encontrado: '+ arg)
return
def gen():
for page in genFactory.getCombinedGenerator():
if page.namespace() % 2 == 0:
page = page.toggleTalkPage()
if page.namespace() in {1, 103}:
yield page
else:
pywikibot.output(u'Página [[{}]] não verificada (domínio não previsto para a colocação de marcas)'.format(page.title()))
for count, page in enumerate(pagegenerators.PreloadingGenerator(gen())):
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 limit and count + 1 == limit:
break
if __name__ == "__main__":
try: main()
finally: pywikibot.stopme()