Attachment 'MonthCalendarHack-1.0.py'
Download 1 """
2 MoinMoin - MonthCalendarHack Macro
3
4 This macro is a hack of the MonthCalendar one delivered with MoinMoin, to enable subpages titles in form
5
6 = title =
7
8 or
9
10 '''title'''
11
12 You can use this macro to put a month's calendar page on a Wiki page.
13
14 The days are links to Wiki pages following this naming convention:
15 BasePageName/year-month-day
16
17 @copyright: 2002-2005 by Thomas Waldmann <ThomasWaldmann@gmx.de>
18 @copyright: 2007- by Eric Veiras Galisson
19 @license: GNU GPL - see http://www.gnu.org/licenses/old-licenses/gpl-1.0.txt for details.
20
21 Revisions:
22 * first revision without a number (=1.0):
23 * work with MoinMoin 1.5
24
25 Usage:
26 [[MonthCalendarHack(BasePage,year,month,monthoffset,monthoffset2,height6)]]
27
28 each parameter can be empty and then defaults to currentpage or currentdate or monthoffset=0
29
30 Samples (paste that to one of your pages for a first try):
31
32 Calendar of current month for current page:
33 [[MonthCalendar]]
34
35 Calendar of last month:
36 [[MonthCalendarHack(,,,-1)]]
37
38 Calendar of next month:
39 [[MonthCalendarHack(,,,+1)]]
40
41 Calendar of Page SampleUser, this years december:
42 [[MonthCalendarHack(SampleUser,,12)]]
43
44 Calendar of current Page, this years december:
45 [[MonthCalendarHack(,,12)]]
46
47 Calendar of December, 2001:
48 [[MonthCalendarHack(,2001,12)]]
49
50 Calendar of the month two months after December, 2001
51 (maybe doesn't make much sense, but is possible)
52 [[MonthCalendarHack(,2001,12,+2)]]
53
54 Calendar of year 2002 (every month padded to height of 6):
55 ||||||Year 2002||
56 ||[[MonthCalendarHack(,2002,1,,,1)]]||[[MonthCalendarHack(,2002,2,,,1)]]||[[MonthCalendarHack(,2002,3,,,1)]]||
57 ||[[MonthCalendarHack(,2002,4,,,1)]]||[[MonthCalendarHack(,2002,5,,,1)]]||[[MonthCalendarHack(,2002,6,,,1)]]||
58 ||[[MonthCalendarHack(,2002,7,,,1)]]||[[MonthCalendarHack(,2002,8,,,1)]]||[[MonthCalendarHack(,2002,9,,,1)]]||
59 ||[[MonthCalendarHack(,2002,10,,,1)]]||[[MonthCalendarHack(,2002,11,,,1)]]||[[MonthCalendarHack(,2002,12,,,1)]]||
60
61 Current calendar of me, also showing entries of A and B:
62 [[MonthCalendarHack(MyPage*TestUserA*TestUserB)]]
63
64 SubPage calendars:
65 [[MonthCalendarHack(MyName/CalPrivate)]]
66 [[MonthCalendarHack(MyName/CalBusiness)]]
67 [[MonthCalendarHack(MyName/CalBusiness*MyName/CalPrivate)]]
68
69
70 Anniversary Calendars: (no year data)
71 [[MonthCalendarHack(Yearly,,,+1,,6,1)]]
72
73 This creates calendars of the format Yearly/MM-DD
74 By leaving out the year, you can set birthdays, and anniversaries in this
75 calendar and not have to re-enter each year.
76
77 This creates a calendar which uses MonthCalendarTemplate for directly editing
78 nonexisting day pages:
79 [[MonthCalendarHack(,,,,,,MonthCalendarTemplate)]]
80 """
81
82 Dependencies = ['namespace','time']
83
84 from MoinMoin import wikiutil
85 from MoinMoin.Page import Page
86 import re, calendar, time
87
88 # The following line sets the calendar to have either Sunday or Monday as
89 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
90 # valid here. All other values will not make good calendars.
91 # If set to Sunday, the calendar is displayed at "March 2003" vs. "2003 / 3" also.
92 # XXX change here ----------------vvvvvv
93 calendar.setfirstweekday(calendar.MONDAY)
94
95 def cliprgb(r,g,b): # don't use 255!
96 if r < 0: r=0
97 if r > 254: r=254
98 if b < 0: b=0
99 if b > 254: b=254
100 if g < 0: g=0
101 if g > 254: g=254
102 return r, g, b
103
104 def yearmonthplusoffset(year, month, offset):
105 month = month+offset
106 # handle offset and under/overflows - quick and dirty, yes!
107 while month < 1:
108 month = month + 12
109 year = year - 1
110 while month > 12:
111 month = month - 12
112 year = year + 1
113 return year, month
114
115 def parseargs(args, defpagename, defyear, defmonth, defoffset, defoffset2, defheight6, defanniversary, deftemplate):
116 strpagename = args.group('basepage')
117 if strpagename:
118 parmpagename = wikiutil.unquoteWikiname(strpagename)
119 else:
120 parmpagename = defpagename
121 # multiple pagenames separated by "*" - split into list of pagenames
122 parmpagename = re.split(r'\*', parmpagename)
123
124 stryear = args.group('year')
125 if stryear:
126 parmyear = int(stryear)
127 else:
128 parmyear = defyear
129
130 strmonth = args.group('month')
131 if strmonth:
132 parmmonth = int(strmonth)
133 else:
134 parmmonth = defmonth
135
136 stroffset = args.group('offset')
137 if stroffset:
138 parmoffset = int(stroffset)
139 else:
140 parmoffset = defoffset
141
142 stroffset2 = args.group('offset2')
143 if stroffset2:
144 parmoffset2 = int(stroffset2)
145 else:
146 parmoffset2 = defoffset2
147
148 strheight6 = args.group('height6')
149 if strheight6:
150 parmheight6 = int(strheight6)
151 else:
152 parmheight6 = defheight6
153
154 stranniversary = args.group('anniversary')
155 if stranniversary:
156 parmanniversary = int(stranniversary)
157 else:
158 parmanniversary = defanniversary
159
160 strtemplate = args.group('template')
161 if strtemplate:
162 parmtemplate = wikiutil.unquoteWikiname(strtemplate)
163 else:
164 parmtemplate = deftemplate
165 return parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, parmanniversary, parmtemplate
166
167 # FIXME: vvvvvv is there a better way for matching a pagename ?
168 _arg_basepage = r'\s*(?P<basepage>[^, ]+)?\s*'
169 _arg_year = r',\s*(?P<year>\d+)?\s*'
170 _arg_month = r',\s*(?P<month>\d+)?\s*'
171 _arg_offset = r',\s*(?P<offset>[+-]?\d+)?\s*'
172 _arg_offset2 = r',\s*(?P<offset2>[+-]?\d+)?\s*'
173 _arg_height6 = r',\s*(?P<height6>[+-]?\d+)?\s*'
174 _arg_anniversary = r',\s*(?P<anniversary>[+-]?\d+)?\s*'
175 _arg_template = r',\s*(?P<template>[^, ]+)?\s*' # XXX see basepage comment
176 _args_re_pattern = r'^(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?$' % \
177 (_arg_basepage,_arg_year,_arg_month, \
178 _arg_offset,_arg_offset2,_arg_height6,_arg_anniversary,_arg_template)
179
180
181 def execute(macro, text):
182 request = macro.request
183 formatter = macro.formatter
184 _ = request.getText
185
186 # return immediately if getting links for the current page
187 if request.mode_getpagelinks:
188 return ''
189
190 args_re = re.compile(_args_re_pattern)
191
192 currentyear, currentmonth, currentday, h, m, s, wd, yd, ds = request.user.getTime(time.time())
193 thispage = formatter.page.page_name
194 # does the url have calendar params (= somebody has clicked on prev/next links in calendar) ?
195 if macro.form.has_key('calparms'):
196 text2 = macro.form['calparms'][0]
197 args2 = args_re.match(text2)
198 if not args2:
199 return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar calparms "%s"!')) % (text2,)
200 else:
201 has_calparms = 1 # yes!
202 cparmpagename, cparmyear, cparmmonth, cparmoffset, cparmoffset2, cparmheight6, cparmanniversary, cparmtemplate = \
203 parseargs(args2, thispage, currentyear, currentmonth, 0, 0, 0, 0, '')
204 else:
205 has_calparms = 0
206
207 if text is None: # macro call without parameters
208 parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, anniversary, parmtemplate = \
209 [thispage], currentyear, currentmonth, 0, 0, 0, 0, ''
210 else:
211 # parse and check arguments
212 args = args_re.match(text)
213 if not args:
214 return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar arguments "%s"!')) % (text,)
215 else:
216 parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, anniversary, parmtemplate = \
217 parseargs(args, thispage, currentyear, currentmonth, 0, 0, 0, 0, '')
218
219 # does url have calendar params and is THIS the right calendar to modify (we can have multiple
220 # calendars on the same page)?
221 #if has_calparms and (cparmpagename,cparmyear,cparmmonth,cparmoffset) == (parmpagename,parmyear,parmmonth,parmoffset):
222
223 # move all calendars when using the navigation:
224 if has_calparms and cparmpagename == parmpagename:
225 year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset + cparmoffset2)
226 parmoffset2 = cparmoffset2
227 parmtemplate = cparmtemplate
228 else:
229 year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset)
230
231 # get the calendar
232 monthcal = calendar.monthcalendar(year, month)
233
234 # european / US differences
235 months = ('January','February','March','April','May','June','July','August','September','October','November','December')
236 # Set things up for Monday or Sunday as the first day of the week
237 if calendar.firstweekday() == calendar.MONDAY:
238 wkend = (5, 6)
239 wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
240 if calendar.firstweekday() == calendar.SUNDAY:
241 wkend = (0, 6)
242 wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
243
244 colorstep = 85
245 p = Page(request, thispage)
246 qpagenames = '*'.join(map(wikiutil.quoteWikinameURL, parmpagename))
247 qtemplate = wikiutil.quoteWikinameURL(parmtemplate)
248 querystr = "calparms=%%s,%d,%d,%d,%%d,%%s" % (parmyear, parmmonth, parmoffset)
249 prevlink = p.url(request, querystr % (qpagenames, parmoffset2 - 1, qtemplate), 0)
250 nextlink = p.url(request, querystr % (qpagenames, parmoffset2 + 1, qtemplate), 0)
251 prevylink = p.url(request, querystr % (qpagenames, parmoffset2 - 12, qtemplate), 0)
252 nextylink = p.url(request, querystr % (qpagenames, parmoffset2 + 12, qtemplate), 0)
253 prevmonth = formatter.url(1, prevlink, 'cal-link') + '<' + formatter.url(0)
254 nextmonth = formatter.url(1, nextlink, 'cal-link') + '>' + formatter.url(0)
255 prevyear = formatter.url(1, prevylink, 'cal-link') + '<<' + formatter.url(0)
256 nextyear = formatter.url(1, nextylink, 'cal-link') + '>>' + formatter.url(0)
257
258 if parmpagename != [thispage]:
259 pagelinks = ''
260 r, g, b = (255, 0, 0)
261 l = len(parmpagename[0])
262 steps = len(parmpagename)
263 maxsteps = (255 / colorstep)
264 if steps > maxsteps:
265 steps = maxsteps
266 chstep = int(l / steps)
267 st = 0
268 while st < l:
269 ch = parmpagename[0][st:st+chstep]
270 r, g, b = cliprgb(r, g, b)
271 pagelinks = pagelinks + '<a style="%s" href="%s">%s</a>' % \
272 ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
273 (r,g,b), Page(request, parmpagename[0]).url(request), ch)
274 r, g, b = (r, g+colorstep, b)
275 st = st + chstep
276 r, g, b = (255-colorstep, 255, 255-colorstep)
277 for page in parmpagename[1:]:
278 pagelinks = pagelinks + '*<a style="%s" href="%s">%s</a>' % \
279 ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
280 (r,g,b), Page(request, page).url(request), page)
281 showpagename = ' %s<BR>\n' % pagelinks
282 else:
283 showpagename = ''
284 if calendar.firstweekday() == calendar.SUNDAY:
285 resth1 = ' <th colspan="7" class="cal-header">\n' \
286 '%s' \
287 ' %s %s <b> %s %s</b> %s\n %s\n' \
288 ' </th>\n' % (showpagename, prevyear, prevmonth, months[month-1], str(year), nextmonth, nextyear)
289 if calendar.firstweekday() == calendar.MONDAY:
290 resth1 = ' <th colspan="7" class="cal-header">\n' \
291 '%s' \
292 ' %s %s <b> %s / %s</b> %s\n %s\n' \
293 ' </th>\n' % (showpagename, prevyear, prevmonth, str(year), month, nextmonth, nextyear)
294 restr1 = ' <tr>\n%s </tr>\n' % resth1
295
296 r7 = range(7)
297 restd2 = []
298 for wkday in r7:
299 wday = _(wkdays[wkday])
300 if wkday in wkend:
301 cssday = "cal-weekend"
302 else:
303 cssday = "cal-workday"
304 restd2.append(' <td class="%s" width="14%%">%s</td>\n' % (cssday, wday))
305 restr2 = ' <tr>\n%s </tr>\n' % "".join(restd2)
306
307 if parmheight6:
308 while len(monthcal) < 6:
309 monthcal = monthcal + [[0,0,0,0,0,0,0]]
310
311 maketip_js = []
312 restrn = []
313 for week in monthcal:
314 restdn = []
315 for wkday in r7:
316 day = week[wkday]
317 if not day:
318 restdn.append(' <td class="cal-invalidday"> </td>\n')
319 else:
320 page = parmpagename[0]
321 if anniversary:
322 link = "%s/%02d-%02d" % (page, month, day)
323 else:
324 link = "%s/%4d-%02d-%02d" % (page, year, month, day)
325 daypage = Page(request, link)
326 if daypage.exists() and request.user.may.read(link):
327 csslink = "cal-usedday"
328 query = {}
329 r, g, b, u = (255, 0, 0, 1)
330 daycontent = daypage.get_raw_body()
331 header1_re = re.compile(r"^\s*('''\s*(.*)\s*'''|=\s+(.*)\s+=)\s*$", re.MULTILINE) # re.UNICODE
332 titletext = []
333 for match in header1_re.finditer(daycontent):
334 if match:
335 if match.group(2) == None:
336 title = match.group(3)
337 else:
338 title = match.group(2)
339 title = wikiutil.escape(title).replace("'","\\'")
340 titletext.append(title)
341 tipname = link
342 tiptitle = link
343 tiptext = '<br>'.join(titletext)
344 maketip_js.append("maketip('%s','%s','%s');" % (tipname, tiptitle, tiptext))
345 onmouse = {'onMouseOver': "tip('%s')" % tipname,
346 'onMouseOut': "untip()"}
347 else:
348 csslink = "cal-emptyday"
349 if parmtemplate:
350 query = {'action': 'edit', 'template': parmtemplate}
351 else:
352 query = {}
353 r, g, b, u = (255, 255, 255, 0)
354 if wkday in wkend:
355 csslink = "cal-weekend"
356 onmouse = {}
357 for otherpage in parmpagename[1:]:
358 otherlink = "%s/%4d-%02d-%02d" % (otherpage, year, month, day)
359 otherdaypage = Page(request, otherlink)
360 if otherdaypage.exists():
361 csslink = "cal-usedday"
362 if u == 0:
363 r, g, b = (r-colorstep, g, b-colorstep)
364 else:
365 r, g, b = (r, g+colorstep, b)
366 r, g, b = cliprgb(r, g, b)
367 style = 'background-color:#%02x%02x%02x' % (r, g, b)
368 fmtlink = formatter.url(1, daypage.url(request, query), csslink, **onmouse) + str(day) + formatter.url(0)
369 if day == currentday and month == currentmonth and year == currentyear:
370 cssday = "cal-today"
371 fmtlink = "<b>%s</b>" % fmtlink # for browser with CSS probs
372 else:
373 cssday = "cal-nottoday"
374 restdn.append(' <td style="%s" class="%s">%s</td>\n' % (style, cssday, fmtlink))
375 restrn.append(' <tr>\n%s </tr>\n' % "".join(restdn))
376
377 restable = '<table border="2" cellspacing="2" cellpadding="2">\n%s%s%s</table>\n'
378 restable = restable % (restr1, restr2, "".join(restrn))
379
380 result = """\
381 <script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script>
382 <div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div>
383 <script language="JavaScript" type="text/javascript">
384 <!--
385 %s
386 // -->
387 </script>
388 %s
389 """ % (request.cfg.url_prefix, "\n".join(maketip_js), restable)
390 return formatter.rawHTML(result)
391
392 # EOF
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.