Viquipèdia:Viquitrobada 2009/Taller de bots/Traduir Plantilles

# -*- coding:latin2 -*-
'''
Bot per traduir plantilles en base a la plantilla actual, la plantilla traduida
pel traducot automatic i les indicacions de la pàgina de traducció de plantilles 

La pàgina original i la pàgina traduida han de tenir exactament el mateix nombre de plantilles
i exactament en el mateix ordre.

La pàgina amb les indicacions de traducció de plantiles està a Usuari:Jrgoma/Plantilles/"codi de idioma"

Les plentilles per les quals no s'hagi indicat com traduir es copien tal com estan a l'article original.

La sintaci és:
***Nom de plantilla en l'idioma origina
(Nom de plantilla en català
**Nom de variable en idioma original
**Nom de variable en català
**Tipus de tractament a donar al valor de la variable)

Les tres últimes línies es poden repetir tantes vegades com variables pugui tenir la plantilla
Els noms de les variables poden estar buits però sempre hi ha d'haver tres línies per cada variable

Els tipus de tractament possibles són:
S (Si) Tradueix el valor de la variable, en la plantilla traduida posa el valor donat pel traductor automàtic
N (No) No el tradueix, conserva el valor de l'article en l'idioma original.
TEI Tracta com enllaç intern: Cerca en la viquipèdia del idioma original un article que tingui per nom el valor de la variable
	Si té interwiki al català dóna com a valor de la variable auqesta interwiki, si no hi ha l'article o aquest no 
	te insterwiki al català hi posa el text traduit.					  
'''

#Carrega mòduls
import wikipedia
import re


#Funció per trobar el títol en català duna pàgina donada en l'idioma origen
#Si la pàgina en l'idioma oringinal no exiteix o no té interwiki en català retorna ''
#Altrament retorna el títol de la pàgina en català en majúscules o minúscules segon estigui el títol
#de la pàgina original.
interwikicatala=re.compile("(?<=\[\[ca:)[^|\]]+")
def titol_catala(idioma,titol):
	page = wikipedia.Page( wikipedia.getSite(idioma,"wikipedia"), titol) 
	try:
		# Carrega la pàgina
		contingut = page.get(get_redirect = True)
	except wikipedia.NoPage:
		# L'enllaç en l'idioma original no existeix
		return ''
	enllaccatala=interwikicatala.search(contingut)
	if enllaccatala:
		enllacara=enllaccatala.group(0)
		#posar la primera lletra en minúscules si l'enllaç original la tenia.
		if titol[0]==titol[0].lower():
			enllacara=enllacara[0].lower()+enllacara[1:]
		return enllacara
	else:
		#A l'article en lidioma original no hi ha interwiki al català
		return ''

#Demana nom de la pàgina en català i idioma d'origen
pagina_a_traduir = wikipedia.input(u"Pàgina a traduïr?")
pagina_traduida = wikipedia.input(u"Pàgina traduida?")
idioma = wikipedia.input(u"Idioma?")

#llegeix la pàgina original 
pagina = wikipedia.Page( wikipedia.getSite(idioma,"wikipedia"), pagina_a_traduir)  
text = pagina.get()
noutext = text

#llegeix la pàgina destí 
paginadesti = wikipedia.Page( wikipedia.getSite("ca","wikipedia"), pagina_traduida)  
text_desti = paginadesti.get()
noutext_desti = text_desti
wikipedia.output(noutext_desti)

#Llegeix la pàgina amb el tractament de les plantilles
paginatractament = wikipedia.Page( wikipedia.getSite('ca',"wikipedia"), 'Usuari:Jrgoma/Plantilles/'+idioma)  
tractament = paginatractament.get()

#Prepara expressions regulars
'''
p és una expressió regular per trobar plantilles
q és una ER per trobar el nom de la plantilla
r per trobar les variables
s per separar el nom i el valor de cada variable
t per trobar les instruccions de traducció de plantilles
u per trobar les instruccions de cada variable de la plantilla
v per trobar el títol de la plantilla en les instruccions de traducció
w per trobar la traducció del títol de la plantilla
t1 per treure els | entre claudat de dins de les plantilles es substiuiran per {{ segur que no hi és dins
t2 per tornar a posar els | entra claudatos es cerca els {{
'''
p = re.compile('{{.+?}}')
q = re.compile('(?<={{).+?(?= *[\|}])')
r = re.compile('(?<=\|).+?(?=[\|}])')
s = re.compile('.+(?=[=])|(?<=[=]).+')
t = re.compile('[^)]+\)')
u = re.compile('(?<=[\*][\*])[^\*]*?(?=[\n\)])')
v = re.compile('(?<=\*\*\*).*?(?=\n)')
w = re.compile('(?<=\().*?(?=[\n\)])')
t1 = re.compile('(\[\[.*?)\|(.*\]\])')
t2 = re.compile('(\[\[.*?){{(.*\]\])')
#cadena i cadena2 per funconar amb t1 i t2
cadena='\\1{{\\2'
cadena2='\\1|\\2'

#Trobar totes les plantilles de la pagina a traduir
plantilles=p.findall(text)
maxim = len(plantilles)

#Trobar totes les plantilles de la pagina destí
plantilles_desti=p.findall(text_desti)
maxim_desti = len(plantilles_desti)

#Trobar totes les instruccions de tractament
instruccions=t.findall(tractament)
maxim_instruccions = len(instruccions)

'''
Crear diccionaris a partir de les instruccions
* traduccio_titol, és un diccionari que a cada títol de plantilla li asigna la seva traducció
* traducció_variable, és un diccionari de diccionaris, a cada títol de plantilla li assigna el 
diccionari de traducció de noms de variables (aquest a cada nom li assigna la seva traducció)
* traduccio_tractament, altre diccionari de diccionaris, a cada títol de plantilla li assigna e
un diccionri que a cada nom de variable li assigna el tipus de tractament que s'ha de donar al
valor de la variable.
'''
traduccio_titol = {}
traduccio_variable = {}
tractament_variable = {}
i=0
while i < maxim_instruccions:
	#Trobar el títol
	titol = v.findall(instruccions[i])[0]
	#afegir al diccionari la traducció del títol
	traduccio_titol[titol] = w.findall(instruccions[i])[0]
	#trobar totes les instruccions de cada variable
	variables = u.findall(instruccions[i])
	maxim_variables = len(variables)
	#Crear diccionaris amb la traducció i el tractament de cada variable dins la plantilla
	j = 1
	diccionari_traduccio = {}
	diccionari_tractament = {}
	contavariables = 1
	while j+2 < maxim_variables:
		nomvariable = variables[j]
		if nomvariable == '':
			nomvariable = contavariables
			contavariables = contavariables +1
		diccionari_traduccio[nomvariable] = variables[j+1]
		diccionari_tractament[nomvariable] = variables[j+2]
		j = j+3
	#afegir aquests diccionaris als diccionaris de diccionaris 
	traduccio_variable[titol] = diccionari_traduccio
	tractament_variable[titol] = diccionari_tractament
	i = i+1

#Intenta traduir cada una de les plantilles
i=0
while i < maxim:
	print u'Plantilles fetes', i, 'de:', maxim
	plantilla = plantilles[i]
	plantilla_desti = plantilles_desti[i]
	#treu | entre claudators de plantilla i de plantilladesti
	plantilla = t1.sub(cadena, plantilla)
	plantilla_desti = t1.sub(cadena, plantilla_desti)
	#cerca el nom de la plantilla a traduir
	nomplantilla = q.findall(plantilla)[0]
	nomplantilla = nomplantilla[0].upper()+nomplantilla[1:]
	#compila expressio regular de la plantilla desti per podrla substituir
	pre_er_plantilla_desti = plantilles_desti[i]
	# substituir "metacaracter" per \"metacaracter"
	#barres = re.compile('([\^\$\*\+\?\{\}\[\]\|\(\)])')
	barres = re.compile('([\|\.\^\$\*\+\?\{\}\[\]\(\)])')
	pre_er_plantilla_desti = barres.sub('\\\\\\1',pre_er_plantilla_desti)
	er_plantilla_desti = re.compile(pre_er_plantilla_desti)
	#si la plantilla no té instruccions per traduir-la deixa la original i continua
	if not(nomplantilla in traduccio_titol):
		noutext_desti = er_plantilla_desti.sub(plantilles[i],noutext_desti)
		i = i+1
		continue
	
	#tradueix el títol de la plantilla
	plantilla_traduida = '{{'+traduccio_titol[nomplantilla]
	
	#tradueix i tracta les variables
	
	#troba les variables
	variables = r.findall(plantilla)
	variables_desti = r.findall(plantilla_desti)
	maxim_variables = len(variables)
	j = 0
	contavariables = 1
	while j < maxim_variables:
		variable = variables[j]
		variable_desti = variables_desti[j]
		#separa nom i valor
		dades_variable = s.findall(variable)
		dades_variable_desti = s.findall(variable_desti)
		if len(dades_variable)>0:
			nom_variable = dades_variable[0]
			#elimina espais an blanc al començament del nom
			while nom_variable[0] == ' ':
				nom_variable = nom_variable[1:]
			valor_variable = dades_variable[1]
			valor_variable_desti = dades_variable_desti[1]
			#vigilar si no esta definida la variable
			if nom_variable in traduccio_variable[nomplantilla]:
				plantilla_traduida = plantilla_traduida + '|'+traduccio_variable[nomplantilla][nom_variable] +' = '
			else:
				plantilla_traduida = plantilla_traduida + '|'+nom_variable +' = '
		else:
			valor_variable = variable
			valor_variable_desti = variable_desti
			nom_variable = contavariables
			contavariables = contavariables + 1
			plantilla_traduida = plantilla_traduida + '|'
		#vigilar si no esta definida la variable
		if nom_variable in tractament_variable[nomplantilla]:
			tractament = tractament_variable[nomplantilla][nom_variable]
		else:
			tractament = 'N'
		if tractament == 'N':
			plantilla_traduida = plantilla_traduida + valor_variable
		elif tractament == 'S':
			plantilla_traduida = plantilla_traduida + valor_variable_desti
		elif tractament == 'TEI':
			titol = titol_catala(idioma,valor_variable)
			if titol == '':
				plantilla_traduida = plantilla_traduida + valor_variable_desti
			else:
				plantilla_traduida = plantilla_traduida + titol		
		j = j+1
	i = i+1	
	
	#tanca la plantilla amb }}
	plantilla_traduida = plantilla_traduida + '}}'
	#torna a posar els | en lloc dels {{ entre claudators
	plantilla_traduida = t2.sub(cadena2, plantilla_traduida)
	
	#substitueix la plantilla per la seva traducció
	noutext_desti = er_plantilla_desti.sub(plantilla_traduida,noutext_desti)

wikipedia.showDiff(noutext_desti, text_desti)	
editem = wikipedia.input("editem?")	
#Grava la pàgina modificada	
paginadesti.put(noutext_desti,u'bot traduint automaticament plantilles')