Attachment 'MonthCalendar-moin12.py'
Download 1 """
2 MoinMoin - MonthCalendar Macro
3
4 You can use this macro to put a months calendar page on a Wiki page.
5
6 The days are links to Wiki pages following this naming convention:
7 BasePageName/year-month-day
8
9 Copyright (c) 2002 by Thomas Waldmann <ThomasWaldmann@gmx.de>
10 Licensed under GNU GPL - see COPYING for details.
11
12 ----
13
14 Revisions:
15 * first revision without a number (=1.0):
16 * was only online for a few hours and then replaced by 1.1
17 * 1.1:
18 * changed name to MonthCalendar to avoid conflict with "calendar" under case-insensitive OSes like Win32
19 * days as subpages
20 * basepage argument
21 * change order of year/month argument
22 * browsing links to prev/next month/year
23 * current limitation: you can only browse one calendar on the same
24 page/url, if you try
25 to browse another calendar on the same page, the first one jumps back to its original display
26 * show basepage in calendar header if basepage<>currentpage
27 * 1.2:
28 * minor fixes in argument parsing
29 * cosmetic fix for netscape, other cosmetic changes, changed css
30 * i18n support (weekday short names)
31 * 1.3:
32 * fixes to run with MoinMoin 0.11, thanks to JuergenHermann
33 * fix: withspace before "," allowed in argument list
34 * BasePage in calendar header (if present) is a link now
35 * more i18n
36 * HTML cleanup, generating code avoids bracketing errors
37 * colour cosmetics
38 * 1.4:
39 * new parameter for enabling fixed height of 6 "calendar weeks",
40 if you want to show a whole year's calendar, this just looks
41 better than having some months with 4, some with 5 and some with 6.
42 * group calendaring functions:
43 * you can give mutliple BasePages UserName1*UserName2*UserName3
44 * first BasePage is considered "your" Basepage,
45 used days are bright red
46 * 2nd and all other BasePages are considered "others" BasePages
47 and lead to an increasing green component the more "used" days
48 the others have. So white gets greener and red gets more yellowish.
49 * in the head part of the calendar, you can click on each name
50 to get to the Page of the same name
51 * colouring of my and others BasePage is done in a way to show
52 the colouring used in the calendar:
53 * others use green colouring (increasingly green if multiply used)
54 * I use red colouring, which gets more and more yellowish as
55 the day is used by more and more others, too
56 * 1.5:
57 * fixed username colouring when using a BasePage
58 * fixed navigation header of MonthCalendar not to get broken into
59 multiple lines
60 * fixed SubPage handling (please do not use relative SubPages like
61 /SubPage yet. Use MyName/SubPage.)
62 * 1.6:
63 * syntactic cleanup
64 * removed i18n compatibility for moin<1.1 or cvs<2003-06-10
65 * integrated Scott Chapman's changes:
66 * Made it configurable for Sunday or Monday as the first day of the week.
67 Search for "change here".
68 * Made it so that today is not only set to a seperate css style, but also boldfaced.
69 Some browsers don't show the other css style (Netscape).
70 * Made it so weekend dates have different color.
71 * 1.7:
72 * added request parameter where needed
73 * 1.8:
74 * some fixes for moin 1.2 (use this version ONLY if you run moin 1.2, too):
75 * .value backtrace fixed when selecting next/prev month/year
76 * request param added to macro function
77
78 TODO:
79 * integrate patch for including day page contents directly into cal
80 * still thinking over: does this make sense in a MonthCalendar?
81 * it would be definitely nice in a week or day calendar (more space to
82 burn)
83 * integr. daycal -link-> monthcal
84
85 ----
86
87 Usage:
88 [[MonthCalendar(BasePage,year,month,monthoffset,monthoffset2,height6)]]
89
90 each parameter can be empty and then defaults to currentpage or currentdate or monthoffset=0
91
92 Samples (paste that to one of your pages for a first try):
93
94 Calendar of current month for current page:
95 [[MonthCalendar]]
96
97 Calendar of last month:
98 [[MonthCalendar(,,,-1)]]
99
100 Calendar of next month:
101 [[MonthCalendar(,,,+1)]]
102
103 Calendar of Page SampleUser, this years december:
104 [[MonthCalendar(SampleUser,,12)]]
105
106 Calendar of current Page, this years december:
107 [[MonthCalendar(,,12)]]
108
109 Calendar of December, 2001:
110 [[MonthCalendar(,2001,12)]]
111
112 Calendar of the month two months after December, 2001
113 (maybe doesn't make much sense, but is possible)
114 [[MonthCalendar(,2001,12,+2)]]
115
116 Calendar of year 2002 (every month padded to height of 6):
117 ||||||Year 2002||
118 ||[[MonthCalendar(,2002,1,,,1)]]||[[MonthCalendar(,2002,2,,,1)]]||[[MonthCalendar(,2002,3,,,1)]]||
119 ||[[MonthCalendar(,2002,4,,,1)]]||[[MonthCalendar(,2002,5,,,1)]]||[[MonthCalendar(,2002,6,,,1)]]||
120 ||[[MonthCalendar(,2002,7,,,1)]]||[[MonthCalendar(,2002,8,,,1)]]||[[MonthCalendar(,2002,9,,,1)]]||
121 ||[[MonthCalendar(,2002,10,,,1)]]||[[MonthCalendar(,2002,11,,,1)]]||[[MonthCalendar(,2002,12,,,1)]]||
122
123 Current calendar of me, also showing entries of A and B:
124 [[MonthCalendar(MyPage*TestUserA*TestUserB)]]
125
126 SubPage calendars:
127 [[MonthCalendar(MyName/CalPrivate)]]
128 [[MonthCalendar(MyName/CalBusiness)]]
129 [[MonthCalendar(MyName/CalBusiness*MyName/CalPrivate)]]
130
131 ----
132
133 You need to have some stylesheet entries like the following.
134 Paste that to default.css / moinmoin.css:
135
136 /* begin css for MonthCalendar macro */
137 /* days without and with pages linked to them */
138 a.cal-emptyday {
139 color: #777777;
140 text-align: center;
141 }
142 a.cal-usedday {
143 font-weight: bold;
144 color: #000000;
145 text-align: center;
146 }
147 /* general stuff: workdays, weekend, today */
148 td.cal-workday {
149 background-color: #DDDDFF;
150 text-align: center;
151 }
152 td.cal-weekend {
153 background-color: #FFDDDD;
154 text-align: center;
155 }
156 td.cal-today {
157 background-color: #CCFFCC;
158 border-style: solid;
159 border-width: 2pt;
160 text-align: center;
161 }
162 /* invalid places on the monthly calendar sheet */
163 td.cal-invalidday {
164 background-color: #CCCCCC;
165 }
166 /* links to prev/next month/year */
167 a.cal-link {
168 color: #000000;
169 text-decoration: none;
170 }
171 th.cal-header {
172 background-color: #DDBBFF;
173 text-align: center;
174 }
175 /* end css for MonthCalendar macro */
176
177 ----
178
179 If you want translated (german) messages, add something like this to
180 i18n/de.py (if you have >=0.11, the weekday translation might be already
181 there):
182
183 'Mon':'Mo','Tue':'Di','Wed':'Mi','Thu':'Do','Fri':'Fr','Sat':'Sa','Sun':'So',
184
185 'Invalid MonthCalendar calparms "%s"!':
186 'Ung\366ltige MonthCalendar calparms "%s"!',
187
188 'Invalid MonthCalendar arguments "%s"!':
189 'Ung\366ltige MonthCalendar Argumente "%s"!',
190
191 """
192
193 # Imports
194 from MoinMoin import config, user, wikiutil
195 from MoinMoin.Page import Page
196 import sys, re, calendar, time, string
197
198 # The following line sets the calendar to have either Sunday or Monday as
199 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
200 # valid here. All other values will not make good calendars.
201 # If set to Sunday, the calendar is displayed at "March 2003" vs. "2003 / 3" also.
202 # XXX change here ----------------vvvvvv
203 calendar.setfirstweekday(calendar.MONDAY)
204
205 def cliprgb(r,g,b): # don't use 255!
206 if r < 0: r=0
207 if r > 254: r=254
208 if b < 0: b=0
209 if b > 254: b=254
210 if g < 0: g=0
211 if g > 254: g=254
212 return r, g, b
213
214 def yearmonthplusoffset(year, month, offset):
215 month = month+offset
216 # handle offset and under/overflows - quick and dirty, yes!
217 while month < 1:
218 month = month+12
219 year = year-1
220 while month > 12:
221 month = month-12
222 year = year+1
223 return year, month
224
225 def parseargs(args, defpagename, defyear, defmonth, defoffset, defoffset2, defheight6):
226 strpagename = args.group('basepage')
227 if strpagename:
228 parmpagename = strpagename
229 else:
230 parmpagename = defpagename
231 # multiple pagenames separated by "*" - split into list of pagenames
232 parmpagename = re.split(r'\*', parmpagename)
233
234 stryear = args.group('year')
235 if stryear:
236 parmyear = int(stryear)
237 else:
238 parmyear = defyear
239
240 strmonth = args.group('month')
241 if strmonth:
242 parmmonth = int(strmonth)
243 else:
244 parmmonth = defmonth
245
246 stroffset = args.group('offset')
247 if stroffset:
248 parmoffset = int(stroffset)
249 else:
250 parmoffset = defoffset
251
252 stroffset2 = args.group('offset2')
253 if stroffset2:
254 parmoffset2 = int(stroffset2)
255 else:
256 parmoffset2 = defoffset2
257
258 strheight6 = args.group('height6')
259 if strheight6:
260 parmheight6 = int(strheight6)
261 else:
262 parmheight6 = defheight6
263
264 return parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6
265
266 # FIXME: vvvvvv is there a better way for matching a pagename ?
267 _arg_basepage = r'\s*(?P<basepage>[^, ]+)?\s*'
268 _arg_year = r',\s*(?P<year>\d+)?\s*'
269 _arg_month = r',\s*(?P<month>\d+)?\s*'
270 _arg_offset = r',\s*(?P<offset>[+-]?\d+)?\s*'
271 _arg_offset2 = r',\s*(?P<offset2>[+-]?\d+)?\s*'
272 _arg_height6 = r',\s*(?P<height6>[+-]?\d+)?\s*'
273 _args_re_pattern = r'^(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?$' % \
274 (_arg_basepage,_arg_year,_arg_month, \
275 _arg_offset,_arg_offset2,_arg_height6)
276
277
278 def execute(macro, text):
279 _ = macro.request.getText
280
281 # return immediately if getting links for the current page
282 if macro.request.mode_getpagelinks:
283 return ''
284
285 args_re=re.compile(_args_re_pattern)
286
287 currentyear, currentmonth, currentday, h, m, s, wd, yd, ds = time.localtime(time.time())
288 thispage = macro.formatter.page.page_name
289 # does the url have calendar params (= somebody has clicked on prev/next links in calendar) ?
290 if macro.form.has_key('calparms'):
291 text2 = macro.form['calparms'][0]
292 args2 = args_re.match(text2)
293 if not args2:
294 return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar calparms "%s"!')) % (text2,)
295 else:
296 has_calparms = 1 # yes!
297 cparmpagename, cparmyear, cparmmonth, cparmoffset, cparmoffset2, cparmheight6 = \
298 parseargs(args2, thispage, currentyear, currentmonth, 0, 0, 0)
299 else:
300 has_calparms = 0
301
302 if text is None: # macro call without parameters
303 parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6 = \
304 [thispage], currentyear, currentmonth, 0, 0, 0
305 else:
306 # parse and check arguments
307 args = args_re.match(text)
308 if not args:
309 return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar arguments "%s"!')) % (text,)
310 else:
311 parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6 = \
312 parseargs(args, thispage, currentyear, currentmonth, 0, 0, 0)
313
314 # does url have calendar params and is THIS the right calendar to modify (we can have multiple
315 # calendars on the same page)?
316 if has_calparms and (cparmpagename,cparmyear,cparmmonth,cparmoffset) == (parmpagename,parmyear,parmmonth,parmoffset):
317 year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset + cparmoffset2)
318 parmoffset2 = cparmoffset2
319 else:
320 year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset)
321
322 # get the calendar
323 monthcal = calendar.monthcalendar(year, month)
324
325 # european / US differences
326 months = ('January','February','March','April','May','June','July','August','September','October','November','December')
327 # Set things up for Monday or Sunday as the first day of the week
328 if calendar.firstweekday() == calendar.MONDAY:
329 wkend = (5, 6)
330 wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
331 if calendar.firstweekday() == calendar.SUNDAY:
332 wkend = (0, 6)
333 wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
334
335 colorstep = 85
336 p = Page(thispage)
337 querystr = "calparms=%s,%d,%d,%d,%%d" % (string.join(parmpagename,'*'), parmyear, parmmonth, parmoffset)
338 prevlink = p.url(macro.request, querystr % (parmoffset2 - 1))
339 nextlink = p.url(macro.request, querystr % (parmoffset2 + 1))
340 prevylink = p.url(macro.request, querystr % (parmoffset2 - 12))
341 nextylink = p.url(macro.request, querystr % (parmoffset2 + 12))
342 prevmonth = macro.formatter.url(prevlink, '<-', 'cal-link')
343 nextmonth = macro.formatter.url(nextlink, '->', 'cal-link')
344 prevyear = macro.formatter.url(prevylink, '<<-', 'cal-link')
345 nextyear = macro.formatter.url(nextylink, '->>', 'cal-link')
346
347 if parmpagename <> [thispage]:
348 pagelinks = ''
349 r,g,b = (255, 0, 0)
350 l = len(parmpagename[0])
351 steps = len(parmpagename)
352 maxsteps = (255 / colorstep)
353 if steps > maxsteps:
354 steps = maxsteps
355 chstep = int(l / steps)
356 st = 0
357 while st < l:
358 ch = parmpagename[0][st:st+chstep]
359 r, g, b = cliprgb(r, g, b)
360 pagelinks = pagelinks + '<a style="%s" href="%s">%s</a>' % \
361 ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
362 (r,g,b), Page(parmpagename[0]).url(macro.request), ch)
363 r, g, b = (r, g+colorstep, b)
364 st = st + chstep
365 r, g, b = (255-colorstep, 255, 255-colorstep)
366 for page in parmpagename[1:]:
367 pagelinks = pagelinks + '*<a style="%s" href="%s">%s</a>' % \
368 ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
369 (r,g,b), Page(page).url(macro.request), page)
370 showpagename = ' %s<BR>\n' % pagelinks
371 else:
372 showpagename = ''
373 if calendar.firstweekday() == calendar.SUNDAY:
374 resth1 = ' <th colspan="7" class="cal-header">\n' \
375 '%s' \
376 ' %s %s <b> %s %s</b> %s\n %s\n' \
377 ' </th>\n' % (showpagename, prevyear, prevmonth, months[month-1], str(year), nextmonth, nextyear)
378 if calendar.firstweekday() == calendar.MONDAY:
379 resth1 = ' <th colspan="7" class="cal-header">\n' \
380 '%s' \
381 ' %s %s <b> %s / %s</b> %s\n %s\n' \
382 ' </th>\n' % (showpagename, prevyear, prevmonth, str(year), month, nextmonth, nextyear)
383 restr1 = ' <tr>\n%s </tr>\n' % resth1
384
385 r7 = range(7)
386 restd2 = []
387 for wkday in r7:
388 wday = _(wkdays[wkday])
389 if wkday in wkend:
390 cssday = "cal-weekend"
391 else:
392 cssday = "cal-workday"
393 restd2.append(' <td class="%s" width="14%%">%s</td>\n' % (cssday, wday))
394 restr2 = ' <tr>\n%s </tr>\n' % "".join(restd2)
395
396 if parmheight6:
397 while len(monthcal) < 6:
398 monthcal = monthcal + [[0,0,0,0,0,0,0]]
399
400 restrn = []
401 for week in monthcal:
402 restdn = []
403 for wkday in r7:
404 day = week[wkday]
405 if not day:
406 restdn.append(' <td class="cal-invalidday"> </td>\n')
407 else:
408 csslink = "cal-emptyday"
409 r, g, b, u = (255, 255, 255, 0)
410 page = parmpagename[0]
411 link = "%s/%4d-%02d-%02d" % (page, year, month, day)
412 daypage = Page(link)
413 if daypage.exists():
414 csslink = "cal-usedday"
415 r, g, b, u = (255, 0, 0, 1)
416 else:
417 if wkday in wkend:
418 csslink = "cal-weekend"
419 for otherpage in parmpagename[1:]:
420 otherlink = "%s/%4d-%02d-%02d" % (otherpage, year, month, day)
421 otherdaypage = Page(otherlink)
422 if otherdaypage.exists():
423 csslink = "cal-usedday"
424 if u == 0:
425 r, g, b = (r-colorstep, g, b-colorstep)
426 else:
427 r, g, b = (r, g+colorstep, b)
428 r, g, b = cliprgb(r, g, b)
429 style = 'background-color:#%02x%02x%02x' % (r, g, b)
430 fmtlink = macro.formatter.url(daypage.url(macro.request), str(day), csslink)
431 if day == currentday and month == currentmonth and year == currentyear:
432 cssday = "cal-today"
433 fmtlink = "<b>%s</b>" % fmtlink # for browser with CSS probs
434 else:
435 cssday = "cal-nottoday"
436 restdn.append(' <td style="%s" class="%s">%s</td>\n' % (style, cssday, fmtlink))
437 restrn.append(' <tr>\n%s </tr>\n' % "".join(restdn))
438
439 restable = '<table border="2" cellspacing="2" cellpadding="2">\n%s%s%s</table>\n'
440 result = restable % (restr1, restr2, "".join(restrn))
441 return macro.formatter.rawHTML(result)
442
443 # 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.