Utilisateur:Looxix/Utilitaires/mklist.py

L'utilitaire suivant sert à faciliter la maintenance des pages de type "listes des articles de ..."

Le principe est le suivant, la liste est stokée dans une micro base de donnée stockée dans un fichier nommé "XXX.db"; l'utilitaire permet facilement de rajouter ou d'enlever des éléments de la liste à partir d'un fichier d'entrée et de formater le contenu en une forme acceptable pour wikipédia.

L'utilitaire ne modifie pas le contenu de wikipédia : il faut copier-coller la sortie du programme dans une page de Wikipédia.

Syntaxe du fichier d'entrée:

modifier
  1. une ligne normale (sans ',', '+' ou '|'), rajoute simplement cette ligne dans la base.
  2. une ligne de type A+B permet de rajouter un article intitulé A B mais de l'afficher B, A (utile pour les noms)
  3. une ligne de type B, A permet de rajouter un article intitulé A B mais de l'afficher B, A (utile pour les noms)
  4. une ligne de type A|B permet de rajouter un article intitulé A mais de l'afficher B (utile pour les homonymies)
  5. une ligne commenceant par '-' permet de retirer cette entrée de la base

Exemple de fichier d'entrée:

modifier
École de Copenhague
Ordre de grandeur
- Ordres de grandeur
Fritz+London

mklist.py nom de la base < nom du fichier d'entrée

Programme

modifier
#!/usr/bin/python2.2

import locale
import sys
import cPickle
import re

def add_nom_prenom(dic, n, p):
    k = n + ', ' + p
    v = p + ' ' + n
    dic[k] = v

def add_entry(dic, line):
    # chop line
    line = line[:-1]

    if line[0] == '-':
	#print '>' + line
	#print  '>>>' + line[2:]
	if dic.has_key(line[2:]):
	    del dic[line[2:]]
	return

    # look for ', ' '+' & '|' sep
    l1 = line.split(', ')
    l2 = line.split('+')
    l3 = line.split('|')
    if len(l1) == 2:
	add_nom_prenom(dic, l1[0], l1[1])
    elif len(l2) == 2:
	add_nom_prenom(dic, l2[1], l2[0])
    elif len(l3) == 2:
	dic[l3[1]] = l3[0]
    else:
	dic[line] = line

reg = re.compile('^(\d*)')

def mycmp(a, b):
  """do locale number/case independent comparision"""
  A = a.upper()
  B = b.upper()
  #print a
  #print b
  if A[0].isdigit() and B[0].isdigit():
    la = reg.split(A, 1) ##A.split(' ', 1)
    lb = reg.split(B, 1) ##B.split(' ', 1)
    #print 'la = %s' % (la)
    #print 'lb = %s' % (lb)
    #print
    na = int(la[1])
    nb = int(lb[1])
    if na == nb:
	return mycmp(la[2], lb[2])
    else:
	return cmp(na, nb)
  else:
    res = locale.strcoll(A, B)
    if res == 0:
	res = cmp(A, B)
	if res == 0:
	    res = cmp(a, b)
    return res

def mycmp_pair((a, va), (b, kb)):
    return mycmp(a, b)

def outitem(k, v):
    if (k == v):
	print '* [[%s]] [[%s:%s| ]]' % (k, talk, k)
    else:
	print '* [[%s|%s]] [[%s:%s| ]]' % (v, k, talk, v)

def output(items):
    tit = '0ABCDEFGHIJKLMNOPQRSTUVWXYZ' + chr(254)
    t = 'Nombres'
    for k, v in items:
	while mycmp(k[0], tit[0]) >= 0:
	    ##print '\n<b id=%s></b>' % (t)
	    print '\n== [[#|-- %s --]] ==' % (t)
	    tit = tit[1:]
	    t = tit[0]
	outitem(k, v)


####################
# process the option
argv = sys.argv

locale.setlocale(locale.LC_ALL, 'fr_BE@euro')
cmpfun = mycmp_pair
talk = 'Discuter'

# fill the dic with the db
if len(argv) == 2:
  dbname = 'db.%s' % (argv[1])
  db = open(dbname, 'r')
  dic = cPickle.load(db)
  db.close()
else:
  dic = {}
  dbname = ''

# read all the entries:
# put them in a dictionary with key = print format; val = name format
for l in sys.stdin.readlines():
    add_entry(dic, l)

lst = dic.items()
lst.sort(cmpfun)
output(lst)

if dbname == '':
  dbname = 'db.db'

db = open(dbname, 'w')
cPickle.dump(dic, db, 1)