# -*- coding: utf-8 -*-
import os, time, wikipedia, sys, re, catlib, pagegenerators, codecs, glob
#################################################
# #
# opereteatrali.py - ver. 2.0 #
# #
#################################################
"""
Questo script raccoglie dati relativi alle opere teatrali
presenti su it.wiki, restituendo un elenco di voci
"""
categoriaprincipale = 'on'
aggiornacategorie = 'on'
wikilinkautore= 'on'
controllalista= 'on'
ts=0
numerogiorni=8
#secondi in un giorno * numero gg
secondiaggiornamento=86400*numerogiorni
numerofileobsoleti=0
pagina_input = wikipedia.Page('it', 'Progetto:Teatro/Opere teatrali')
pagina_output = wikipedia.Page('it', 'Progetto:Teatro/Opere teatrali')
folder = ('opereteatrali')
date_file_list = []
for file in os.listdir(folder):
try:
filetime = os.stat(folder+'\\'+file).st_mtime
date_file_tuple = filetime, file
date_file_list.append(date_file_tuple)
except:
continue
date_file_list.sort()
#cancello i file più vecchi
count=0
for filetime, file in date_file_list:
count = count + 1
if count > numerofileobsoleti:
break
print 'cancello il file obsoleto: '+file
nomefile='opereteatrali/'+file
try:
os.remove(nomefile)
except IOError, (errno, strerror):
print "I/O error(%s): %s" % (errno, strerror)
contenuto='errore'
except ValueError:
print "Could not convert data to an integer."
contenuto='errore'
except:
print "Unexpected error:", sys.exc_info()[0]
contenuto='errore'
raise
def categorie():
catfile='opereteatrali/!categorie.txt'
listacategorie= []
categoryname = u'Opere teatrali per autore'
cat = catlib.Category(wikipedia.getSite(), 'Categoria:%s' % categoryname)
gencat1 = pagegenerators.SubCategoriesPageGenerator(cat, recurse=False)
for subcat in gencat1:
print subcat
if subcat.title() in listacategorie:
continue
else:
listacategorie.append(subcat.title())
categoryname = u'Opere teatrali per nazionalità'
cat = catlib.Category(wikipedia.getSite(), 'Categoria:%s' % categoryname)
gencat2 = pagegenerators.SubCategoriesPageGenerator(cat, recurse=False)
for subcat in gencat2:
print subcat
if subcat.title() in listacategorie:
continue
else:
listacategorie.append(subcat.title())
categoryname = u'Opere teatrali per lingua'
cat = catlib.Category(wikipedia.getSite(), 'Categoria:%s' % categoryname)
gencat3 = pagegenerators.SubCategoriesPageGenerator(cat, recurse=False)
for subcat in gencat3:
print subcat
if subcat.title() in listacategorie:
continue
else:
listacategorie.append(subcat.title())
return listacategorie
def gestorelista():
dizionario={}
lista=[]
listacategorie=categorie()
for categoria in listacategorie:
print '***************** '+categoria
cat = catlib.Category(wikipedia.getSite(), '%s' % categoria)
gen1 = pagegenerators.CategorizedPageGenerator(cat)
for page in gen1:
if page.namespace() == 0:
titolo=page.title()
if titolo not in lista:
if re.search(r'Elenco', titolo):
continue
else:
lista.append(titolo)
print titolo
categoryname = u'Opere teatrali'
cat = catlib.Category(wikipedia.getSite(), 'Categoria:%s' % categoryname)
gen2 = pagegenerators.CategorizedPageGenerator(cat)
for page in gen2:
if page.namespace() == 0:
titolo=page.title()
if titolo not in lista:
if re.search(r'Elenco', titolo):
continue
else:
lista.append(titolo)
print titolo
template=wikipedia.Page('it', 'Template:Dramma')
gen3 = pagegenerators.ReferringPageGenerator(template)
for page in gen3:
if page.namespace() == 0:
titolo=page.title()
if titolo not in lista:
if re.search(r'Elenco', titolo):
continue
else:
lista.append(titolo)
print titolo
for titolo in lista:
titoloord=titoloLink(titolo)
dizionario[titolo]=titoloord
items=dizionario.items()
backitems=[ [v[1],v[0]] for v in items]
backitems.sort()
lista=[ backitems[i][1] for i in range(0,len(backitems))]
return lista
def scrivifile(nomepagina, testo):
nomepagina = re.sub('\/', '_', nomepagina).strip()
nomepagina = re.sub(' ', '_', nomepagina).strip()
nomepagina = re.sub('"', '_', nomepagina).strip()
nomepagina = re.sub('\?', '_', nomepagina).strip()
nomefile='opereteatrali/'+nomepagina+'.txt'
print 'scrivo il file ' + nomefile
contenuto=testo.encode( "utf-8" )
# Scrive un file.
out_file = open(nomefile,"w")
out_file.write(contenuto)
out_file.close()
def leggifile(nomepagina):
nomepagina = re.sub('\/', '_', nomepagina).strip()
nomepagina = re.sub(' ', '_', nomepagina).strip()
nomepagina = re.sub('"', '_', nomepagina).strip()
nomepagina = re.sub('\?', '_', nomepagina).strip()
nomefile='opereteatrali/'+nomepagina+'.txt'
try:
print 'leggo il file ' + nomefile
# Legge un file.
in_file = open(nomefile,"r")
#print os.stat(nomefile)
contenuto = in_file.read()
in_file.close()
except IOError, (errno, strerror):
print "I/O error(%s): %s" % (errno, strerror)
contenuto='errore'
except ValueError:
print "Could not convert data to an integer."
contenuto='errore'
except WindowsError:
print "Unexpected error:", sys.exc_info()[0]
contenuto='errore'
except:
print "Unexpected error:", sys.exc_info()[0]
contenuto='errore'
raise
return contenuto
def cancellafile(nomepagina):
nomepagina = re.sub('\/', '_', nomepagina).strip()
nomepagina = re.sub(' ', '_', nomepagina).strip()
nomepagina = re.sub('"', '_', nomepagina).strip()
nomepagina = re.sub('\?', '_', nomepagina).strip()
nomefile='opereteatrali/'+nomepagina+'.txt'
print 'provo a cancellare il file ' + nomefile
try:
os.remove(nomefile)
except IOError, (errno, strerror):
print "I/O error(%s): %s" % (errno, strerror)
contenuto='errore'
except ValueError:
print "Could not convert data to an integer."
contenuto='errore'
except:
print "Unexpected error:", sys.exc_info()[0]
contenuto='errore'
raise
def templatesWithParams(self, thistxt, get_redirect=False):
# remove commented-out stuff etc.
thistxt = wikipedia.removeDisabledParts(thistxt)
# marker for inside templates or parameters
marker = wikipedia.findmarker(thistxt, '@@', '@')
# marker for links
marker2 = wikipedia.findmarker(thistxt, '##', '#')
# marker for math
marker3 = wikipedia.findmarker(thistxt, '%%', '%')
result = []
inside = {}
count = 0
Rtemplate = re.compile(
ur'{{(msg:)?(?P<name>[^{\|]+?)(\|(?P<params>[^{]*?))?}}')
Rlink = re.compile(ur'\[\[[^\]]+\]\]')
Rmath = re.compile(ur'<math>[^<]+</math>')
Rmarker = re.compile(ur'%s(\d+)%s' % (marker, marker))
Rmarker2 = re.compile(ur'%s(\d+)%s' % (marker2, marker2))
Rmarker3 = re.compile(ur'%s(\d+)%s' % (marker3, marker3))
# Replace math with markers
maths = {}
count = 0
for m in Rmath.finditer(thistxt):
count += 1
text = m.group()
thistxt = thistxt.replace(text, '%s%d%s' % (marker3, count, marker3))
maths[count] = text
while Rtemplate.search(thistxt) is not None:
for m in Rtemplate.finditer(thistxt):
# Make sure it is not detected again
count += 1
text = m.group()
thistxt = thistxt.replace(text,
'%s%d%s' % (marker, count, marker))
# Make sure stored templates don't contain markers
for m2 in Rmarker.finditer(text):
text = text.replace(m2.group(), inside[int(m2.group(1))])
for m2 in Rmarker3.finditer(text):
text = text.replace(m2.group(), maths[int(m2.group(1))])
inside[count] = text
# Name
name = m.group('name').strip()
m2 = Rmarker.search(name) or Rmath.search(name)
if m2 is not None:
# Doesn't detect templates whose name changes,
# or templates whose name contains math tags
continue
# {{#if: }}
if name.startswith('#'):
continue
# Parameters
paramString = m.group('params')
params = []
if paramString:
# Replace links to markers
links = {}
count2 = 0
for m2 in Rlink.finditer(paramString):
count2 += 1
text = m2.group()
paramString = paramString.replace(text,
'%s%d%s' % (marker2, count2, marker2))
links[count2] = text
# Parse string
markedParams = paramString.split('|')
# Replace markers
for param in markedParams:
for m2 in Rmarker.finditer(param):
param = param.replace(m2.group(),
inside[int(m2.group(1))])
for m2 in Rmarker2.finditer(param):
param = param.replace(m2.group(),
links[int(m2.group(1))])
for m2 in Rmarker3.finditer(param):
param = param.replace(m2.group(),
maths[int(m2.group(1))])
params.append(param)
# Add it to the result
result.append((name, params))
return result
def caratteri(parola):
caratteri = {u"È":"E",
u"É":"E",
u"Č":"C"
}
for car in caratteri.keys():
alf=caratteri[car]
if parola.startswith(car):
parolasenza = parola[len(car):]
parola = alf+parolasenza
return parola
def linguaLink(lingua):
#Se il campo è vuoto
if lingua == '':
ops= 'Oooops, stringa nulla'
print ops
else:
if re.search(r'[Ii]nglese', lingua):
lingua='{{en}}'
elif re.search(r'[Ll]atin', lingua):
lingua='{{la}}'
elif re.search(r'[Gg]rec', lingua):
if re.search(r'[Gg]reco [Aa]ntico', lingua):
lingua='{{grc}}'
else:
lingua='{{el}}'
elif re.search(r'[Ff]rancese', lingua):
lingua='{{fr}}'
elif re.search(r'[Tt]edesc', lingua):
lingua='{{de}}'
elif re.search(r'[Ss]pagnol', lingua):
lingua='{{es}}'
elif re.search(r'[Nn]orvegese', lingua):
lingua='{{no}}'
elif re.search(r'[Gg]iapponese', lingua):
lingua='{{ja}}'
elif re.search(r'[Cc]inese', lingua):
lingua='{{zh}}'
elif re.search(r'[Rr]uss', lingua):
lingua='{{ru}}'
elif re.search(r'[Ss]vedese', lingua):
lingua='{{sv}}'
#Dialetti
elif re.search(r'[Nn]apoletan', lingua):
lingua='{{nap}}'
elif re.search(r'[Ll]ombard', lingua):
lingua='{{lmo}}'
elif re.search(r'[Ss]icilian', lingua):
lingua='{{scn}}'
elif re.search(r'[Vv]enet', lingua):
lingua='{{vec}}'
#Se è italiano, va omesso
elif re.search(r'[Ii]talian', lingua):
lingua=''
#Se è una lingua diversa dalle precedenti, avviso
else:
avvisolingua='Trovata nuova lingua: '+lingua
if re.search(r'\[\[', lingua):
lingua=lingua
else:
lingua='[['+lingua+']]'
return lingua
def autoreLink(nomeautore, cognomeautore):
autore=''
nomeautore = re.sub('\[', '', nomeautore).strip()
nomeautore = re.sub('\]', '', nomeautore).strip()
cognomeautore = re.sub('\[', '', cognomeautore).strip()
cognomeautore = re.sub('\]', '', cognomeautore).strip()
if nomeautore and cognomeautore:
autore= nomeautore+' '+cognomeautore
elif nomeautore and not cognomeautore:
autore= nomeautore
elif cognomeautore and not nomeautore:
autore= cognomeautore
else:
autore=''
if wikilinkautore == 'on' and autore:
linkautore=leggifile(autore)
linkautore=linkautore.decode("utf8")
if linkautore == '' or linkautore == 'errore':
voceautore = wikipedia.Page('it', autore)
if voceautore.exists():
linkautore = voceautore.title()
if voceautore.isDisambig():
linkautore = voceautore.title()
elif voceautore.isRedirectPage():
voceautore=voceautore.getRedirectTarget()
linkautore = voceautore.title()
else:
linkautore = autore
scrivifile(autore, linkautore)
linkautore=leggifile(autore)
linkautore=linkautore.decode("utf8")
autore = linkautore
if autore == 'Anonimato':
autore = 'Anonimato|Anonimo'
autore='[['+autore+']]'
nomeautore=''
cognomeautore=''
if autore == '[[]]':
autore=''
return autore
def titoloLink(titoloorig):
titoloorig = re.sub('\n', '', titoloorig).strip()
titoloorig = re.sub('<[Bb][Rr]/>', '', titoloorig).strip()
articoli = ["Il ", "Lo ", "La ", "I ", "Gli ", "Le ",
"L'", "'O ", "'A ", "Los ", "Lu ", "U ", "The ", "El ",
"Un ", "Uno ", "Una ", "Un'", "Uno dei ", "Una delle ", "Uno degli ", "..."]
titolo=titoloorig
for articolo in articoli:
if titoloorig.startswith(articolo):
titolosenza = titoloorig[len(articolo):]
titolomaiuscolo = titolosenza[:1].upper()+titolosenza[1:]
titolo=titolomaiuscolo +', '+articolo
titolo=caratteri(titolo)
return titolo
def stringaDramma(parametri, nomepagina):
pretesto=u'* '
titolodef=''
trattino=u' - '
barra=''
link=''
diz = {'Titoloitaliano':'',
'Titolooriginale':'',
'Nome':'',
'Cognome':'',
'Nome2':'',
'Cognome2':'',
'Nome3':'',
'Cognome3':'',
'Dramma':'',
'Drammalink':'',
'PostDramma':'',
'Immagine':'',
'ImmagineDimensione':'',
'Didascalia':'',
'Titolooriginale':'',
'Source':'',
'Linguaoriginale':'',
'Lingua2':'',
'Genere':'',
'Soggetto':'',
'Scena':'',
'Epocacomposizione':'',
'Primapubblicazione':'',
'Primarappresentazione':'',
'Teatro':'',
'Primaitaliana':'',
'Teatroprimaitaliana':'',
'Premi':'',
'Versionisuccessive':'',
'Personaggi':'',
'Autografo':'',
'Opera':'',
'Cinema':'',
# spettacolo teatrale
'nomesceneggiatore':'',
'nomesoggetto':'',
# opera
'titoloitaliano':'',
'titolooriginale':'',
'musica':'',
'libretto':'',
'soggetto':'',
'linguaoriginale':'',
'epocacomposizione':''
}
rx1 = re.compile(r" ?= ?")
for p in parametri:
p=p.decode("utf8")
pl = re.split(rx1, p, 1)
if len(pl) == 2:
nomep=pl[0]
lunp=len(nomep)
while nomep.startswith(' '):
nomep=nomep[1:]
time.sleep(ts)
while nomep.endswith(' '):
nomep=nomep[lunp:]
lunp=lunp-1
time.sleep(ts)
for k in diz.keys():
kup=k.upper()
pup=pl[0].upper()
if kup == pup:
contp = pl[1]
contp = re.sub('\n', '', contp).strip()
contp = re.sub('=', '', contp).strip()
while contp.startswith(' '):
nomep=nomep[1:]
while contp.endswith(' '):
nomep=nomep[lunp:]
lunp=lunp-1
if len(contp) < 2:
continue
else:
time.sleep(ts)
##scrivo entry nel dizionario##
diz[k] = contp
titolo = diz['Titoloitaliano']
if titolo == '':
titolo = diz['titoloitaliano']
titolo = re.sub('\n', '', titolo).strip()
titolo = re.sub('<[Bb][Rr]/>', ' ', titolo).strip()
titolo = re.sub('<[Bb][Rr]>', ' ', titolo).strip()
titolo = re.sub('<[Bb][Rr] />', ' ', titolo).strip()
titoloorig = diz['Titolooriginale']
if titoloorig == '':
titoloorig = diz['titolooriginale']
titoloorig = re.sub('\n', '', titoloorig).strip()
titoloorig = re.sub('<[Bb][Rr]/>', ' ', titoloorig).strip()
titoloorig = re.sub('<[Bb][Rr]>', ' ', titoloorig).strip()
titoloorig = re.sub('<[Bb][Rr] />', ' ', titoloorig).strip()
if titolo:
if titolo == nomepagina:
barra=''
link=''
else:
barra = u'|'
link = titolo
else:
barra=''
link=''
titolodef= u"[["+nomepagina+barra+link+"]]"
lingualink = linguaLink(diz['Linguaoriginale'])
if lingualink == '':
lingua=''
lingualink = linguaLink(diz['linguaoriginale'])
if lingualink == '':
lingua=''
else:
lingua=lingualink+' '
if titoloorig :
titoloorig=u" ("+lingua+"\'\'"+titoloorig+"'\')"
else:
titoloorig=''
#AUTORE
aut1=''
aut2=''
aut3=''
autore=''
autore = autoreLink(diz['Nome'], diz['Cognome'])
if autore:
stringaautore=' di '+autore
else:
stringaautore=''
if stringaautore=='':
stringaautore = ' - sceneggiatura di '+diz['nomesceneggiatore']
if stringaautore == ' - sceneggiatura di ':
stringaautore = ''
if stringaautore=='':
stringaautore = ' - soggetto di '+diz['nomesoggetto']
if stringaautore == ' - soggetto di ':
stringaautore = ''
#EVENTUALI ALTRI AUTORI
autore2 = autoreLink(diz['Nome2'], diz['Cognome2'])
if autore2:
aut2=', '+autore2
else:
aut2=''
autore3 = autoreLink(diz['Nome3'], diz['Cognome3'])
if autore3:
aut3=', '+autore3
else:
aut3=''
musica = diz['musica']
libretto = diz['libretto']
soggetto = diz['soggetto']
if len(musica) > 4:
musica = trattino+'Musica: '+musica
if len(libretto) > 4:
libretto = trattino+'Libretto: '+libretto
if len(soggetto) > 4:
soggetto = trattino+'Soggetto: '+soggetto
autorem=musica+libretto+soggetto
# EPOCA
epoca = diz['Epocacomposizione']
epoca2 = diz['epocacomposizione']
prima = diz['Primarappresentazione']
pubblicata = diz['Primapubblicazione']
teatro = diz['Teatro']
if epoca:
epoca = re.sub(r'<.*>', '', epoca).strip()
epoca=trattino+epoca
elif epoca2:
epoca2 = re.sub(r'<.*>', '', epoca2).strip()
epoca=trattino+epoca2
else:
epoca=''
if prima:
prima = re.sub(r'<.*>', '', prima).strip()
prima=trattino+'Prima: '+prima
if teatro:
teatro = re.sub(r'<.*>', '', teatro).strip()
prima=prima+', '+teatro+'.'
if pubblicata:
pubblicata = re.sub(r'<.*>', '', pubblicata).strip()
pubblicata=trattino+'Pubblicata: '+pubblicata
#tipo di dramma
dr=diz['Dramma']
post=diz['PostDramma']
if dr:
dram=' - '+dr+' '+post
else:
dram=''
stringa = pretesto+titolodef+titoloorig+dram+stringaautore+aut2+aut3+autorem+epoca+prima+pubblicata
stringa = re.sub('\n', ' ', stringa).strip()
stringa = re.sub(r'<[Bb][Rr] ?/?>', '', stringa).strip()
return stringa
def intestazione():
riga1=u'{| style="font-size:100%;margin:0 auto; background: #EFEFEF" align=center width=100% id=toc\n'
riga2=u'|Questa pagina contiene informazioni ricavate automaticamente dalle voci di opere teatrali con l\'ausilio del \'\'\'[[Template:Dramma]]\'\'\' e di un [[Utente:YuBot|bot]]. L\'aggiornamento è periodico e automatico.\n'
riga3=u'|-\n|align="left"|Se manca un\'opera in questa lista, accertati che la sua voce contenga il template [[template:Dramma|dramma]]. Se i dati riportati sono sbagliati, \'\'\'correggi direttamente la voce dell\'opera teatrale:\'\'\' '
riga4=u'le modifiche saranno visibili in questa lista al prossimo aggiornamento. Per chiarimenti domanda pure al [[Utente:Yuma|manovratore]].\n'
riga5=u'|-\n|\'\'\'N.B.:\'\'\' \'\'Non si garantisce l\'accuratezza delle info riguardanti voci con altri template sinottici: alcune fra tali voci sono segnalate qui solo a scopo di verifica. Non sono incluse in questa lista le voci di opere teatrali [[:Categoria:Da verificare per enciclopedicità - teatro|da verificare per enciclopedicità]]\'\'.</small>'
testata=riga1+riga2+riga3+riga4+'\n|}'
return testata
def main():
testata=intestazione()
indiceinizio=u'\n__NOTOC__\n{| border="1" cellpadding="3" cellspacing="0" style="clear:center; float:center; margin:auto; margin-top:.5em; margin-bottom:.5em; background:#FAFAFA; border:1px solid #CCC; border-collapse:collapse; text-align:center; font-family: Helvetica, Frutiger 45 Light, Arial"\n|\'\'\'{{MediaWiki:Toc}}\'\'\' <br />'
indicelettere=''
indicefine=u'\n|}\n'
newtext=''
sezione=''
autore=''
nomepagina=''
warning=''
barra=''
link=''
epoca=''
voci=[]
voci = gestorelista()
count=0
for nomepagina in voci:
if nomepagina:
wikipedia.output('\n>>> %s <<<' % nomepagina)
contenuto=leggifile(nomepagina)
if contenuto == '' or contenuto == 'errore':
pagina=wikipedia.Page('it', nomepagina)
try:
contenuto=pagina.get()
scrivifile(nomepagina, contenuto)
testo=leggifile(nomepagina)
except:
voci.remove(nomepagina)
time.sleep(4)
continue
else:
testo=contenuto
else:
continue
titor=False
titoloorig=''
diz= {}
dizOpera= {}
autore=''
titolodef=''
titoloorig=''
epoca=''
warning=''
stringa=''
listaparametri=templatesWithParams(nomepagina, testo)
stringa = '* \'\'\'[['+nomepagina+']]\'\'\''
warning = u' <small>\'\'\'N.B.:\'\'\' Non è presente un template sinottico, oppure vi sono errori di compilazione.</small>'
for parametri in listaparametri:
if re.search(r'[Dd]ramma', parametri[0]):
avviso='trovato tl. dramma'
print avviso
stringa=stringaDramma(parametri[1], nomepagina)
warning=''
break
elif re.search(r'[Oo]pera', parametri[0]):
avviso='trovato tl. opera'
print avviso
stringa=stringaDramma(parametri[1], nomepagina)
warning = u' <small>\'\'\'N.B.:\'\'\' in questa voce è in uso il [[Template:Opera]]</small>'
break
elif re.search(r'[Ss]pettacolo', parametri[0]):
avviso='trovato tl. spettacolo teatrale'
print avviso
stringa=stringaDramma(parametri[1], nomepagina)
warning = u' <small>\'\'\'N.B.:\'\'\' in questa voce è in uso il [[Template:Spettacolo teatrale]].</small>'
break
else:
continue
if stringa == '':
continue
titolopersezione=titoloLink(nomepagina)
letteranuovasezione=titolopersezione[0]
if sezione:
if titolopersezione.startswith(sezione):
nuovasezione=''
else:
sezione=titolopersezione[0]
nuovasezione=u'=='+sezione+'==\n'
indicelettera=u' [[#'+sezione+'|'+sezione+']]'
indicelettere=indicelettere+indicelettera
else:
sezione=titolopersezione[0]
nuovasezione=u'=='+sezione+'==\n'
indicelettera=u' [[#'+sezione+'|'+sezione+']]'
indicelettere=indicelettere+indicelettera
stringa= nuovasezione+stringa+warning
wikipedia.output(stringa)
newtext=newtext+stringa+"\n"
print '*************************************************'
print '* *'
print '* Elaborazione dei dati completata *'
print '* *'
print '*************************************************'
inizio=testata+indiceinizio+indicelettere+indicefine
fine=''
lista=pagina_output
nuovotesto = inizio + newtext + fine
vecchiotesto=pagina_input.get()
wikipedia.showDiff(vecchiotesto, nuovotesto)
choice = wikipedia.inputChoice(u"Aggiorno?", ['Yes', 'No'], ['y', 'N'], 'N')
if choice in ['Y', 'y']:
wikipedia.setAction('opere teatrali.py 2.0: aggiorno')
lista.put(nuovotesto)
else:
wikipedia.stopme()
if __name__ == "__main__":
try:
main()
finally:
wikipedia.stopme()