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