Attachment 'IncludeUpcoming-v0.1.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 degrade_titles(body, level):
59 rval = ""
60 for linea in body.split('\n'):
61 if len(linea) >=4:
62 if linea[0]=="=" and linea[-1]=="=":
63 rval = rval + level*"=" + linea + level*"="
64 continue
65 rval = rval + linea + '\n'
66 return rval
67
68 def execute(macro, text, args_re=re.compile(_args_re_pattern), title_re=re.compile(_title_re, re.M), called_by_toc=0):
69 import datetime
70 request = macro.request
71 _ = request.getText
72
73 # return immediately if getting links for the current page
74 if request.mode_getpagelinks:
75 return ''
76
77 # parse and check arguments
78 args = text and args_re.match(text)
79 if not args:
80 return (_sysmsg % ('error', _('Invalid include arguments "%s"!')) % (text,))
81
82 # prepare including page
83 result = []
84 print_mode = macro.form.has_key('action') and macro.form['action'][0] in ("print", "format")
85 this_page = macro.formatter.page
86 if not hasattr(this_page, '_macroInclude_pagelist'):
87 this_page._macroInclude_pagelist = {}
88
89 # get list of pages to include
90 inc_name = wikiutil.AbsPageName(request, this_page.page_name, args.group('name'))
91 pagelist = [inc_name]
92 todaystr = datetime.date.today()
93 #inc_name = u"^%s/%4d-%02d-.." % (inc_name, todaystr.year, todaystr.month)
94 inc_name = u"^%s/....-..-.." % inc_name
95 if inc_name.startswith("^"):
96 try:
97 inc_match = re.compile(inc_name)
98 except re.error:
99 pass # treat as plain page name
100 else:
101 # Get user filtered readable page list
102 pagelist = request.rootpage.getPageList(filter=inc_match.match)
103 tmppglist = []
104 todayint = (
105 10000*int(todaystr.year)+
106 100*int(todaystr.month)+
107 int(todaystr.day)
108 )
109 for mypg in pagelist:
110 pagedateint = (
111 10000*int(mypg[-10:-6])+
112 100*int(mypg[-5:-3])+
113 int(mypg[-2:])
114 )
115 if pagedateint >= todayint:
116 tmppglist.append(mypg)
117 pagelist = tmppglist
118
119 # sort and limit page list
120 pagelist.sort()
121 sort_dir = args.group('sort')
122 if sort_dir == 'descending':
123 pagelist.reverse()
124 max_items = args.group('items')
125 if max_items:
126 pagelist = pagelist[:int(max_items)]
127
128 skipitems = 0
129 if args.group("skipitems"):
130 skipitems = int(args.group("skipitems"))
131 titlesonly = args.group('titlesonly')
132 editlink = args.group('editlink')
133
134 # iterate over pages
135 for inc_name in pagelist:
136 if not request.user.may.read(inc_name):
137 continue
138 if this_page._macroInclude_pagelist.has_key(inc_name):
139 result.append(u'<p><strong class="error">Recursive include of "%s" forbidden</strong></p>' % (inc_name,))
140 continue
141 if skipitems:
142 skipitems -= 1
143 continue
144 fmt = macro.formatter.__class__(request, is_included=True)
145 fmt._base_depth = macro.formatter._base_depth
146 inc_page = Page(request, inc_name, formatter=fmt)
147 if not inc_page.exists():
148 continue
149 inc_page._macroInclude_pagelist = this_page._macroInclude_pagelist
150
151 # check for "from" and "to" arguments (allowing partial includes)
152 body = inc_page.get_raw_body() + '\n'
153 from_pos = 0
154 to_pos = -1
155 from_re = args.group('from')
156 if from_re:
157 try:
158 from_match = re.compile(from_re, re.M).search(body)
159 except re.error, e:
160 ##result.append("*** fe=%s ***" % e)
161 from_match = re.compile(re.escape(from_re), re.M).search(body)
162 if from_match:
163 from_pos = from_match.end()
164 else:
165 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % from_re)
166 to_re = args.group('to')
167 if to_re:
168 try:
169 to_match = re.compile(to_re, re.M).search(body, from_pos)
170 except re.error:
171 to_match = re.compile(re.escape(to_re), re.M).search(body, from_pos)
172 if to_match:
173 to_pos = to_match.start()
174 else:
175 result.append(_sysmsg % ('warning', 'Include: ' + _('Nothing found for "%s"!')) % to_re)
176
177 if titlesonly:
178 newbody = []
179 levelstack = []
180 for title, level in extract_titles(body[from_pos:to_pos], title_re):
181 if levelstack:
182 if level > levelstack[-1]:
183 result.append(macro.formatter.bullet_list(1))
184 levelstack.append(level)
185 else:
186 while levelstack and level < levelstack[-1]:
187 result.append(macro.formatter.definition_list(0))
188 levelstack.pop()
189 if not levelstack or level != levelstack[-1]:
190 result.append(macro.formatter.bullet_list(1))
191 levelstack.append(level)
192 else:
193 result.append(macro.formatter.definition_list(1))
194 levelstack.append(level)
195 result.append(macro.formatter.definition_term(1))
196 result.append(inc_name[-10:])
197 result.append(macro.formatter.definition_term(0))
198 result.append(macro.formatter.definition_desc(1))
199 result.append(inc_page.link_to(request, title))
200 result.append(macro.formatter.definition_desc(0))
201 while levelstack:
202 result.append(macro.formatter.bullet_list(0))
203 levelstack.pop()
204 continue
205
206 if from_pos or to_pos!=-1:
207 thisbody = body[from_pos:to_pos]
208 thisbody = degrade_titles(thisbody,2)
209 inc_page.set_raw_body(thisbody, modified=True)
210 ##result.append("*** f=%s t=%s ***" % (from_re, to_re))
211 ##result.append("*** f=%d t=%d ***" % (from_pos, to_pos))
212
213 if called_by_toc:
214 result.append(inc_page.get_raw_body())
215 continue
216
217 if not hasattr(request, "_Include_backto"):
218 request._Include_backto = this_page.page_name
219
220 # do headings
221 level = None
222 if args.group('heading') and args.group('hquote'):
223 heading = args.group('htext') or inc_page.split_title(request)
224 level = 1
225 if args.group('level'):
226 level = int(args.group('level'))
227 if print_mode:
228 result.append(macro.formatter.heading(1, level) +
229 macro.formatter.text(heading) +
230 macro.formatter.heading(0, level))
231 else:
232 import sha
233 from MoinMoin import config
234 # this heading id might produce duplicate ids,
235 # if the same page is included multiple times
236 # Encode stuf we feed into sha module.
237 pntt = (inc_name + heading).encode(config.charset)
238 hid = "head-" + sha.new(pntt).hexdigest()
239 request._page_headings.setdefault(pntt, 0)
240 request._page_headings[pntt] += 1
241 if request._page_headings[pntt] > 1:
242 hid += '-%d'%(request._page_headings[pntt],)
243 result.append(
244 #macro.formatter.heading(1, level, hid,
245 # icons=edit_icon.replace('<img ', '<img align="right" ')) +
246 macro.formatter.heading(1, level, id=hid) +
247 inc_page.link_to(request, heading, css_class="include-heading-link") +
248 macro.formatter.heading(0, level)
249 )
250
251 # set or increment include marker
252 this_page._macroInclude_pagelist[inc_name] = \
253 this_page._macroInclude_pagelist.get(inc_name, 0) + 1
254
255 # output the included page
256 strfile = StringIO.StringIO()
257 request.redirect(strfile)
258 try:
259 cid = request.makeUniqueID("Include_%s" % wikiutil.quoteWikinameURL(inc_page.page_name))
260 inc_page.send_page(request, content_only=1, content_id=cid,
261 omit_footnotes=True)
262 result.append(macro.formatter.table(1,style='width: 100%'))
263 result.append(macro.formatter.table_row(1,style='background-color: #ADB9CC'))
264 result.append(macro.formatter.table_cell(1))
265 result.append(inc_name[-10:])
266 result.append(macro.formatter.table_cell(0))
267 result.append(macro.formatter.table_row(0))
268 result.append(macro.formatter.table_row(1, style='background-color: #ffeeee'))
269 result.append(macro.formatter.table_cell(1))
270 result.append(strfile.getvalue())
271 result.append(macro.formatter.table_cell(0))
272 result.append(macro.formatter.table_row(0))
273 result.append(macro.formatter.table(0))
274 finally:
275 request.redirect()
276
277 # decrement or remove include marker
278 if this_page._macroInclude_pagelist[inc_name] > 1:
279 this_page._macroInclude_pagelist[inc_name] = \
280 this_page._macroInclude_pagelist[inc_name] - 1
281 else:
282 del this_page._macroInclude_pagelist[inc_name]
283
284 # if no heading and not in print mode, then output a helper link
285 if editlink and not (level or print_mode):
286 result.extend([
287 macro.formatter.div(1, css_class="include-link"),
288 inc_page.link_to(request, '[%s]' % (inc_name,), css_class="include-page-link"),
289 inc_page.link_to(request, '[%s]' % (_('edit'),), css_class="include-edit-link", querystr={'action': 'edit', 'backto': request._Include_backto}),
290 macro.formatter.div(0),
291 ])
292 # XXX page.link_to is wrong now, it escapes the edit_icon html as it escapes normal text
293
294 # return include text
295 return ''.join(result)
296
297 # 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.You are not allowed to attach a file to this page.