From 9f766f81e3d304e175b0fc0f5c091128f024cbfa Mon Sep 17 00:00:00 2001
From: Antoine Durand-Gasselin
Date: Mon, 10 Nov 2008 17:09:22 +0100
Subject: [PATCH] =?UTF-8?q?[wiki-lenny/local/macro]=20d'autres=20macros=20?=
=?UTF-8?q?qui=20passaient=20=C3=A0=20la=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
darcs-hash:20081110160922-bd074-0b8f0a7ffd4e53456642c93b1c0017cbe5c9f682.gz
---
wiki-lenny/local/macro/RandomIncludeQuote.py | 244 +++++++++++++++++++
wiki-lenny/local/macro/RandomPageInclude.py | 219 +++++++++++++++++
wiki-lenny/local/macro/RandomQuoteNum.py | 57 +++++
wiki-lenny/local/macro/SubscribeTo.py | 157 ++++++++++++
wiki-lenny/local/macro/TableOfContents.py | 186 ++++++++++++++
wiki-lenny/local/macro/TerminalSsh.py | 53 ++++
6 files changed, 916 insertions(+)
create mode 100644 wiki-lenny/local/macro/RandomIncludeQuote.py
create mode 100644 wiki-lenny/local/macro/RandomPageInclude.py
create mode 100644 wiki-lenny/local/macro/RandomQuoteNum.py
create mode 100644 wiki-lenny/local/macro/SubscribeTo.py
create mode 100644 wiki-lenny/local/macro/TableOfContents.py
create mode 100644 wiki-lenny/local/macro/TerminalSsh.py
diff --git a/wiki-lenny/local/macro/RandomIncludeQuote.py b/wiki-lenny/local/macro/RandomIncludeQuote.py
new file mode 100644
index 00000000..78efccb2
--- /dev/null
+++ b/wiki-lenny/local/macro/RandomIncludeQuote.py
@@ -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
+ @copyright: 2000-2001 by Richard Jones
+ @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 = '%s
'
+
+## keep in sync with TableOfContents macro!
+_arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))'
+_arg_level = r',\s*(?P\d*)'
+_arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?'
+_arg_to = r'(,\s*to=(?P[\'"])(?P.+?)(?P=tquote))?'
+_arg_sort = r'(,\s*sort=(?P(ascending|descending)))?'
+_arg_items = r'(,\s*items=(?P\d+))?'
+_arg_skipitems = r'(,\s*skipitems=(?P\d+))?'
+_arg_titlesonly = r'(,\s*(?Ptitlesonly))?'
+_arg_editlink = r'(,\s*(?Peditlink))?'
+_args_re_pattern = r'^(?P[^,]+)(%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\s*(?P=+)\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'Recursive include of "%s" forbidden
' % (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('
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([
+ '',
+ 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}),
+ '
',
+ ])
+ # 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
diff --git a/wiki-lenny/local/macro/RandomPageInclude.py b/wiki-lenny/local/macro/RandomPageInclude.py
new file mode 100644
index 00000000..dc4844fb
--- /dev/null
+++ b/wiki-lenny/local/macro/RandomPageInclude.py
@@ -0,0 +1,219 @@
+# -*- 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 = '%s
'
+
+## keep in sync with TableOfContents macro!
+_arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))'
+_arg_level = r',\s*(?P\d*)'
+_arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?'
+_arg_to = r'(,\s*to=(?P[\'"])(?P.+?)(?P=tquote))?'
+_arg_sort = r'(,\s*sort=(?P(ascending|descending)))?'
+_arg_items = r'(,\s*items=(?P\d+))?'
+_arg_skipitems = r'(,\s*skipitems=(?P\d+))?'
+_arg_titlesonly = r'(,\s*(?Ptitlesonly))?'
+_arg_editlink = r'(,\s*(?Peditlink))?'
+_args_re_pattern = r'^(?P[^,]+)(%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\s*(?P=+)\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)
+ results.sortByPagename()
+ 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'Recursive include of "%s" forbidden
' % (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('
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([
+ '',
+ 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}),
+ '
',
+ ])
+ # 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
diff --git a/wiki-lenny/local/macro/RandomQuoteNum.py b/wiki-lenny/local/macro/RandomQuoteNum.py
new file mode 100644
index 00000000..5b237729
--- /dev/null
+++ b/wiki-lenny/local/macro/RandomQuoteNum.py
@@ -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
+ @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
+
diff --git a/wiki-lenny/local/macro/SubscribeTo.py b/wiki-lenny/local/macro/SubscribeTo.py
new file mode 100644
index 00000000..5f6e6e34
--- /dev/null
+++ b/wiki-lenny/local/macro/SubscribeTo.py
@@ -0,0 +1,157 @@
+# -*- 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
+ 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'' + macro.formatter.icon ("info") + u' '
+ p_notice = u'
' + macro.formatter.icon ("info") + u' '
+ p_info = u'
' + 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'
'
+ if missingemail:
+ result += p_warning + _(u'Follwing users(s) missing an email address in their profile: %s') % u', '.join (missingemail.keys()) + u'
'
+ 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''
+ if addeduname:
+ result += p_info + _(u'Following new user(s) will be subscribed to %s before saving: %s') % (page_name, u', '.join (addeduname)) + u''
+ if subscribeduname:
+ result += p_info + _(u'Following user(s) are already subsribed to %s: %s') % (page_name, u', '.join (subscribeduname)) + u''
+ if faileduname:
+ result += p_warning + _(u'This user(s) failed to subscribe to: %s') % u', '.join (faileduname) + u''
+
+ if outofdateversion:
+ result += p_warning + _(u'Sorry, out-of-date version of SubscribeTo marcro installed! Functionality disabled until an update occurs.') + u''
+
+ if is_preview:
+ return result
+ return u''
+
diff --git a/wiki-lenny/local/macro/TableOfContents.py b/wiki-lenny/local/macro/TableOfContents.py
new file mode 100644
index 00000000..3242c7d4
--- /dev/null
+++ b/wiki-lenny/local/macro/TableOfContents.py
@@ -0,0 +1,186 @@
+# -*- coding: iso-8859-1 -*-
+"""
+ MoinMoin - TableOfContents Macro
+
+ Optional integer argument: maximal depth of listing.
+
+ @copyright: 2000, 2001, 2002 by Jürgen Hermann
+ @copyright: 2006 by Grégoire Détrez
+ @license: GNU GPL, see COPYING for details.
+"""
+
+import re, sha
+from MoinMoin import config, wikiutil
+
+#Dependencies = ["page"]
+Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks
+
+# from macro Include (keep in sync!)
+_arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))'
+_arg_level = r',\s*(?P\d*)'
+_arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?'
+_arg_to = r'(,\s*to=(?P[\'"])(?P.+?)(?P=tquote))?'
+_arg_sort = r'(,\s*sort=(?P(ascending|descending)))?'
+_arg_items = r'(,\s*items=(?P\d+))?'
+_arg_skipitems = r'(,\s*skipitems=(?P\d+))?'
+_arg_titlesonly = r'(,\s*(?Ptitlesonly))?'
+_arg_editlink = r'(,\s*(?Peditlink))?'
+_args_re_pattern = r'^(?P[^,]+)(%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)
+
+# from Include, too, but with extra htext group around header text
+_title_re = r"^(?P(?P=+)\s(?P.*)\s(?P=hmarker))$"
+
+class TableOfContents:
+ """
+ TOC Macro wraps all global variables without disturbing threads
+ """
+
+ def __init__(self, macro, args):
+ self.macro = macro
+
+ self.inc_re = re.compile(r"^\[\[Include\((.*)\)\]\]")
+ self.arg_re = re.compile(_args_re_pattern)
+ self.head_re = re.compile(_title_re) # single lines only
+ self.pre_re = re.compile(r'\{\{\{.+?\}\}\}', re.S)
+
+ self.result = []
+ self.baseindent = 0
+ self.indent = 0
+ self.lineno = 0
+ self.titles = {}
+
+ self.include_macro = None
+
+ try:
+ self.mindepth = int(macro.request.getPragma('section-numbers', 1))
+ except (ValueError, TypeError):
+ self.mindepth = 1
+
+ try:
+ self.maxdepth = max(int(args), 1)
+ except (ValueError, TypeError):
+ self.maxdepth = 99
+
+ def IncludeMacro(self, *args, **kwargs):
+ if self.include_macro is None:
+ self.include_macro = wikiutil.importPlugin(self.macro.request.cfg,
+ 'macro', "Include")
+ return self.pre_re.sub('',apply(self.include_macro, args, kwargs)).split('\n')
+
+ def run(self):
+ f = self.macro.formatter
+ r = self.result
+ try:
+ # Wikipedia-style table of contents
+ r.append(f.open('div', True, {'id': 'tableOfContents'}))
+ r.append(f.open('h2', False, {'id': 'toctitle'}))
+ r.append(f.text(u'Sommaire'))
+ r.append(f.close('h2', True))
+ r.append(f.open('div', True, {'id': 'tableOfContentsList'}))
+ except:
+ pass
+
+ self.process_lines(self.pre_re.sub('',self.macro.parser.raw).split('\n'),
+ self.macro.formatter.page.page_name)
+ # Close pending lists
+ for i in range(self.baseindent, self.indent):
+ self.result.append(self.macro.formatter.listitem(0))
+ self.result.append(self.macro.formatter.number_list(0))
+
+ try:
+ r.append(f.close('div', True))
+ r.append(f.close('div', True))
+ r.append(f.open('div', False, {'class': 'visualClear'}))
+ r.append(f.close('div', True))
+ r.append(f.open('script', False,
+ {'type': 'text/javascript',
+ 'src': '/wiki/common/toc/toc.js'}))
+ r.append(f.close('script', True))
+ except:
+ pass
+
+ return u''.join(r)
+
+ def process_lines(self, lines, pagename):
+ for line in lines:
+ # Filter out the headings
+ self.lineno = self.lineno + 1
+ match = self.inc_re.match(line)
+ if match:
+ # this is an [[Include()]] line.
+ # now parse the included page and do the work on it.
+
+ ## get heading and level from Include() line.
+ tmp = self.arg_re.match(match.group(1))
+ if tmp and tmp.group("name"):
+ inc_pagename = tmp.group("name")
+ else:
+ # no pagename? ignore it
+ continue
+ if tmp.group("heading"):
+ if tmp.group("htext"):
+ heading = tmp.group("htext")
+ else:
+ heading = inc_pagename
+ if tmp.group("level"):
+ level = int(tmp.group("level"))
+ else:
+ level = 1
+ inc_page_lines = ["%s %s %s" %("=" * level, heading, "=" * level)]
+ else:
+ inc_page_lines = []
+
+ inc_page_lines = inc_page_lines + self.IncludeMacro(self.macro, match.group(1), called_by_toc=1)
+
+ self.process_lines(inc_page_lines, inc_pagename)
+ else:
+ self.parse_line(line, pagename)
+
+ def parse_line(self, line, pagename):
+ # FIXME this also finds "headlines" in {{{ code sections }}}:
+ match = self.head_re.match(line)
+ if not match: return
+ title_text = match.group('htext').strip()
+ pntt = pagename + title_text
+ self.titles.setdefault(pntt, 0)
+ self.titles[pntt] += 1
+
+ # Get new indent level
+ newindent = len(match.group('hmarker'))
+ if newindent > self.maxdepth: return
+ if newindent < self.mindepth: return
+ if not self.indent:
+ self.baseindent = newindent - 1
+ self.indent = self.baseindent
+
+ # Close lists
+ for i in range(0,self.indent-newindent):
+ self.result.append(self.macro.formatter.listitem(0))
+ self.result.append(self.macro.formatter.number_list(0))
+
+ # Open Lists
+ for i in range(0,newindent-self.indent):
+ self.result.append(self.macro.formatter.number_list(1))
+
+ # Add the heading
+ unique_id = ''
+ if self.titles[pntt] > 1:
+ unique_id = '-%d' % (self.titles[pntt],)
+
+ if self.indent == newindent:
+ self.result.append(self.macro.formatter.listitem(0))
+
+ self.result.append(self.macro.formatter.listitem(1))
+ self.result.append(self.macro.formatter.anchorlink(1,
+ "head-" + sha.new(pntt.encode(config.charset)).hexdigest() + unique_id) +
+ self.macro.formatter.text(title_text) +
+ self.macro.formatter.anchorlink(0))
+
+ # Set new indent level
+ self.indent = newindent
+
+def execute(macro, args):
+ toc=TableOfContents(macro,args)
+ return toc.run()
diff --git a/wiki-lenny/local/macro/TerminalSsh.py b/wiki-lenny/local/macro/TerminalSsh.py
new file mode 100644
index 00000000..2017503e
--- /dev/null
+++ b/wiki-lenny/local/macro/TerminalSsh.py
@@ -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'' % (key, value))
+ return u'\n'.join(html)
+
+ def __init__(self, args):
+ self.parseArgs(args)
+
+ def run(self):
+ html = [
+ u'',
+ u'',
+ u'
',
+ ]
+ 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 o.run()