Utilisateur:Cynddl/Autogen leçons par niveau

Le code suivant permet de générer automatiquement une version statique des pages du type Leçons par niveau des départements de la Faculté de Mathématiques.

Code Python modifier

Ce code n’est pas parfait, loin de là... je ne fais que débuter dans la programmation python (mon deuxième prog !). Pour le lancer, vous avez besoin de pyyaml et pywikibot-rewrite.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
 
import re
import yaml
 
from optparse import OptionParser
 
import pywikibot
from pywikibot import catlib # DEBUG
from pywikibot import Category
from pywikibot import pagegenerators
 
site = pywikibot.getSite()

def join(a,b):
	return list(set(a)|set(b))
 
def articles_in_cat(cat_name, recurse=True):
	cat = catlib.Category(site, cat_name)
	return list(cat.articles(recurse=recurse))
 
def articles_from_level(k, recurse=False):
	cat = catlib.Category(site, u'Catégorie:Leçon de niveau '+str(k))
	return list(cat.articles(recurse=recurse))
  
class GeneratorBot:
	def __init__(self, page_name, category_name, patterns, code):
		self.page_name = page_name
		
		self.category_name = category_name
		self.category = Category(site, self.category_name)
		
		self.category_lecons = reduce(join,[list(cat.articles()) for cat in self.category.subcategories()])
		
		self.patterns = patterns
		self.code = code
		self.articles_names_from_level = [[x.title() for x in articles_from_level(k) if x in self.category_lecons] for k in range(0,19)]
		self.avcm_cats_names = frozenset([u"Catégorie:Leçon d'avancement 0", u"Catégorie:Leçon d'avancement 1", u"Catégorie:Leçon d'avancement 2", u"Catégorie:Leçon d'avancement 3", u"Catégorie:Leçon d'avancement 4"])
		
		# Pour l'instant un seul type d'action !
		self.actions = dict(GENERATE_LEVEL = lambda args : self.generate_level(range(args['from'], args['to']+1)))
		
	def	get_avancement(self, lecon_name):
		'''Renvoie l'avancement d'une leçon à partir de son nom'''
		cat = set(pywikibot.Page(site, u"Discussion:" + lecon_name).categories())
		cat_names = set([x.title() for x in cat])
		if cat_names.isdisjoint(self.avcm_cats_names):
			return u"0"
		else:
			return cat_names.intersection(self.avcm_cats_names).pop()[-1]
	
	def generate_level(self, seq):
		'''Génère une "liste" (formatée sous forme de code wiki) des articles de self.category, de niveau dans seq.'''
		return "\n".join(["* {{L|[[%s]]|%s|%i}}" % (x, self.get_avancement(x), k) for k in seq for x in self.articles_names_from_level[k]])
	
	def parse(self):
		p = re.compile(r'\$(.*?)\$')
		for	i in p.findall(self.code):
			t = self.patterns[i]
			self.code = self.code.replace("$"+i+"$", self.actions[t['type']](t['args']))
		print "All code has been parsed !"
 
	def run(self):
		p = pywikibot.Page(site, self.page_name)
		self.parse()
		p.put(self.code, "Mise à jour automatique de la page.")
 
def main():
	parser = OptionParser()
	parser.add_option('-f', '--file', type="string")
	options, args = parser.parse_args()
 
	stream = open(options.file, 'r')
	inc = yaml.load(stream)
	stream.close()
 
	bot = GeneratorBot(inc['page'], inc['category'], inc['patterns'], inc['code'])
	bot.run()
 
 
if __name__ == '__main__':
    try: 
        main() 
    finally: 
        pywikibot.stopme()

Utilisation modifier

Il suffit d'exécuter le script avec en argument --file=fichier_template, où fichier_template est un fichier YAML du type :

page: "Utilisateur:Cynddl/Test_leçons"

category: "Catégorie:Algèbre"

patterns:
    NIV_1_3: {type: "GENERATE_LEVEL", args: {from: 1, to: 3}}
    NIV_4_6: {type: "GENERATE_LEVEL", args: {from: 4, to: 6}}
    NIV_7_9: {type: "GENERATE_LEVEL", args: {from: 7, to: 9}}
    NIV_10_12: {type: "GENERATE_LEVEL", args: {from: 10, to: 12}}
    NIV_13_15: {type: "GENERATE_LEVEL", args: {from: 13, to: 15}}
    NIV_16_18: {type: "GENERATE_LEVEL", args: {from: 16, to: 18}}

code: |
    {| width=100% border=0 style="background-color: #{{Idfaculté/pastel/mathématiques}};"
    | width=33% valign="top" | '''Novice''' <span style="font-size: 80%; border: ">[[Aide:Niveau de difficulté|Niveau]] 0 à 2</span>
    $NIV_1_3$
    | width=33% valign="top" | '''Débutant''' <span style="font-size: 80%; border:">[[Aide:Niveau de difficulté|Niveau]] 2 à 5</span>
    $NIV_4_6$
    | width=33% valign="top" | '''Intermédiaire''' <span style="font-size: 80%; border: ">[[Aide:Niveau de difficulté|Niveau]] 6 à 9</span>
    $NIV_7_9$
    |-
    |valign="top" | '''Avancé''' <span style="font-size: 80%; border: ">[[Aide:Niveau de difficulté|Niveau]] 10 à 12</span>
    $NIV_10_12$
    |valign="top" | '''Expert''' <span style="font-size: 80%; border: ">[[Aide:Niveau de difficulté|Niveau]] 13 à 15</span>
    $NIV_13_15$
    |valign="top" | '''Perfectionnement''' <span style="font-size: 80%; border: ">[[Aide:Niveau de difficulté|Niveau]] 16 à 18</span>
    $NIV_16_18$
    |}
    [[Catégorie:Algèbre]]