1 """
   2     MoinMoin - IncludeUrl macro
   3 
   4     Copyright (c) 2000, 2001, 2002, 2003 by Jürgen Hermann <jh@web.de>
   5     Copyright (c) 2000, 2001 by Richard Jones <richard@bizarsoftware.com.au>
   6     Copyright (c) 2001-2003 by Conectiva, Inc.
   7     All rights reserved, see COPYING for details.
   8 
   9     This macro includes the formatted content of the given url, following
  10     recursive includes if encountered. It has been implemented by
  11     Gustavo Niemeyer <niemeyer@conectiva.com> by modifying the code of
  12     Include macro. Check
  13 
  14         http://purl.net/wiki/moinmaster/HelpOnMacros/Include
  15 
  16     for detailed docs.
  17     
  18     $Id: Include.py,v 1.21 2003/04/25 16:15:17 jhermann Exp $
  19 """
  20 
  21 import sys, re, cStringIO
  22 from MoinMoin import config, user, wikiutil
  23 from MoinMoin.Page import Page
  24 
  25 
  26 # CNC:2003-06-05 {
  27 
  28 __version__ = "2.0"
  29 
  30 import urllib
  31 try:
  32     allowed_schemes = config.includeurl_schemes
  33 except AttributeError:
  34     allowed_schemes = ["http", "https", "ftp"]
  35 
  36 class PageUrl(Page):
  37     def split_title(self):
  38         return self.page_name
  39 
  40     def exists(self):
  41         return 1
  42 
  43     def link_to(self, text=None, querystr=None, anchor=None, **kw):
  44         text = text or self.split_title()
  45         return '<a href="%s">%s</a>' % (self.page_name, text)
  46 
  47     def get_raw_body(self):
  48         """Load the raw markup from the page file"""
  49         if self._raw_body is not None:
  50             return self._raw_body
  51         try:
  52             file = urllib.urlopen(self.page_name)
  53         except IOError, er:
  54             return ""
  55         try:
  56             self.set_raw_body(file.read())
  57         finally:
  58             file.close()
  59         return self._raw_body
  60 
  61 # CNC }
  62 
  63 _sysmsg = '<p><strong class="%s">%s</strong></p>'
  64 _arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
  65 _arg_level = r',\s*(?P<level>\d+)'
  66 _arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
  67 _arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
  68 _arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
  69 _arg_items = r'(,\s*items=(?P<items>\d+))?'
  70 _args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s)?$' % (
  71     _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items)
  72 
  73 def execute(macro, text, args_re=re.compile(_args_re_pattern)):
  74     _ = macro.request.getText
  75 
  76     # return immediately if getting links for the current page
  77     if macro.request.mode_getpagelinks:
  78         return ''
  79 
  80     # parse and check arguments
  81     args = args_re.match(text)
  82     if not args:
  83         return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,))
  84 
  85     # prepare including page
  86     result = []
  87     print_mode = macro.form.has_key('action') and macro.form['action'].value == "print"
  88     this_page = macro.formatter.page
  89     if not hasattr(this_page, '_macroInclude_pagelist'):
  90         this_page._macroInclude_pagelist = {}
  91 
  92     # get list of pages to include
  93     inc_name = wikiutil.AbsPageName(macro.request, this_page.page_name, args.group('name'))
  94     pagelist = [inc_name]
  95     # CNC:2003-06-05
  96     """
  97     if inc_name.startswith("^"):
  98         try:
  99             inc_match = re.compile(inc_name)
 100         except re.error:
 101             pass # treat as plain page name
 102         else:
 103             pagelist = wikiutil.getPageList(config.text_dir)
 104             pagelist = filter(inc_match.match, pagelist)
 105     """ 
 106 
 107     # sort and limit page list
 108     pagelist.sort()
 109     sort_dir = args.group('sort')
 110     if sort_dir == 'descending':
 111         pagelist.reverse()
 112     max_items = args.group('items')
 113     if max_items:
 114         pagelist = pagelist[:int(max_items)]
 115 
 116     # iterate over pages
 117     for inc_name in pagelist:
 118         # CNC:2003-06-05
 119         scheme = urllib.splittype(inc_name)[0]
 120         if scheme not in allowed_schemes:
 121             result.append('<p><strong class="error">Scheme "%s" not allowed for IncludeUrl</strong></p>' % scheme)
 122             continue # CNC:2003-06-05
 123 
 124         if this_page._macroInclude_pagelist.has_key(inc_name):
 125             result.append('<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name,))
 126             continue # CNC:2003-06-05
 127         # CNC:2003-06-05
 128         inc_page = PageUrl(inc_name, formatter=macro.formatter.__class__(macro.request))
 129         inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
 130 
 131         # check for "from" and "to" arguments (allowing partial includes)
 132         body = inc_page.get_raw_body() + '\n'
 133         from_pos = 0
 134         to_pos = -1
 135         from_re = args.group('from')
 136         if from_re:
 137             try:
 138                 from_match = re.compile(from_re, re.M).search(body)
 139             except re.error, e:
 140                 ##result.append("*** fe=%s ***" % e)
 141                 from_match = re.compile(re.escape(from_re), re.M).search(body)
 142             if from_match:
 143                 from_pos = from_match.end()
 144             else:
 145                 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
 146         to_re = args.group('to')
 147         if to_re:
 148             try:
 149                 to_match = re.compile(to_re, re.M).search(body, from_pos)
 150             except re.error:
 151                 to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
 152             if to_match:
 153                 to_pos = to_match.start()
 154             else:
 155                 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
 156         if from_pos or to_pos != -1:
 157             inc_page.set_raw_body(body[from_pos:to_pos])
 158         ##result.append("*** f=%s t=%s ***" % (from_re, to_re))
 159         ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
 160 
 161         # CNC:2003-06-05
 162         edit_icon = ""
 163         """
 164         # edit icon
 165         edit_icon = inc_page.link_to(
 166             macro.formatter.image(border=0, hspace=2,
 167                 src="%s/img/moin-edit.gif" % (config.url_prefix,)),
 168             css_class="include-edit-link",
 169             querystr={'action': 'edit', 'backto': this_page.page_name})
 170         """
 171 
 172         # do headings
 173         level = None
 174         if args.group('htext'):
 175             heading = args.group('htext') or inc_page.split_title()
 176             level = 1
 177             if args.group('level'):
 178                 level = int(args.group('level'))
 179             if print_mode:
 180                 result.append(macro.formatter.heading(level, heading))
 181             else:
 182                 result.append(macro.formatter.heading(level,
 183                     inc_page.link_to(heading, css_class="include-heading-link"),
 184                     icons=edit_icon.replace('<img ', '<img align="right" ')
 185                                    .replace('&amp;', '&')))
 186 
 187         # set or increment include marker
 188         this_page._macroInclude_pagelist[inc_name] = \
 189             this_page._macroInclude_pagelist.get(inc_name, 0) + 1
 190 
 191         # output the included page
 192         stdout = sys.stdout
 193         sys.stdout = cStringIO.StringIO()
 194         try:
 195             inc_page.send_page(macro.request, content_only=1)
 196             result.append(sys.stdout.getvalue())
 197         finally:
 198             sys.stdout = stdout
 199 
 200         # decrement or remove include marker
 201         if this_page._macroInclude_pagelist[inc_name] > 1:
 202             this_page._macroInclude_pagelist[inc_name] = \
 203                 this_page._macroInclude_pagelist[inc_name] - 1
 204         else:
 205             del this_page._macroInclude_pagelist[inc_name]
 206 
 207         # if no heading and not in print mode, then output a helper link
 208         if not (level or print_mode):
 209             result.extend([
 210                 '<div class="include-link">',
 211                 inc_page.link_to('[%s]' % (inc_name,), css_class="include-page-link"),
 212                 edit_icon,
 213                 '</div>',
 214             ])
 215 
 216     # return include text
 217     return ''.join(result)
 218 
 219 # vim:sw=4:ts=4:et

MoinMoin: macro/IncludeUrl.py (last edited 2007-10-29 19:09:26 by localhost)