Attachment 'IncludeUpcoming-v0.0.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - Include macro
   4 
   5     This macro includes the formatted content of the given page(s). See
   6 
   7         http://purl.net/wiki/moinmaster/HelpOnMacros/Include
   8 
   9     for detailed docs.
  10     
  11     @copyright: 2000-2004 by Jürgen Hermann <jh@web.de>
  12     @copyright: 2000-2001 by Richard Jones <richard@bizarsoftware.com.au>
  13     @license: GNU GPL, see COPYING for details.
  14 
  15     This macro has been slightly modified for displaying upcoming events.
  16     Look for updates here:
  17 
  18        http://moinmoin.wikiwikiweb.de/JesusFernandez/IncludeUpcoming
  19 """
  20 
  21 #Dependencies = ["pages"] # included page
  22 Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks
  23 
  24 import re, StringIO
  25 from MoinMoin import wikiutil
  26 from MoinMoin.Page import Page
  27 from MoinMoin.util import web
  28 
  29 _sysmsg = '<p><strong class="%s">%s</strong></p>'
  30 
  31 ## keep in sync with TableOfContents macro!
  32 _arg_heading = r'(?P<heading>,)\s*(|(?P<hquote>[\'"])(?P<htext>.+?)(?P=hquote))'
  33 _arg_level = r',\s*(?P<level>\d*)'
  34 _arg_from = r'(,\s*from=(?P<fquote>[\'"])(?P<from>.+?)(?P=fquote))?'
  35 _arg_to = r'(,\s*to=(?P<tquote>[\'"])(?P<to>.+?)(?P=tquote))?'
  36 _arg_sort = r'(,\s*sort=(?P<sort>(ascending|descending)))?'
  37 _arg_items = r'(,\s*items=(?P<items>\d+))?'
  38 _arg_skipitems = r'(,\s*skipitems=(?P<skipitems>\d+))?'
  39 _arg_titlesonly = r'(,\s*(?P<titlesonly>titlesonly))?'
  40 _arg_editlink = r'(,\s*(?P<editlink>editlink))?'
  41 _args_re_pattern = r'^(?P<name>[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % (
  42     _arg_heading, _arg_level, _arg_from, _arg_to, _arg_sort, _arg_items,
  43     _arg_skipitems, _arg_titlesonly, _arg_editlink)
  44 
  45 _title_re = r"^(?P<heading>\s*(?P<hmarker>=+)\s.*\s(?P=hmarker))$"
  46 
  47 def extract_titles(body, title_re):
  48     titles = []
  49     for title, _ in title_re.findall(body):
  50         h = title.strip()
  51         level = 1
  52         while h[level:level+1] == '=': level = level+1
  53         depth = min(5,level)
  54         title_text = h[level:-level].strip()
  55         titles.append((title_text, level))
  56     return titles
  57 
  58 def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0):
  59     import datetime
  60     request = macro.request
  61     _ = request.getText
  62 
  63     # return immediately if getting links for the current page
  64     if request.mode_getpagelinks:
  65         return ''
  66 
  67     # parse and check arguments
  68     args = text and args_re.match(text)
  69     if not args:
  70         return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,))
  71 
  72     # prepare including page
  73     result = []
  74     print_mode = macro.form.has_key('action') and macro.form['action'][0] in ("print", "format")
  75     this_page = macro.formatter.page
  76     if not hasattr(this_page, '_macroInclude_pagelist'):
  77         this_page._macroInclude_pagelist = {}
  78 
  79     # get list of pages to include
  80     inc_name = wikiutil.AbsPageName(request, this_page.page_name, args.group('name'))
  81     pagelist = [inc_name]
  82     todaystr = datetime.date.today()
  83     #inc_name = u"^%s/%4d-%02d-.." % (inc_name, todaystr.year, todaystr.month)
  84     inc_name = u"^%s/....-..-.." % inc_name
  85     if inc_name.startswith("^"):
  86         try:
  87             inc_match = re.compile(inc_name)
  88         except re.error:
  89             pass # treat as plain page name
  90         else:
  91             # Get user filtered readable page list
  92             pagelist = request.rootpage.getPageList(filter=inc_match.match)
  93             tmppglist = []
  94             todayint = (
  95                10000*int(todaystr.year)+
  96                  100*int(todaystr.month)+
  97                      int(todaystr.day)
  98             )
  99             for mypg in pagelist:
 100                pagedateint = (
 101                  10000*int(mypg[-10:-6])+
 102                    100*int(mypg[-5:-3])+
 103                        int(mypg[-2:])
 104                )
 105                if pagedateint >= todayint:
 106                  tmppglist.append(mypg)
 107             pagelist = tmppglist
 108 
 109     # sort and limit page list
 110     pagelist.sort()
 111     sort_dir = args.group('sort')
 112     if sort_dir == 'descending':
 113         pagelist.reverse()
 114     max_items = args.group('items')
 115     if max_items:
 116         pagelist = pagelist[:int(max_items)]
 117 
 118     skipitems = 0
 119     if args.group("skipitems"):
 120         skipitems = int(args.group("skipitems"))
 121     titlesonly = args.group('titlesonly')
 122     editlink = args.group('editlink')
 123 
 124     # iterate over pages
 125     for inc_name in pagelist:
 126         if not request.user.may.read(inc_name):
 127             continue
 128         if this_page._macroInclude_pagelist.has_key(inc_name):
 129             result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name,))
 130             continue
 131         if skipitems:
 132             skipitems -= 1
 133             continue
 134         fmt = macro.formatter.__class__(request, is_included=True)
 135         fmt._base_depth = macro.formatter._base_depth
 136         inc_page = Page(request, inc_name, formatter=fmt)
 137         if not inc_page.exists():
 138             continue
 139         inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
 140 
 141         # check for "from" and "to" arguments (allowing partial includes)
 142         body = inc_page.get_raw_body() + '\n'
 143         from_pos = 0
 144         to_pos = -1
 145         from_re = args.group('from')
 146         if from_re:
 147             try:
 148                 from_match = re.compile(from_re, re.M).search(body)
 149             except re.error, e:
 150                 ##result.append("*** fe=%s ***" % e)
 151                 from_match = re.compile(re.escape(from_re), re.M).search(body)
 152             if from_match:
 153                 from_pos = from_match.end()
 154             else:
 155                 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
 156         to_re = args.group('to')
 157         if to_re:
 158             try:
 159                 to_match = re.compile(to_re, re.M).search(body, from_pos)
 160             except re.error:
 161                 to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
 162             if to_match:
 163                 to_pos = to_match.start()
 164             else:
 165                 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
 166 
 167         if titlesonly:
 168             newbody = []
 169             levelstack = []
 170             for title, level in extract_titles(body[from_pos:to_pos], title_re):
 171                 if levelstack:
 172                     if level > levelstack[-1]:
 173                         result.append(macro.formatter.bullet_list(1))
 174                         levelstack.append(level)
 175                     else:
 176                         while levelstack and level < levelstack[-1]:
 177                             result.append(macro.formatter.bullet_list(0))
 178                             levelstack.pop()
 179                         if not levelstack or level != levelstack[-1]:
 180                             result.append(macro.formatter.bullet_list(1))
 181                             levelstack.append(level)
 182                 else:
 183                     result.append(macro.formatter.bullet_list(1))
 184                     levelstack.append(level)
 185                 result.append(macro.formatter.listitem(1))
 186                 result.append(inc_page.link_to(request, title))
 187                 result.append(macro.formatter.listitem(0))
 188             while levelstack:
 189                 result.append(macro.formatter.bullet_list(0))
 190                 levelstack.pop()
 191             continue
 192 
 193         if from_pos or to_pos != -1:
 194             inc_page.set_raw_body(body[from_pos:to_pos], modified=True)
 195         ##result.append("*** f=%s t=%s ***" % (from_re, to_re))
 196         ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
 197 
 198         if called_by_toc:
 199             result.append(inc_page.get_raw_body())
 200             continue
 201 
 202         if not hasattr(request, "_Include_backto"):
 203             request._Include_backto = this_page.page_name
 204         
 205         # do headings
 206         level = None
 207         if args.group('heading') and args.group('hquote'):
 208             heading = args.group('htext') or inc_page.split_title(request)
 209             level = 1
 210             if args.group('level'):
 211                 level = int(args.group('level'))
 212             if print_mode:
 213                 result.append(macro.formatter.heading(1, level) +
 214                               macro.formatter.text(heading) +
 215                               macro.formatter.heading(0, level))
 216             else:
 217                 import sha
 218                 from MoinMoin import config
 219                 # this heading id might produce duplicate ids,
 220                 # if the same page is included multiple times
 221                 # Encode stuf we feed into sha module.
 222                 pntt = (inc_name + heading).encode(config.charset)
 223                 hid = "head-" + sha.new(pntt).hexdigest()
 224                 request._page_headings.setdefault(pntt, 0)
 225                 request._page_headings[pntt] += 1
 226                 if request._page_headings[pntt] > 1:
 227                     hid += '-%d'%(request._page_headings[pntt],)
 228                 result.append(
 229                     #macro.formatter.heading(1, level, hid,
 230                     #    icons=edit_icon.replace('<img ', '<img align="right" ')) +
 231                     macro.formatter.heading(1, level, id=hid) +
 232                     inc_page.link_to(request, heading, css_class="include-heading-link") +
 233                     macro.formatter.heading(0, level)
 234                 )
 235 
 236         # set or increment include marker
 237         this_page._macroInclude_pagelist[inc_name] = \
 238             this_page._macroInclude_pagelist.get(inc_name, 0) + 1
 239 
 240         # output the included page
 241         strfile = StringIO.StringIO()
 242         request.redirect(strfile)
 243         try:
 244             cid = request.makeUniqueID("Include_%s" % wikiutil.quoteWikinameURL(inc_page.page_name))
 245             inc_page.send_page(request, content_only=1, content_id=cid,
 246                                omit_footnotes=True)
 247             result.append(strfile.getvalue())
 248         finally:
 249             request.redirect()
 250 
 251         # decrement or remove include marker
 252         if this_page._macroInclude_pagelist[inc_name] > 1:
 253             this_page._macroInclude_pagelist[inc_name] = \
 254                 this_page._macroInclude_pagelist[inc_name] - 1
 255         else:
 256             del this_page._macroInclude_pagelist[inc_name]
 257 
 258         # if no heading and not in print mode, then output a helper link
 259         if editlink and not (level or print_mode):
 260             result.extend([
 261                 macro.formatter.div(1, css_class="include-link"),
 262                 inc_page.link_to(request, '[%s]' % (inc_name,), css_class="include-page-link"),
 263                 inc_page.link_to(request, '[%s]' % (_('edit'),), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
 264                 macro.formatter.div(0),
 265             ])
 266         # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
 267 
 268     # return include text
 269     return ''.join(result)
 270 
 271 # vim:ts=4:sw=4:et

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2006-11-29 09:44:25, 10.7 KB) [[attachment:IncludeUpcoming-v0.0.py]]
  • [get | view] (2006-12-02 15:22:52, 11.9 KB) [[attachment:IncludeUpcoming-v0.1.py]]
  • [get | view] (2008-03-05 19:50:09, 12.0 KB) [[attachment:IncludeUpcoming-v0.2.py]]
  • [get | view] (2008-03-07 21:49:48, 12.0 KB) [[attachment:IncludeUpcoming2-v0.3.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.