« Chronobot » : différence entre les versions
(Wikipastbot update) |
(Annulation des modifications 37577 de Orthobot (discussion)) |
||
Ligne 3 : | Ligne 3 : | ||
[[Chronobot]] est un bot programmé en langage [[Python]] et qui agit sur des pages [[Wikipast]]. Il permet de regrouper tous les événements qui se sont passés en une année dans une même page | [[Chronobot]] est un bot programmé en langage [[Python]] et qui agit sur des pages [[Wikipast]]. Il permet de regrouper tous les événements qui se sont passés en une année dans une même page | ||
=Fonctionnement= | =Fonctionnement= | ||
[[Chronobot]] va d'abord effectuer un | [[Chronobot]] va d'abord effectuer un scan sur l'ensemble des pages biographiques crées par les élèves du cours "Humanités Digitales" (2017). Il effectue ensuite un scan sur tous les événements relevés dans chaque page et en stocke la date (sous forme AAAA.MM.JJ) et la description dans une liste. Une fois cette liste en main, il crée une page pour chaque jour différent. Pour des raisons pratiques, il est plus logique de n'avoir qu'une seule page par année avec tous les événements relevés durant cette année classés chronologiquement. Pour ce faire, au lieu d'agir directement sur l'url de la page, [[Chronobot]] redirige chaque lien d'un jour vers l'url de l'année correspondante. Enfin, il y écrit l'événement en bas de la page de l'année correspondante. Quand il finit le scan, il ordonne tous les événements des pages années qui ont été modifiées. La gestion des doublons est résolue ultérieurement. | ||
==Généralités== | ==Généralités== | ||
Ligne 17 : | Ligne 11 : | ||
==Liste des fonctions== | ==Liste des fonctions== | ||
=== Fonctions principales === | === Fonctions principales === | ||
* ''select_page. | * ''select_page.py'' parcourt les différentes pages sur une séléection précise de Users (ceux du cours SHS) et en retourne les pages crées sous formes de chaînes brutes (String). Les images (.png) sont ôtées ainsi que | ||
* ''recherchedates.py'' prend en argument une page donnée (string) et en sort une liste année/événement | |||
* ''modify_links.py'' modifie toutes les pages des dates pour qu'elles soient redirigées vers la page de l'année. | |||
* ''create_new_site.py'' crée une page [[Wikipast]] avec le contenu donné | |||
* ''order.py'' ordonne une page dans l'ordre chronologique et ''order_all.py'' effectue ''order.py'' sur toutes les pages une fois qu'elles sont toutes écrites. | |||
* '' | * ''place_evenement.py'' écrit un événement dans une page. | ||
* ''event_not_in_page.py'' gère les doublons en comparant deux strings-évenements caractère par caractère. Il considère ainsi deux évenements identiques s'ils contiennent les mêmes suites de caractères. Il ne tient pas compte des virgules (,), points (.) et espaces ( ) s'ils sont différents dans les deux strings. | |||
* '' | |||
* '' | |||
* '' | |||
* '' | |||
* ''event_not_in_page. | |||
=== Fonctions secondaires === | === Fonctions secondaires === | ||
* '' | * ''retrieve_content.py'' prend en input le nom d'une page et retourne tout le texte contenu en syntaxe wiki. | ||
* ''split_date.py'' prend en input une date 'aaaa.mm.jj' et retourne une array [année, mois, jour]. | |||
* '' | |||
=Exemples de pages créées= | =Exemples de pages créées= | ||
* [[1990.02.23]] - | * [[1990.02.23]] -> redirection vers [[1990]] | ||
* [[1990.06]] -> redirection vers [[1990]] | |||
* [[1990.06]] - | |||
* [[1990]] | * [[1990]] | ||
=Critiques et faiblesses du bot= | =Critiques et faiblesses du bot= | ||
* Optimisation du code (plusieurs minutes pour s' | * Optimisation du code (plusieurs minutes pour s'exéctuer sur toutes les pages.) | ||
* Si une année a déjà été crée avant notre bot et une phrase a été ajoutée, par exemeple "Grande année" redigirigée vers "1995" comportait une phrase commançant par "Grande année". Pour résoudre ce problème, deux solutions sont enbisageables : la première, assez radicale, est d'effacer la ligne en question dans la page Wikpast. La seconde (celle choisie, plus douce) est | |||
* Si une année a déjà été crée avant notre bot et une phrase a été ajoutée, par | * Gestion des doublons : pourrait être amélioré dans la comparaison de deux événements similaires. Actuellement, seules deux événements écrits exactement pareils ne sont pas dédoublés (par la fonction ''event_not_in_page.py''), mais on pourrait imaginer qu'un événement du type [[Mariage]] qui serait écrit comme "A se marie avec B" dans la page de A et "B se marie avec A" dans la page de B, et qui serait donc relevé deux fois. | ||
* Normalisation des dates sur les pages de la database (car par exemple une inversion mois-jour pas prise en compte actuellement) | |||
* Classement chronologique des événements dans les pages de la database | |||
* Gestion des doublons : pourrait être amélioré dans la comparaison de deux événements similaires. Actuellement, seules deux événements écrits exactement pareils ne sont pas dédoublés (par la fonction ''event_not_in_page. | |||
* Normalisation des dates sur les pages de la | |||
* Classement chronologique des événements dans les pages de la | |||
* Section "Mois" dans les pages années | * Section "Mois" dans les pages années | ||
=Scheduling= | =Scheduling= | ||
Tant que le nombre d'utilisateurs reste en accord avec le nombre d'étudiants dans le cours "Humanités Digitales" de l'EPFL, le bot va tourner une fois par semaine. Si | Tant que le nombre d'utilisateurs reste en accord avec le nombre d'étudiants dans le cours "Humanités Digitales" de l'EPFL, le bot va tourner une fois par semaine. Si wikiapst devient un site ouvert au public, il faudra éventuellement le lancer plus fréquemment. | ||
=Code source= | =Code source= | ||
== | ==main_one_page.py et main.py== | ||
===main_one_page.py=== | |||
=== | |||
<nowiki> | <nowiki> | ||
from | from create_new_site import create_new_site | ||
from create_site import create_site | |||
from modify_links import modify_links | |||
from | from place_evenement import place_evenement | ||
from | |||
from | |||
from event_not_in_page import event_not_in_page | from event_not_in_page import event_not_in_page | ||
from | from recherchedates2 import recherchedates2 | ||
#ajouter ici les autres fonctions dont on aura besoin | #ajouter ici les autres fonctions dont on aura besoin | ||
def | def main_one_page(page): | ||
page=page.replace(" ","_") | page=page.replace(" ","_") | ||
#modifie les dates pour rediger vers une année | #modifie les dates pour rediger vers une année | ||
modify_links(page) | |||
#renvoie un | #renvoie un array de deux colonnes: une colonne de dates et une colonne d'evenements | ||
elements=recherchedates2(page) | |||
elements= | |||
for element in elements: | for element in elements: | ||
evenement = element[1] | |||
date = element[0] | date = element[0] | ||
annee = date[:4] | annee = date[:4] | ||
#cree le site si il existe pas encore | #cree le site si il existe pas encore | ||
create_site(annee) | |||
if event_not_in_page(annee, | if event_not_in_page(annee,evenement): | ||
content=place_evenement(date,evenement) | |||
content= | create_new_site(annee,content) | ||
</nowiki> | </nowiki> | ||
===main. | ===main.py=== | ||
<nowiki> | <nowiki> | ||
''' | ''' | ||
Ligne 159 : | Ligne 81 : | ||
from select_page import select_page | from select_page import select_page | ||
from | from main_one_page import main_one_page | ||
import datetime | import datetime | ||
from | from order_all import order_all | ||
page_list=select_page() | page_list=select_page() | ||
Ligne 175 : | Ligne 91 : | ||
print('Je suis en train de faire la page: '+page) | print('Je suis en train de faire la page: '+page) | ||
print("J'ai fait un "+str(i/len(page_list)*100)+'%') | print("J'ai fait un "+str(i/len(page_list)*100)+'%') | ||
years_modified=years_modified+ | years_modified=years_modified+main_one_page(page) | ||
i=i+1 | i=i+1 | ||
print("j'ai fini, il me reste qu'à tout ordonner") | print("j'ai fini, il me reste qu'à tout ordonner") | ||
#ici il ordonne toutes les pages, parce que la fonction | #ici il ordonne toutes les pages, parce que la fonction place_evenement | ||
#met les evenements juste à la fin de la page | #met les evenements juste à la fin de la page | ||
order_all(years_modified) | |||
now = datetime.datetime.now() | now = datetime.datetime.now() | ||
Ligne 206 : | Ligne 118 : | ||
</nowiki> | </nowiki> | ||
==select_pages. | ==select_pages.py== | ||
===Code source=== | ===Code source=== | ||
<nowiki> | <nowiki> | ||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||
#return a list of str containing | #return a list of str containing all the name of wikipast page, without the one beginin with "Fichier:" or the one beginin with 4 number (ex:"1945") | ||
#only pages changed by user in the "whiteliste.txt" and done AFTER the date write in "lastdate.txt" are given | #only pages changed by user in the "whiteliste.txt" and done AFTER the date write in "lastdate.txt" are given | ||
#to change the "lastdate.txt", please put those line where needed : | #to change the "lastdate.txt", please put those line where needed : | ||
Ligne 225 : | Ligne 133 : | ||
def select_page(): | def select_page(): | ||
baseurl='http://wikipast. | baseurl='http://wikipast.epfl.ch/wikipast/' | ||
fichier=open('whiteliste.txt', 'r') | fichier=open('whiteliste.txt', 'r') | ||
protected_logins=fichier.read() | protected_logins=fichier.read() | ||
fichier.close() | fichier.close() | ||
protected_logins=protected_logins. | protected_logins=protected_logins.split('\n') | ||
protected_logins=protected_logins[:(len(protected_logins)-1)] | protected_logins=protected_logins[:(len(protected_logins)-1)] | ||
Ligne 318 : | Ligne 224 : | ||
== | == recherchedates2.py == | ||
<nowiki> | <nowiki> | ||
import requests | import requests | ||
from bs4 import BeautifulSoup | from bs4 import BeautifulSoup | ||
from | from retrieve_content import retrieve_content | ||
def | def recherchedates2(page_name): | ||
x=str( | x=str(retrieve_content(page_name)) | ||
x=x. | x=x.split("\n") | ||
dates=[] | dates=[] | ||
for i in x: | for i in x: | ||
Ligne 350 : | Ligne 249 : | ||
</nowiki> | </nowiki> | ||
== | ==modify_links.py== | ||
<nowiki> | <nowiki> | ||
''' | ''' | ||
cette fonction prend en input le nom d'une page. | cette fonction prend en input le nom d'une page. | ||
Pour toutes les dates de type [[AAAA/MM/JJ]], elle crée le | Pour toutes les dates de type [[AAAA/MM/JJ]], elle crée le | ||
lien de | lien de redirection vers la page de l'année. | ||
Pour les dates de type [[AAAA]] elle ne fait | Pour les dates de type [[AAAA]] elle ne fait | ||
rien puisqu'elles sont déjà un lien vers l'année | rien puisqu'elles sont déjà un lien vers l'année | ||
Ligne 365 : | Ligne 260 : | ||
import requests | import requests | ||
from bs4 import BeautifulSoup | from bs4 import BeautifulSoup | ||
from | from retrieve_content import retrieve_content | ||
months=["Janvier","F.C3.A9vrier","Mars","Avril","Mai","Juin","Juillet","Ao.C3.BBt","Septembre","Octobre","Novembre","D.C3.A9cembre"] | months=["Janvier","F.C3.A9vrier","Mars","Avril","Mai","Juin","Juillet","Ao.C3.BBt","Septembre","Octobre","Novembre","D.C3.A9cembre"] | ||
def | def modify_links(page_name): | ||
############### | ############### | ||
############### | ############### | ||
# | #retrieve dates | ||
text=retrieve_content(page_name) | |||
text= | text=text.split("\n") | ||
text=text. | |||
dates=[] | dates=[] | ||
for line in text: | for line in text: | ||
Ligne 394 : | Ligne 282 : | ||
############### | ############### | ||
############### | ############### | ||
# | #create pages with redirection code | ||
user = "ChronoBOT" | user = "ChronoBOT" | ||
passw = "sajas2017" | passw = "sajas2017" | ||
baseurl='http://wikipast. | baseurl='http://wikipast.epfl.ch/wikipast/' | ||
summary='ChronoBOT page creation' | summary='ChronoBOT page creation' | ||
Ligne 433 : | Ligne 318 : | ||
</nowiki> | </nowiki> | ||
== | ==create_site.py== | ||
<nowiki> | <nowiki> | ||
Ligne 445 : | Ligne 328 : | ||
import requests | import requests | ||
def | def create_site(year): | ||
#check if year is a four digit number | #check if year is a four digit number | ||
year=str(year) | year=str(year) | ||
Ligne 455 : | Ligne 337 : | ||
user = "ChronoBOT" | user = "ChronoBOT" | ||
passw = "sajas2017" | passw = "sajas2017" | ||
baseurl='http://wikipast. | baseurl='http://wikipast.epfl.ch/wikipast/' | ||
summary='ChronoBOT page creation' | summary='ChronoBOT page creation' | ||
#check if page already exists | #check if page already exists | ||
if(requests.get('http://wikipast. | if(requests.get('http://wikipast.epfl.ch/wikipast/index.php/'+year)).status_code!=404: | ||
return | return | ||
Ligne 491 : | Ligne 371 : | ||
== | ==order.py et order_all.py== | ||
===order.py=== | |||
=== | |||
<nowiki> | <nowiki> | ||
from smaller_than import smaller_than | from smaller_than import smaller_than | ||
def | def order(text):#ça ordonne un text | ||
text1=text.split('\n') | |||
text1=text. | |||
#separate events from other useless lines in the page | #separate events from other useless lines in the page | ||
newtext=[] | newtext=[] | ||
Ligne 516 : | Ligne 387 : | ||
craptext.append(line) | craptext.append(line) | ||
#case where page is empty, only has | #case where page is empty, only has one line in it, or only has crap in it | ||
if len(newtext)<2: | if len(newtext)<2: | ||
return text | return text | ||
Ligne 546 : | Ligne 416 : | ||
</nowiki> | </nowiki> | ||
=== | ===order_all.py=== | ||
<nowiki> | <nowiki> | ||
from | from order import order | ||
from retrieve_content import retrieve_content | |||
from create_new_site import create_new_site | |||
from | |||
from | |||
def | def order_all(years):#ça ordonne toutes les annees | ||
done=[] | done=[] | ||
for year in years: | for year in years: | ||
if year not in done: | if year not in done: | ||
print('I am ordering page '+year) | print('I am ordering page '+year) | ||
content= | content=order(retrieve_content(year)) | ||
create_new_site(year,content) | |||
done.append(year) | done.append(year) | ||
</nowiki> | </nowiki> | ||
== | ==place_evenement.py== | ||
<nowiki> | <nowiki> | ||
from | from retrieve_content import retrieve_content | ||
def place_evenement(annee,evenement): #format annee: 'aaaa' | |||
#format dans wikipast: '*[[aaaa.mm.jj]] (...)' seulement le début du format nous intéress | |||
def | return retrieve_content(annee)+'\n'+evenement | ||
#format dans wikipast: '*[[ | |||
return | |||
</nowiki> | </nowiki> | ||
==event_not_in_page. | ==event_not_in_page.py== | ||
<nowiki> | <nowiki> | ||
''' | ''' | ||
cette fonction prend en input une annee et un | cette fonction prend en input une annee et un evenement. | ||
Si cet evenement est déja dans la page de l'année il renvoie 0 | |||
Si cet | |||
Si il n'est pas encore dans la page de l'année il renvoie 1 | Si il n'est pas encore dans la page de l'année il renvoie 1 | ||
''' | ''' | ||
from | from retrieve_content import retrieve_content | ||
def event_not_in_page(date, | def event_not_in_page(date,evenement): | ||
text=retrieve_content(str(date)).replace(' ','') | |||
text= | |||
text=text.replace(',','') | text=text.replace(',','') | ||
text=text.replace('.','') | text=text.replace('.','') | ||
pos= | pos=evenement.find(']]') | ||
evenement=evenement[pos+2:].replace(' ','') | |||
evenement=evenement.replace(',','') | |||
evenement=evenement.replace('.','') | |||
if evenement in text: | |||
if | |||
return 0 | return 0 | ||
else: | else: | ||
Ligne 634 : | Ligne 464 : | ||
</nowiki> | </nowiki> | ||
== | ==retrieve_content.py== | ||
<nowiki> | <nowiki> | ||
''' | ''' | ||
cette fonction prend en input le nom d'une page | cette fonction prend en input le nom d'une page | ||
et retourne tout le text qu'il y a dedans, en code | et retourne tout le text qu'il y a dedans, en code wiki | ||
''' | ''' | ||
import requests | import requests | ||
from bs4 import BeautifulSoup | from bs4 import BeautifulSoup | ||
def | def retrieve_content(name): | ||
baseurl='http://wikipast.epfl.ch/wikipast/' | |||
baseurl='http://wikipast. | |||
result=requests.post(baseurl+'api.php?action=query&titles='+name+'&export&exportnowrap') | result=requests.post(baseurl+'api.php?action=query&titles='+name+'&export&exportnowrap') | ||
soup=BeautifulSoup(result.text, "html.parser") | soup=BeautifulSoup(result.text, "html.parser") | ||
Ligne 660 : | Ligne 485 : | ||
</nowiki> | </nowiki> | ||
== | ==split_date.py== | ||
<nowiki> | <nowiki> | ||
def | def split_date(date): #format date: 'aaaa.mm.jj' /!\ la date doit être au format string | ||
date=str(date); #on est jamais trop sûr | date=str(date); #on est jamais trop sûr | ||
annee=''; | annee=''; | ||
Ligne 679 : | Ligne 499 : | ||
</nowiki> | </nowiki> | ||
==smaller_than. | ==smaller_than.py== | ||
<nowiki> | <nowiki> | ||
def smaller_than(date1,date2):#need to be format | def smaller_than(date1,date2):#need to be format aaaa.mm.dd | ||
#a year of format aaaa is always smaller | |||
#a year of format | #case aaaa | ||
#case | |||
if(len(date1)==4): | if(len(date1)==4): | ||
return 1 | return 1 |
Dernière version du 30 mai 2017 à 11:37
Chronobot est un bot programmé en langage Python et qui agit sur des pages Wikipast. Il permet de regrouper tous les événements qui se sont passés en une année dans une même page
Fonctionnement
Chronobot va d'abord effectuer un scan sur l'ensemble des pages biographiques crées par les élèves du cours "Humanités Digitales" (2017). Il effectue ensuite un scan sur tous les événements relevés dans chaque page et en stocke la date (sous forme AAAA.MM.JJ) et la description dans une liste. Une fois cette liste en main, il crée une page pour chaque jour différent. Pour des raisons pratiques, il est plus logique de n'avoir qu'une seule page par année avec tous les événements relevés durant cette année classés chronologiquement. Pour ce faire, au lieu d'agir directement sur l'url de la page, Chronobot redirige chaque lien d'un jour vers l'url de l'année correspondante. Enfin, il y écrit l'événement en bas de la page de l'année correspondante. Quand il finit le scan, il ordonne tous les événements des pages années qui ont été modifiées. La gestion des doublons est résolue ultérieurement.
Généralités
- Concepteurs : Arnau Albà Jacas, Sonia Bouchiba, Jonathan Charrière, Sébastien Morel, Aurélien Verdier.
- UserName : ChronoBOT
Liste des fonctions
Fonctions principales
- select_page.py parcourt les différentes pages sur une séléection précise de Users (ceux du cours SHS) et en retourne les pages crées sous formes de chaînes brutes (String). Les images (.png) sont ôtées ainsi que
- recherchedates.py prend en argument une page donnée (string) et en sort une liste année/événement
- modify_links.py modifie toutes les pages des dates pour qu'elles soient redirigées vers la page de l'année.
- create_new_site.py crée une page Wikipast avec le contenu donné
- order.py ordonne une page dans l'ordre chronologique et order_all.py effectue order.py sur toutes les pages une fois qu'elles sont toutes écrites.
- place_evenement.py écrit un événement dans une page.
- event_not_in_page.py gère les doublons en comparant deux strings-évenements caractère par caractère. Il considère ainsi deux évenements identiques s'ils contiennent les mêmes suites de caractères. Il ne tient pas compte des virgules (,), points (.) et espaces ( ) s'ils sont différents dans les deux strings.
Fonctions secondaires
- retrieve_content.py prend en input le nom d'une page et retourne tout le texte contenu en syntaxe wiki.
- split_date.py prend en input une date 'aaaa.mm.jj' et retourne une array [année, mois, jour].
Exemples de pages créées
- 1990.02.23 -> redirection vers 1990
- 1990.06 -> redirection vers 1990
- 1990
Critiques et faiblesses du bot
- Optimisation du code (plusieurs minutes pour s'exéctuer sur toutes les pages.)
- Si une année a déjà été crée avant notre bot et une phrase a été ajoutée, par exemeple "Grande année" redigirigée vers "1995" comportait une phrase commançant par "Grande année". Pour résoudre ce problème, deux solutions sont enbisageables : la première, assez radicale, est d'effacer la ligne en question dans la page Wikpast. La seconde (celle choisie, plus douce) est
- Gestion des doublons : pourrait être amélioré dans la comparaison de deux événements similaires. Actuellement, seules deux événements écrits exactement pareils ne sont pas dédoublés (par la fonction event_not_in_page.py), mais on pourrait imaginer qu'un événement du type Mariage qui serait écrit comme "A se marie avec B" dans la page de A et "B se marie avec A" dans la page de B, et qui serait donc relevé deux fois.
- Normalisation des dates sur les pages de la database (car par exemple une inversion mois-jour pas prise en compte actuellement)
- Classement chronologique des événements dans les pages de la database
- Section "Mois" dans les pages années
Scheduling
Tant que le nombre d'utilisateurs reste en accord avec le nombre d'étudiants dans le cours "Humanités Digitales" de l'EPFL, le bot va tourner une fois par semaine. Si wikiapst devient un site ouvert au public, il faudra éventuellement le lancer plus fréquemment.
Code source
main_one_page.py et main.py
main_one_page.py
from create_new_site import create_new_site from create_site import create_site from modify_links import modify_links from place_evenement import place_evenement from event_not_in_page import event_not_in_page from recherchedates2 import recherchedates2 #ajouter ici les autres fonctions dont on aura besoin def main_one_page(page): page=page.replace(" ","_") #modifie les dates pour rediger vers une année modify_links(page) #renvoie un array de deux colonnes: une colonne de dates et une colonne d'evenements elements=recherchedates2(page) for element in elements: evenement = element[1] date = element[0] annee = date[:4] #cree le site si il existe pas encore create_site(annee) if event_not_in_page(annee,evenement): content=place_evenement(date,evenement) create_new_site(annee,content)
main.py
''' Alors ça c'est le main. Si on le lance ça crée toutes las pages année normalement. ''' from select_page import select_page from main_one_page import main_one_page import datetime from order_all import order_all page_list=select_page() i=0 years_modified=[] for page in page_list: print('Je suis en train de faire la page: '+page) print("J'ai fait un "+str(i/len(page_list)*100)+'%') years_modified=years_modified+main_one_page(page) i=i+1 print("j'ai fini, il me reste qu'à tout ordonner") #ici il ordonne toutes les pages, parce que la fonction place_evenement #met les evenements juste à la fin de la page order_all(years_modified) now = datetime.datetime.now() year=str(now.year) month=str(now.month) day=str(now.day) hour=str(now.hour) minute=str(now.minute) if len(month)==1: month='0'+month if len(day)==1: day='0'+day if len(hour)==1: hour='0'+hour if len(minute)==1: minute='0'+minute fichier=open('lastdate.txt','w') fichier.write(year+'-'+month+'-'+day+'T'+hour+':'+minute+':00Z') fichier.close()
select_pages.py
Code source
# -*- coding: utf-8 -*- #return a list of str containing all the name of wikipast page, without the one beginin with "Fichier:" or the one beginin with 4 number (ex:"1945") #only pages changed by user in the "whiteliste.txt" and done AFTER the date write in "lastdate.txt" are given #to change the "lastdate.txt", please put those line where needed : #if needed, it strated with "2017-02-05T16:00:00Z" import requests from bs4 import BeautifulSoup def select_page(): baseurl='http://wikipast.epfl.ch/wikipast/' fichier=open('whiteliste.txt', 'r') protected_logins=fichier.read() fichier.close() protected_logins=protected_logins.split('\n') protected_logins=protected_logins[:(len(protected_logins)-1)] fichier=open('lastdate.txt', 'r') depuis_date=fichier.read() fichier.close() liste_pages=[] for user in protected_logins: result=requests.post(baseurl+'api.php?action=query&list=usercontribs&ucuser='+user+'&format=xml&ucend='+depuis_date) soup=BeautifulSoup(result.content,'html.parser') for primitive in soup.usercontribs.findAll('item'): title=primitive['title'] if title[0:8]!='Fichier:': if not title[0:3].isnumeric(): liste_pages.append(title) liste_pages=list(set(liste_pages)) return liste_pages
Whitelist
Frederickaplan Maud Vbuntinx Testbot SparqlBot IB SourceBot PageUpdaterBot Orthobot BioPathBot ChronoBOT Amonbaro AntoineL AntoniasBanderos Arnau Arnaudpannatier Aureliver Brunowicht Burgerpop Cedricviaccoz Christophe Claudioloureiro Ghislain Gregoire3245 Hirtg Houssm Icebaker JenniCin JiggyQ JulienB Kl Kperrard Leandro Kieliger Marcus Martin MatteoGiorla Mireille Mj2905 Musluoglucem Nacho Nameless Nawel O'showa PA Qantik QuentinB Raphael.barman Roblan11 Romain Fournier Sbaaa Snus Sonia Tboyer Thierry Titi Vlaedr Wanda
recherchedates2.py
import requests from bs4 import BeautifulSoup from retrieve_content import retrieve_content def recherchedates2(page_name): x=str(retrieve_content(page_name)) x=x.split("\n") dates=[] for i in x: d_start=i.find("[[") if (d_start!=-1) and i[d_start+2:d_start+6].isnumeric(): d_start=d_start+2 d_end=i[d_start:].find("]]")+d_start date=i[d_start:d_end] d_start=d_start-2 even='*'+i[d_start:] dates.append([date,even]) return(dates)
modify_links.py
''' cette fonction prend en input le nom d'une page. Pour toutes les dates de type [[AAAA/MM/JJ]], elle crée le lien de redirection vers la page de l'année. Pour les dates de type [[AAAA]] elle ne fait rien puisqu'elles sont déjà un lien vers l'année ''' import requests from bs4 import BeautifulSoup from retrieve_content import retrieve_content months=["Janvier","F.C3.A9vrier","Mars","Avril","Mai","Juin","Juillet","Ao.C3.BBt","Septembre","Octobre","Novembre","D.C3.A9cembre"] def modify_links(page_name): ############### ############### #retrieve dates text=retrieve_content(page_name) text=text.split("\n") dates=[] for line in text: d_start=line.find("[[") if (d_start!=-1) and line[d_start+2:d_start+6].isnumeric(): d_start=d_start+2 d_end=line[d_start:].find("]]")+d_start date=line[d_start:d_end] if len(date)!=4: dates.append(date) ############### ############### #create pages with redirection code user = "ChronoBOT" passw = "sajas2017" baseurl='http://wikipast.epfl.ch/wikipast/' summary='ChronoBOT page creation' # 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) for date in dates: year=date[:4] if(int(date[5:7])<13): month=months[int(date[5:7])-1] content="#REDIRECT [["+year+"#"+month+"]]" else: content="#REDIRECT [["+year+"]]" # save action payload={'action':'edit','assert':'user','format':'json','utf8':'','text':content,'summary':summary,'title':date,'token':edit_token} r4=requests.post(baseurl+'api.php',data=payload,cookies=edit_cookie)
create_site.py
''' cette fonction prend en input une année, et crée un site en blanc pour cette année Si le site existe déjà, il ne fait rien ''' import requests def create_site(year): #check if year is a four digit number year=str(year) if(len(year)!=4)or not(year.isnumeric()): return user = "ChronoBOT" passw = "sajas2017" baseurl='http://wikipast.epfl.ch/wikipast/' summary='ChronoBOT page creation' #check if page already exists if(requests.get('http://wikipast.epfl.ch/wikipast/index.php/'+year)).status_code!=404: return # 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) content="" # save action payload={'action':'edit','assert':'user','format':'json','utf8':'','text':content,'summary':summary,'title':year,'token':edit_token} r4=requests.post(baseurl+'api.php',data=payload,cookies=edit_cookie)
order.py et order_all.py
order.py
from smaller_than import smaller_than def order(text):#ça ordonne un text text1=text.split('\n') #separate events from other useless lines in the page newtext=[] craptext=[] for line in text1: if (line[:3]=='*[[') and (line[3:7].isnumeric()): newtext.append(line) else: craptext.append(line) #case where page is empty, only has one line in it, or only has crap in it if len(newtext)<2: return text #check for repeated lines provisional=[] for line in newtext: if line not in provisional: provisional.append(line) newtext=provisional ok=0 while(ok==0): ok=1 for i in range(len(newtext)-1): pos1 = newtext[i].find(']]') date1 = newtext[i][3:pos1] pos2 = newtext[i+1].find(']]') date2 = newtext[i+1][3:pos2] if not smaller_than(date1,date2): ok=0 event=newtext[i] newtext[i]=newtext[i+1] newtext[i+1]=event newtext='\n'.join(newtext)+'\n'+'\n'.join(craptext) return newtext
order_all.py
from order import order from retrieve_content import retrieve_content from create_new_site import create_new_site def order_all(years):#ça ordonne toutes les annees done=[] for year in years: if year not in done: print('I am ordering page '+year) content=order(retrieve_content(year)) create_new_site(year,content) done.append(year)
place_evenement.py
from retrieve_content import retrieve_content def place_evenement(annee,evenement): #format annee: 'aaaa' #format dans wikipast: '*[[aaaa.mm.jj]] (...)' seulement le début du format nous intéress return retrieve_content(annee)+'\n'+evenement
event_not_in_page.py
''' cette fonction prend en input une annee et un evenement. Si cet evenement est déja dans la page de l'année il renvoie 0 Si il n'est pas encore dans la page de l'année il renvoie 1 ''' from retrieve_content import retrieve_content def event_not_in_page(date,evenement): text=retrieve_content(str(date)).replace(' ','') text=text.replace(',','') text=text.replace('.','') pos=evenement.find(']]') evenement=evenement[pos+2:].replace(' ','') evenement=evenement.replace(',','') evenement=evenement.replace('.','') if evenement in text: return 0 else: return 1
retrieve_content.py
''' cette fonction prend en input le nom d'une page et retourne tout le text qu'il y a dedans, en code wiki ''' import requests from bs4 import BeautifulSoup def retrieve_content(name): baseurl='http://wikipast.epfl.ch/wikipast/' result=requests.post(baseurl+'api.php?action=query&titles='+name+'&export&exportnowrap') soup=BeautifulSoup(result.text, "html.parser") code='' if soup.findAll("text")[0]['bytes']=='0': return code for primitive in soup.findAll("text"): code+=primitive.string return code
split_date.py
def split_date(date): #format date: 'aaaa.mm.jj' /!\ la date doit être au format string date=str(date); #on est jamais trop sûr annee=''; mois=''; jour=''; for i in range(len(date)): if(i<4): annee=annee+date[i]; if(i>4 and i<7): mois=mois+date[i]; if(i>7 and i<10): jour=jour+date[i]; return [annee, mois, jour];
smaller_than.py
def smaller_than(date1,date2):#need to be format aaaa.mm.dd #a year of format aaaa is always smaller #case aaaa if(len(date1)==4): return 1 if(len(date2)==4): return 0 #case m1=date1[5:7] d1=date1[8:] m2=date2[5:7] d2=date2[8:] if(m1<m2): return 1 elif(m1>m2): return 0 elif(m1==m2): if(d1<=d2): return 1 else: return 0