[wiki] wiki-lenny -> wiki
darcs-hash:20090427173001-bd074-51c7f6aea2843640e34adc0921b478f40ea98609.gz
This commit is contained in:
parent
5f26116790
commit
cd037bbbe9
31 changed files with 0 additions and 0 deletions
5
wiki/action/__init__.py
Normal file
5
wiki/action/__init__.py
Normal 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
116
wiki/action/fillpoll.py
Normal 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
118
wiki/creer_compte_wiki.py
Normal 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."
|
5
wiki/formatter/__init__.py
Normal file
5
wiki/formatter/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
from MoinMoin.util import pysupport
|
||||
|
||||
modules = pysupport.getPackageModules(__file__)
|
361
wiki/formatter/text_latex.py
Normal file
361
wiki/formatter/text_latex.py
Normal 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 ''
|
29
wiki/macro/EtatCommutationSecours.py
Normal file
29
wiki/macro/EtatCommutationSecours.py
Normal 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
28
wiki/macro/EtatSecours.py
Normal 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
4173
wiki/macro/EventCalendar.py
Normal file
File diff suppressed because it is too large
Load diff
21
wiki/macro/Gravatar.py
Normal file
21
wiki/macro/Gravatar.py
Normal 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
61
wiki/macro/HostStatus.py
Normal 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
173
wiki/macro/ImageLink.py
Normal 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&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
89
wiki/macro/InfosBornes.py
Normal 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
275
wiki/macro/MonitStatus.py
Normal 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
86
wiki/macro/MuninStatus.py
Normal 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
19
wiki/macro/PagesClubs.py
Normal 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
104
wiki/macro/PagesPerso.py
Normal 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
225
wiki/macro/ProgressBar.py
Normal 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 ('&','&').replace ('<', '<').replace ('>', '>')
|
||||
|
||||
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
142
wiki/macro/Questionnaire.py
Normal 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)
|
244
wiki/macro/RandomIncludeQuote.py
Normal file
244
wiki/macro/RandomIncludeQuote.py
Normal 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
|
218
wiki/macro/RandomPageInclude.py
Normal file
218
wiki/macro/RandomPageInclude.py
Normal 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
|
57
wiki/macro/RandomQuoteNum.py
Normal file
57
wiki/macro/RandomQuoteNum.py
Normal 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
|
||||
|
16
wiki/macro/ShowCategories.py
Normal file
16
wiki/macro/ShowCategories.py
Normal 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
162
wiki/macro/SubscribeTo.py
Normal 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
91
wiki/macro/TV.py
Normal 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
53
wiki/macro/TerminalSsh.py
Normal 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
27
wiki/macro/YouTube.py
Normal 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
5
wiki/macro/__init__.py
Normal 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
118
wiki/parser/Doodle.py
Normal 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&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
5
wiki/parser/__init__.py
Normal 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
220
wiki/parser/latex.py
Normal 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
5
wiki/theme/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
from MoinMoin.util import pysupport
|
||||
|
||||
modules = pysupport.getPackageModules(__file__)
|
Loading…
Add table
Add a link
Reference in a new issue