[wiki] wiki-lenny -> wiki

darcs-hash:20090427173001-bd074-51c7f6aea2843640e34adc0921b478f40ea98609.gz
This commit is contained in:
Antoine Durand-Gasselin 2009-04-27 19:30:01 +02:00
parent 5f26116790
commit cd037bbbe9
31 changed files with 0 additions and 0 deletions

5
wiki/action/__init__.py Normal file
View file

@ -0,0 +1,5 @@
# -*- coding: iso-8859-1 -*-
from MoinMoin.util import pysupport
modules = pysupport.getPackageModules(__file__)

116
wiki/action/fillpoll.py Normal file
View file

@ -0,0 +1,116 @@
# -*- coding: iso-8859-1 -*-
"""
_vi
<Ii _aa.
:I> aZ2^
v` .we^
. . .. + _2~
._auqXZZX ._auqXZZZ` ...._... ~ ._|ii~
.aXZZY""^~~ vX#Z?""~~~._=ii|+++++++ii=, _=|+~-
JXXX` )XXX' _|i+~ .__..._. +l= -~-
SXXo )XZX: |i> ._%i>~~+|ii| .i| ._s_ass,,. ._a%ssssssss
-SXZ6,,. )XZX: =l> _li+~` iii| .ii _uZZXX??YZ#Za, uXUX*?!!!!!!!
"!XZ#ZZZZZXZXZ` <i> =i: .|ii| .l|.dZXr 4XXo.XXXs,.
-~^^^^^^^` -||, +i|=. |ii| :i>:ZXZ( ]XZX.-"SXZUZUXoa,,
+l|, ~~|++|++i|||+~:ZXZ( ]ZZX ---~"?Z#m
.__;=- ~+l|=____.___, :ZXZ( ]ZXX_________auXX2
._||>+~- . -~+~++~~~- :ZXZ( ]ZXZZ#######UX*!"
-+-- .>` _
.<}` 3;
.<l> .Zc
.ii^ )Xo
]XX
MoinMoin - gallery2Image Actionmacro
PURPOSE::
This action macro is used to update a poll
CALLING SEQUENCE::
called by Doodle area with POST
PROCEDURE::
Ask adg@crans.org to stop doing drugs
RESTRICTIONS::
Written in python
AUTHOR::
Antoine Durand-Gasselin <adg@crans.org>
"""
import re, locale, base64
from MoinMoin import wikiutil
from MoinMoin.Page import Page
from MoinMoin.PageEditor import PageEditor
def execute(pagename, request):
if not request.user.may.write(pagename):
request.theme.add_msg(_('You are not allowed to edit this page.'), "error")
Page(request, pagename).send_page()
return
raw = Page(request, pagename).body
pollname = request.form.get("pollname")[0]
doosearchre = "{{{\s*#!Doodle\s*%s.*?}}}" % re.escape(pollname)
doosearch = re.search(doosearchre, raw, re.S)
doos = doosearch.start()
dooe = doosearch.end()
if not doosearch:
request.theme.add_msg(request.getText (u"Le sondage \"%s\" n'a pas été trouvé" % pollname), "error")
Page(request, pagename).send_page()
return
doostring= raw[doos+3:dooe-3]
doolines = [ l.strip() for l in doostring.splitlines()]
doodata = filter (lambda x: x != "", doolines)
fields = filter (lambda x: x != "", [f.strip() for f in doodata[0].split(';')[1:]])
userl = request.form.get("user")
if not userl: user = request.user.name
else:
if userl[0].strip(): user = userl[0].strip()
else: user = request.user.name
newentry = user + ";"
for f in fields:
if isinstance(f, unicode):
# l'utf-8, c'est bien! On encode l'unicode en utf-8 avant
# de le base64er
formfield = base64.encodestring(f.strip().encode('utf-8')).strip('\r\t \n=')
else:
# Bon, si on n'a pas un unicode, on encode sauvagement, mais
# ça peut chier
formfield = base64.encodestring(f.strip()).strip('\r\t \n=')
disp = request.form.get(formfield)
if disp:
newentry += " %s=%s;" % (f, disp[0])
else:
newentry += " %s=%s;" % (f, '0')
updatepoll = False
newdoolist = doodata[0:1]
for participant in doodata[1:]:
findentry = re.search ("^\s*%s\s*;.*$" % re.escape(user), participant)
if findentry:
if updatepoll: pass
else:
updatepoll = True
newdoolist.append(newentry)
else:
newdoolist.append(participant)
if not updatepoll:
newdoolist.append(newentry)
newdoostring = "\n".join(newdoolist)
pg = PageEditor(request, pagename)
try:
pg.saveText(raw[:doos+3]+ newdoostring + raw[dooe-3:], 0)
except:
request.theme.add_msg(request.getText(u"Aucune modification n'a été effectuée"), "error")
Page(request, pagename).send_page()

118
wiki/creer_compte_wiki.py Normal file
View file

@ -0,0 +1,118 @@
#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Script de création de compte sur le wiki
# Auteur : Stéphane Glondu
# Licence : GPLv2
import sys, os, httplib, urllib, locale
from getpass import getpass
from smtplib import SMTP
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.Encoders import encode_7or8bit
sys.path.append("/usr/scripts/gestion")
from affich_tools import coul, prompt, cprint
from user_tests import getuser
bugmail = ["glondu@crans.org", "adg@crans.org"]
bugreport = u"""
Nom d'utilisateur : %(name)s
Adresse e-mail : %(email)s
"""
# C'est l'encodage du wiki et des bugreports
encoding = "utf-8"
# Utilisateur qui lance le script
user = getuser()
def send(msg):
msg['From'] = '%s@crans.org' % user
msg['To'] = ','.join(bugmail)
msg['User-Agent'] = 'creer_compte_wiki.py'
smtp = SMTP()
smtp.connect()
smtp.sendmail('%s@crans.org' % user, bugmail, msg.as_string())
smtp.quit()
def creer_compte(nom, mdp, email):
form = {'action': 'newaccount',
'name': nom.encode(encoding),
'password1': mdp,
'password2': mdp,
'email': email.encode(encoding),
'create_only': 'Create+Profile'}
params = urllib.urlencode(form)
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
conn = httplib.HTTPSConnection("wiki.crans.org")
conn.request("POST", "/UserPreferences", params, headers)
response = conn.getresponse()
data = response.read()
conn.close()
if 'User account created!' in data:
msg = MIMEText(bugreport.encode(encoding) % form, 'plain', encoding)
msg['Subject'] = "creer_compte_wiki.py: success"
send(msg)
return coul(u"Compte %s créé avec succès !" % nom, "vert")
elif 'This user name already belongs to somebody else.' in data:
return coul(u"Le compte %s existe déjà !" % nom, "rouge")
elif 'This email already belongs to somebody else.' in data:
return coul(u"L'adresse %s est déjà utilisée !" % email, "rouge")
elif 'Password not acceptable: Password too short.' in data:
return coul(u"Le mot de passe choisi est trop court", "rouge")
elif 'Invalid user name' in data or "Nom d'utilisateur invalide" in data:
msg = coul(u"Le nom d'utilisateur %s est invalide !" % nom, "rouge")
msg += u"""
Le nom d'utilisateur doit être un WikiNom, voir à ce sujet :
http://wiki.crans.org/NomWiki
Il peut contenir n'importe quel caractère alphanumérique, avec
éventuellement un espace facultatif entre chaque mot. Il peut aussi
contenir des accents, mais assurez-vous que votre terminal est
correctement configuré (en %s).""" % (locale.getdefaultlocale()[1])
return msg
else:
html = MIMEBase('text', 'html')
html.set_payload(data)
html.add_header('Content-Disposition', 'attachment', filename='response.html')
txt = MIMEText(bugreport.encode(encoding) % form, 'plain', encoding)
msg = MIMEMultipart()
msg['Subject'] = '[Bugreport] creer_compte_wiki.py: creer_compte'
msg.attach(txt)
msg.attach(html)
send(msg)
return coul(u"Erreur inconnue\n", "rouge") + \
u"Un rapport de bug a été automatiquement envoyé. Réessayez plus tard."
if __name__ == '__main__':
try:
nom = prompt("Nom d'utilisateur (utiliser un WikiNom) : ")
while True:
mdp = getpass(coul("Mot de passe (ne pas utiliser le même que pour zamok) : ", "gras"))
if getpass(coul("Confirmation du mot de passe : ", "gras")) == mdp:
break
else:
cprint(u"Les deux mots de passe sont différents, veuillez réessayer...", "jaune")
email = prompt("Adresse e-mail : ")
print creer_compte(nom, mdp, email)
except KeyboardInterrupt:
print "Interruption par l'utilisateur."
exit = 255
except SystemExit, c:
if c.__str__() == '254':
os.system('reset')
print "Votre session d'édition à été tuée."
exit = c
except:
import traceback
msg = MIMEText('\n'.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)).encode(encoding), 'plain', encoding)
msg['Subject'] = '[Bugreport] creer_compte_wiki.py: __main__'
send(msg)
print coul(u"Erreur inconnue\n", "rouge") + \
u"Un rapport de bug a été automatiquement envoyé. Réessayez plus tard."

View file

@ -0,0 +1,5 @@
# -*- coding: iso-8859-1 -*-
from MoinMoin.util import pysupport
modules = pysupport.getPackageModules(__file__)

View file

@ -0,0 +1,361 @@
# -*- coding: utf-8 -*-
"""
MoinMoin - "text/latex" Formatter
Copyright 2005 Johannes Berg <johannes@sipsolutions.net>
Copyright (c) 2003 by João Neves <moin@silvaneves.org>
Copyright (c) 2000, 2001, 2002 by Jürgen Hermann <jh@web.de>
All rights reserved, see COPYING for details.
"""
# Imports
import sys, re
from MoinMoin.formatter import FormatterBase
from MoinMoin.Page import Page
#############################################################################
### LaTeX Formatter
#############################################################################
class Formatter(FormatterBase):
"""
Send text data.
"""
hardspace = ' '
def __init__(self, request, **kw):
apply(FormatterBase.__init__, (self, request), kw)
self.verbatim = False
self.itemized = False
def text2latex(self, text):
"Escape special characters if not in verbatim mode"
if self.verbatim: return text
text = text.replace('\\', '$\\backslash$ ');
text = text.replace('$', r'\$');
text = text.replace(r'\$\backslash\$', r'$\backslash$')
text = text.replace('#', r'\#');
text = text.replace('%', r'\%');
text = text.replace('^', r'\^{}');
text = text.replace('&', r'\&');
text = text.replace('_', r'\_');
text = text.replace('{', r'\{');
text = text.replace('}', r'\}');
text = text.replace('~', r'\~{}');
text = text.replace('"', r'\"{}');
text = text.replace(u'ä', r'"a');
text = text.replace(u'ü', r'"u');
text = text.replace(u'ö', r'"o');
text = text.replace(u'Ä', r'"A');
text = text.replace(u'Ü', r'"U');
text = text.replace(u'Ö', r'"O');
text = text.replace(u'ß', r'\ss{}');
return text
def write_text(self, text):
if self.item is None:
return text
else:
self.item = (self.item[0], self.item[1]+text)
return ''
def startDocument(self, pagename):
extra_preamble = ''
preamble_page = self.request.pragma.get('latex_preamble', None)
if preamble_page is not None:
extra_preamble = Page(self.request, preamble_page).get_raw_body()
extra_preamble = re.sub(re.compile('^#'), '%', extra_preamble)
return """
\\documentclass[a4paper,12pt]{article}
\\usepackage[utf8]{inputenc}
\\usepackage{helvet}
\\usepackage{graphicx}
\\usepackage{multicol}
\\usepackage{fullpage}
\\usepackage{fancyhdr}
\\usepackage{multirow}
\\makeatletter
\\DeclareRobustCommand*\\textsubscript[1]{%%
\\@textsubscript{\\selectfont#1}}
\\def\\@textsubscript#1{%%
{\\m@th\\ensuremath{_{\\mbox{\\fontsize\\sf@size\\z@#1}}}}}
\\makeatother
%% begin extra preamble inclusion %%
%s
%% end extra preamble inclusion %%
\\title{%s}
\\author{ }
\\date{ }
\\renewcommand{\\theenumi}{\\arabic{enumi}}
\\renewcommand{\\theenumii}{\\arabic{enumi}.\\arabic{enumii}}
\\renewcommand{\\theenumiii}{\\arabic{enumi}.\\arabic{enumii}.\\arabic{enumiii}}
\\renewcommand{\\theenumiv}{\\arabic{enumi}.\\arabic{enumii}.\\arabic{enumiii}.\\arabic{enumiv}}
\\begin{document}
""" % (extra_preamble, pagename)
def endDocument(self):
return '\\end{document}\n'
def sysmsg(self, text, **kw):
return self.write_text('')
def pagelink(self, on, pagename, text=None, **kw):
return self.write_text('')
def url(self, on, url=None, css=None, **kw):
if not on:
return self.write_text('}')
if url[-4:] == '.pdf':
nid = self.next_img_data
self.next_img_data = ''
return '\\includegraphics%s{' % nid
url = url.replace('&', '\\&')
return self.write_text('\\href{%s}{' % self.text2latex(url))
def text(self, text):
return self.write_text(self.text2latex(text))
def rule(self, size=0):
size = min(size, 10)
ch = "---~=*+#####"[size]
return self.write_text('\n\n\\hrulefill{}\n\n')
def strong(self, on):
return self.write_text(['{\\bf ', '}'][not on])
def emphasis(self, on):
return self.write_text(['{\\em ', '}'][not on])
def highlight(self, on):
return self.write_text(['{\\tt ', '}'][not on])
def number_list(self, on, type=None, start=None):
self.itemized = on
if on:
text = "\\begin{enumerate}"
else:
text = '\\end{enumerate}\n'
return self.write_text(text)
def bullet_list(self, on):
self.itemized = on
return self.write_text(['\\begin{itemize}\n', '\n\\end{itemize}\n'][not on])
def listitem(self, on, **kw):
if not self.itemized: return ''
self._in_li = on != 0
if on:
return self.write_text('\\item ')
else:
return ''
def sup(self, on):
return self.write_text(['\\textsuperscript{', '}'][not on])
def sub(self, on):
return self.write_text(['\\textsubscript{', '}'][not on])
def code(self, on, **kw):
return self.write_text(['{\\tt ', '}'][not on])
def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
res = self.preformatted(on)
self.verbatim = False
return self.write_text(res)
def code_token(self, on, tok_type):
return self.write_text('')
def code_line(self, on):
return self.write_text('\n')
def preformatted(self, on):
FormatterBase.preformatted(self, on)
self.verbatim = on
return self.write_text(['\\begin{verbatim}\n', '\\end{verbatim}\n'][not on])
def smiley(self, text):
return self.write_text(self.text2latex(text))
def paragraph(self, on, **kw):
FormatterBase.paragraph(self, on)
return self.write_text(['', '\n\n'][not on])
def linebreak(self, preformatted=1):
if preformatted==1:
return self.write_text('\n')
else:
return self.write_text('\\newline')
def heading(self, on, depth, **kw):
if depth == 1:
rv = (r'\section{','}\n')
elif depth == 2:
rv = ('\\subsection{','}\n')
elif depth == 3:
rv = ('\\subsubsection{','}\n')
else:
rv = (r'\paragraph{','}\n',)
return self.write_text(rv[not on])
rows = []
row = []
item = None
def table(self, on, attrs={}):
def count_cols(row):
cols = 0
for cell in row:
if cell[0].has_key('colspan'):
cols += int(cell[0]['colspan'][1:-1])
else:
cols += 1
return cols
if on:
self.rows = []
self.item = None
self.row = []
return ''
# not on:
if self.rows == []: return ''
cols = count_cols(self.rows[0])
rows = len(self.rows)
_table = [[0 for i in xrange(0,cols)] for j in xrange(0,rows)]
_rownum = -1
for _row in self.rows:
_rownum += 1
_cellnum = -1
for _cell in _row:
_cellnum += 1
while _table[_rownum][_cellnum] is None or type(_table[_rownum][_cellnum]) == type(()):
_cellnum += 1
if _cell[0].get('rowspan') == '"1"':
del _cell[0]['rowspan']
if _cell[0].get('colspan') == '"1"':
del _cell[0]['colspan']
_rowspan = int(_cell[0].get('rowspan', '"1"')[1:-1])
_colspan = int(_cell[0].get('colspan', '"1"')[1:-1])
for j in xrange(0,_rowspan):
for i in xrange(0,_colspan):
_table[_rownum+j][_cellnum+i] = None
_table[_rownum+j][_cellnum] = ({'colspan':'"%d"'%_colspan},None)
_table[_rownum][_cellnum] = _cell
table = '\\begin{tabular}{|%s}\n' % (cols * 'l|')
for _row in _table:
row = ''
cellnum = 0
_lines = []
_do_line = True
for _cell in _row:
cellnum+=1
if _cell == 0:
return 'INVALID TABLE'
if _cell is None:
if _do_line:
_lines += [cellnum]
continue
_rowspan = int(_cell[0].get('rowspan', '"1"')[1:-1])
_colspan = int(_cell[0].get('colspan', '"1"')[1:-1])
format = '%s'
if not (_cell[1] is None):
_do_line = True
_lines += [cellnum]
else:
_do_line = False
_cell = (_cell[0], u'')
if _rowspan > 1:
format = r'\multirow{%d}*{%%s}' % _rowspan
if _colspan > 1:
format = r'\multicolumn{%d}{|l|}{ %s }' % (_colspan, format)
row += (format+' & ') % _cell[1].replace('\n',' ')
for l in _lines:
table += r'\cline{%d-%d}' % (l,l)
table += row[0:-3] + '\\\\ \n'
table += '\\hline\\end{tabular}\n\n'
return table
def table_row(self, on, attrs={}):
if not on:
self.rows += [self.row]
self.row = []
return ''
def table_cell(self, on, attrs={}):
if not on:
self.row += [self.item]
self.item = None
else:
self.item = (attrs,'')
return ''
def underline(self, on):
return self.write_text(['\\underline{', '}'][not on])
def definition_list(self, on):
return self.write_text(['\\begin{description}\n', '\\end{description}\n'][not on])
def definition_term(self, on, compact=0):
return self.write_text(['\\item[', '] '][not on])
def definition_desc(self, on):
return self.write_text('')
def attachment_image(self, fname, **kw):
return self.image(src=fname)
def image(self, **kw):
# I am using alt for caption, but how to integrate the image?
text = ''
imgname = kw['src'].split('=')[-1]
nid = self.next_img_data
self.next_img_data = ''
return '\\includegraphics%s{%s}' % (nid, imgname)
#if kw.has_key('alt'):
# text += '\\begin{picture}\n'
# text += '\\caption{%s}\n' % kw[alt]
# text += '\\end{picture}\n'
#return self.write_text(text)
def crans_portal(self, entries):
code = ''
for pic, tit, bod in entries:
code += "\\begin{minipage}{0.5\\linewidth}\n%s\\\\\n%s\n\\end{minipage}\n" % (tit, bod)
return code
def crans_box(self, tit, bod, color=None):
return '%s\n%s' % (tit, bod)
def johill_sidecall_emit_latex(self, code):
# nothing else for now
return code
next_img_data = ''
def johill_sidecall_next_image_data(self, data):
self.next_img_data = '['+data+']'
def open(self, on, **kw):
return ""
def close(self, on, **kw):
return ""
# suckers who call this. we can't do raw HTML, so we ignore it
def rawHTML(self, markup):
return ''

View file

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
import sys
sys.path.append('/usr/scripts/secours')
import secours
def Cellule(texte, couleur, f) :
"""
Retourne le code HTML d'une cellule formattée aver le formatter f
"""
code = f.table(1)
code += f.table_row(1)
code += f.table_cell(1,{'style':'background-color:%s' % couleur })
code += f.text(texte)
code += f.table_cell(0)
code += f.table_row(0)
code += f.table(0)
return code
def execute(macro, text) :
try :
f = open(secours.ETAT_MAITRE)
f.readline()
if f.readline().strip() == 'auto' :
return "" #Cellule('La commutation automatique de l\'état est activée.','lime',macro.formatter)
else :
return Cellule(u'La commutation automatique de l\'état a été désactivée.','red',macro.formatter)
except :
return Cellule(u'Impossible de déterminer le type de commutation.','yellow',macro.formatter)

28
wiki/macro/EtatSecours.py Normal file
View file

@ -0,0 +1,28 @@
# -*- coding: iso-8859-1 -*-
import sys
sys.path.append('/usr/scripts/secours')
import secours
def Cellule(texte, couleur, f) :
"""
Retourne le code HTML d'une cellule formattée aver le formatter f
"""
code = f.table(1)
code += f.table_row(1)
code += f.table_cell(1,{'style':'background-color:%s; color: black;' % couleur })
code += f.text(texte)
code += f.table_cell(0)
code += f.table_row(0)
code += f.table(0)
return code
def execute(macro, text) :
try:
f = open(secours.ETAT_MAITRE)
if f.readline().strip() == 'normal':
return Cellule('Nous sommes actuellement en connexion normale.','lime',macro.formatter)
else :
return Cellule('Nous sommes actuellement en connexion de secours.','red',macro.formatter)
except :
return Cellule('Impossible de déterminer l\'état de la connexion.','yellow',macro.formatter)

4173
wiki/macro/EventCalendar.py Normal file

File diff suppressed because it is too large Load diff

21
wiki/macro/Gravatar.py Normal file
View file

@ -0,0 +1,21 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Gravatar Macro
Gregoire Detrez, 2007
v 0.0.1
You can include a gravatar image by using this macro
[[Gravatar(name@exemple.com)]]
"""
def execute(macro, text):
import md5
parseargs = text.split(',')
if len(parseargs)<2:
return '<small><strong class="error">MailTo macro must have at least two arguments</strong></small>'
emailname, emailurl= parseargs[:2]
email = emailname.strip() + "@" + emailurl.strip()
user_id = md5.md5( email.strip() ).hexdigest()
url = 'http://www.gravatar.com/avatar.php?gravatar_id=%s&size=80' % user_id
html = "<img src=\"%s\" alt=\"Gravatar\" />" % url
return macro.formatter.rawHTML(html)

61
wiki/macro/HostStatus.py Normal file
View file

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
import re
from commands import getstatusoutput,getoutput
def execute(macro, text) :
lines = open('/usr/scripts/var/local.status').readlines()
f = macro.formatter
code = f.table(1)
typlist = ['routes', 'serveurs', 'serveurs de la ferme', 'switches', 'bornes', u'services extérieurs au crans']
for typ in typlist:
lines = lines [1:]
trucsdown = ''
while lines and not re.match('dummy_host_\d+ 0 \n', lines[0]):
if not re.search(' 0 ', lines[0]):
line = lines[0].split(' ')
trucsdown += f.table_row(1)
trucsdown += f.table_cell(1,{'style':'background-color:lightgrey; color: black;'})
trucsdown += unicode(f.text('%s (%s)' % (line [0], getoutput("grep '^%s[^-.a-zA-Z]' /usr/scripts/var/autostatus/hosts | cut -d ' ' -f 5-" % line [0])) ), "utf-8")
trucsdown += f.table_cell(0)
# nombre de non réponse au ping
if int(line[1]) > 2 :
trucsdown += f.table_cell(1,{'style':'background-color:red; color: black;'})
trucsdown += f.text(u'down')
else :
trucsdown += f.table_cell(1,{'style':'background-color:blue;'})
trucsdown += f.text(u'état incertain')
trucsdown += f.table_cell(0)
trucsdown += f.table_row(0)
lines = lines [1:]
if trucsdown == '':
code += f.table_row(1)
code += f.table_cell(1, {'style':'background-color:silver; color: black;'})
code += f.text(u'Autostatus des '+typ)
code += f.table_cell(0)
code += f.table_cell(1, {'style':'background-color:lime; color: black;'})
code += f.text(u'OK')
code += f.table_cell(0)
code += f.table_row(0)
else:
code += f.table_row(1)
code += f.table_cell(1, {'style':'background-color:silver; color:black;', 'colspan':'2' })
code += f.text(u'Autostatus des '+typ)
code += f.table_cell(0)
code += f.table_row(0)
code += f.table_row(1)
code += f.table_cell(1, {'style':'background-color:aliceblue', 'colspan':'2'})
code += f.table(1) + trucsdown + f.table(0)
code += f.table_cell(0)
code += f.table_row(0)
trucsdown = ''
code += f.table(0)
return code

173
wiki/macro/ImageLink.py Normal file
View file

@ -0,0 +1,173 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - ImageLink Macro
PURPOSE:
This macro is used to set a link as WikiName for an attached image. Optional the size of the
image could be adjusted. If no WikiName is given the attachment is linked to the image itselfs.
CALLING SEQUENCE:
[[ImageLink(attachment|URL,[WikiName|URL],[width=width,[height=heigt]])]]
INPUTS:
attachment:image name of attachment or the URL to an image
OPTIONAL INPUTS:
WikiName: the page to set the link to or the URL to link to
KEYWORD PARAMETERS:
width: width of the embedded image
height: height of the embedded image
EXAMPLE:
[[ImageLink(plot.png,FrontPage,width=20,height=20)]]
[[ImageLink(plot.png,FrontPage,height=20)]]
[[ImageLink(plot.png,FrontPage)]]
[[ImageLink(plot.png,width=20,height=20)]]
[[ImageLink(plot.png,width=20)]]
[[ImageLink(plot.png)]]
[[ImageLink(http://localhost/wiki/modern/img/to_slide.png,http://localhost/StartSeite,width=50)]]
[[ImageLink(http://localhost/wiki/modern/img/to_slide.png,FrontPage,width=50)]]
[[ImageLink(plot.png,http://localhost/StartSeite,width=50)]]
[[ImageLink(http://localhost/wiki/modern/img/to_slide.png)]]
[[ImageLink(http://localhost/wiki/modern/img/to_slide.png,alt=whateveryouwant)]]
PROCEDURE:
This routine requires attachment enabled. If the attachment isn't downloaded at all
the attachment line is shown.
If you give only one image size argument e.g. width only the other one is calculated
It must be in "MoinMoin/macro"
Please remove the version number from the file name!
From JeffKunce ImageLink.py I have copied _is_URL to this routine. I have no better idea too.
HISTORY:
The first published version on MoinMoin I know of ImageLink was written by JeffKunce in 2001.
MODIFICATION HISTORY:
@copyright: 2004 by Reimar Bauer (R.Bauer@fz-juelich.de)
@license: GNU GPL, see COPYING for details.
Marcin Zalewski:
Some things that were causing problems on my wiki are changed
(wikiutil.link_tag and macro.formatter.pagelink implemented)
Marcin Zalewski:
Added title attribute to the created link. One could generalize that to
add arbitrary attributes.
One could also add class attributes to <a> and/or
<img> elements. I do not see the need for such modifications. If however this is
to be done in the future one would need to add 'html_class' key to the kw dictionary
with a corresponding value to add class to <img> element. To add class to <a> element
one needs to add 'css_class' key with a corresponding value to the dictionary passed to
pagelink call.
Reimar Bauer:
2004-12-23 Adopted to MoinMoin Version 1.3.1-1
2004-12-23 SYNTAX CHANGE Version 1.3.1-2
width and height and probably other keywords must be called as keywords (e.g. height=20)
2004-12-31 Version 1.3.1-3 code clean up
2005-01-16 Bug fixed in the errorhandler found and patch code from Malte Helmert
2005-03-05 Version 1.3.3-5 Bug fixed found by cypress
''If I put [[ImageLink(moinmoin.png)]] it bombs''
2005-03-28 Version 1.3.3-6 feature request added by CDPark:
''Can we use an external image? And an external target? ''
2005-04-16 Version 1.3.3-7 no default alt tag definition requested by CDPark and AlexanderSchremmer
Chong-Dae Park:
2005-04-17 Version 1.3.3-8 code refactored
IMG with no alt tag is not recommended in the HTML standard.
It keeps user specified alt tag. If it is not, it tries to use WikiName or image name instead.
Reimar Bauer:
2005-04-21 Version 1.3.3-9 bug fixed
When the image does not exist yet, it gives you a "Upload Image" link, this link does not
work. I suspect that this only is a problem on sub-pages, caused by incorrect escaping of
"/". -- CraigJohnson
"""
from MoinMoin.action import AttachFile
from MoinMoin import wikiutil, config
import os,string
def _is_URL(aString):
'''answer true if aString is a URL.
The method used here is pretty dumb. Improvements are welcome.
jjk 03/28/01'''
return string.find(aString, '://')>0
def execute(macro, text):
kw ={} # create a dictionary for the formatter.image call
if text:
args=text.split(',')
else:
args=[]
number_args=len(args)
count=0
for a in args :
if (a.find('=') > -1):
count=count+1
key=a.split('=')
kw[str(key[0])]=wikiutil.escape(string.join(key[1],''), quote=1)
number_args=number_args-count
if (number_args < 1):
msg='Not enough arguments to ImageLink macro! Try [[ImageLink(attachment,[WikiName],[width=width,[height=heigt]])]]'
return macro.formatter.sysmsg(1)+macro.formatter.text(msg)+ macro.formatter.sysmsg(0)
attname=wikiutil.taintfilename(macro.formatter.text(args[0]))
if (number_args >= 2) :
wikiname=args[1]
current_pagename=macro.formatter.page.page_name
if _is_URL(args[0]):
kw['src']=args[0]
else:
kw['src']=AttachFile.getAttachUrl(current_pagename,attname,macro.request)
attachment_path = os.path.join(AttachFile.getAttachDir(macro.request,current_pagename), attname)
if not os.path.exists(attachment_path):
import urllib
linktext = macro.request.getText('Upload new attachment "%(filename)s"'%{
"filename":attname})
return wikiutil.link_tag(macro.request,
"%(pagename)s?action=AttachFile&amp;rename=%(newname)s" % {
"pagename":current_pagename,
"newname": attname},linktext)
if not kw.has_key('alt'):
if (number_args == 1) or _is_URL(args[1]):
if _is_URL(args[0]):
# Get image name http://here.com/dir/image.gif -> image.gif
kw['alt'] = wikiutil.taintfilename(macro.formatter.text(args[0].split('/')[-1]))
kw['alt'] = args[0].split('/')[-1]
else:
kw['alt'] = attname
else:
kw['alt'] = wikiname
if (number_args == 1):
image_link=macro.formatter.image(**kw)
return macro.formatter.url(1,kw['src'] )+image_link +macro.formatter.url(0)
if (number_args == 2 ):
image_link=macro.formatter.image(**kw)
if _is_URL(args[1]):
return macro.formatter.url(1,args[1] )+image_link+macro.formatter.url(0)
else:
return macro.formatter.pagelink(1,wikiname)+image_link+macro.formatter.url(0)

89
wiki/macro/InfosBornes.py Normal file
View file

@ -0,0 +1,89 @@
#! /usr/bin/env python
# -*- encoding: iso-8859-1 -*-
# Génération d'un fichier XML indiquant le status des bornes
import sys
import os
import time, urllib2
import xml.dom.minidom
def execute(macro, text):
f=macro.formatter
# ouverture du fichier d'info et parsage
try:
#os.putenv("http_proxy", "http://proxy.crans.org:3128")
status=xml.dom.minidom.parseString(urllib2.urlopen("https://wifi.crans.org/status.xml").read())
except:
return f.text(u"Impossible d'accéder aux informations des bornes")
# On récupère l'ensemble des bornes
bornes = status.childNodes[0]
code = f.text(u"Mise à jour le "+bornes.getAttribute("date"))
code += f.linebreak(0)
code += f.table(True, {'tablealign': 'center'})
code += f.table_row(True, {'rowbgcolor': '#FFFFA0'})
for nom_col in (u"Nom", u"Hotspot", u"État", u"Localisation", u"Clients",
u"MAC", u"Canal", u"Uptime", u"°E", u"°N"):
code += f.table_cell(True)
code += f.strong(True)
code += f.text(nom_col)
code += f.strong(False)
code += f.table_cell(False)
code += f.table_row(False)
bornes.childNodes.sort(lambda x, y: cmp(x.getAttribute(u"nom"),
y.getAttribute(u"nom")))
dico = {u"hotspot": {u"1": f.smiley('(./)'), u"0": f.text(u"")},
u"up": {u"1": f.smiley(u"(!)"), u"0": f.smiley(u"{X}")}}
for b in bornes.childNodes:
code += f.table_row(1)
code += f.table_cell(1)
code += f.text(b.getAttribute(u"nom"))
code += f.table_cell(0)
for nom_attribut in (u"hotspot", u"up"):
code += f.table_cell(1)
code += dico[nom_attribut][b.getAttribute(nom_attribut)]
code += f.table_cell(0)
for tag in [u'description', u"clients",u"mac",u"canal"]:
code += f.table_cell(1)
if (b.getElementsByTagName(tag)!=[]):
code += f.text(b.getElementsByTagName(tag)[0].firstChild.data)
else:
code += f.text(u"")
code += f.table_cell(0)
code += f.table_cell(1)
if (b.getElementsByTagName(u"uptime")!=[]):
code += f.text("%.2f" % float(b.getElementsByTagName(u"uptime")[0].firstChild.data)+" j")
else:
code += f.text(u"")
code += f.table_cell(0)
if (b.getElementsByTagName(u"position")!=[]):
for nom_attribut in [u'x',u'y']:
code += f.table_cell(1)
code += f.text(b.getElementsByTagName(u"position")[0].getAttribute(nom_attribut))
code += f.table_cell(0)
else:
code += f.table_cell(1)
code += f.text(u"")
code += f.table_cell(0)
code += f.table_cell(1)
code += f.text(u"")
code += f.table_cell(0)
code += f.table_row(0)
code += f.table(0)
return code

275
wiki/macro/MonitStatus.py Normal file
View file

@ -0,0 +1,275 @@
# -*- coding: iso-8859-1 -*-
import os, sys, commands, time
"""
Permet d'intégrer au wiki les résultats de Monit.
La macro wiki est :
[[MonitStatus(hotes=host,categories=[All|Process|File],services=[All|Off|On])]]
Exemple :
[[MonitStatus(All|Off|service@host)
"""
statusfolder = '/usr/scripts/monit/status'
def NotRunningHosts() :
"""
Retourne la liste des hotes ou Monit ne tourne pas ou que
le fichier de status est trop vieux
"""
hosts = []
for host in os.listdir(statusfolder) :
if os.path.getmtime('/usr/scripts/monit/status/%s' % host) < time.time() - 240 :
hosts.append(host)
return hosts
def HostStatus (host) :
"""
Retourne un dictionnaire représentation de l'état des services de
la machine.
"""
status = {}
f = open('%s/%s' % (statusfolder,host) )
# c'est un hote sous Debian
###########################
# s est le service qu'on est en trainde parser
s = None
for line in f.readlines()[2:] :
line = line.strip()
if not line :
# ligne vide, on passe au service suivant
s = None
elif not s :
# création d'un nouveau service
s = line.split(' ')[1][1:-1]
t = line.split(' ')[0]
# ajout du type s'il n'est pas dedans
if not status.has_key(t) :
status[t] = {}
status[t][s] = {}
else :
# on ajoute les données
status[t][s][line[:34].strip()] = line[34:].strip()
# on supprime les données system
try :
status.pop('System')
except :
pass
return status
def AllStatus () :
"""
Retourne la configuration de toutes les machines
"""
status = {}
for host in os.listdir(statusfolder) :
status[host] = HostStatus(host)
return status
def AllStatusOff () :
"""
Retourne status avec juste les services off
"""
status = AllStatus()
for h in status.keys() :
# si c'est un host qui est down, on le laisse tel quel pour éviter qu'il le supprime
if h in NotRunningHosts() :
continue
# on supprime les types
for t in status[h].keys() :
for s in status[h][t].keys() :
# on supprime un status s'il est Up
if status[h][t][s]['status'] in ['running','accessible'] :
status[h][t].pop(s)
# reste-t-il des services dans le groupe
if not status[h][t] :
status[h].pop(t)
# reste-t-il des groupes dans l'hote
if not status[h] :
status.pop(h)
return status
def FormatService(Type, Service, Data, f) :
"""
Retourne le code HTML d'un sercice
Type : type de service
Service : Nom du service
Data : dictionnaire contenant toutes les données Data[info]
f : formatter
"""
result = ''
result += f.table_row(1)
result += f.table_cell(1,{'style':'background-color:silver'})
if Type == 'Device' :
Service = Service[2:]
elif Type == 'File' :
Service = Service[4:]
result += f.strong(1)
result += f.text(Service)
result += f.strong(0)
result += f.table_cell(0)
if Data['status'] in ['running','accessible'] :
result += f.table_cell(1,{'style':'background-color:lime'})
else :
result += f.table_cell(1,{'style':'background-color:red'})
result += f.text(Data['status'])
result += f.table_cell(0)
result += f.table_row(0)
return result
def FormatType(Type, Data, f) :
"""
Retourne le code HTML d'une liste de services
Host : nom de l'hote
Data : dictionnaire contenant toutes les données Data[service][info]
f : formatter
"""
result = ''
# titre
result += f.heading(1,3)
result += f.text(Type)
result += f.heading(0,3)
# les services
result += f.table(1)
for s in Data.keys() :
result += FormatService(Type,s,Data[s],f)
result += f.table(0)
return result
def FormatHost (Host, Data, f) :
"""
Retourne le code HTML d'un hôte
Host : nom de l'hote
Data : dictionnaire contenant toutes les données Data[type][service][info]
f : formatter
"""
result = ''
# titre
result += f.heading(1,2)
result += f.text(Host)[0].upper() + f.text(Host)[1:]
result += f.heading(0,2)
# si monit ne tourne pas
if Host in NotRunningHosts() :
return result + Cellule('Monit ne semble pas tourner sur %s' % Host,'yellow',f)
result += f.table(1)
result += f.table_row(1)
for t in Data.keys() :
result += f.table_cell(1,{'valign':'top'})
result += FormatType(t,Data[t],f)
result += f.table_cell(0)
result += f.table_row(0)
result += f.table(0)
return result
def FormatHosts(Data, f) :
"""
Retourne le code HTML de tous les hotes fournis
Data : dictionnaire contenant toutes les données Data[hote][type][service][info]
f : formatter
"""
result = ''
for h in Data.keys() :
result += FormatHost(h,Data[h],f)
return result
def Cellule(texte, couleur, f) :
"""
Retourne le code HTML d'une cellule formattée aver le formatter f
"""
code = f.table(1)
code += f.table_row(1)
code += f.table_cell(1,{'style':'background-color:%s' % couleur })
code += f.text(texte)
code += f.table_cell(0)
code += f.table_row(0)
code += f.table(0)
return code
def execute(macro, filtre) :
"""
Corps principal de la macro
"""
f = macro.formatter
# on met en forme le filtre
if not filtre :
filtre = 'all'
else :
filtre = filtre.lower()
if filtre == 'off' :
# tous les services off
status = AllStatusOff()
if status :
return FormatHosts(status, f)
else :
# aucun service off, on affiche OK
return Cellule(u'Tous les services semblent opérationnels.','lime',f)
elif filtre == 'all' :
# tous les services
status = AllStatus()
return FormatHosts(status, f)
elif '@' in filtre :
# affichage d'un service simple
host = filtre.split('@')[1]
service = filtre.split('@')[0]
status = HostStatus(host)
# recherche du service dans la config
s = {}
for t in status.keys() :
if service in status[t].keys() :
s = status[t][service]
if not s :
# service non trouvé
code = f.table_cell(0)
code += f.table_cell(1,{'style':'background-color:yellow'})
code += f.text(u'Service introuvable')
return code
# création de la chaine de retour
code = f.table_cell(0)
if s['status'] in ['running','accessible'] :
code += f.table_cell(1,{'style':'background-color:lime'})
else :
code += f.table_cell(1,{'style':'background-color:red'})
code += f.text(s['status'])
return code
else :
return Cellule('Erreur de filtre','yellow',f)

86
wiki/macro/MuninStatus.py Normal file
View file

@ -0,0 +1,86 @@
#!/usr/bin/env python2.5
# -*- encoding: utf-8 -*-
#
# MuninStatus.py: récupère la page munin et la filtre pour ne garder que les liens intéressants
#
# Copyright (c) 2009, Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
#
# This file is released under the GNU General Public License version 2
#
import sys
import urllib
try:
import BeautifulSoup
except ImportError:
print "munin.py nécessite BeautifulSoup (paquet python-beautifulsoup)"
sys.exit(2)
URL = "http://munin.crans.org/"
ENCODING = "utf-8"
ATTRS = {
'class': ('crit', 'warn'),
}
def to_unicode(input, encodings=None):
if not encodings:
encodings = ['utf-8', 'iso-8859-15']
for encoding in encodings:
try:
return input.decode(encoding)
except UnicodeDecodeError:
pass
return input.decode(encodings[-1], 'ignore')
def family(nodes):
parents = sum((node.findParents() for node in nodes), [])
children = sum((node.findChildren() for node in nodes), [])
return nodes + parents + children
def keep_item_headings(headings, items, level = 1):
kept = []
def level_up(heading):
parent = heading
for _ in range(level):
parent = parent.parent
return parent
for heading in headings:
parent = level_up(heading)
found_parent = False
for parents in [item.findParents() for item in items]:
if parent in parents:
found_parent = True
break
if found_parent:
kept.append(heading)
return kept
def execute(macro, _):
munin = BeautifulSoup.BeautifulSoup(urllib.urlopen(URL).read(), fromEncoding = ENCODING)
warning_items = munin.findAll(attrs=ATTRS)
warning_hosts = keep_item_headings(munin.findAll(attrs = "host"), warning_items)
warning_domains = keep_item_headings(munin.findAll(attrs = "domain"), warning_items)
keep = family(warning_items + warning_hosts + warning_domains)
for item in munin.findChildren():
if item not in keep:
item.extract()
for tag in munin.findAll(href=True):
tag["href"] = u'http://munin.crans.org/' + tag["href"]
if munin.html and munin.html.body:
return to_unicode(munin.html.body.prettify())
else:
return u"Munin n'a rien à dire."

19
wiki/macro/PagesClubs.py Normal file
View file

@ -0,0 +1,19 @@
# -*- encoding: iso-8859-1 -*-
import os
import PagesPerso
def comptes():
"""Retourne la liste des comptes"""
return filter(lambda x: os.path.isdir(u"/home/club/%s" % x) and not os.path.islink(u"/home/club/%s" % x),
os.listdir(u"/home/club"))
def url(self):
"""URL vers la page perso"""
return u"http://clubs.ens-cachan.fr/%s/" % self.login
PagesPerso.comptes = comptes
PagesPerso.account.home = "/home/club"
PagesPerso.account.www = ""
PagesPerso.account.url = url
execute = PagesPerso.execute

104
wiki/macro/PagesPerso.py Normal file
View file

@ -0,0 +1,104 @@
# -*- encoding: iso-8859-1 -*-
import os
class account:
"""Classe représentant la page perso d'une personne"""
home = "/home"
www = "/www"
def __init__(self, login):
"""Instanciation avec le `login' de la personne"""
self.login = login
self.home = "%s/%s" % (self.home, login)
_info = None
def info(self, champ):
"""Retourne le contenu du champ `champ' dans le fichier info"""
if self._info == None:
try:
lignes = file("%s/.info" % self.home)
except IOError:
lignes = []
# self._info est un dictionnaire qui reprend le contenu du .info
self._info = dict(map(lambda z: (unicode(z[0].lower(),"iso-8859-15"),
unicode(z[1],"iso-8859-15")),
filter(lambda w: len(w) == 2 and len(w[1]),
map(lambda x: map(lambda y: y.strip(),
x.split(":")),
lignes))))
print self._info
if self._info.has_key(champ.lower()):
return self._info[champ.lower()]
else:
return u""
def chemin(self):
"""Chemin vers le www"""
return u"%s%s" % (self.home, self.www)
def url(self):
"""URL vers la page perso"""
return u"http://perso.crans.org/%s/" % self.login
def logo(self):
"""URL du logo s'il y en a un"""
if self.info("logo"):
# Le logo peut être en absolu ou en relatif
if self.info("logo").startswith(self.chemin()):
logo = self.info("logo").replace("%s/" % self.chemin(), "")
else:
logo = self.info("logo")
if os.path.isfile("%s/%s" % (self.chemin(), logo)):
return u"%s%s" % (self.url(), logo)
return u"http://perso.crans.org/pageperso.png"
def __str__(self):
"""Renvoie le code HTML correspondant au fichier .info"""
html = [ u'<div class="vignetteperso">',
u'<a href="%s">' % self.url(),
u'<img src="%s" alt="%s">' % (self.logo(), self.login),
u'</a><br>',
self.info("nom") and u'<b>%s</b><br>' % self.info("nom") or u'%s<br>' % self.login,
self.info("devise") and u'<i>%s</i>' % self.info("devise") or u'',
u'</div>' ]
return u'\n'.join(html)
def comptes():
"""Retourne la liste des comptes"""
return filter(lambda x: os.path.isdir(u"/home/%s/www" % x) and not os.path.islink(u"/home/%s/www" % x),
os.listdir(u"/home/mail"))
def makeAnchor(letter):
return u"<div class=\"vignetteperso\"><a class=\"letter_anchor\" name=\"index_%s\"><span>%s:</span></a></div>" % ( letter, letter )
def makeIndex(letter_list):
index = u''
for aLetter in letter_list:
index = u"%s<a href=\"#index_%s\">%s</a>" % ( index, aLetter, aLetter)
return u"<div class=\"alphabetic_index\">%s</div>" % index
def execute(macro, args):
dirs = comptes()
dirs.sort()
html = u""
premiere_lettre = ''
letter_list = []
for d in dirs:
if premiere_lettre != d[0]:
premiere_lettre = d[0]
letter_list.append(premiere_lettre)
html = u"%s\n%s" % ( html, makeAnchor(premiere_lettre) )
html = u"%s\n%s" % (html, account(d).__str__())
index = makeIndex(letter_list)
html = index + html
html += u'<br style="clear: both">'
return macro.formatter.rawHTML(html)

225
wiki/macro/ProgressBar.py Normal file
View file

@ -0,0 +1,225 @@
"""
MoinMoin - ProgressBar Macro
Generates a progress bar (in the form of a table)
@copyright: Pascal Bauermeister <pascal DOT bauermeister AT gmail DOT cm>
@license: GPL
Updates:
* [v0.1.1] Sun Dec 18 21:31:17 CET 2005
Changed table cell percentage markup.
* [v0.1.0] Fri Dec 16 22:30:10 CET 2005
Original version
----
The ProgressBar macro generates a table showing a progress indicator.
Usage:
<< ProgressBar >>
<< ProgressBar (TABLEWIDTH TABLEFORMAT PROGRESS%) >>
<< ProgressBar (TABLEWIDTH TABLEFORMAT CURRENT/STEPS) >>
<< ProgressBar (TABLEWIDTH TABLEFORMAT STARTDATE,ENDDATE) >>
If no arguments are given, the usage is inserted in the HTML result.
Options:
TABLEWIDTH (optional prefix)
A wiki tablewidth attribute value between []'s
Examples:
[100%]
[80px]
TABLEFORMAT (optional prefix)
A pair of wiki table attribute, to format the inactive and active cells.
Examples:
<bgcolor="black"><bgcolor="white"> # black on white bar
<tablewidth="90%" bgcolor="black"><bgcolor="white"> # same, 90% table
A third format may be given for STARTDATE,ENDDATE usage
By default: <tablewidth="100px"#808080><><#8080ff>
PROGRESS
Will display a table with two cells:
- left: completion, taking PROGRESS % of the table width
- right: remaining
CURRENT/STEPS
Will display a table with STEPS cells, CURRENT of which are active.
STARTDATE,ENDDATE
Will display a table with the number of days, with the cell
representing today in active format and background in inactive format.
If today is before STARTDATE, the left-most cell will be in the
3rd format. If today is after ENDDATE the rightmost cell will be
in the 3rd format.
Dates are in this format: YYYY-MM-DD
Debugging
Please prepend a '?' to the arguments.
Examples:
<<ProgressBar(60%)>>
<<ProgressBar(6/10)>>
<<ProgressBar(2005-11-01,2006-01-06)>>
<<ProgressBar([50%] 60%)>>
<<ProgressBar([50px] 60%)>>
<<ProgressBar([90%]<#8080ff><#808080> 6/10)>>
----
"""
# Imports
import time, re, StringIO
from MoinMoin import version
from MoinMoin.parser import text_moin_wiki as wiki
Dependencies = ["time"] # macro cannot be cached
class _Error (Exception):
pass
def escape (str):
return str.replace ('&','&amp;').replace ('<', '&lt;').replace ('>', '&gt;')
def usage (full = False):
"""Returns the interesting part of the module's doc"""
if full:
return __doc__
else:
rx = re.compile ("--$(.*)^--", re.DOTALL + re.MULTILINE)
return rx.findall (__doc__) [0].strip ()
def s2t (s):
return time.mktime (time.strptime (s, "%Y-%m-%d"))
def execute (macro, text, args_re=None):
try: res = _execute (macro, text)
except Exception, msg:
return macro.formatter.rawHTML("""
<p><strong class="error">
Error: macro ProgressBar: %s</strong> </p>
""" % escape ("%s" % msg))
return macro.formatter.rawHTML(res)
def _execute (macro, text):
fmt = ['#808080','','#8080ff']
width ="100px"
res = ""
text = text.strip ()
# help if empty text
help = len (text) == 0
# debug if starts with '?'
if text.startswith ('?'):
debug = True
text = text [1:]
else:
debug = False
orig_text = text
# Formats
try:
# Table width
if text.startswith ('['):
pos = text.rfind (']')
width = text [1:pos]
text = text [pos+1:].strip ()
# Cells format
if text.startswith ('<'):
pos = text.rfind ('>')
f = text [1:pos].split ('><')
text = text [pos+1:].strip ()
fmt [:len (f)] = f
except:
help = True
# Show help
if help:
return """
<p>
<pre>%s</pre></p>
""" % escape (usage (0))
# Cell formatting utility
def cell (txt, fmt):
if len (txt) == 0:
fmt = 'tablewidth="%s" ' % width + fmt
txt = "||"
if len (fmt): t = "<%s> ||" % fmt
else: t = " ||"
return txt + t
# Progress
if text.endswith ('%'):
# correction du bug des 0%
if text == "0%":
for f in [fmt [1]] :
res = cell (res, f)
else:
for f in fmt [0] + ' %s' % text, fmt [1] :
res = cell (res, f)
# Current/Steps
elif text.find ('/') > 0:
cur, steps = map (int, text.split ('/'))
for i in range (steps):
res = cell (res, fmt [i>=cur])
# Start/end date
else:
starts, ends = map (lambda s:s.strip (), text.split (","))
start, end = s2t (starts), s2t (ends)
now = time.mktime (time.localtime ())
duration = int ( (end-start) / 86400)
progress = int ( (now-start) / 86400) -1
pcent = int (90 / duration)
for i in range (duration):
if i == 0 and progress < 0:
f = fmt [2]
elif i == progress:
f = fmt [0]
else:
f = fmt [1]
res = cell (res, f)
if progress >= duration:
res = cell (res, fmt [2])
else:
res = cell (res, fmt [1])
# Output
if debug:
res = "{{{<<ProgressBar(%s)>>\n%s}}}\n%s" % (orig_text, res, res)
return _format (res, macro.request, macro.formatter)
def _format (src_text, request, formatter):
# parse the text (in wiki source format) and make HTML,
# after diverting sys.stdout to a string
str_out = StringIO.StringIO () # create str to collect output
request.redirect (str_out) # divert output to that string
# parse this line
wiki.Parser (src_text, request).format (formatter)
request.redirect () # restore output
return str_out.getvalue () # return what was generated

142
wiki/macro/Questionnaire.py Normal file
View file

@ -0,0 +1,142 @@
#! /usr/bin/env python
# -*- encoding: iso-8859-15 -*-
#generation d'une question de questionnaire si il y a des arguments, sinon affiche le résultat
class questionnaire:
execute = 0
liste_questions = []
min_point = 0
max_point = 0
fonction_affiche = True
def int_try(point):
try:
return int(point)
except ValueError :
return 0
def parse(text):
ligne = text.split("\\")
question = []
for l in ligne:
l = l.split(":",1)
if len(l)>=2:
question+=[(l[0],l[1])]
return question
def question_choix_unique(f,QR,quest):
r=""
id = QR[0][0]
r+=f.rawHTML("""
<p> %(id)i : %(Q)s <br>
""" % { "id" : quest.execute , "Q" : QR[0][1]})
QR=QR[1:]
max = 0
min = 0
for (point,rep) in QR:
point = int_try(point)
if (max < point):
max = point
if (min > point):
min = point
r+=f.rawHTML("""<input type="radio" name="radio%(id)i" onclick="ajoute(%(id)i,%(point)i)" > %(rep)s<br>\n"""% { "point" : point , "id" : quest.execute, "rep" : rep})
quest.max_point += max
quest.min_point += min
r += f.rawHTML("\n</p>\n")
return r
def question_choix_multiple(f,QR,quest):
r = ""
r +=f.rawHTML("<p> %(id)i : %(Q)s <br>\n" % { "id" : quest.execute , "Q" : QR[0][1]})
QR=QR[1:]
for (point,rep) in QR:
point = int_try(point)
if point > 0:
quest.max_point += point
else:
quest.min_point += point
r+=f.rawHTML("""<input type="checkbox" name="radio%(id)i" onclick="ajoute_multiple(%(point)i,this.checked)" > %(rep)s<br>\n"""% { "point" : point , "id" : quest.execute, "rep" : rep})
r +=f.rawHTML("\n</p>\n")
return r
def fonction_javascript(f,quest):
if (quest.fonction_affiche==True):
quest.fonction_affiche = False
return f.rawHTML("""
<script type="text/javascript">
var point_globale = 0
var pointQ = new Array(%(nb_quest)i)
var i=0
function update()
{
var result_p = document.getElementsByName('result_p')
var point_result_p = Math.round((point_globale-(%(min_point)i)) * 10000 / %(intervalle)i)/100
for (var i=0;i<result_p.length;i++)
{
result_p[i].innerHTML = point_result_p
}
var result = document.getElementsByName('result')
for (var i=0;i<result.length;i++)
{
result[i].innerHTML = point_globale
}
}
function ajoute_multiple(point,on)
{
if(on)
{point_globale = point_globale + point}
else
{point_globale = point_globale - point}
update()
}
function ajoute(id_Q,point)
{
if(isNaN(pointQ[id_Q])){pointQ[id_Q]=0}
point_globale = point_globale + point - pointQ[id_Q]
pointQ[id_Q] = point
update()
}
</script>
""" % {"min_point": quest.min_point,
"intervalle": quest.max_point-quest.min_point,
"nb_quest": quest.execute})
else:
return ""
def result(f,quest):
return f.rawHTML("""<span name="result"> 0 </span>""")
def result_pourcent(f,quest):
return f.rawHTML('<span name="result_p"> 0 </span><script type="text/javascript">update()</script>')
def result_max(f,quest):
return f.text("%i" % quest.max_point)
def result_min(f,quest):
return f.text("%i" % quest.min_point)
def execute(macro,text):
try:
macro._macro_questionnaire.execute +=1
except :
macro._macro_questionnaire = questionnaire()
f = macro.formatter
quest = macro._macro_questionnaire
if text == None:
return fonction_javascript(f,quest) + result(f,quest)
elif text == "%":
return fonction_javascript(f,quest) + result_pourcent(f,quest)
elif text == "M":
return fonction_javascript(f,quest) + result_max(f,quest)
elif text == "m":
return fonction_javascript(f,quest) + result_min(f,quest)
else:
QR = parse(text)
if QR[0][0][0]=='*':
return question_choix_multiple(f,QR,quest)
else:
return question_choix_unique(f,QR,quest)

View file

@ -0,0 +1,244 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - RandomIncludeQuote macro
This macro includes the formatted content of the given page(s). See
http://purl.net/wiki/moinmaster/HelpOnMacros/Include
for detailed docs.
@copyright: 2000-2004 by Jürgen Hermann <jh@web.de>
@copyright: 2000-2001 by Richard Jones <richard@bizarsoftware.com.au>
@license: GNU GPL, see COPYING for details.
"""
#Dependencies = ["pages"] # included page
Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks
import re, StringIO
from MoinMoin import wikiutil
from MoinMoin.Page import Page
from MoinMoin.util import web
_sysmsg = '<p><strong class="%s">%s</strong></p>'
## keep in sync with TableOfContents macro!
_arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
_arg_level = r',\s*(?P<level>\d*)'
_arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
_arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
_arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
_arg_items = r'(,\s*items=(?P<items>\d+))?'
_arg_skipitems = r'(,\s*skipitems=(?P<skipitems>\d+))?'
_arg_titlesonly = r'(,\s*(?P<titlesonly>titlesonly))?'
_arg_editlink = r'(,\s*(?P<editlink>editlink))?'
_args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % (
_arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
_arg_skipitems, _arg_titlesonly, _arg_editlink)
_title_re = r"^(?P<heading>\s*(?P<hmarker>=+)\s.*\s(?P=hmarker))$"
def extract_titles(body, title_re):
titles = []
for title, _ in title_re.findall(body):
h = title.strip()
level = 1
while h[level:level+1] == '=': level = level+1
depth = min(5,level)
title_text = h[level:-level].strip()
titles.append((title_text, level))
return titles
def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0):
request = macro.request
_ = request.getText
# return immediately if getting links for the current page
if request.mode_getpagelinks:
return ''
# parse and check arguments
args = args_re.match(text)
if not args:
return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,))
# prepare including page
result = []
print_mode = macro.form.has_key('action') and macro.form['action'][0] == "print"
this_page = macro.formatter.page
if not hasattr(this_page, '_macroInclude_pagelist'):
this_page._macroInclude_pagelist = {}
# get list of pages to include
inc_name = wikiutil.AbsPageName(request, this_page.page_name, args.group('name'))
pagelist = [inc_name]
if inc_name.startswith("^"):
try:
inc_match = re.compile(inc_name)
except re.error:
pass # treat as plain page name
else:
# Get user filtered readable page list
pagelist = request.rootpage.getPageList(filter=inc_match.match)
# sort and limit page list
pagelist.sort()
sort_dir = args.group('sort')
if sort_dir == 'descending':
pagelist.reverse()
max_items = args.group('items')
if max_items:
pagelist = pagelist[:int(max_items)]
skipitems = 0
if args.group("skipitems"):
skipitems = int(args.group("skipitems"))
titlesonly = args.group('titlesonly')
editlink = args.group('editlink')
# iterate over pages
for inc_name in pagelist:
if not request.user.may.read(inc_name):
continue
if this_page._macroInclude_pagelist.has_key(inc_name):
result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name,))
continue
if skipitems:
skipitems -= 1
continue
fmt = macro.formatter.__class__(request, is_included=True)
fmt._base_depth = macro.formatter._base_depth
inc_page = Page(request, inc_name, formatter=fmt)
inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
# check for "from" and "to" arguments (allowing partial includes)
body = inc_page.get_raw_body() + '\n'
from_pos = 0
to_pos = -1
from_re = args.group('from')
if from_re:
try:
from_match = re.compile(from_re, re.M).search(body)
except re.error, e:
##result.append("*** fe=%s ***" % e)
from_match = re.compile(re.escape(from_re), re.M).search(body)
if from_match:
from_pos = from_match.end()
else:
result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
to_re = args.group('to')
if to_re:
try:
to_match = re.compile(to_re, re.M).search(body, from_pos)
except re.error:
to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
if to_match:
to_pos = to_match.start()
else:
result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
if titlesonly:
newbody = []
levelstack = []
for title, level in extract_titles(body[from_pos:to_pos], title_re):
if levelstack:
if level > levelstack[-1]:
result.append(macro.formatter.bullet_list(1))
levelstack.append(level)
else:
while levelstack and level < levelstack[-1]:
result.append(macro.formatter.bullet_list(0))
levelstack.pop()
if not levelstack or level != levelstack[-1]:
result.append(macro.formatter.bullet_list(1))
levelstack.append(level)
else:
result.append(macro.formatter.bullet_list(1))
levelstack.append(level)
result.append(macro.formatter.listitem(1))
result.append(inc_page.link_to(request, title))
result.append(macro.formatter.listitem(0))
while levelstack:
result.append(macro.formatter.bullet_list(0))
levelstack.pop()
continue
if from_pos or to_pos != -1:
inc_page.set_raw_body(body[from_pos:to_pos], modified=True)
##result.append("*** f=%s t=%s ***" % (from_re, to_re))
##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
if called_by_toc:
result.append(inc_page.get_raw_body())
continue
if not hasattr(request, "_Include_backto"):
request._Include_backto = this_page.page_name
# do headings
level = None
if args.group('heading') and args.group('hquote'):
heading = args.group('htext') or inc_page.split_title(request)
level = 1
if args.group('level'):
level = int(args.group('level'))
if print_mode:
result.append(macro.formatter.heading(1, level) +
macro.formatter.text(heading) +
macro.formatter.heading(0, level))
else:
import sha
from MoinMoin import config
# this heading id might produce duplicate ids,
# if the same page is included multiple times
# Encode stuf we feed into sha module.
pntt = (inc_name + heading).encode(config.charset)
hid = "head-" + sha.new(pntt).hexdigest()
request._page_headings.setdefault(pntt, 0)
request._page_headings[pntt] += 1
if request._page_headings[pntt] > 1:
hid += '-%d'%(request._page_headings[pntt],)
result.append(
#macro.formatter.heading(1, level, hid,
# icons=edit_icon.replace('<img ', '<img align="right" ')) +
macro.formatter.heading(1, level, hid) +
inc_page.link_to(request, heading, css_class="include-heading-link") +
macro.formatter.heading(0, level)
)
# set or increment include marker
this_page._macroInclude_pagelist[inc_name] = \
this_page._macroInclude_pagelist.get(inc_name, 0) + 1
# output the included page
strfile = StringIO.StringIO()
request.redirect(strfile)
try:
cid = request.makeUniqueID("Include_%s" % wikiutil.quoteWikinameFS(inc_page.page_name))
inc_page.send_page(request, content_only=1, content_id=cid)
result.append(strfile.getvalue())
finally:
request.redirect()
# decrement or remove include marker
if this_page._macroInclude_pagelist[inc_name] > 1:
this_page._macroInclude_pagelist[inc_name] = \
this_page._macroInclude_pagelist[inc_name] - 1
else:
del this_page._macroInclude_pagelist[inc_name]
# if no heading and not in print mode, then output a helper link
if editlink and not (level or print_mode):
result.extend([
'<div class="include-link">',
inc_page.link_to(request, '[%s]' % (inc_name,), css_class="include-page-link"),
inc_page.link_to(request, '[%s]' % (_('edit'),), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
'</div>',
])
# XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
# return include text
return ''.join(result)
# vim:ts=4:sw=4:et

View file

@ -0,0 +1,218 @@
# -*- coding: iso-8859-1 -*-
#Dependencies = ["pages"] # included page
Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks
import re, StringIO
from MoinMoin import wikiutil, search
from MoinMoin.Page import Page
from MoinMoin.util import web
from random import choice
_sysmsg = '<p><strong class="%s">%s</strong></p>'
## keep in sync with TableOfContents macro!
_arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
_arg_level = r',\s*(?P<level>\d*)'
_arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
_arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
_arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
_arg_items = r'(,\s*items=(?P<items>\d+))?'
_arg_skipitems = r'(,\s*skipitems=(?P<skipitems>\d+))?'
_arg_titlesonly = r'(,\s*(?P<titlesonly>titlesonly))?'
_arg_editlink = r'(,\s*(?P<editlink>editlink))?'
_args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % (
_arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
_arg_skipitems, _arg_titlesonly, _arg_editlink)
_title_re = r"^(?P<heading>\s*(?P<hmarker>=+)\s.*\s(?P=hmarker))$"
def extract_titles(body, title_re):
titles = []
for title, _ in title_re.findall(body):
h = title.strip()
level = 1
while h[level:level+1] == '=': level = level+1
depth = min(5,level)
title_text = h[level:-level].strip()
titles.append((title_text, level))
return titles
def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0):
request = macro.request
_ = request.getText
qnumber = choice(range(1, 10, 1))
text = u'QuestionnaireCrans/Question\d+[a-z]?$,, from="^= Question =$", to="^----$"'
# return immediately if getting links for the current page
if request.mode_getpagelinks:
return ''
# parse and check arguments
args = args_re.match(text)
if not args:
return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,))
# Search the pages and return the results
query = search.QueryParser(regex=1).parse_query(args.group('name'))
results = search.searchPages(request, query, sort='page_name')
pagelist = [results.hits[qnumber].page_name]
# prepare including page
result = []
print_mode = macro.form.has_key('action') and macro.form['action'][0] == "print"
this_page = macro.formatter.page
if not hasattr(this_page, '_macroInclude_pagelist'):
this_page._macroInclude_pagelist = {}
skipitems = 0
if args.group("skipitems"):
skipitems = int(args.group("skipitems"))
titlesonly = args.group('titlesonly')
editlink = args.group('editlink')
# iterate over pages
for inc_name in pagelist:
if not request.user.may.read(inc_name):
continue
if this_page._macroInclude_pagelist.has_key(inc_name):
result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name,))
continue
if skipitems:
skipitems -= 1
continue
fmt = macro.formatter.__class__(request, is_included=True)
fmt._base_depth = macro.formatter._base_depth
inc_page = Page(request, inc_name, formatter=fmt)
inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
# check for "from" and "to" arguments (allowing partial includes)
body = inc_page.get_raw_body() + '\n'
from_pos = 0
to_pos = -1
from_re = args.group('from')
if from_re:
try:
from_match = re.compile(from_re, re.M).search(body)
except re.error, e:
##result.append("*** fe=%s ***" % e)
from_match = re.compile(re.escape(from_re), re.M).search(body)
if from_match:
from_pos = from_match.end()
else:
result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
to_re = args.group('to')
if to_re:
try:
to_match = re.compile(to_re, re.M).search(body, from_pos)
except re.error:
to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
if to_match:
to_pos = to_match.start()
else:
result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
if titlesonly:
newbody = []
levelstack = []
for title, level in extract_titles(body[from_pos:to_pos], title_re):
if levelstack:
if level > levelstack[-1]:
result.append(macro.formatter.bullet_list(1))
levelstack.append(level)
else:
while levelstack and level < levelstack[-1]:
result.append(macro.formatter.bullet_list(0))
levelstack.pop()
if not levelstack or level != levelstack[-1]:
result.append(macro.formatter.bullet_list(1))
levelstack.append(level)
else:
result.append(macro.formatter.bullet_list(1))
levelstack.append(level)
result.append(macro.formatter.listitem(1))
result.append(inc_page.link_to(request, title))
result.append(macro.formatter.listitem(0))
while levelstack:
result.append(macro.formatter.bullet_list(0))
levelstack.pop()
continue
if from_pos or to_pos != -1:
inc_page.set_raw_body(body[from_pos:to_pos], modified=True)
##result.append("*** f=%s t=%s ***" % (from_re, to_re))
##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
if called_by_toc:
result.append(inc_page.get_raw_body())
continue
if not hasattr(request, "_Include_backto"):
request._Include_backto = this_page.page_name
# do headings
level = None
if args.group('heading') and args.group('hquote'):
heading = args.group('htext') or inc_page.split_title(request)
level = 1
if args.group('level'):
level = int(args.group('level'))
if print_mode:
result.append(macro.formatter.heading(1, level) +
macro.formatter.text(heading) +
macro.formatter.heading(0, level))
else:
import sha
from MoinMoin import config
# this heading id might produce duplicate ids,
# if the same page is included multiple times
# Encode stuf we feed into sha module.
pntt = (inc_name + heading).encode(config.charset)
hid = "head-" + sha.new(pntt).hexdigest()
request._page_headings.setdefault(pntt, 0)
request._page_headings[pntt] += 1
if request._page_headings[pntt] > 1:
hid += '-%d'%(request._page_headings[pntt],)
result.append(
#macro.formatter.heading(1, level, hid,
# icons=edit_icon.replace('<img ', '<img align="right" ')) +
macro.formatter.heading(1, level, hid) +
inc_page.link_to(request, heading, css_class="include-heading-link") +
macro.formatter.heading(0, level)
)
# set or increment include marker
this_page._macroInclude_pagelist[inc_name] = \
this_page._macroInclude_pagelist.get(inc_name, 0) + 1
# output the included page
strfile = StringIO.StringIO()
request.redirect(strfile)
try:
cid = request.make_unique_id("Include_%s" % wikiutil.quoteWikinameFS(inc_page.page_name))
inc_page.send_page(content_only=1) #, content_id=cid)
result.append(strfile.getvalue())
finally:
request.redirect()
# decrement or remove include marker
if this_page._macroInclude_pagelist[inc_name] > 1:
this_page._macroInclude_pagelist[inc_name] = \
this_page._macroInclude_pagelist[inc_name] - 1
else:
del this_page._macroInclude_pagelist[inc_name]
# if no heading and not in print mode, then output a helper link
if editlink and not (level or print_mode):
result.extend([
'<div class="include-link">',
inc_page.link_to(request, '[%s]' % (inc_name,), css_class="include-page-link"),
inc_page.link_to(request, '[%s]' % (_('edit'),), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
'</div>',
])
# XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
# return include text
return ''.join(result)
# vim:ts=4:sw=4:et

View file

@ -0,0 +1,57 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - RandomQuote Macro
Selects a random quote from FortuneCookies or a given page.
Usage:
<<RandomQuote()>>
<<RandomQuote(WikiTips)>>
Comments:
It will look for list delimiters on the page in question.
It will ignore anything that is not in an "*" list.
@copyright: 2002-2004 by Jürgen Hermann <jh@web.de>
@license: GNU GPL, see COPYING for details.
Originally written by Thomas Waldmann.
Gustavo Niemeyer added wiki markup parsing of the quotes.
"""
import random, StringIO
from MoinMoin.Page import Page, wikiutil
Dependencies = ["time"]
def execute(macro, args):
_ = macro.request.getText
pagename = args or 'FortuneCookies'
if macro.request.user.may.read(pagename):
page = Page(macro.request, pagename)
raw = page.get_raw_body()
else:
raw = ""
# this selects lines looking like a list item
# !!! TODO: make multi-line quotes possible (optionally split by "----" or something)
quotes = raw.splitlines()
quotes = [quote.strip() for quote in quotes]
quotes = [quote[2:] for quote in quotes if quote.startswith('1. ')]
if not quotes:
return (macro.formatter.highlight(1) +
_('No quotes on %(pagename)s.') % {'pagename': pagename} +
macro.formatter.highlight(0))
quote = random.choice(quotes)
page.set_raw_body(quote, 1)
out = StringIO.StringIO()
macro.request.redirect(out)
page.send_page(macro.request, content_only=1, content_id="RandomQuote_%s" % wikiutil.quoteWikinameFS(page.page_name) )
quote = out.getvalue()
macro.request.redirect()
return quote

View file

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
#
# SHOWCATEGORIES.PY--
#
# Copyright (C) 2008 Antoine Durand-Gasselin
# Author: Antoine Durand-Gasselin <adg@crans.org>
#
def execute (macro, text):
f = macro.formatter
code = [f.heading(1,2), "Liste des liens", f.heading(0,2)]
code += macro.request.page.getPageLinks(macro.request)
code += [f.heading(1,2), u"Liste des Catégories", f.heading(0,2)]
code += macro.request.page.getCategories(macro.request)
return "\n".join(code)

162
wiki/macro/SubscribeTo.py Normal file
View file

@ -0,0 +1,162 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - Automaticaly subscribe user(s) on save
<<SubscribeTo(UserName1[,+GroupName1[,-UserName2]])>>
Will add those users and/or group of users as subscribers while saving the
page. These users are not subscribed for templates nor while preview the
page. To subscribe to this template the FQTN (full-qualified template name)
has to be specified as one of the parameters.
Using (-) and (+) it's possible to create a flexible list of users will
be subscribed to this page. E.g. select a long group and remove with (-)
some group members. Or select a short group and extend the list by adding
(+) additional users. By default users are added if no (-) or (+) is
specified. (-) does not remove the subscribtion for the specified user.
(-) does not change the status of the subscription for the specified user.
@copyright: (C) 2005,2006 Raphael Bossek
@license: GNU GPL 2, see COPYING for details
@version: 20060402
@url: http://www.solutions4linux.de/cgi-bin/view/Main/MoinMoinSubscribeTo
"""
from MoinMoin import user
import re
def execute (macro, args):
_ = macro.request.getText
# return immediately if getting links for the current page
if request.mode_getpagelinks:
return ''
unknownuname = {}
missingemail = {}
outofdateversion = 0
result = u''
allusers = re.split (r'[,;\s]+', args)
subscribeto = {}
page_name = macro.request.page.page_name
is_preview = macro.form.has_key ('button_preview')
p_warning = u'<p class="warning" style="margin: 0; padding: 0.4em; background: #FFFF80">' + macro.formatter.icon ("info") + u' '
p_notice = u'<p class="notice" style="margin: 0; padding: 0.4em; background: #81BBF2">' + macro.formatter.icon ("info") + u' '
p_info = u'<p class="info" style="margin: 0; padding: 0.4em; background: #E6EAF0">' + macro.formatter.icon ("info") + u' '
# TODO: Should be compiled only once, and cached in cfg
group_re = re.compile (macro.cfg.page_group_regex, re.UNICODE)
# By default templates are not subsribed. This can be changed by
# specifing the FQTN as parameter.
is_template = re.search (macro.cfg.page_template_regex, page_name, re.UNICODE)
# Proceed the list in the same order as specified by the user.
# This allow us to work with groups and users in the same way
# as specifing all members of a group.
for uname in allusers:
# Skip empty names
if not uname:
continue
# Determine what to do with the user/group members.
if uname[:1] == '-':
uname = uname[1:]
remove_action = True
else:
if uname[:1] == '+':
uname = uname[1:]
remove_action = False
# It's a special feature. If the FQTN (full-qualified template name)
# is one of the parameters we allow to subscribe to this template too.
if remove_action == False and uname == page_name:
is_template = False
continue
members = []
# Distinguish between user and group. Create a list of
# users which has to be subscribed to.
if group_re.search (uname):
# Recursively expand groups
groupdict = macro.request.dicts
if groupdict.hasgroup (uname):
members = groupdict.members (uname)
else:
unknownuname[uname] = 1
else:
members = [uname]
# Go through all members and proceed with the same action.
for uname in members:
uid = user.getUserId (macro.request, uname)
if not uid:
# Only if this user has to be added and does not exists put
# his name in our unknwonuname list. Otherwise the use does
# not matter.
if remove_action == False:
unknownuname[uname] = 1
# If this user was added before but we know now that should
# be skipped we update the unknownuname list afterward.
else:
if uname in subscribeto:
del subscribeto[uname]
if uname in unknownuname:
del unknownuname[uname]
else:
thisuser = user.User (macro.request, id = uid)
if not thisuser.email:
missingemail[uname] = 1
else:
subscribeto[uname] = (thisuser, remove_action)
# MoinMoin compatibility check
if not 'subscribePage' in dir (thisuser) and not 'subscribe' in dir (thisuser):
outofdateversion = 1
break
if not outofdateversion:
if unknownuname:
result += p_warning + _(u'This user(s)/group(s) are unknown by now: %s') % u', '.join (unknownuname.keys()) + u'</p>'
if missingemail:
result += p_warning + _(u'Follwing users(s) missing an email address in their profile: %s') % u', '.join (missingemail.keys()) + u'</p>'
if subscribeto:
addeduname = []
faileduname = []
subscribeduname = []
subscribe_status = (1 == 1)
if not is_template:
for uname, (thisuser, remove_action) in subscribeto.iteritems():
# Do not modify the subscribtion of this usser.
if remove_action == True:
continue
# Do _not_ subscribe these users while preview the page
if not thisuser.isSubscribedTo ([page_name]):
if not is_preview:
# Support for MoinMoin 1.3
if 'subscribePage' in dir (thisuser):
subscribe_status = thisuser.subscribePage (page_name)
if subscribe_status:
thisuser.save()
# Support for MoinMoin 1.5
elif 'subscribe' in dir (thisuser):
subscribe_status = thisuser.subscribe (page_name)
else:
outofdateversion = 1
break
if not subscribe_status:
faileduname.append (uname)
else:
addeduname.append (uname)
else:
subscribeduname.append (uname)
else:
result += p_notice + _(u'This template will not be subscribed!') + u' ' + _(u'Follwing user(s)/group(s) are remembered to be subscribed later with a regular page: %s') % u', '.join (subscribeto.keys()) + u'</p>'
if addeduname:
result += p_info + _(u'Following new user(s) will be subscribed to %s before saving: %s') % (page_name, u', '.join (addeduname)) + u'</p>'
if subscribeduname:
result += p_info + _(u'Following user(s) are already subsribed to %s: %s') % (page_name, u', '.join (subscribeduname)) + u'</p>'
if faileduname:
result += p_warning + _(u'This user(s) failed to subscribe to: %s') % u', '.join (faileduname) + u'</p>'
if outofdateversion:
result += p_warning + _(u'Sorry, out-of-date version of SubscribeTo marcro installed! Functionality disabled until an update occurs.') + u'</p>'
if is_preview:
return result
return u''

91
wiki/macro/TV.py Normal file
View file

@ -0,0 +1,91 @@
Dependencies = ["Time"]
SAP_FILE_URL = "http://tv/sap.txt"
BASE_IMAGE_URL = "http://tv/images/"
IMAGE_SUFFIX = ".jpg"
SMALL_IMAGE_SUFFIX = "_petites.jpg"
def image_url_for_channel(channel_name, channel_ip, small=0 ):
if small:
return BASE_IMAGE_URL + str(channel_ip) + IMAGE_SUFFIX
else:
return BASE_IMAGE_URL + str(channel_ip) + SMALL_IMAGE_SUFFIX
def get_channel_list():
import urllib
# Getsap file from web sever.
f = urllib.urlopen(SAP_FILE_URL)
# Read it.
s = f.read()
f.close()
s = s.split("\n")
channel_list = []
for a_line in s:
try:
ch_name, ch_ip = a_line.split(":")
url = "udp://@%s:1234" % ch_ip
d = {
"name": ch_name,
"url": url,
"image_url": image_url_for_channel( ch_name, ch_ip ),
"small_image_url": image_url_for_channel( ch_name, ch_ip, small=1 ),
}
channel_list.append(d)
except:
pass
return channel_list
def execute(macro, args):
opt = {"col":4,"cat":False,"ch":False, "width":"10em"}
# parse args
if args:
try:
for name, value in [(x.split("=")[0].strip(), x.split("=")[1].strip()) for x in args.split(",")]:
opt[name] = value
except:
pass
IMAGES_PER_LINE = int(opt["col"])
CATHEGORY = opt["cat"]
CHANNEL = opt["ch"]
IMAGE_WIDTH = opt["width"]
# display all channel
ch_list = get_channel_list()
text = macro.formatter.table(1,{})
i = 0
for a_channel in ch_list:
if CATHEGORY:
if not a_channel["name"].startswith(CATHEGORY):
continue
if CHANNEL:
if a_channel["name"].find(CHANNEL)<0:
continue
if i == 0:
text+= macro.formatter.table_row(1)
text+= macro.formatter.table_cell(1, {'style':'text-align:center;'})
text+= macro.formatter.strong( 1 )
text+= macro.formatter.text( a_channel["name"] )
text+= macro.formatter.strong( 0 )
text+= macro.formatter.linebreak( 0 )
#text+= macro.formatter.url(1, href=a_channel["url"], style="text-decoration:none;")
text+= macro.formatter.url(1, url=a_channel["url"], style="text-decoration:none;")
text+= macro.formatter.image( src=a_channel["image_url"], alt="No image", style="width:%s;" % IMAGE_WIDTH )
text+= macro.formatter.linebreak( 0 )
text+= macro.formatter.text( "Regarder maintenant" )
text+= macro.formatter.url(0)
text+= macro.formatter.table_cell(0)
if i == IMAGES_PER_LINE - 1:
text+= macro.formatter.table_row(0)
i = (i + 1) % IMAGES_PER_LINE
while i != 0 and i < IMAGES_PER_LINE:
text+= macro.formatter.table_cell(1)
text+= macro.formatter.table_cell(0)
i += 1
text+= macro.formatter.table(0)
return text

53
wiki/macro/TerminalSsh.py Normal file
View file

@ -0,0 +1,53 @@
Dependencies = ["Time"]
class ssh:
settings = {
'protocol' : "ssh2",
'server' : 'ssh.crans.org',
'port' : '22',
"auth-method" : "keyboard-interactive",
"bg-color" : "black",
"fg-color" : "white",
"cursor-color" : "yellow",
"menus" : "pop3",
"geometry" : "94x32",
"allow-new-server" : "false",
}
#appletLocation = "/wiki/applets/mindterm.jar"
appletLocation = "https://ssh.crans.org/mindterm.jar"
def parseArgs(self, args):
argList = args.split(u',')
for anArg in argList:
try:
key = anArg.split(u'=')[0]
value = anArg.split(u'=')[1]
self.settings[key] = value
except:pass
def formatParams(self):
html = []
for key, value in self.settings.items():
html.append(u'<param name="%s" value="%s">' % (key, value))
return u'\n'.join(html)
def __init__(self, args):
self.parseArgs(args)
def run(self):
html = [
u'<p>',
u'<applet code=com.mindbright.application.MindTerm.class width=667 height=481 archive="%s">' % self.appletLocation,
self.formatParams(),
u'</applet>',
u'</p>',
]
return u'\n'.join(html)
def execute(macro, args):
# return macro.formatter.text("I got these args from a macro %s: %s" %
# (str(macro), args))
o = ssh(args)
return macro.formatter.rawHTML(o.run())

27
wiki/macro/YouTube.py Normal file
View file

@ -0,0 +1,27 @@
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - YouTube Macro
Jesus L. Alvaro 2006
v 0.0.2
You can include YouTube videos in the wiki by using this macro:
[[YouTube(V8tSRJ8e3b0)]] or
[[YouTube(http://www.youtube.com/v/V8tSRJ8e3b0)]]
visit "http://www.iesvaldebernardo.es/w/Post/2006-11-30-1447/YouTube_en_la_Wiki."
"""
def execute(macro, text):
if text.find('http://')> -1:
try:
text = text.split('v=')[1]
except:
return u"URL non valide..."
url = 'http://www.youtube.com/v/%s' % text
html = u'''
<object width="425" height="350">
<param name="movie" value="%(youtubelink)s"></param>
<param name="wmode" value="transparent"></param>
<embed src="%(youtubelink)s" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed>
</object>
''' % {"youtubelink": url}
return macro.formatter.rawHTML(html)

5
wiki/macro/__init__.py Normal file
View file

@ -0,0 +1,5 @@
# -*- coding: iso-8859-1 -*-
from MoinMoin.util import pysupport
modules = pysupport.getPackageModules(__file__)

118
wiki/parser/Doodle.py Normal file
View file

@ -0,0 +1,118 @@
# -*- coding: iso-8859-1 -*-
"""
_vi
<Ii _aa.
:I> aZ2^
v` .we^
. . .. + _2~
._auqXZZX ._auqXZZZ` ...._... ~ ._|ii~
.aXZZY""^~~ vX#Z?""~~~._=ii|+++++++ii=, _=|+~-
JXXX` )XXX' _|i+~ .__..._. +l= -~-
SXXo )XZX: |i> ._%i>~~+|ii| .i| ._s_ass,,. ._a%ssssssss
-SXZ6,,. )XZX: =l> _li+~` iii| .ii _uZZXX??YZ#Za, uXUX*?!!!!!!!
"!XZ#ZZZZZXZXZ` <i> =i: .|ii| .l|.dZXr 4XXo.XXXs,.
-~^^^^^^^` -||, +i|=. |ii| :i>:ZXZ( ]XZX.-"SXZUZUXoa,,
+l|, ~~|++|++i|||+~:ZXZ( ]ZZX ---~"?Z#m
.__;=- ~+l|=____.___, :ZXZ( ]ZXX_________auXX2
._||>+~- . -~+~++~~~- :ZXZ( ]ZXZZ#######UX*!"
-+-- .>` _
.<}` 3;
.<l> .Zc
.ii^ )Xo
]XX
MoinMoin - Doodle poll parser
PURPOSE:
un joli sondage doodle sur le wiki
AUTHOR:
Antoine Durand-Gasselin <adg@crans.org>
CALLING SEQUENCE:
{{{
#!Doodle pollname; choix1; choix2; choix3
participant1; choix1=1; choix2=0; choix3=1
participant2; choix1=0; choix2=1; choix3=1
}}}
"""
import os, string, re, StringIO, base64
from MoinMoin import config, wikiutil
from MoinMoin.parser.text_moin_wiki import Parser as WikiParser
Dependencies = []
class Parser:
parsername = "Doodle"
Dependencies = Dependencies
def __init__ (self, raw, request, **kw):
self.form = request.form
self.request = request
self.raw = raw
self.parseArgs(kw["format_args"])
def parseArgs(self, argsString):
argList = argsString.split(';')
self.poll_name=argList[0]
self.poll_choices=filter ((lambda x: x != ""), [ i.strip() for i in argList[1:]])
def format(self, f):
entries = self.raw.splitlines()
stylefmt = 'background-color: %s; border: 1px solid %s;'
code = '\n\n<form action="?action=fillpoll&amp;pollname=%s" method="post">' % self.poll_name
code += f.table(1)
code += f.table_row(1)
code += f.table_cell(1)
code += f.table_cell(0)
for choice in self.poll_choices:
code += f.table_cell(1)
code += f.text(choice)
code += f.table_cell(0)
code += f.table_row(0)
for entry in entries:
code += f.table_row(1)
code += f.table_cell(1)
code += f.text(entry.split(";",1)[0].strip())
code += f.table_cell(0)
for choice in self.poll_choices:
resp = re.search(re.escape(choice)+'=?', entry)
if resp:
disp = entry[resp.end()]
if '1' == disp: colors= ('#a8ffa6', '#64d06a')
elif '0' == disp: colors= ('#ffaca8', '#e88782')
else: color = ('grey', 'grey')
code += f.table_cell(1,{'style': stylefmt% colors})
code += f.text(disp)
else:
code += f.table_cell(1,{'style': stylefmt % ('grey', 'grey')})
code += f.text('nsp')
code += f.table_cell(0)
code += f.table_row(0)
code += f.table_row(1)
code += f.table_cell(1)
code += ('<input type="text" name="user" />')
code += f.table_cell(0)
for choice in self.poll_choices:
if isinstance(choice, unicode):
# l'utf-8, c'est bien! On encode l'unicode en utf-8 avant
# de le base64er
name = base64.encodestring(choice.strip().encode('utf-8')).strip('\r\t \n=')
else:
# Bon, si on n'a pas un unicode, on encode sauvagement, mais
# ça peut chier
name = base64.encodestring(choice.strip()).strip('\r\t \n=')
code += f.table_cell(1)
code += '<input type="checkbox" name="%s" value="1">' % name
code += f.table_cell(0)
code += f.table(0)
code += '<input type="submit" name="boutok" value="envoyer"/>'
code += '</form>'
self.request.write(code)

5
wiki/parser/__init__.py Normal file
View file

@ -0,0 +1,5 @@
# -*- coding: iso-8859-1 -*-
from MoinMoin.util import pysupport
modules = pysupport.getPackageModules(__file__)

220
wiki/parser/latex.py Normal file
View file

@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
"""
New latex formatter using dvipng and tempfile
Author: JohannesBerg <johannes@sipsolutions.net>
This parser (and the corresponding macro) was tested with Python 2.3.4 and
* Debian Linux with out-of-the-box tetex-bin and dvipng packages installed
* Windows XP (not by me)
In the parser, you can add stuff to the prologue by writing
%%end-prologue%%
somewhere in the document, before that write stuff like \\usepackage and after it put
the actual latex display code.
"""
Dependencies = []
import sha, os, tempfile, shutil, re
from MoinMoin.action import AttachFile
from MoinMoin.Page import Page
latex_template = r'''
\documentclass[12pt]{article}
\pagestyle{empty}
\usepackage[utf8]{inputenc}
%(prologue)s
\begin{document}
%(raw)s
\end{document}
'''
max_pages = 10
MAX_RUN_TIME = 5 # seconds
latex = "latex" # edit full path here, e.g. reslimit = "C:\\path\\to\\latex.exe"
dvipng = "dvipng" # edit full path here (or reslimit = r'C:\path\to\latex.exe')
# last arg must have %s in it!
latex_args = ("--interaction=nonstopmode", "%s.tex")
# last arg must have %s in it!
dvipng_args = ("-bgTransparent", "-Ttight", "--noghostscript", "-l%s" % max_pages, "%s.dvi")
# this is formatted with hexdigest(texcode),
# page number and extension are appended by
# the tools
latex_name_template = "latex_%s_p"
# keep this up-to-date, also with max_pages!!
latex_attachment = re.compile((latex_name_template+'%s%s') % (r'[0-9a-fA-F]{40}', r'[0-9]{1,2}', r'\.png'))
anchor = re.compile(r'^%%anchor:[ ]*([a-zA-Z0-9_-]+)$', re.MULTILINE | re.IGNORECASE)
# the anchor re must start with a % sign to be ignored by latex as a comment!
end_prologue = '%%end-prologue%%'
def call_command_in_dir_NT(app, args, targetdir):
reslimit = "runlimit.exe" # edit full path here
os.environ['openin_any'] = 'p'
os.environ['openout_any'] = 'p'
os.environ['shell_escape'] = 'f'
stdouterr = os.popen('%s %d "%s" %s %s < NUL' % (reslimit, MAX_RUN_TIME, targetdir, app, ' '.join(args)), 'r')
output = ''.join(stdouterr.readlines())
err = stdouterr.close()
if not err is None:
return ' error! exitcode was %d, transscript follows:\n\n%s' % (err,output)
return None
def call_command_in_dir_unix(app, args, targetdir):
# this is the unix implementation
(r,w) = os.pipe()
pid = os.fork()
if pid == -1:
return 'could not fork'
if pid == 0:
# child
os.close(r)
os.dup2(os.open("/dev/null", os.O_WRONLY), 0)
os.dup2(w, 1)
os.dup2(w, 2)
os.chdir(targetdir)
os.environ['openin_any'] = 'p'
os.environ['openout_any'] = 'p'
os.environ['shell_escape'] = 'f'
import resource
resource.setrlimit(resource.RLIMIT_CPU,
(MAX_RUN_TIME * 1000, MAX_RUN_TIME * 1000)) # docs say this is seconds, but it is msecs on my system.
# os.execvp will raise an exception if the executable isn't
# present. [[ try os.execvp("aoeu", ['aoeu']) ]]
# If we don't catch exceptions here, it will be caught at the
# main body below, and then os.rmdir(tmpdir) will be called
# twice, once for each fork. The second one raises an exception
# in the main code, which gets back to the user. This is bad.
try:
os.execvp(app, [app] + list(args))
finally:
print "failed to exec()",app
os._exit(2)
else:
# parent
os.close(w)
r = os.fdopen(r,"r")
output = ''.join(r.readlines())
(npid, exi) = os.waitpid(pid, 0)
r.close()
sig = exi & 0xFF
stat = exi >> 8
if stat != 0 or sig != 0:
return ' error! exitcode was %d (signal %d), transscript follows:\n\n%s' % (stat,sig,output)
return None
# notreached
if os.name == 'nt':
call_command_in_dir = call_command_in_dir_NT
else:
call_command_in_dir = call_command_in_dir_unix
class Parser:
extensions = ['.tex']
def __init__ (self, raw, request, **kw):
self.raw = raw
if len(self.raw)>0 and self.raw[0] == '#':
self.raw[0] = '%'
self.request = request
self.exclude = []
if not hasattr(request, "latex_cleanup_done"):
request.latex_cleanup_done = {}
def cleanup(self, pagename):
attachdir = AttachFile.getAttachDir(self.request, pagename, create=1)
for f in os.listdir(attachdir):
if not latex_attachment.match(f) is None:
os.remove("%s/%s" % (attachdir, f))
def _internal_format(self, formatter, text):
tmp = text.split(end_prologue, 1)
if len(tmp) == 2:
prologue,tex=tmp
else:
prologue = ''
tex = tmp[0]
if callable(getattr(formatter, 'johill_sidecall_emit_latex', None)):
return formatter.johill_sidecall_emit_latex(tex)
return self.get(formatter, tex, prologue, True)
def format(self, formatter):
self.request.write(self._internal_format(formatter, self.raw))
def get(self, formatter, inputtex, prologue, para=False):
if not self.request.latex_cleanup_done.has_key(self.request.page.page_name):
self.request.latex_cleanup_done[self.request.page.page_name] = True
self.cleanup(self.request.page.page_name)
if len(inputtex) == 0: return ''
if callable(getattr(formatter, 'johill_sidecall_emit_latex', None)):
return formatter.johill_sidecall_emit_latex(inputtex)
extra_preamble = ''
preamble_page = self.request.pragma.get('latex_preamble', None)
if preamble_page is not None:
extra_preamble = Page(self.request, preamble_page).get_raw_body()
extra_preamble = re.sub(re.compile('^#'), '%', extra_preamble)
tex = latex_template % { 'raw': inputtex, 'prologue': extra_preamble + prologue }
enctex = tex.encode('utf-8')
fn = latex_name_template % sha.new(enctex).hexdigest()
attachdir = AttachFile.getAttachDir(self.request, formatter.page.page_name, create=1)
dst = "%s/%s%%d.png" % (attachdir, fn)
if not os.access(dst % 1, os.R_OK):
tmpdir = tempfile.mkdtemp()
try:
data = open("%s/%s.tex" % (tmpdir, fn), "w")
data.write(enctex)
data.close()
args = list(latex_args)
args[-1] = args[-1] % fn
res = call_command_in_dir(latex, args, tmpdir)
if not res is None:
return formatter.preformatted(1)+formatter.text('latex'+res)+formatter.preformatted(0)
args = list(dvipng_args)
args[-1] = args[-1] % fn
res = call_command_in_dir(dvipng, args, tmpdir)
if not res is None:
return formatter.preformatted(1)+formatter.text('dvipng'+res)+formatter.preformatted(0)
page = 1
while os.access("%s/%s%d.png" % (tmpdir, fn, page), os.R_OK):
shutil.copyfile ("%s/%s%d.png" % (tmpdir, fn, page), dst % page)
page += 1
finally:
for root,dirs,files in os.walk(tmpdir, topdown=False):
for name in files:
os.remove(os.path.join(root,name))
for name in dirs:
os.rmdir(os.path.join(root,name))
os.rmdir(tmpdir)
result = ""
page = 1
loop = False
for match in anchor.finditer(inputtex):
result += formatter.anchordef(match.group(1))
for match in anchor.finditer(prologue):
result += formatter.anchordef(match.group(1))
while os.access(dst % page, os.R_OK):
url = AttachFile.getAttachUrl(formatter.page.page_name, fn+"%d.png" % page, self.request)
if loop:
result += formatter.linebreak(0)+formatter.linebreak(0)
if para:
result += formatter.paragraph(1)
result += formatter.image(src="%s" % url, alt=inputtex, title=inputtex, align="absmiddle")
if para:
result += formatter.paragraph(0)
page += 1
loop = True
return result

5
wiki/theme/__init__.py Normal file
View file

@ -0,0 +1,5 @@
# -*- coding: iso-8859-1 -*-
from MoinMoin.util import pysupport
modules = pysupport.getPackageModules(__file__)