Youni Verciti has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/273573

Change subject: Release 0 vcb folder with firsts reviews and git ignore pyc
......................................................................

Release 0 vcb folder with firsts reviews and git ignore pyc

Change-Id: Iac5030a924f073331612b6fb06ebee354aafcf68
---
A vcb/.gitignore
A vcb/international.py
A vcb/vcb.py
A vcb/vcbformat.py
A vcb/vcbscan.py
5 files changed, 628 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/labs/tools/vocabulary-index 
refs/changes/73/273573/1

diff --git a/vcb/.gitignore b/vcb/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/vcb/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/vcb/international.py b/vcb/international.py
new file mode 100755
index 0000000..e5db2c5
--- /dev/null
+++ b/vcb/international.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import re
+import urllib
+import pywikibot
+import datetime #???
+
+langPack = {}
+
+
+### PORTUGAIS: Liste des articles
+genre = re.compile('[o|a]\\s') # ATTENTION PARAMETRES REGIONAUX
+pluriel_masculin = re.compile('os\\s')    # ATTENTION REMPLACER PAR LES 
ARTICLES DE LA LANGUE ÉTUDIÉE
+pluriel_feminin = re.compile('as\\s')    # ATTENTION
+um = re.compile('um\\s')       # ATTENTION
+uma = re.compile('uma\\s')     # ATTENTION
+ptPack= [genre, pluriel_masculin, pluriel_feminin, um, uma]   # Les articles 
de la langue portugaise
+langPack['pt']= ptPack
+
+## Check langPack
+def chkarticle(locution, word, pack):
+  kToDelete = []
+  for k in locution:           # Chaque clé de tupLocution
+    liste_mots = k.split()     # Listes les mots
+    nombre_mots = len(liste_mots)    # Calcul le nbre de mots
+    if nombre_mots ==2:              # Si DEUX mots
+      for article in pack:    # Pour chaque regex article dans...
+        moArticle = article.match(k)     # Cherche l'article en debut de chaine
+        if moArticle:              # Si la clé commence par un article
+          newKey = liste_mots[1] + ' (' +liste_mots[0] + ')'   # newKey 
déplace l'article après le nom
+          word[newKey] = locution[k]             # tupWord reçoit newKey
+          kToDelete.append(k)                          # On enregistre la clé 
à supprimer
+        else: # pas d'article à gérer
+          pass
+    # Le Wiktionnaire (fr) reconnait l'article et le lien fonctionne ce sera 
necessaire de déplacer
+    # les articles français uniquement si on fait une liste triée sur le nom 
français...
+    
+  for k in kToDelete:    # Pour chaque clé à supprimer
+    del locution[k]      # Enlève les couples article/mots du tupLocution
diff --git a/vcb/vcb.py b/vcb/vcb.py
new file mode 100755
index 0000000..6c2a970
--- /dev/null
+++ b/vcb/vcb.py
@@ -0,0 +1,295 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import urllib
+import re
+import sys
+import pywikibot # PWB now
+import codecs
+import argparse
+import time
+
+from vcbscan import *
+from vcbformat import *
+from international import *
+
+srv="https://fr.wikiversity.org/w/api.php";      # Adresse du serveur API
+site = pywikibot.Site('fr', u'wikiversity')     ### Variables PWB The site we 
want to run our bot on
+arg1 = sys.argv[1]
+uArg1 = unicode(arg1, 'utf-8')    # Encodage den UNICODE pour PWB 
+lPath = pathname(arg1, srv)   # pathname avec l'argument et le serveur forme 
la variable lPath
+[name, rootName, lastName, nbName, lSec, linker] = lPath # dont ceci est la 
composition
+[className, titleS, linkTo, link, reLink, retplk, defaultKey ] = linker # avec 
la composition de linker
+print className # Affiche  le type de page
+### ARGPARSE
+parser = argparse.ArgumentParser()
+parser.add_argument("scan", type=str,
+                    help="Le titre de la leçon du département de langues 
étrangère dont vous souhaitez collecter le vocabulaire. Par défaut la liste 
obtenue sera sauvegardée varDpt/Index vocabulaire/vcb-varPage")
+parser.add_argument("-t", "--test", help="enregistre la liste dans l'espace de 
test du laboratoire. Projet:Laboratoire/Propositions/Index_vocabulaire",
+                    action="store_true")
+args = parser.parse_args()
+###PYWIKIBOT
+title = uArg1   # Titre UNICODE
+page = pywikibot.Page(site, title) # PWB variable
+
+rqRootLang = '?action=languagesearch&format=xml&search=%s' % rootName
+fromPage = arg1
+toPage = arg1 + 'a'
+rqAllPages = 
'?action=query&list=allpages&format=xml&apfrom='+fromPage+'&apto='+toPage+'&aplimit=275'
+rqParseWkt = 
'?action=parse&format=xml&page=%s&prop=wikitext&contentdataZone=wikitext' % 
arg1   # REQUETE PARSE Format XML content WIKITEXT
+
+### RECHERCHE PAGELANG
+sts =  str(site)
+i=sts.find(':')
+sts = sts[i+1:]
+pageLang = sts
+### RECHERCHE ROOTLANG
+askRootLang = srv + rqRootLang
+objr = urllib.urlopen(askRootLang)
+varf = objr.read()
+strl1 = str(varf)
+reRootLang = re.compile('languagesearch \w*=') # The API changed
+moRootLang = reRootLang.search(strl1)
+rootLang = moRootLang.group()
+rootLang = rootLang[ 15 : len(rootLang)-1 ]
+print rootLang  + '-' + pageLang 
+###
+strLog = ''   # Variable pour le journal
+lAudio = []   # Liste pour la 3ème colonne de modèle Prononciation
+globalDict = {} # Dictionnaire global 
+###
+
+### TRAITEMENT DE LA LISTE DEs PAGES
+fileList = urllib.urlopen(srv + rqAllPages) ### ATTENTION Si Dept, Leçon, 
Chap: liste des fichiers à traiter
+vfileList = fileList.read()
+ufileList = unicode(vfileList, 'utf-8')
+rePg=re.compile('title=".*"')                 # recherche du nom de page
+rePron = re.compile('[P|p]rononciation\w*')   # recherche le modèle
+reTrad = re.compile('[T|t]raduction\w*')      # ''
+reEq = re.compile('=')                        # recherche des parametres
+l1 = re.compile('langue1')                    # First raw (filtre param 
Langue1)
+l2 = re.compile('langue2')                    # Second raw ('' langue2)
+
+### Analyse ufileList pour créer liste de page lPage
+listePg = ufileList.split('>')   # divise pour filtre nom page
+lPage = []                       # liste pour pages
+for l in listePg:   # pour chaque chaine dans xml listePg
+  moPg = rePg.search(l)   # Cherche le titre
+  if moPg:                # 
+    p=moPg.group()        # 
+    cp = p[7:len(p)-1]    # filtre la chaine nom de page
+    lPage.append(cp)      # enregistre liste des pages
+allFiles = len(lPage)   # Voir nbPages
+# Liste pour Leçon et defaut
+if className == 'Leçon':  # ATTENTION Si type page 'none' traite uniquement la 
page = chapitre
+  lPage = shortlist(lPage, uArg1)   # Filtre les fichiers de la leçon 
ATTENTION uArg1 et l'enfer unicode
+# Analyse modèles de chaque page, creation de listes distinctes pour chaque 
modèle, 
+lPron = []   # Liste des modèles Prononcition
+lTrad = []   # Liste des modèles Traduction
+for p in lPage: # chaque pages
+  title = p
+  page = pywikibot.Page(site, p)
+  gen = page.templatesWithParams() # liste les modèles et contenu
+  linkIn = 'none'
+  if gen:# si  modeles
+    for g in gen: #pour chaque item du generator
+      a = g[0] # a le nom de la pge du modele
+      b = g[1] # b a liste des params
+      stra = str(a)
+      moTrad = reTrad.search(stra) # cherche trad dans liste des modele
+      if moTrad:
+       lTrad.append(g) # si trad enregistre dans LISTE TRAD
+      moPron = rePron.search(stra)
+      if moPron:
+       lPron.append(g) # si pron enregistre dans LISTE PRON
+nbPages = len(lPage)
+nbPron = len(lPron)
+nbTrad = len(lTrad)
+part1Log = str(nbPages) + '  pages\n' + str(nbPron) + '  modèle PRON, ' + 
str(nbTrad) + '  modèle TRAD\n'
+strLog = strLog + part1Log
+print strLog
+print '### Les Listes sont prêtes ###' # On a une liste pour chaque modele
+### LISTES FIN
+
+if nbPron > 0: ### TRAITEMENT LISTE PRONONCIATION
+  # crèer fxpron ; déclarer ou passer les var: reEq, lAudio à linterieur
+  # retourner une liste qui sera revèrsée dans lTrad
+  for l in lPron: # LPRON
+    # Ce modèle propose une qutrimr colonne transcritpion
+    # quand cette 4èmme colonne existe
+    # les données ne sont pas collectée cf strLog
+    a = l[0] # Nom du modele
+    lb = l[1] # Liste des parametres
+    lrm = []  # liste des elements à supprimer
+    count = 1 # initialise le compteur
+    for b in lb:  # pour chaque parametre
+      i = lb.index(b)  # calcul l'index du parametre
+      moEq = reEq.search(b)   # cherche symbol egual, param nommé
+      if moEq: # Si le param est nommé
+       pass    
+      else:  # c'est une cellule
+       if count % 3 == 0:   # si elle est multiple de trois
+         lAudio.append(b)   # copie dans la liste lAudio
+         lrm.append(b)      # copie dans liste à supprmer
+      count =count + 1     # prochain param
+    for rm in lrm:    #  chaque element
+      lb.remove(rm)   # est supprimé
+    lTrad.append(l)   # copie les param restants dans lTrad
+###LPRON FIN Il faudrait detecter la quatrième colonne si existe
+
+nbMod = len(lTrad) # Les modèles pron. versés dans lTrad, lTrad donne le 
nombre de modele.
+strLog = strLog + str(nbMod) + ' modèles à traiter\n'   #LogInfo
+
+if nbMod > 0:   ### TRAITEMENT LISTE TRADUCTION
+  for l in lTrad: # LTRAD
+    a = l[0]      # le nom du modèle
+    lb = l[1]     # la liste des paramètres
+    lParam = []   # Nouvelle liste pour les parametres nommés
+    raw1 = rootLang   # initialise les langues
+    raw2 = pageLang   # avec paramètres par défaut
+    for b in lb:    # PARAMETRES
+    # print b ATTENTION API retourne lzh pour chinois mais wikversité utilise 
zh
+      moEq = reEq.search(b)   # cherche symbole egal param nommés
+      if moEq:     # Si symbol
+        lParam.append(lb.index(b)) # enregistre son index dans liste lParam
+        mol2 = l2.search(b)        # Cherche langue2
+        if mol2:   # SI langue2
+         spl2 = b.split('=')  # split sur symbol=
+         raw2 = spl2[1]       # enregistre dans raw2
+         raw2 = raw2.strip()  # retire éspaces inutiles
+        mol1 = l1.search(b) # Cherche langue1
+        if mol1:   # SI langue1
+          spl1 = b.split('=') # split egual
+         raw1 = spl1[1]      # stock valeur
+         raw1 = raw1.strip() # enleve espaces
+    cdl = raw1+'-'+raw2     # variable cdl = langue1-langue2
+    iMaxData = min(lParam)  # Calcul dernière donnée = premier paramètre nommé 
???
+    data = lb[0:iMaxData]   # Calcul la zone de données
+    nbCel = len(data)       # Pour vérifier parité du nombre de cellule
+    tplParam = [cdl, iMaxData, nbCel]   # langue1-langue2, dernier index de 
donnée, nombre de cellules
+    lb.append(tplParam)     # Stoque les paramètres dans lb
+    if nbCel %2 <> 0:   # Si le nombre de cellule n'est pas paire
+      lastCel = lb[iMaxData-1]
+      print '######'
+      print lastCel
+      print '#######'
+      reSpaces = re.compile('\s\n') # resoud le cas 
Anglais/Grammaire/Conjugaison/Impératif
+      # Attention le problème reste relatif à la 4ème colonne de prononciation
+      moSpaces = reSpaces.match(lastCel)
+      if lastCel == '':
+        print 'DERNIERE CELLULE VIDE A DETRUIRE'
+        # resoud le cas de la dernière cellule vide sans espaces ni saut de 
ligne
+        # il reste à supprimer l'element de la liste lb
+      if moSpaces:
+        print 'Celule vide à détruire'
+        print moSpaces.group()
+        #lb.remove[lastCel]        
+    if cdl == rootLang + '-' + pageLang and nbCel % 2 == 0:   # Si langues par 
defaut et nombre cellule paire
+      for d in data:   # Pour chaque donnée dans dataZone
+        if data.index(d) % 2 == 0: # Si son index est paire
+         iTmp = data.index(d)+1   # Calcul index prochaine valeur
+         tmp = data[iTmp]         # tmp = prochaine valeur
+         globalDict[d] = tmp      # Dictionnaire Global reçoit mot_PT : mot_FR
+        else:          # Ce n'est pas une clé mais une valeur (deja traité)
+         pass
+    elif cdl == pageLang + '-' + rootLang and nbCel % 2 == 0: # Si langues 
INVERSE fr-pt celulles paire
+      for d in data:   # Pour chaque donnée dans dataZone
+        if data.index(d) % 2 == 0:   # Si son index est paire
+         iTmp = data.index(d) + 1   # Calcul index prochaine valeur
+         tmp = data[iTmp]           # tmp = prochaine valeur
+         globalDict[tmp] = d        # On inverse d et tmp dans le dictionnaire
+        else: # IMPAIR PASS
+          pass
+    else:
+      errorLog = 'Template error:\nVérifier le nombre de cellules: '
+      print errorLog
+      print nbCel
+      # si nbCel impair alors verifier si dernière cellule vide
+      error2 = 'Titres de colonnes: \n'
+      print cdl
+      print page #Affiche page erronée
+      print a
+      print data
+      # chinois code langue sur 3 caractères tronque le l, lzh devient zh
+      #tplErrorLog = unicode(str(page), 'utf-8') +'\n'+ unicode(str(lb), 
'utf-8') +'\n'
+      #print  tplErrorLog
+      #strLog = strLog + errorLog + tplErrorLog
+ligd = len(globalDict)
+strLog = strLog + str(ligd) + ' lignes dans dictionnaire global\n'
+### LTRAD FIN
+
+### Traitement des APOSTROPHES et des espaces inutiles
+finalDict = {}
+for t in globalDict:
+  v = globalDict[t]
+  t = aposoff(t)
+  v = aposoff(v)
+  t = t.strip()
+  v = v.strip()
+  finalDict[t] = v
+###
+
+#### Suppression des données contenant des modèles
+### inclure condition
+#if len(removeDict) > 0:
+tplInsideLog = ''
+removeDict = tplinside(finalDict)
+for rmk in removeDict:
+  rmv = removeDict[rmk]
+  tplInsideLog = 'Les entrées suivantes contiennent des modèles et ne sont pas 
prise en compte\n'
+  tplInsideLog = tplInsideLog  + str(rmv)#unicode(rmk, 'utf-8')# +  str(rmv) + 
'\n'
+  # Japonais/Vocabulaire ne reussit pas à convertir rmk et rmv en string ni en 
unicode
+  del finalDict[rmk]
+strLog = strLog + tplInsideLog
+#else:
+#  pass
+
+nbLine = len(finalDict)   # Le nombre de ligne dans le dictionnaire
+wlp = divdict(finalDict)  # Division en 3 listes
+[tupWord, tupLocution, tupPhrase] = wlp
+chkword(tupLocution, tupWord)   # Sépare les locutions dont le formatage 
suppose apartenir à la liste des mots simples
+### TRAITEMENT DES ARTICLES RECONNUS SELON LANGPACK
+for lang in langPack:  
+  pack = langPack[lang]
+  if lang == rootLang:
+    chkarticle(tupLocution, tupWord, pack)
+  else:
+    print ' Pas de langPack'
+### JOURNALISE TAILLE DES LISTES
+words = len(tupWord)
+locutions = len(tupLocution)
+phrases = len(tupPhrase)
+format1Log = str(words) + ' mots, ' + str(locutions) + ' locutions, ' + 
str(phrases) + ' phrases.\n'
+strLog = strLog + format1Log
+
+secW = linkedlines(tupWord, rootLang)
+secL = linesans(tupLocution)
+secP = linesans(tupPhrase)
+
+scriptName = sys.argv[0]
+writePack = [scriptName, allFiles, nbMod, nbLine, uArg1, secW, secL, secP]
+print '### Log: ###'
+print strLog
+if nbLine < 5:
+  print 'Pas suffisament de données pour créer une page. Minimum 5 lignes.'
+  print nbLine
+else:
+  txtin = writelist(writePack)
+  comment = 'Indexation automatique du vocabulaire pour les langues 
étrangères. Youni Verciti Bot'
+  if args.test:
+    titleS = 'Projet:Laboratoire/Propositions/Index_vocabulaire/vcb '+ lastName
+  print 'Page à publier:       ' + titleS
+  #print type(titleS)
+  titleS = unicode(titleS, 'utf-8')
+  page = pywikibot.Page(site, titleS)
+  page.text = txtin
+  try:
+    page.save(comment)
+  except:
+    print 'Pas sauvegardé, exception'
+  else:
+    print 'Feĺicitaion vous avez enregistré une nouvelle page de vocabulaire'
+    print 'Hote du lien à créer:  ' + linkTo
+
+    
+#time.sleep(15)
+#wait = input('PRESS ENTER TO CONTINUE')
\ No newline at end of file
diff --git a/vcb/vcbformat.py b/vcb/vcbformat.py
new file mode 100755
index 0000000..1a5706a
--- /dev/null
+++ b/vcb/vcbformat.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import re
+import urllib
+import pywikibot
+import datetime
+
+### USTR transforme en string puis unicode
+def ustr(myvar):
+  mystr = str(myvar)
+  myu = unicode(mystr, 'utf-8')
+  return myu
+
+### DEF APOSOFF
+def aposoff(instr):   # Apostrophe_Off(Inside_String) enleve les '' et ''' de 
la chaine
+  reAps = re.compile('\'{2,3}')
+  nbApo = len(re.findall(reAps, instr))   # nombre d'item
+  if nbApo > 0:   # SI apostrophes dans mystr
+    filAps = re.finditer(reAps, instr)    # Find Iter List les occurences  
regex '' et '''
+    iDeb = 0      # debut de la recherche
+    cleaned = ''  # initialise la chaîne pour recevoir la clé sans apostrophe 
de formatage
+    n=1           # initialise le compteur de boucle
+    for l in filAps:   # POUR CHAQUE mo in fil
+      if n < nbApo:       # TANT QUE ce n'est pas le dernier
+       clean = instr[iDeb:l.start()]   # Calcul le debut sans aps
+        cleaned = cleaned + clean       # Ajoute la section debut sans aps à 
la mystr cleaned
+        iDeb = l.end()                  # Position de départ pour le prochain 
tour de boucle = après le dernier aps
+        n=n+1                           # Compteur de tours
+      else:               # On arrive au dernier aps
+        clean = instr[iDeb:l.start()]   # calcul le debut sans aps
+        fin = instr[l.end():]           # calcul la fin sans aps
+        cleaned = cleaned + clean + fin # ajoute le début et la fin à la mystr 
cleaned
+        cleaned = cleaned.strip()       # Enleve espace inutile
+    instr = cleaned
+  else:          # SANS aposoff
+    cleaned = instr.strip()   # cleaned est identique à instr
+  return cleaned   # Renvoi la version sans apostrophe de instr
+### APOSOFF FIN
+
+### DIVDICT Divise le dictionnaire global en 3 
+def divdict(myDict):
+  tupWord = {} # stockage des mots simples
+  tupLocution = {} # stockage des clés de plus de 2 mots
+  tupPhrase = {}   # traitement des clés de plus de 5 mot
+  wlp = [tupWord, tupLocution, tupPhrase]
+  # En premier detecter phrases selon premìere majuscule et dernier point
+  # Enlever le couple de tupLesson pour le copier dans tupPhrase
+  reMaj = re.compile('[A-Z]')   # Une majuscule alnum
+  rePoint = re.compile('\.\Z')    # Un point à la fin de la chaîne
+  kToDelete = []           # Liste pour stocker les clé à supprimer de 
tupLocution
+  if len(myDict) > 0:
+    for k in myDict:   # Pour chauqe cle dans tupLocution
+      moMaj = re.match(reMaj, k)   # Commence par une majuscule alphanumerique
+      moPoint = re.search(rePoint, k)  # Termine par un point (ajouter 
exclamation et interrogation)
+    if moMaj and moPoint:   # Si Majuscule début et point final
+      tupPhrase[k] = myDict[k]    # copie le couple dans tupPhrase
+      kToDelete.append(k)   # Stock k dans liste à supprimer
+    for k in kToDelete:
+      del myDict[k]    # enlève les phrases courtes du tupLocution
+    for k in myDict: # Pour chaque clé
+      v = myDict[k]  # definition de sa valeur
+      kSplit = k.split()   # découpe la clé en nombre de mots
+      kSize = len(kSplit)  # calcul le nombre de mot dans la clé
+      if kSize > 5:   # Si plus de 5 mots dans la clé
+        tupPhrase[k] = v   # Copie dans tupPhrase
+      else:   #SINON
+        if kSize > 1: # SI plus que 1 mot dans la clé
+          tupLocution[k] = v   # On copie dans tupLocution
+        else: # SINON
+          tupWord[k] = v   # On copie dans tupWord
+    wlp = [tupWord, tupLocution, tupPhrase]
+  return wlp
+### DIVDICT FIN
+
+### CHECK WORDS
+# Certaines occurrences de tupLocution seront re-affectées à tupWord
+# Tester si ksize = 2 et virgule ou articles. Si oui affecter à tupWrd
+def chkword(locution, word):
+  kToDelete = []   # Liste de clés à detruire après déplacement
+  for k in locution:    # Chaque clé de tupLocution
+    kSplit = k.split()     # Listes les mots
+    kSize = len(kSplit)    # Calcul le nbre de mots
+    if kSize ==2:      # Si DEUX mots
+      if ',' in k:       # Et une virgule
+        word[k] = locution[k] # Déplace dans tWord
+        kToDelete.append(k)         # Enregistre la clé à detruire
+      
+  for k in kToDelete:    # Pour chaque clé à supprimer
+    del locution[k]      # Enlève les couples article/mots du tupLocution
+### Gérer les couples qui commencent par un mot entre parentèses (os)
+### Gérer les occurences dont chaque mot est séparé par virgules
+### Observer les listes des autres dept
+### Tester si article+1mot+virgule
+
+
+### linesans formate les lignes sans liens (locutions & phrases)
+def linesans(locuPhrase):
+  sectionSans = ''
+  if len(locuPhrase ) > 0:
+    for k in sorted(locuPhrase):
+      v = locuPhrase[k]
+      lineSans = '* ' + k + ' : '+ v + '<br>\n'
+      sectionSans = sectionSans + lineSans
+  return sectionSans
+### Lignes sans Fin
+
+### LINKEDLINES formate les lignes avec liens (mots simples)
+def linkedlines(simplewords, rootLang):
+  sectionWords = ''
+  if len(simplewords) > 0:
+    for k in sorted(simplewords):
+      v = simplewords[k]
+      kSplit = k.split()
+      kSize = len(kSplit)
+      if kSize ==2: # Deux mots dans la clé, l'article est en seconde position
+       if ',' in k:
+         kCut = k.split(',')   # on split sur la virgule et on créé les liens 
avec premier element du split
+         line = '* [[wikt:' + rootLang +':'+ kCut[0] + '|' + k + ']] : 
[[wikt:' + kCut[0] + '#'+ rootLang + '|' + v + ']]<br>\n'
+         sectionWords = sectionWords +line
+       else: # Deux mots sans virgule
+         line = u'* [[wikt:' + rootLang +u':'+ kSplit[0] + u'|' + k + u']] : 
[[wikt:' + kSplit[0] + u'#' + rootLang + u'|' + v + u']]<br>\n'
+         sectionWords = sectionWords +line
+      else: # Un seul mot dans la clé création des liens wikt
+       line = u'* [[wikt:'+ rootLang + u':' + k + u'|' + k + u']] : [[wikt:' + 
k + u'#' + rootLang + u'|' + v + u']]<br>\n'
+       sectionWords = sectionWords +line
+  return sectionWords
+###LINKEDLINES FIN
+
+### ECRITURE DE LA LISTE A PUBLIER
+def writelist(dataPack):
+  [scriptName, allFiles, nbMod, nbLine, uArg1, secW, secL, secP] = dataPack
+  now = datetime.date.today()   # PASSER AU FORMAT FRANÇAIS
+  tnow = str(now)               # pour écrire la date 
+  head1 = u'{{Entête de fiche}}<small> Liste auto. script: ' + scriptName + ' 
- Date: ' + tnow + ' - ' + ustr(allFiles) + ' pages - '
+  head2 = str(nbMod) + ' modèles - ' + str(nbLine) + ' lignes.</small><br>'
+  head2 = unicode(head2, 'utf-8')
+  #head2 = unicode(str(nbMod), 'utf-8') + ' modèles - ' + ustr(nbLine) + ' 
lignes.</small><br>'
+  backLink = 'Retour: [[' + uArg1 + ']]\n' # Lien pour retourner à la leçon
+  txtin = head1 + head2 + backLink
+  if secW <> '':
+    section1 = '== Mots ==\n<div style="-moz-column-count:2; 
column-count:2;">\n'
+    txtin = txtin + section1 + secW
+  if secL <> '':
+    section2 = '</div>\n== Locutions ==\n'
+    txtin = txtin + section2 + secL
+  if secP <> '':
+    section3 = '== Phrases ==\n'
+    txtin = txtin + section3 + secP
+  txtin = txtin + unicode('[[Catégorie:Page auto]]', 'utf-8')
+  #txtin = headDraft+suite+backLnk + section1 + secW + section2 + secL + 
section3 + secP
+  return txtin 
\ No newline at end of file
diff --git a/vcb/vcbscan.py b/vcb/vcbscan.py
new file mode 100755
index 0000000..030ac4d
--- /dev/null
+++ b/vcb/vcbscan.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import re
+import urllib
+import pywikibot
+
+### SHORTLIST
+def shortlist(mylist, arg1) :
+  shortList = []    # Liste pour les pages à traiter
+  subFolder = ['Annexe', 'Exercices', 'Fiche', 'Quiz', 'Travail_pratique'] # 
LES DOSSIERS DES LEÇONS
+  prefix = arg1 + '/'       # declare prefix pour tronquer la première partie
+  for page in mylist:   
+    for sub in subFolder:
+      argSub = arg1 + '/' + sub
+      if re.match(argSub, page):   # si la ligne commence par argv1/sub
+        shortList.append(page)       # place la page dans la liste
+  for page in mylist:
+    if re.match(prefix, page):   # on gardera la page racine
+      moPlace = re.match(prefix, page)   
+      iMoPlace =  moPlace.end()  #index de la fin du prefix
+      page = page[iMoPlace : ]    #tronque le prefix
+      if '/' in page:   # Si il reste une barre oblique : sous dossier, on ne 
traitera pas
+        pass             # on ne traite pas les sous dossiers
+      else:
+        shortList.append(arg1 + '/' + page)   # On place la page dans 
PAGESHORTLIST
+  return shortList 
+
+### PATHNAME sépare l'argument initial en élements du path
+def pathname(name, srv):
+  rqParseWkt = 
'?action=parse&format=xml&page=%s&prop=wikitext&contentdataZone=wikitext' % 
name   # REQUETE PARSE Format XML content WIKITEXT
+  objf = urllib.urlopen(srv + rqParseWkt)   # Ouvre l'url dans l'objet
+  varf = objf.read()              # Lit le contenu dans la variable.
+  objf.close()                    # ferme l'objet url
+  strfile = str(varf)
+  ufile = unicode(varf, 'utf-8')
+  reLesson = re.compile('{{[L|l]eçon')   # ATTENTION probleme ecodage unicode 
sur le ç de leçon
+  reChapitre = re.compile('{{[C|c]hapitre')
+  splName = name.split('/')
+  nbName = len(splName)   ### -2 (rootname et lastname ex: 
rootname/nSec1/nSec2/lastname)
+  rootName = splName[0]
+  lastName = splName[nbName -1]
+  lSec = []
+  for sname in splName[1:splName.index(lastName)]:
+    lSec.append(sname)
+  lPath = [name, rootName, lastName, nbName, lSec]
+  uSec=''
+  for sec in lSec:
+    uSec = uSec + u'/' + sec
+  moLesson = reLesson.search(strfile)
+  moChapitre = reChapitre.search(ufile)
+  if nbName == 1:
+    print ' La cible est un département'
+    className = 'Département'
+    titleS = rootName + '/Index vocabulaire/vcb Global'
+    linkTo = rootName + '/Leçons par thèmes'
+    link = '[['+ titleS + '| Index du vocabulaire]]'
+    retplk = ''
+    reLink = re.compile(titleS)
+    defaultKey = ''
+  elif moLesson:
+    className = 'Leçon'    
+    titleS = rootName + '/Index vocabulaire/vcb ' + lastName
+    linkTo = rootName + '/Index vocabulaire/Inventaire des fiches'
+    link = '{{F|vcb'+lastName   # chercher la ligne commençant par {{F|¿?
+    retplk = re.compile('[F|f]iche\s*=')
+    reLink = re.compile(link)
+    defaultKey = 'fiche = '  
+    moLink = reLink.search(strfile)
+    if moLink:
+      print 'Le lien existe: '
+      print moLink.group()
+    else : 
+      motplk = retplk.search(strfile)
+      if motplk:
+       print 'Attention la leçon contient une fiche: \n'
+       print motplk.group()
+       print 'Placer le lien dans la leçon manuellement'
+      else:
+       print 'On peut envisager de créer le lien dans le modèle leçon'
+       
+  elif moChapitre:
+    print moChapitre.group()
+    print 'La cible est un chapitre'
+    className = 'Chapitre'    
+    titleS = rootName + '/Index vocabulaire/vcb '+ lastName
+    linkTo = rootName + '/Index vocabulaire/Inventaire des fiches'
+    link = '[[' + rootName + '/Index vocabulaire/vcb '+ lastName
+    retplk = re.compile('page_liée\s*=')
+    reLink = re.compile(titleS)
+    defaultKey = 'page_liée = '
+    moLink = reLink.search(strfile)
+    motplk = retplk.search(strfile)
+    if moLink:
+      print 'Le lien est en place'
+      print moLink.group()
+    else:
+      if motplk:
+       print 'Attention une page liée: '
+       print motplk.group()
+       print 'Etablir le lien manuellement'
+      else:
+       print 'On peut écrire le lien: '
+       print defaultKey + link 
+       print 'Le modèle Chapitre est infernal et le paramètre page_liée un 
cauchemard.'
+       print 'cibler la page rootName/Index vocabulaire/Inventaire des fiches'
+  else:
+    print 'Le type de cible est indéfini, none'
+    className = 'none'
+    titleS = rootName + '/Index vocabulaire/vcb ' + lastName
+    linkTo = rootName + '/Index vocabulaire/Fiches vocabulaire'
+    print lSec
+    for sec in lSec:
+      print sec
+    link = titleS
+    reLink = re.compile(link)
+    retplk=''
+    defaultKey=''
+  linker = [className, titleS, linkTo, link, reLink, retplk, defaultKey]
+  lPath.append(linker)
+  #print cible
+  return lPath
+### PATHNAME FIN
+
+### TPLINSIDE Vérifie la présence de modèle à l'interieur des cellules
+def tplinside (myDict):   # Attend un dictionnaire en entrée
+  tplInsideDict = {}      # Dictionnaire des items à supprimer
+  reTplInside = re.compile('{{')   # Expression régulière à chercher
+  for k in myDict:   # Pour chaque clé
+    v = myDict[k]    # La valeur correspondante
+    moTplk = reTplInside.search(k)   # Cherche modèle et répond 
+    moTplv = reTplInside.search(v)   # Cherche modèle et répond 
+    if moTplk:   # Si model dans la clé
+      tplInsideDict[k] =  myDict[k]   # Copie dans liste à supprimer
+    elif moTplv: # Si model dans la valeur
+      tplInsideDict[k] =  myDict[k]   # Copie dans liste à supprimer
+  return tplInsideDict   # Retourne le dictionnaire des items à supprimer
+### TPLINSIDE FIN
+
+### FXPRON Scan les modèles Prononciation
+## Améliorer en testant la présence de la colonne 4
+
+  
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/273573
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iac5030a924f073331612b6fb06ebee354aafcf68
Gerrit-PatchSet: 1
Gerrit-Project: labs/tools/vocabulary-index
Gerrit-Branch: master
Gerrit-Owner: Youni Verciti <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to