Utilisateur:Probot/ArticlesRecents
Un article de Wikipédia, l'encyclopédie libre.
Script permettant de mettre à jour une liste semblable à la page articles récents du portail du jeu vidéo, en se basant sur une liste d'articles liés (ici Modèle:Portail jeu vidéo).
Il a été volontairement simplifié et n'a par exemple aucun contrôle d'erreurs. Si le bot plante, ce n'est de toute façon pas très grave car il n'aura sûrement pas eu le temps d'enregistrer la modification qu'il aurait faite, vous devrez au pire faire un revert.
Vous devez modifier les champs "utilisateur" et "mot de passe" dans le code.
Si tout fonctionne, vous pouvez modifier l'endroit où il va sauver la liste. Attention ! Il analyse la page existante plus la complète avant de la sauver. Il ne fait pas de grosse analyse, si par exemple un article récent est renommé, il est fort probable que le script va rajouter ce nouveau nom d'article en article récent, même si l'ancien nom y est déjà présent. Il est conçu pour laisser aux opérateurs humains la liberté de compléter l'article, ou de changer la mise en forme. Il ne fait que faciliter la recherche des articles récents.
[modifier] Exemple de session
Connexion à fr.wikipedia.org Liste d'articles récupérées... 934 articles sont liés Récupère l'article cible pour le compléter... Fermeture de la connexion Terminé sans mise à jour nécessaire
[modifier] Code
Important : à cause de problèmes techniques liés à l'affichage dans Mediawiki, il faut éditer cette page pour copier le code. Ne pas le copier depuis la page actuellement visible.
#!/usr/bin/python # -*- coding: utf-8 -*- # Probot RC - Bot de mise à jour des articles récents sur les portails # Code : Utilisateur:Dake, Utilisateur:bayo # 2005 - (code sous license GPL) import httplib import urllib import re import sys from datetime import datetime def utf8(text): return unicode(text, 'UTF-8') ########################### PARAMETRAGE ########################### mois = [ '', utf8('janvier'), utf8('février'), utf8('mars'), utf8('avril'), utf8('mai'), utf8('juin'), utf8('juillet'), utf8('août'), utf8('septembre'), utf8('octobre'), utf8('novembre'), utf8('décembre'), ] utilisateur = "XXXXXXXXXXXXXXXXXXX" motDePasse = "XXXXXXXXXXXXXXXXXXX" pageSrc = "Modèle:Portail_jeu_vidéo" pageDest = "Modèle:Portail_jeu_vidéo/Articles_récents" charset = 'UTF-8' ########################### FONCTIONS ########################### # sauve la connexion (globale) conn = None ## Récupère la liste des pages liée à la page passée en paramètre # def getWhatlinkshere(pageName): conn = httplib.HTTPConnection('fr.wikipedia.org') # attention, s'il y a plus de 5000 articles liés, il faut changer l'offset ci-dessous # (5000 = limite sur Wikipédia lors de la création d'une liste) conn.request('GET', "/w/wiki.phtml?title=Special:Whatlinkshere&target=%s&limit=5000&offset=0&action=edit" % pageName) # connexion serveur et lecture reponse = conn.getresponse() article = reponse.read() # expressions régulieres pour récuperer l'article #<!-- start content --> debut = re.search('<!-- start content -->', article).end() fin = re.search('<!-- end content -->', article).start() contenu = article[debut:fin] debut = re.search('.<ul>', contenu).end() fin = re.search('</ul>\nV', contenu).start() contenu = contenu[debut:fin] #print contenu[debut:fin] contenu = contenu.replace('<li>', '') contenu = contenu.replace('(page de redirection)', '</li>') elements = contenu.split('</li>') result = [] # mise en forme du résultat for e in elements: i = e.find('>') e = e[i + 1:] i = e.find('</a>') e = e[:i] e = unicode(e, charset) # fixe quelques entitées html e = e.replace('<', '<') e = e.replace('>', '>') e = e.replace(''', "'") e = e.replace('"', '"') e = e.replace('&', '&') # doit être dernier result.append(e) return result def getPage(pageName): conn.request('GET', "/w/wiki.phtml?title=%s&action=edit" % pageName) # connexion serveur et lecture reponse = conn.getresponse() article = reponse.read() # expressions régulieres pour récuperer l'article #<!-- start content --> debut = re.search('<textarea', article).end() debut = article.find('>', debut) + 1 fin = re.search('</textarea>', article).start() contenu = article[debut:fin] # fixe quelques entitées html contenu = contenu.replace('<', '<') contenu = contenu.replace('>', '>') contenu = contenu.replace(''', "'") contenu = contenu.replace('"', '"') contenu = contenu.replace('&', '&') # doit être dernier return unicode(contenu, charset) def savePage(pageName, description, comment = ''): print utf8("Connexion utilisateur/mot de passe") parametres = urllib.urlencode({"wpName" : utilisateur, "wpPassword" : motDePasse, "wpLoginattempt" : "Identification", "wpRemember" : "1"}) entetes = { "Content-type" : "application/x-www-form-urlencoded", "User-agent" : "Probot/1.0"} conn = httplib.HTTPConnection('fr.wikipedia.org') conn.request("POST", "/w/wiki.phtml?title=Special:Userlogin&action=submit", parametres, entetes); reponse = conn.getresponse() cookie = reponse.getheader("set-cookie") print utf8("Analyse de la réponse du serveur") # analyse de la réponse (cookie) cookieMatch = re.compile(': (.*?);') cookieString = "" for resultat in reponse.msg.getallmatchingheaders('set-cookie'): m = cookieMatch.search(resultat) if m: cookieString += m.group(1) + "; " cookieString = cookieString[:-2] # lit la page à écrire pageName = urllib.quote(pageName) print utf8("Lecture de la page " + pageName) entetes = {"Content-type" : "application/x-www-form-urlencoded", "User-agent" : "Probot/1.0", "Cookie" : cookie} conn.request('GET', "/w/wiki.phtml?title=%s&action=edit" % pageName, {}, entetes) reponse = conn.getresponse() body = reponse.read() # récupère les informations du temps d'édition et le jeton de session pattern = re.compile(r'value="(\d+)" name=\"wpEdittime\"') editTime = pattern.search(body).group(1) pattern = re.compile(r'value="(\w+)" name=\"wpEditToken\"') editToken = pattern.search(body).group(1) # préparation des paramètres et sauvegarde de l'article parametres = urllib.urlencode({"wpTextbox1" : description.encode('utf-8'), "wpSummary" : comment.encode('utf-8'), "wpEdittime" : editTime, "wpMinoredit" : "1", "wpWatchthis" : "0", "wpEditToken" : editToken}) print utf8("Ecriture de la page ") + utf8(pageName) conn.request("POST", "/w/wiki.phtml?title=%s&action=submit" % pageName, parametres, entetes) reponse = conn.getresponse() print utf8("Fermeture de la connexion") conn.close() ## analyse la description et la retourne complété par les articles recents # def analyseEtComplete(description, articles): # récupère les pages se trouvant dans les articles recents articlesPresent = re.findall("\[\[([^\|\]]*)", description) comment = "" # force une majuscule sur la première lettre # retire les underscore l = articlesPresent articlesPresent = [] for a in l: a = a[0].upper() + a[1:] a = a.replace('_', ' ') articlesPresent.append(a) # retire les articles déjà trésents for a in articlesPresent: try: articles.remove(a) except ValueError: pass # il n'y a peut être rien a faire if len(articles) == 0: return '', '' comment = '+' + str(len(articles)) # construit le texte à ajouter aajouter = ']] ;\n[['.join(articles) aajouter = '[[' + aajouter + ']]' # vérifie si une section pour le jour courant existe today = datetime.today() matching = "=[^0-9]*%d[^0-9]*%s.*=" % (today.day, mois[today.month]) isSectionExist = re.search(matching, description) if isSectionExist: # complète la section existante # il est pratique de considère que c'est la première aajouter = '==\n' + aajouter + ' ;\n' description = description.replace('==\n', aajouter, 1) else: # la section du jour doit être créée comment = comment + utf8(' ; création de section') title = "" if today.day == 1: title = '1{{er}} ' + mois[today.month] else: title = str(today.day) + ' ' + mois[today.month] # utilise le niveau de titrage utilisé dans la page titleLevel = re.search('=+', description) if titleLevel: titleUse = titleLevel.group(0) title = titleUse + ' ' + title + ' ' + titleUse else: title = '==' + title + '==' aajouter = title + '\n' + aajouter + '.\n\n==' description = description.replace('==', aajouter, 1) return description, comment ########################### TEST ########################### descriptionTest1 = utf8("""<noinclude>{{Portail jeu vidéo/Retour}}</noinclude>__NOTOC__ N'hésitez pas à ajouter les articles récemment créés ainsi que ceux qui ont subit d'importantes modifications. ===12 novembre=== [[First Person Adventure|blabla]], un type de jeu vidéo. ===11 novembre=== [[Sega Chihiro]], une plateforme d'arcade basée sur la Xbox. ===8 novembre=== [[Sim City 3000]], un jeu de simulation de ville ; [[Twinklestar Sprites]], un ''shoot them up'' ; """) descriptionTest2 = utf8("""<noinclude>{{Portail jeu vidéo/Retour}}</noinclude>__NOTOC__ N'hésitez pas à ajouter les articles récemment créés ainsi que ceux qui ont subit d'importantes modifications. =====18 novembre===== [[Atotooto]]. =====12 novembre===== [[First Person Adventure|blabla]], un type de jeu vidéo. =====11 novembre===== [[Sega Chihiro]], une plateforme d'arcade basée sur la Xbox. =====8 novembre===== [[Sim City 3000]], un jeu de simulation de ville ; [[Twinklestar Sprites]], un ''shoot them up'' ; """) descriptionTest3 = utf8("""<noinclude>{{Portail jeu vidéo/Retour}}</noinclude>__NOTOC__ N'hésitez pas à ajouter les articles récemment créés ainsi que ceux qui ont subit d'importantes modifications. =====18 novembre===== [[Atotooto]]. =====12 novembre===== [[first Person Adventure|blabla]], un type de jeu vidéo. =====11 novembre===== [[Sega Chihiro]], une plateforme d'arcade basée sur la Xbox. =====8 novembre===== [[Sim_City_3000]], un jeu de simulation de ville ; [[Twinklestar Sprites]], un ''shoot them up'' ; """) articlesTest = ["a", "b", "Sim City 3000", "First Person Adventure"] def test(): print '---------------------------' description, comment = analyseEtComplete(descriptionTest1, articlesTest) print description print comment print '---------------------------' description, comment = analyseEtComplete(descriptionTest2, articlesTest) print description print comment print '---------------------------' description, comment = analyseEtComplete(descriptionTest3, articlesTest) print description print comment ########################### TRAITEMENT ########################### def traitement(): global conn print utf8("Connexion à fr.wikipedia.org") conn = httplib.HTTPConnection('fr.wikipedia.org') print utf8("Liste d'articles récupérée...") articles = getWhatlinkshere(pageSrc) print str(len(articles)) + utf8(" articles sont liés") # filtrage sur les noms d'article l = [] for name in articles: if name == "": continue if name.find(utf8('Discuter:')) == 0: continue if name.find(utf8('Discussion ')) == 0: continue if name.find(utf8('Wikipédia:')) == 0: continue if name.find(utf8('Portail:')) == 0: continue if name.find(utf8('Utilisateur:')) == 0: continue if name.find(utf8('Modèle:')) == 0: continue if name.find(utf8('Aide:')) == 0: continue if name.find(utf8('Image:')) == 0: name = ':' + name if name.find(utf8('Catégorie:')) == 0: name = ':' + name l.append(name) articles = l # on ne traite que les 10 derniers if len(articles) > 10: articles = articles[len(articles) - 10:] articles.reverse() print utf8("Récupère l'article cible pour le compléter...") description = getPage(pageDest) description, comment = analyseEtComplete(description, articles) print utf8("Fermeture de la connexion") conn.close() if description == '': print utf8("Terminé sans mise à jour nécessaire") return savePage(pageDest, description, comment) print utf8("Terminé") ##################################################### traitement() #test()