Code Creatobot

De Wikipast
Version datée du 7 mai 2019 à 11:42 par Assi (discussion | contributions) (Page créée avec « <nowiki> ################################# ###### Creatobot #### ################################# import regex as re import requests from urllib.request import urlopen... »)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigation Aller à la recherche
#################################
###### Creatobot ####
#################################

import regex as re
import requests
from urllib.request import urlopen
from bs4 import BeautifulSoup

user='Creatobot'
passw='creatobot_mdp'
baseurl='http://wikipast.epfl.ch/wikipast/'
summary='Wikipastbot Creatobot'


###################################################################################################

### Initialisations :


#ouverture dictionnnaire
dictionnaryFileName= 'Lexique381.txt'
dictionnaryFile=open(dictionnaryFileName, encoding='utf-8')
dictionnaryString=dictionnaryFile.read()
dictionnaryLine=dictionnaryString.split('\n')
dictionnary = []
for line in dictionnaryLine:
    dictionnary.append(line.split('\t')[0])
dictionnaryFile.close()

#recherche des prénoms francais sur wikipédia
response=urlopen("https://fr.wikipedia.org/wiki/Liste_de_pr%C3%A9noms_fran%C3%A7ais_et_de_la_francophonie")
page_source=response.read()
soupPrenoms=BeautifulSoup(page_source,'html.parser')
prenoms=[]
for dlTag in soupPrenoms.findAll('dl'):
        for ddTag in dlTag.findAll('dd'):
            bTag = ddTag.find('b')
            if bTag:
                aTag = bTag.find('a')
                if aTag:
                    prenoms.append(aTag.string)


#Accès aux biographies du wikipast
response=urlopen("http://wikipast.epfl.ch/wikipast/index.php/Biographies")
page_source=response.read()
soupBiographies=BeautifulSoup(page_source,'html.parser')
biographies=[]
for primitive in soupBiographies.findAll("table"):
    for cap_and_count in primitive.findAll("td"):
        for text in cap_and_count.findAll("a"):
            if text.string != None:
                biographies.append(text.string)

# Login request
payload={'action':'query','format':'json','utf8':'','meta':'tokens','type':'login'}
r1=requests.post(baseurl + 'api.php', data=payload)

#login confirm
login_token=r1.json()['query']['tokens']['logintoken']
payload={'action':'login','format':'json','utf8':'','lgname':user,'lgpassword':passw,'lgtoken':login_token}
r2=requests.post(baseurl + 'api.php', data=payload, cookies=r1.cookies)

#get edit token2
params3='?format=json&action=query&meta=tokens&continue='
r3=requests.get(baseurl + 'api.php' + params3, cookies=r2.cookies)
edit_token=r3.json()['query']['tokens']['csrftoken']

edit_cookie=r2.cookies.copy()
edit_cookie.update(r3.cookies)




###################################################################################################

### Fonctions :


def inDictionnary(word):
    return word.lower() in dictionnary

def inPrenoms(word):
    return (word.lower()).capitalize() in prenoms

def onlyContainLetters(word):
    return not re.match("^[\D]*$", word) == None

def beginWithACapitalLetter(word):
    return not re.match("^[A-Z](.)*$", word) == None

#Si le mot ne contient que des lettres et commence par une majuscule
def needBracketsLight(word):
    return onlyContainLetters(word) and beginWithACapitalLetter(word)

#Si le mot ne contient que des lettres, commence par une majuscule et n'est pas dans le dictionnaire ou est un prénom
def needBracketsHard(word):
    return needBracketsLight(word) and (not inDictionnary(word) or inPrenoms(word))

def separatePunctuation(word):
    punctuationAfter = ''
    punctuationBefore = ''
    if re.match('^.+(\p{P}){1,3}$',word): #si on a une ponctuation après un mot
            punctuationAfter = re.search('[\p{P}]{1,3}$',word).group()
            word = re.sub('(\p{P}){1,3}$',"", word)
    if re.match ('^[\w\d_-]{0,1}(\p{P}){1,3}[\w\d_-]+$',word): #si on a une ponctuation avant un mot
            punctuationBefore = re.search('^[\w\d_-]{0,1}[\p{P}]{1,3}',word).group()
            word = re.sub('^[\w\d_-]{0,1}[\p{P}]{1,3}',"", word)

    return [word, punctuationBefore, punctuationAfter]

def addBracketsAfter(word):
    [word, punctuationBefore, punctuationAfter]=separatePunctuation(word)
    return punctuationBefore+word+']]'+punctuationAfter

def addBracketsBefore(word):
    [word, punctuationBefore, punctuationAfter]=separatePunctuation(word)
    return punctuationBefore+'[['+word+punctuationAfter


def main(*args):

    pages = ""

    if len(args) == 0:
        pages = biographies
    else:
        pages = args

    for p in pages:
        print(p)
        #récupération du texte dans la page voulue:
        title = p
        result=requests.post(baseurl+'api.php?action=query&titles='+title+'&export&exportnowrap')
        soup=BeautifulSoup(result.text, "lxml")
        #prend la partie de la page qui est le texte
        lines = soup.find('page').find('text').text.split('\n')

        ### Algorithme :
        #Prend les groupes de noms composés de 2 noms ou plus.
        #Il faut que le premier nom ne contienne que des lettres et commence par une majuscule et qu'il soit : soit pas dans le dictionnaire, soit dans la liste des prénoms.
        #Pour les noms suivants ils doivent simplement ne contenir que des lettres et commencer par une majuscule.
        newText = ''

        #Découpage du texte en ligne
        j=0
        while j < len(lines) :
            line=lines[j]
            if not re.match('^[=]{1,6}.*[=]{1,6}$', line): #Si la ligne n'est pas un titre
                #Mise en forme des référence au titre de la page
                line=line.replace('[['+soup.title.text+']]',soup.title.text)
                line=line.replace(soup.title.text,'[['+soup.title.text+']]')

                words = line.split(" ") #Découpage du texte en mot

                modifyFlag = False #Flag pour la gestion groupe de noms
                firstWord = False

                i=0
                while i < len(words):

                    #Evitement des mots déjà balisés
                    if re.match('[\[]{2}(.)*', words[i]): #Si présence d'une balise
                        flag = True #Flag pour la gestion des mot déjà balisé
                        wordID = i;
                        while i < len(words)-1 and flag :
                            [wordNoPunc, punctuationBefore, punctuationAfter]=separatePunctuation(words[i])

                            if i == wordID :
                                if punctuationBefore != '[[' :
                                    words[wordID]=re.sub('^[\[]{2}',"", words[wordID])
                                    flag = False
                                    i=-1
                                elif punctuationAfter == ']]' :
                                    flag = False
                                elif punctuationAfter != '' :
                                    words[wordID]=re.sub('^[\[]{2}',"", words[wordID])
                                    flag = False
                                    i=-1
                            else :
                                if punctuationBefore != '' :
                                    words[wordID]=re.sub('^[\[]{2}',"", words[wordID])
                                    flag = False
                                    i=-1
                                elif punctuationAfter == ']]' :
                                    flag = False
                                elif punctuationAfter != '' :
                                    words[wordID]=re.sub('^[\[]{2}',"", words[wordID])
                                    flag = False
                                    i=-1
                            i+=1

                    else :
                        [wordNoPunc, punctuationBefore, punctuationAfter]=separatePunctuation(words[i])

                        if modifyFlag :
                            if firstWord :
                                firstWord=False
                                if needBracketsLight(wordNoPunc) :
                                    words[i-1]=addBracketsBefore(words[i-1])
                                else :
                                    modifyFlag=False
                            else :
                                if not needBracketsLight(wordNoPunc) :
                                    words[i-1]=addBracketsAfter(words[i-1])
                                    modifyFlag=False

                        #Ouverture des balises si elles ne sont pas déjà ouvertes et si le test est ok
                        elif needBracketsHard(wordNoPunc):
                            modifyFlag = True
                            firstWord = True

                        #Fermeture des balises si dernier mot ou si ponctuation après le mot
                        if modifyFlag and needBracketsLight(wordNoPunc) and (i == len(words)-1 or punctuationAfter != '') :
                            modifyFlag=False
                            if not firstWord :
                                words[i]=addBracketsAfter(words[i])

                    i+=1
                line = ' '.join(words)
            newText += line + '\n'
            j+=1

        print(newText)


        payload={'action':'edit','assert':'user','format':'json','utf8':'','text':newText,'summary':summary,'title':title,'token':edit_token}
        r4=requests.post(baseurl+'api.php',data=payload,cookies=edit_cookie)
        print(r4.text)