Attachment 'EventCalendar-099b.py'
Download 1 """
2 EventCalendar.py Version 0.99 May 22, 2006
3
4 This macro gives a list of the events recorded at the sub-pages in the form of various views:
5 monthly, weekly, daily, simple-month, list, and upcoming.
6
7 @copyright: 2006 by Seungik Lee <seungiklee<at>gmail.com> http://www.silee.net/
8 @license: GPL
9
10 For more information, please visit http://moinmoin.wikiwikiweb.de/MacroMarket/EventCalendar
11
12 <Usage>
13
14 * To list the events in a page, just insert <<EventCalendar>>
15 * To insert an event, insert the event information in any pages of specified category (CategoryEventCalendar by default).
16
17 <Parameters>
18
19 * category: the category of the event data to be used in the calendar. default: 'CategoryEventCalendar'
20 * menubar: shows menubar or not (1: show, 0: no menubar). default: 1
21 * monthlywidth: calendar width in pixel or percent (monthly view). default: '600' (pixel)
22 * simplewidth: calendar width in pixel or percent (simpleview). default: '150' (pixel)
23 * firstview: initial calendar view: monthly, weekly, daily, list, simple, upcoming. default: 'monthly'
24 * curdate: initial calendar date (in YYYYMM format). default: current month
25 * upcomingrange: # of days for the range of upcoming event list. default: 7 (days)
26 * changeview: enables to change the calendar view or not (1: enalbed, 0: disabled). default: 1
27 * numcal: # of calendar. default: 1
28 * showlastweekday: shows the event at the last weekday if the recurred weekday is not available. (1: enalbed, 0: disabled). default: 0
29 * showerror: shows error messages below the calendar if event data format is invalid. (1: enalbed, 0: disabled). default: 1
30 * showweeknumber: shows the week number of the year (1: enalbed, 0: disabled). default: 0
31
32
33 <Event Data Format>
34
35 * Event data fields:
36 ...
37
38 [default_description:: [page_default_description_text]]
39 [default_bgcolor:: [page_default_background_color]]
40 [label_def:: [label_name], [label_background_color]]
41
42 == <title> ==
43 start:: <startdate> [starttime]
44 [end:: [enddate] [endtime]]
45 [description:: [description_text]]
46 [bgcolor:: [custom_background_color]]
47 [recur:: <recur_freq> <recur_type> [until <recur_until>]]
48 [label:: <label_name>]
49
50 ...
51
52 ----
53 CategoryEventCalendar
54
55 * default_bgcolor, default_description: default values of bgcolor and description in the page if unavailable. optional
56 * label_def: label definition with name, bgcolor. optional
57
58 * title: event title. required
59 * should be enclosed with heading marker ('='), Title cannot be omitted.
60
61 * startdate: date of start. required
62 * should be in date format or date format
63
64 * starttime: time of start. optional
65 * should be in time format
66
67 * enddate: date of end. optional
68 * should be in date format or date format. If omitted, it will be assigned equal to <startdate>.
69
70 * endtime: time of end. optional
71 * should be in time format. Both of start|end Time can be omitted but not either of them.
72
73 * description: description of the event. optional
74 * any text with no markup. should be in a line.
75
76 * bgcolor: custom background color of the event in monthly view. optional
77 * e.g., #abcdef
78
79 * recur: recurrence information of the event. optional
80 * recur_freq: how many intervals, digit or 'last' for weekday, required
81 * recur_type: [day|week|weekday|month|year], required
82 * day: every [recur_freq] days
83 * week: every [recur_freq] weeks
84 * weekday: on the same weekday of [recur_freq]-th week of the month. or 'last weekday'
85 * month: on the same day of [recur_freq]-th month
86 * year: on the same day of [recur_freq]-th year
87 * recur_until: recurred until when, date format, optional
88
89 * e.g., 10 day, 2 week until 2006-06-31, 3 weekday, 6 month until 2007-12-31, 1 year
90
91 * label: custom label for specific name, bgcolor. optional
92
93 * The order of the fields after an event title does not matter.
94 * Priority of bgcolor: bgcolor > default_bgcolor > label_bgcolor
95
96
97 * Datetime format:
98
99 * Date format:
100 * YYYY/MM/DD, YYYY-MM-DD, YYYY.MM.DD: 2006/05/12; 2006-05-12; 2006.05.12; 2006-5-12; 06/5/12
101 * B DD, YYYY: May 12, 2006; May 5th, 2006; January 1st, 2006; Jan 5, 06
102 * YYYYMMDD, YYMMDD: 20060512; 060512
103
104 * Year: YY = 20YY. e.g., 06-2-2 = 2006-02-02, allowed 1900 ~ 2099 only.
105
106 * Time format:
107 * H:M, HHMM: 12:00; 22:00; 2:00; 2 (= 2 o'clock); 2200; 12:0; 2:0
108 * I:M PP, IIMM PP: 12:00 PM; 3:00p; 2a (= 2 o'clock AM); 3:0pm; 0200 am; 10pm
109
110
111
112 <Event Data Examples>
113
114 == Default values ==
115 default_bgcolor:: #c0c0c0
116 default_description:: testing...
117
118 == Labels ==
119 label_def:: Holiday, #ff0000
120 label_def:: Meeting, #00ff00
121
122 === Test event ===
123 start:: 2006-01-10 02:00p
124 end:: 2006-01-12 17:00
125 description:: test event
126 bgcolor:: #cfcfcf
127
128 === Jinah's Birthday ===
129 start:: 1977-10-20
130 recur:: 1 year
131 label:: Holiday
132
133 === Weekly meeting ===
134 start:: Jan 17, 2006 7:00pm
135 end:: 21:00
136 recur:: 1 week until 061231
137 label:: Meeting
138
139 ----
140 CategoryEventCalendar
141
142
143 <Notes>
144
145 * It caches all the page list of the specified category and the event information.
146 * If you added/removed a page into/from a category, you need to do 'Delete cache' in the macro page.
147
148 * 'MonthCalendar.py' developed by Thomas Waldmann <ThomasWaldmann@gmx.de> has inspired this macro.
149 * Much buggy.. : please report bugs and suggest your ideas.
150 * If you missed to add css for EventCalender, monthly view may not be readable.
151 * Insert the EventCalendar css classes into the screen.css of an appropriate theme.
152
153
154
155 """
156
157 from MoinMoin import wikiutil, config, search, caching
158 from MoinMoin.Page import Page
159 import re, calendar, time, datetime
160 import codecs, os, urllib, sha
161
162 try:
163 import cPickle as pickle
164 except ImportError:
165 import pickle
166
167 # Set pickle protocol, see http://docs.python.org/lib/node64.html
168 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
169
170
171 # The following line sets the calendar to have either Sunday or Monday as
172 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
173 # valid here. All other values will not make good calendars.
174 # XXX change here ----------------vvvvvv
175 calendar.setfirstweekday(calendar.SUNDAY)
176
177
178 class Globs:
179 month_style_us = 1 # 1: October 2005; 2: 2005 / 10
180 defaultcategory = 'CategoryEventCalendar'
181 upcomingrange = 40 # days
182 dailystart = 9
183 dailyend = 18
184 pagename = ''
185 baseurl = ''
186 subname = ''
187 wkend = ''
188 months = ''
189 wkdays = ''
190 today = ''
191 now = ''
192 request = None
193 formatter = None
194 cal_action = ''
195 debugmsg = ''
196 errormsg = ''
197 page_action = ''
198 form_vals = {}
199 events = None
200 labels = None
201
202
203 class Params:
204 menubar = 0
205 monthlywidth = ''
206 weeklywidth = ''
207 dailywidth = ''
208 simplewidth = ''
209 firstview = ''
210 curdate = ''
211 bgcolor = ''
212 category = ''
213 upcomingrange = 0
214 changeview = 0
215 numcal = 1
216 showlastweekday = 0
217 showerror = 1
218 showweeknumber = 0
219 debug = 0
220
221
222 class EventcalError(Exception):
223 def __init__(self, value):
224 self.value = value
225
226 def __str__(self):
227 return repr(self.value)
228
229
230 def execute(macro, args):
231
232 request = macro.request
233 formatter = macro.formatter
234
235 # INITIALIZATION ----------------------------------------
236 setglobalvalues(macro)
237 getparams(args)
238
239 # allowed actions
240 allowed_action = ['monthly', 'list', 'simple', 'upcoming', 'daily', 'weekly']
241 default_action = Params.firstview
242
243 # Internal variables
244 cal_action = ''
245 form_vals = {}
246
247 # PROCESSING ARGUEMENTS ----------------------------------------
248 if args:
249 args=request.getText(args)
250
251 for item in macro.request.values.items():
252 if not form_vals.has_key(item[0]):
253 try:
254 form_vals[item[0]]=item[1]
255 except AttributeError:
256 pass
257
258 # PROCESSING ACTIONS ----------------------------------------
259 cal_action = form_vals.get('calaction', default_action)
260 page_action = form_vals.get('action', 'show')
261
262 if not cal_action in allowed_action:
263 cal_action = default_action
264
265 form_vals['calaction'] = cal_action
266
267 Globs.form_vals = form_vals
268
269 # CONTROL FUNCTIONS ----------------------------------------
270
271 html = []
272 html_result = ''
273
274 Globs.cal_action = cal_action
275 Globs.page_action = page_action
276
277
278 # redirect to the appropriate view
279 if cal_action == 'monthly':
280 html_result = showcalendar()
281
282 if cal_action == 'list':
283 html_result = showeventlist()
284
285 if cal_action == 'simple':
286 html_result = showsimplecalendar()
287
288 if cal_action == 'upcoming':
289 html_result = showupcomingeventlist()
290
291 if cal_action == 'daily':
292 html_result = showdailycalendar()
293
294 if cal_action == 'weekly':
295 html_result = showweeklycalendar()
296
297
298 # format output
299 html.append( html_result )
300 html.append( showmenubar() )
301
302 if Params.showerror and Globs.errormsg:
303 html.append(u'<p><i><font size="2" color="#aa0000"><ol>%s</ol></font></i>' % Globs.errormsg)
304
305 if Params.debug and Globs.debugmsg:
306 html.append(u'<p><b>Debug messages:</b><font color="#000099"><ol>%s</ol></font>' % Globs.debugmsg)
307
308 return formatter.rawHTML(u''.join(html))
309
310
311
312 def getparams(args):
313 # process arguments
314
315 params = {}
316 if args:
317 # Arguments are comma delimited key=value pairs
318 sargs = args.split(',')
319
320 for item in sargs:
321 sitem = item.split('=')
322
323 if len(sitem) == 2:
324 key, value = sitem[0], sitem[1]
325 params[key.strip()] = value.strip()
326
327 # category name:
328 # default: 'CategoryEventCalendar'
329 Params.category = params.get('category', Globs.defaultcategory)
330
331 # menu bar: shows menubar or not (1: show, 0: no menubar)
332 # default: 1
333 try:
334 Params.menubar = int(params.get('menubar', 1))
335 except (TypeError, ValueError):
336 Params.menubar = 1
337
338 # calendar width in pixel or percent (monthly)
339 # default: 600px
340 Params.monthlywidth = params.get('monthlywidth', '600')
341 if Params.monthlywidth:
342 Params.monthlywidth = ' width="%s" ' % Params.monthlywidth
343
344 # calendar width in pixel or percent (weekly)
345 # default: 600px
346 Params.weeklywidth = params.get('weeklywidth', '600')
347 if Params.weeklywidth:
348 Params.weeklywidth = ' width="%s" ' % Params.weeklywidth
349
350 # calendar width in pixel or percent (daily)
351 # default: 600px
352 Params.dailywidth = params.get('dailywidth', '600')
353 if Params.monthlywidth:
354 Params.dailywidth = ' width="%s" ' % Params.dailywidth
355
356 # calendar width in pixel or percent (simply)
357 # default: 150px
358 Params.simplewidth = params.get('simplewidth', '150')
359 if Params.simplewidth:
360 # Params.simplewidth = Params.simplewidth.replace('%', '%%')
361 Params.simplewidth = ' width="%s" ' % Params.simplewidth
362
363 # calendar view: monthly, list, simple
364 # default: 'monthly'
365 Params.firstview = params.get('firstview', 'monthly')
366
367 # calendar date: in YYYYMM format (in monthly, simple view)
368 # default: current month
369 Params.curdate = params.get('curdate', '')
370
371 # upcoming range: # of days for upcoming event list
372 # default: 7
373 try:
374 Params.upcomingrange = int(params.get('upcomingrange', Globs.upcomingrange))
375 except (TypeError, ValueError):
376 Params.upcomingrange = Globs.upcomingrange
377
378 # number of calendar: # of calendar for monthly & simple view
379 # default: 1
380 try:
381 Params.numcal = int(params.get('numcal', '1'))
382 except (TypeError, ValueError):
383 Params.numcal = 1
384
385 # change view enabled?
386 # default: 1
387 try:
388 Params.changeview = int(params.get('changeview', '1'))
389 except (TypeError, ValueError):
390 Params.changeview = 1
391
392 # shows the event at the last weekday if the recurred weekday is not available.
393 # default: 0
394 try:
395 Params.showlastweekday = int(params.get('showlastweekday', '0'))
396 except (TypeError, ValueError):
397 Params.showlastweekday = 0
398
399 # show error message?
400 # default: 1
401 try:
402 Params.showerror = int(params.get('showerror', '1'))
403 except (TypeError, ValueError):
404 Params.showerror = 1
405
406 # show week number?
407 # default: 0
408 try:
409 Params.showweeknumber = int(params.get('showweeknumber', '0'))
410 except (TypeError, ValueError):
411 Params.showweeknumber = 0
412
413 # default bgcolor
414 Params.bgcolor = '#ddffdd'
415
416
417 def setglobalvalues(macro):
418
419 request = macro.request
420 formatter = macro.formatter
421
422 # Useful variables
423 Globs.baseurl = request.getBaseURL() + '/'
424 Globs.pagename = formatter.page.page_name
425 Globs.request = request
426 Globs.formatter = formatter
427 Globs.pageurl = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(formatter.page.page_name))
428
429 # This fixes the subpages bug. subname is now used instead of pagename when creating certain urls
430 Globs.subname = Globs.pagename.split('/')[-1]
431
432 pagepath = formatter.page.getPagePath()
433 Globs.pagepath = formatter.page.getPagePath()
434
435 # european / US differences
436 months = ('January','February','March','April','May','June','July','August','September','October','November','December')
437
438 # Set things up for Monday or Sunday as the first day of the week
439 if calendar.firstweekday() == calendar.MONDAY:
440 wkend = 6
441 wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
442 elif calendar.firstweekday() == calendar.SUNDAY:
443 wkend = 0
444 wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
445
446 Globs.months = months
447 Globs.wkdays = wkdays
448 Globs.wkend = wkend
449
450 year, month, day, h, m, s, wd, yd, ds = request.user.getTime(time.time())
451 Globs.today = datetime.date(year, month, day)
452 Globs.now = datetime.time(h, m, s)
453
454 Globs.debugmsg = ''
455 Globs.errormsg = ''
456
457
458 def showReferPageParsed(event, targettext='title', showdesc=0):
459 request = Globs.request
460 pagename = Globs.pagename
461
462 refer = event['refer']
463 targettext = event[targettext]
464 startdate = event['startdate']
465 enddate = event['enddate']
466 description = event['description']
467 starttime = event['starttime']
468 endtime = event['endtime']
469 hid = event['hid']
470
471 refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
472
473 if not Params.changeview:
474 refer_url = ''
475 hid = ''
476
477 if showdesc:
478 if (startdate == enddate) and (starttime and endtime):
479 timedescription = '(%s:%s ~ %s:%s)' % (starttime[:2], starttime[2:], endtime[:2], endtime[2:])
480 if description:
481 timedescription = '%s ' % timedescription
482 else:
483 timedescription = ''
484
485 targetlink = '<a href="%s#%s" title="%s%s">%s</a>' % ( refer_url, hid, timedescription, wikiutil.escape(description), wikiutil.escape(targettext) )
486
487 else:
488 targetlink = '<a href="%s#%s">%s</a>' % ( refer_url, hid, wikiutil.escape(targettext))
489
490 return targetlink
491
492
493 def showReferPageParsedForLabel(thelabel, targettext='name', showdesc=1):
494 request = Globs.request
495 pagename = Globs.pagename
496
497 labels = Globs.labels
498
499 label_bgcolor = ''
500 refer = ''
501
502 if labels and labels.has_key(thelabel):
503 targettext = labels[thelabel][targettext]
504 refer = labels[thelabel]['refer']
505 if showdesc:
506 label_bgcolor = labels[thelabel]['bgcolor']
507
508 if not refer:
509 return '<i>%s</i>' % thelabel
510
511 refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
512
513 if showdesc:
514 targetlink = '<a href="%s" title="%s">%s</a>' % ( refer_url, label_bgcolor, wikiutil.escape(targettext) )
515 else:
516 targetlink = '<a href="%s">%s</a>' % ( refer_url, wikiutil.escape(targettext))
517
518 return targetlink
519
520
521 def getheadingid(request, referpage, title):
522
523 pntt = (referpage + title).encode(config.charset)
524 hid = "head-" + sha.new(pntt).hexdigest()
525
526 if not hasattr(request, '_eventcal_headings'):
527 request._eventcal_headings = {}
528
529 request._eventcal_headings.setdefault(pntt, 0)
530 request._eventcal_headings[pntt] += 1
531 if request._eventcal_headings[pntt] > 1:
532 hid += '-%d'%(request._eventcal_headings[pntt],)
533
534 return hid
535
536
537 def getquerystring(req_fields):
538
539 m_query = []
540 tmp_form_vals = Globs.form_vals
541
542 # format querystring
543 # action should be poped out
544 for field in req_fields:
545 if tmp_form_vals.has_key(field):
546 m_query.append(u'%s=%s' % (field, tmp_form_vals[field]) )
547
548 if 'prevcalaction' in req_fields:
549 if not tmp_form_vals.has_key('prevcalaction'):
550 m_query.append(u'%s=%s' % ('prevcalaction', tmp_form_vals['calaction']) )
551
552 m_query = u'&'.join(m_query)
553
554 if m_query:
555 m_query = '&%s' % m_query
556
557 return m_query
558
559
560 # bottom menu bar
561 def showmenubar():
562
563 request = Globs.request
564 cal_action = Globs.cal_action
565 page_name = Globs.pagename
566
567 page_url = Globs.pageurl
568
569 if not Params.menubar: return ''
570
571 if cal_action == 'simple':
572 menuwidth = Params.simplewidth
573 elif cal_action == 'monthly':
574 menuwidth = Params.monthlywidth
575 else:
576 menuwidth = ''
577
578 left_menu_selected = []
579 right_menu_selected = []
580
581 # Go Today
582 year, month, day = gettodaydate()
583 mnu_curmonthcal = u'<a href="%s?calaction=%s&caldate=%d%02d%02d%s" title="Go Today">[Today]</a>' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
584
585 # List View
586 mnu_listview = u'<a href="%s?calaction=list%s" title="List of all events">[List]</a>' % (page_url, getquerystring(['caldate', 'numcal']))
587
588 # Monthly View
589 mnu_monthview = u'<a href="%s?calaction=monthly%s" title="Monthly view">[Monthly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
590
591 # Simple Calendar View
592 mnu_simpleview = u'<a href="%s?calaction=simple%s" title="Simple calendar view">[Simple]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
593
594 # Upcoming Event List
595 mnu_upcomingview = u'<a href="%s?calaction=upcoming%s" title="Upcoming event list">[Upcoming]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
596
597 # Daily View
598 mnu_dayview = u'<a href="%s?calaction=daily%s" title="Daily view">[Daily]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
599
600 # Weekly View
601 mnu_weekview = u'<a href="%s?calaction=weekly%s" title="Weekly view">[Weekly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
602
603 html = [
604 u'\r\n',
605 u'<table class="eventcalendar_menubar" %s>',
606 u' <tr>',
607 u' <td class="eventcalendar_menubar" align="left">%s</td>',
608 u' <td class="eventcalendar_menubar" align="right">%s</td>',
609 u' </tr>',
610 u'</table>',
611 ]
612
613 if cal_action == 'list':
614 left_menu_selected.append(mnu_monthview)
615 left_menu_selected.append(mnu_weekview)
616 left_menu_selected.append(mnu_dayview)
617 left_menu_selected.append(mnu_simpleview)
618 right_menu_selected.append(mnu_upcomingview)
619
620 elif cal_action == 'simple':
621 left_menu_selected.append(mnu_monthview)
622 left_menu_selected.append(mnu_weekview)
623 left_menu_selected.append(mnu_dayview)
624 right_menu_selected.append(mnu_listview)
625 right_menu_selected.append(mnu_upcomingview)
626 right_menu_selected.append(mnu_curmonthcal)
627
628 elif cal_action == 'upcoming':
629 left_menu_selected.append(mnu_monthview)
630 left_menu_selected.append(mnu_weekview)
631 left_menu_selected.append(mnu_dayview)
632 left_menu_selected.append(mnu_simpleview)
633 right_menu_selected.append(mnu_listview)
634
635 elif cal_action == 'weekly':
636 left_menu_selected.append(mnu_monthview)
637 left_menu_selected.append(mnu_dayview)
638 left_menu_selected.append(mnu_simpleview)
639 right_menu_selected.append(mnu_upcomingview)
640 right_menu_selected.append(mnu_listview)
641 right_menu_selected.append(mnu_curmonthcal)
642
643 elif cal_action == 'daily':
644 left_menu_selected.append(mnu_monthview)
645 left_menu_selected.append(mnu_weekview)
646 left_menu_selected.append(mnu_simpleview)
647 right_menu_selected.append(mnu_upcomingview)
648 right_menu_selected.append(mnu_listview)
649 right_menu_selected.append(mnu_curmonthcal)
650
651 else:
652 left_menu_selected.append(mnu_weekview)
653 left_menu_selected.append(mnu_dayview)
654 left_menu_selected.append(mnu_simpleview)
655 right_menu_selected.append(mnu_upcomingview)
656 right_menu_selected.append(mnu_listview)
657 right_menu_selected.append(mnu_curmonthcal)
658
659 left_menu_selected = u'\r\n'.join(left_menu_selected)
660 right_menu_selected = u'\r\n'.join(right_menu_selected)
661
662 html = u'\r\n'.join(html)
663 html = html % (menuwidth, left_menu_selected, right_menu_selected)
664
665 return html
666
667
668 def getdatefield(str_date):
669 str_year = ''
670 str_month = ''
671 str_day = ''
672
673 if len(str_date) == 6:
674 # year+month
675 str_year = str_date[:4]
676 str_month = str_date[4:]
677 str_day = '1'
678
679 elif len(str_date) == 8:
680 # year+month+day
681 str_year = str_date[:4]
682 str_month = str_date[4:6]
683 str_day = str_date[6:]
684
685 elif len(str_date) == 10:
686 # year+?+month+?+day
687 str_year = str_date[:4]
688 str_month = str_date[5:7]
689 str_day = str_date[8:]
690
691 else:
692 raise ValueError
693
694 # It raises exception if the input date is incorrect
695 temp = datetime.date(int(str_year), int(str_month), int(str_day))
696
697 return temp.year, temp.month, temp.day
698
699
700 def gettimefield(str_time):
701 str_hour = ''
702 str_min = ''
703
704 if len(str_time) == 4:
705 # hour+minute
706 str_hour = str_time[:2]
707 str_min = str_time[2:]
708
709 elif len(str_time) == 5:
710 # hour+?+minute
711 str_hour = str_time[:2]
712 str_min = str_time[3:]
713
714 else:
715 raise ValueError
716
717 # It raises exception if the input date is incorrect
718 temp = datetime.time(int(str_hour), int(str_min))
719
720 return temp.hour, temp.minute
721
722
723 def gettodaydate():
724 today = Globs.today
725 return today.year, today.month, today.day
726
727
728 def cal_listhead():
729
730 html = [
731 u' <tr>',
732 u' <td class="list_head">Title</td>',
733 u' <td class="list_head">Start Date</td>',
734 u' <td class="list_head">End Date</td>',
735 u' <td class="list_head">Recurrence</td>',
736 u' <td class="list_head">Label</td>',
737 u' <td class="list_head">Description</td>',
738 u' <td class="list_head">Reference</td>',
739 u' </tr>',
740 ]
741
742 return u'\r\n'.join(html)
743
744
745 def showeventlist():
746
747 debug('Show Calendar: List view')
748
749 request = Globs.request
750 formatter = Globs.formatter
751
752 html_event_rows = []
753 html_list_header = cal_listhead()
754
755 # read all the events
756 events, cal_events, labels = loadEvents()
757
758 # sort events
759 sorted_eventids = events.keys()
760 sorted_eventids.sort(comp_list_events)
761
762 for eid in sorted_eventids:
763 if not events[eid]['clone']:
764 html_event_rows.append( listshow_event(events[eid]) )
765
766 html_event_rows = u'\r\n'.join(html_event_rows)
767
768 html_list_table = [
769 u'\r\n<div id="eventlist">',
770 u'<table class="eventlist">',
771 u'%s' % html_list_header,
772 u'%s' % html_event_rows,
773 u'</table>',
774 u'</div>',
775 ]
776 html_list_table = u'\r\n'.join(html_list_table)
777
778 return html_list_table
779
780
781 def listshow_event(event):
782
783 if event['recur_freq']:
784 if event['recur_freq'] == -1:
785 recur_desc = 'last %s' % event['recur_type']
786 else:
787 recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type'])
788
789 if event['recur_until']:
790 recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until']))
791 else:
792 recur_desc = ''
793
794 html = [
795 u' <tr>',
796 u' <td class="list_entry">%s</td>' % converttext(event['title']),
797 u' <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']),
798 u' <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']),
799 u' <td class="list_entry">%s</td>' % recur_desc,
800 u' <td class="list_entry">%s</td>' % showReferPageParsedForLabel(event['label']),
801 u' <td class="list_entry">%s</td>' % converttext(event['description']),
802 u' <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'),
803 u' </tr>',
804 ]
805
806 return u'\r\n'.join(html)
807
808
809 def showupcomingeventlist():
810
811 debug('Show Calendar: Upcoming Event View')
812
813 request = Globs.request
814 formatter = Globs.formatter
815
816 html_event_rows = []
817 html_list_header = cal_listhead()
818
819 year, month, day = gettodaydate()
820 day_delta = datetime.timedelta(days=Params.upcomingrange)
821 cur_date = datetime.date(year, month, day)
822 next_range = cur_date + day_delta
823
824 # set ranges of events
825 datefrom = u'%04d%02d%02d' % (year, month, day)
826 dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day)
827
828 # read all the events (no cache)
829 events, cal_events, labels = loadEvents(datefrom, dateto, 1)
830
831 nowtime = formattimeobject(Globs.now)
832
833 datefrom = formatcfgdatetime(cur_date, nowtime)
834 #u'%04d-%02d-%02d %s:%s' % (year, month, day, nowtime[:2], nowtime[2:])
835 dateto = formatcfgdatetime(formatdateobject(next_range))
836 #u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day)
837
838 # sort events
839 sorted_eventids = events.keys()
840 sorted_eventids.sort(comp_list_events)
841
842 for eid in sorted_eventids:
843 if events[eid]['enddate'] >= formatdateobject(Globs.today):
844 if (not events[eid]['endtime']) or events[eid]['endtime'] >= formattimeobject(Globs.now):
845 html_event_rows.append( listshow_event(events[eid]) )
846
847 html_event_rows = u'\r\n'.join(html_event_rows)
848
849 html_list_table = [
850 u'\r\n<div id="eventlist">',
851 u'<table class="eventlist">',
852 u'<tr><td colspan="7" class="list_entry" style="border-width: 0px;"><b>Upcoming Event List: %s ~ %s</b><p><br><p></td></tr>' % (datefrom, dateto),
853 u'%s' % html_list_header,
854 u'%s' % html_event_rows,
855 u'</table>',
856 u'</div>',
857 ]
858 html_list_table = u'\r\n'.join(html_list_table)
859
860 return html_list_table
861
862
863
864
865 def showcalendar():
866
867 request = Globs.request
868 formatter = Globs.formatter
869 form_vals = Globs.form_vals
870
871 html = []
872
873 if form_vals.has_key('caldate'):
874 try:
875 year, month, str_temp = getdatefield(form_vals['caldate'])
876 except (TypeError, ValueError):
877 errormsgcode('invalid_caldate')
878 year, month, dy = gettodaydate()
879
880 elif Params.curdate:
881 try:
882 year, month, str_temp = getdatefield(Params.curdate)
883 except (TypeError, ValueError):
884 errormsgcode('invalid_curdate')
885 year, month, dy = gettodaydate()
886
887 else:
888 year, month, dy = gettodaydate()
889
890 # check number of calendar
891 numcal = Params.numcal
892
893 if form_vals.has_key('numcal'):
894 try:
895 numcal = int(form_vals['numcal'])
896 except (TypeError, ValueError):
897 errormsgcode('invalid_numcal')
898
899 if numcal < 1:
900 numcal = 1
901 elif numcal > 12:
902 numcal = 12
903
904 for index in range(numcal):
905
906 cyear, cmonth = yearmonthplusoffset(year, month, index)
907
908 cal_html = showeventcalendar(cyear, cmonth)
909 html.append(cal_html)
910
911 return u''.join(html)
912
913
914 def showdailycalendar():
915
916 request = Globs.request
917 formatter = Globs.formatter
918
919 form_vals = Globs.form_vals
920
921 if form_vals.has_key('caldate'):
922 try:
923 year, month, dy = getdatefield(form_vals['caldate'])
924
925 if len(form_vals['caldate']) <= 6:
926 tyear, tmonth, tdy = gettodaydate()
927 if tyear == year and month == tmonth:
928 dy = tdy
929
930 except (TypeError, ValueError):
931 errormsgcode('invalid_caldate')
932 year, month, dy = gettodaydate()
933
934 elif Params.curdate:
935 try:
936 year, month, dy = getdatefield(Params.curdate)
937 except (TypeError, ValueError):
938 errormsgcode('invalid_curdate')
939 year, month, dy = gettodaydate()
940
941 else:
942 year, month, dy = gettodaydate()
943
944 html = showdailyeventcalendar(year, month, dy)
945
946 return u''.join(html)
947
948
949 def showweeklycalendar():
950
951 request = Globs.request
952 formatter = Globs.formatter
953
954 form_vals = Globs.form_vals
955
956 if form_vals.has_key('caldate'):
957 try:
958 year, month, dy = getdatefield(form_vals['caldate'])
959
960 if len(form_vals['caldate']) <= 6:
961 tyear, tmonth, tdy = gettodaydate()
962 if tyear == year and month == tmonth:
963 dy = tdy
964
965 except (TypeError, ValueError):
966 errormsgcode('invalid_caldate')
967 year, month, dy = gettodaydate()
968
969 elif Params.curdate:
970 try:
971 year, month, dy = getdatefield(Params.curdate)
972 except (TypeError, ValueError):
973 errormsgcode('invalid_curdate')
974 year, month, dy = gettodaydate()
975 else:
976 year, month, dy = gettodaydate()
977
978 html = showweeklyeventcalendar(year, month, dy)
979
980 return u''.join(html)
981
982
983 def showsimplecalendar():
984
985 request = Globs.request
986 formatter = Globs.formatter
987 form_vals = Globs.form_vals
988
989 html = []
990
991 if form_vals.has_key('caldate'):
992 try:
993 year, month, str_temp = getdatefield(form_vals['caldate'])
994 except (TypeError, ValueError):
995 errormsgcode('invalid_caldate')
996 year, month, dy = gettodaydate()
997 elif Params.curdate:
998 try:
999 year, month, str_temp = getdatefield(Params.curdate)
1000 except (TypeError, ValueError):
1001 errormsgcode('invalid_curdate')
1002 year, month, dy = gettodaydate()
1003 else:
1004 year, month, dy = gettodaydate()
1005
1006 # check number of calendar
1007 numcal = Params.numcal
1008
1009 if form_vals.has_key('numcal'):
1010 try:
1011 numcal = int(form_vals['numcal'])
1012 except (TypeError, ValueError):
1013 errormsgcode('invalid_numcal')
1014
1015
1016 if numcal < 1:
1017 numcal = 1
1018 elif numcal > 12:
1019 numcal = 12
1020
1021 for index in range(numcal):
1022
1023 cyear, cmonth = yearmonthplusoffset(year, month, index)
1024
1025 cal_html = showsimpleeventcalendar(cyear, cmonth)
1026 html.append(cal_html)
1027
1028 return u''.join(html)
1029
1030
1031
1032 # sort events in cal_events by length of days of the event
1033 def comp_cal_events(xid, yid):
1034 events = Globs.events
1035
1036 if events[xid]['date_len'] > events[yid]['date_len']:
1037 return -1
1038 elif events[xid]['date_len'] == events[yid]['date_len']:
1039 if events[xid]['date_len'] == 1:
1040 if events[xid]['starttime'] == events[yid]['starttime']:
1041 return cmp(events[yid]['time_len'], events[xid]['time_len'])
1042 else:
1043 return cmp(events[xid]['starttime'], events[yid]['starttime'])
1044 else:
1045 return 0
1046 else:
1047 return 1
1048
1049
1050 # sort events in the list by start date of the event
1051 def comp_list_events(xid, yid):
1052 events = Globs.events
1053
1054 return cmp(events[xid]['startdate'], events[yid]['startdate'])
1055
1056 # load events from wiki pages
1057 def loadEvents(datefrom='', dateto='', nocache=0):
1058
1059 request = Globs.request
1060
1061 debug('Loading event information.')
1062
1063 events = {}
1064 labels = {}
1065 cal_events = {}
1066 raw_events = {}
1067
1068 raw_events, labels = loadEventsFromWikiPages()
1069
1070 # handling cal_events
1071 if datefrom or dateto:
1072
1073 # cache configurations
1074 arena = Page(request, Globs.pagename)
1075 eventkey = 'events'
1076 filteredeventkey = 'events_%s-%s' % (datefrom, dateto)
1077 caleventkey = 'calevents_%s-%s' % (datefrom, dateto)
1078
1079 cache_events = caching.CacheEntry(request, arena, eventkey,scope='item')
1080 cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey,scope='item')
1081 cache_calevents = caching.CacheEntry(request, arena, caleventkey,scope='item')
1082
1083 dirty = 1
1084
1085 debug('Checking cal_events cache')
1086
1087 if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())):
1088
1089 try:
1090 events = pickle.loads(cache_filteredevents.content())
1091 cal_events = pickle.loads(cache_calevents.content())
1092 debug('Cached event (filtered) information is used: total %d events' % len(events))
1093 dirty = 0
1094 except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1095 debug('Picke error at fetching cached events (filtered)')
1096 events = {}
1097 cal_events = {}
1098
1099
1100 # if cache is dirty, update the cache
1101 if dirty:
1102
1103 debug('Checking event cache: it\'s dirty or requested to refresh')
1104 debug('Building new cal_event information')
1105
1106 try:
1107 datefrom, dateto = int(datefrom), int(dateto)
1108 except (TypeError, ValueError):
1109 datefrom, dateto = 0, 0
1110
1111 clone_num = 0
1112
1113 for e_id in raw_events.keys():
1114
1115 cur_event = raw_events[e_id]
1116
1117 # handling event recurrence
1118 recur_freq = cur_event['recur_freq']
1119
1120 if recur_freq or recur_freq == -1:
1121
1122 if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto:
1123
1124 if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1125 # generating cal_events for iteself
1126 events[e_id] = cur_event.copy()
1127 insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1128
1129 delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 )
1130
1131 if cur_event['recur_type'] == 'day':
1132
1133 day_delta = int(recur_freq)
1134 startdate = getdatetimefromstring(cur_event['startdate'])
1135 datefrom_date = getdatetimefromstring(datefrom)
1136
1137 if int(datefrom) > int(cur_event['startdate']):
1138 diffs = datefrom_date - startdate
1139 q_delta = diffs.days / day_delta
1140 if diffs.days % day_delta > 0:
1141 q_delta += 1
1142 else:
1143 q_delta = 1
1144
1145 while 1:
1146
1147 if q_delta == 0:
1148 q_delta += 1
1149 continue
1150
1151 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1152 recurred_enddate = recurred_startdate + delta_date_len
1153
1154 new_startdate = formatdateobject(recurred_startdate)
1155 new_enddate = formatdateobject(recurred_enddate)
1156
1157 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1158 break
1159
1160 clone_num += 1
1161 clone_id = 'c%d' % clone_num
1162
1163 events[clone_id] = cur_event.copy()
1164 events[clone_id]['id'] = clone_id
1165 events[clone_id]['startdate'] = new_startdate
1166 events[clone_id]['enddate'] = new_enddate
1167 events[clone_id]['clone'] = 1
1168
1169 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1170
1171 q_delta += 1
1172
1173 elif cur_event['recur_type'] == 'week':
1174
1175 day_delta = int(recur_freq) * 7
1176
1177 startdate = getdatetimefromstring(cur_event['startdate'])
1178 datefrom_date = getdatetimefromstring(datefrom)
1179
1180 if int(datefrom) > int(cur_event['startdate']):
1181 diffs = datefrom_date - startdate
1182 q_delta = diffs.days / day_delta
1183 if diffs.days % day_delta > 0:
1184 q_delta += 1
1185 else:
1186 q_delta = 1
1187
1188 while 1:
1189
1190 if q_delta == 0:
1191 q_delta += 1
1192 continue
1193
1194 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1195 recurred_enddate = recurred_startdate + delta_date_len
1196
1197 new_startdate = formatdateobject(recurred_startdate)
1198 new_enddate = formatdateobject(recurred_enddate)
1199
1200 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1201 break
1202
1203 clone_num += 1
1204 clone_id = 'c%d' % clone_num
1205
1206 events[clone_id] = cur_event.copy()
1207 events[clone_id]['id'] = clone_id
1208 events[clone_id]['startdate'] = new_startdate
1209 events[clone_id]['enddate'] = new_enddate
1210 events[clone_id]['clone'] = 1
1211
1212 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1213
1214 q_delta += 1
1215
1216
1217 elif cur_event['recur_type'] == 'weekday':
1218
1219 syear, smonth, sday = getdatefield(cur_event['startdate'])
1220 cyear, cmonth, cday = getdatefield(str(datefrom))
1221
1222 recur_weekday = calendar.weekday(syear, smonth, sday)
1223
1224 while 1:
1225
1226 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1227 firstmatch = (recur_weekday - firstweekday) % 7 + 1
1228
1229 if recur_freq == -1:
1230 therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1231 else:
1232 #XXX should handle error
1233 try:
1234 therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1]
1235 except IndexError:
1236 if Params.showlastweekday:
1237 # if no matched weekday, the last weekday will be displayed
1238 therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1239 else:
1240 # if no matched weekday, no event will be displayed
1241 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1242 continue
1243
1244
1245 recurred_startdate = datetime.date(cyear, cmonth, therecur_day)
1246 recurred_enddate = recurred_startdate + delta_date_len
1247
1248 new_startdate = formatdateobject(recurred_startdate)
1249 new_enddate = formatdateobject(recurred_enddate)
1250
1251 if int(new_startdate) < int(datefrom) or new_startdate == cur_event['startdate']:
1252 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1253 continue
1254
1255 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1256 break
1257
1258 clone_num += 1
1259 clone_id = 'c%d' % clone_num
1260
1261 events[clone_id] = cur_event.copy()
1262 events[clone_id]['id'] = clone_id
1263 events[clone_id]['startdate'] = new_startdate
1264 events[clone_id]['enddate'] = new_enddate
1265 events[clone_id]['clone'] = 1
1266
1267 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1268
1269 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1270
1271
1272 elif cur_event['recur_type'] == 'month':
1273
1274 cyear, cmonth, therecurday = getdatefield(cur_event['startdate'])
1275
1276 while 1:
1277
1278 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq)
1279 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1280 recur_day = therecurday
1281 if daysinmonth < recur_day:
1282 recur_day = daysinmonth
1283 new_startdate = formatDate(cyear, cmonth, recur_day)
1284
1285 if int(new_startdate) < int(datefrom):
1286 continue
1287
1288 recurred_startdate = datetime.date(cyear, cmonth, recur_day)
1289 recurred_enddate = recurred_startdate + delta_date_len
1290
1291 new_startdate = formatdateobject(recurred_startdate)
1292 new_enddate = formatdateobject(recurred_enddate)
1293
1294 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1295 break
1296
1297 clone_num += 1
1298 clone_id = 'c%d' % clone_num
1299
1300 events[clone_id] = cur_event.copy()
1301 events[clone_id]['id'] = clone_id
1302 events[clone_id]['startdate'] = new_startdate
1303 events[clone_id]['enddate'] = new_enddate
1304 events[clone_id]['clone'] = 1
1305
1306 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1307
1308 elif cur_event['recur_type'] == 'year':
1309
1310 ryear, rmonth, rday = getdatefield(cur_event['startdate'])
1311 cyear, cmonth, cday = getdatefield(str(datefrom))
1312
1313 while 1:
1314
1315 ryear += recur_freq
1316 new_startdate = formatDate(ryear, rmonth, rday)
1317
1318 if int(new_startdate) < int(datefrom):
1319 continue
1320
1321 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1322 break
1323
1324 recurred_startdate = datetime.date(ryear, rmonth, rday)
1325 recurred_enddate = recurred_startdate + delta_date_len
1326
1327 new_startdate = formatdateobject(recurred_startdate)
1328 new_enddate = formatdateobject(recurred_enddate)
1329
1330 clone_num += 1
1331 clone_id = 'c%d' % clone_num
1332
1333 events[clone_id] = cur_event.copy()
1334 events[clone_id]['id'] = clone_id
1335 events[clone_id]['startdate'] = new_startdate
1336 events[clone_id]['enddate'] = new_enddate
1337 events[clone_id]['clone'] = 1
1338
1339 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1340
1341 else:
1342
1343 if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1344 events[e_id] = cur_event.copy()
1345 insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1346
1347
1348 # sort cal_events
1349 # store event list into global variables in order to sort them
1350 Globs.events = events
1351
1352 for eachdate in cal_events.keys():
1353 cal_events[eachdate].sort(comp_cal_events)
1354
1355 # cache update
1356 if not nocache:
1357 cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL))
1358 cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL))
1359
1360 else:
1361 events = raw_events
1362
1363 # store event list into global variables in order to sort them
1364 Globs.events = events
1365
1366 Globs.labels = labels
1367
1368 debug(u'Total %d events are loaded finally.' % len(events))
1369 debug(u'Total %d labels are loaded finally.' % len(labels))
1370
1371 return events, cal_events, labels
1372
1373
1374
1375 def loadEventsFromWikiPages():
1376
1377 events = {}
1378 labels = {}
1379 cached_event_loaded = 0
1380 dirty = 0
1381
1382 eventrecord_list = []
1383 labelrecord_list = []
1384 eventpages = []
1385 stored_errmsg = ''
1386
1387 request = Globs.request
1388 category = Params.category
1389
1390 # cache configurations
1391 arena = Page(request, Globs.pagename)
1392
1393 eventkey = 'events'
1394 labelkey = 'labels'
1395 pagelistkey = 'eventpages'
1396 errmsglistkey = 'eventcalerrormsglist'
1397
1398 cache_events = caching.CacheEntry(request, arena, eventkey,scope='item')
1399 cache_labels = caching.CacheEntry(request, arena, labelkey,scope='item')
1400 cache_pages = caching.CacheEntry(request, arena, pagelistkey,scope='item')
1401 cache_errmsglist = caching.CacheEntry(request, arena, errmsglistkey,scope='item')
1402
1403 # page list cache
1404
1405 debug('Checking page list cache')
1406
1407 # check the time at which page list cache has been created
1408
1409 cp_mtime = cache_pages.mtime()
1410 timedelta_days = 9999
1411
1412 if cp_mtime:
1413 cp_date = datetime.datetime.fromtimestamp(cp_mtime)
1414 today = datetime.datetime.fromtimestamp(time.time())
1415 datediff = today - cp_date
1416 timedelta_days = datediff.days
1417 debug('Time from page list cache built = %s' % datediff)
1418
1419
1420 if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1:
1421 categorypages = searchPages(request, category)
1422 for page in categorypages:
1423 eventpages.append(page.page_name)
1424 cache_pages.update('\n'.join(eventpages).encode('utf-8'))
1425 debug('New page list is built: %d pages' % len(eventpages))
1426 else:
1427 eventpages = cache_pages.content().decode('utf-8').split('\n')
1428 debug('Cached page list is used: %d pages' % len(eventpages))
1429
1430 if not Globs.page_action == 'refresh':
1431 # check the cache validity
1432 for page_name in eventpages:
1433
1434 p = Page(request, page_name)
1435 e_ref = page_name
1436
1437 if cache_events.needsUpdate(p._text_filename()) or cache_labels.needsUpdate(p._text_filename()) or cache_errmsglist.needsUpdate(p._text_filename()):
1438 dirty = 1
1439 break
1440 else:
1441 dirty = 1
1442
1443 if dirty:
1444 # generating events
1445
1446 dirty_local = 0
1447 debug_records = {}
1448
1449 eventrecordkey = 'eventrecords'
1450 labelrecordkey = 'labelrecords'
1451 errmsgkey = 'eventcalerrormsg'
1452
1453 # fetch event records from each page in the category
1454 for page_name in eventpages:
1455
1456 p = Page(request, page_name)
1457 e_ref = page_name
1458
1459
1460 cache_errmsg = caching.CacheEntry(request, p, errmsgkey,scope='item')
1461 cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey,scope='item')
1462 cache_labelrecords = caching.CacheEntry(request, p, labelrecordkey,scope='item')
1463
1464 if cache_eventrecords.needsUpdate(p._text_filename()) or cache_labelrecords.needsUpdate(p._text_filename()) or Globs.page_action == 'refresh':
1465 page_content = p.get_raw_body()
1466 eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref)
1467
1468 debug_records[e_ref] = '%d events are fetched from %s' % (len(eventrecords), e_ref)
1469
1470 # XXXXX
1471 #debug('events: %s' % eventrecords)
1472 #debug('labels: %s' % labelrecords)
1473
1474 cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1475 cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL))
1476 cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL))
1477
1478 stored_errmsg += Globs.errormsg
1479 Globs.errormsg = ''
1480
1481 else:
1482 try:
1483 eventrecords = pickle.loads(cache_eventrecords.content())
1484 labelrecords = pickle.loads(cache_labelrecords.content())
1485 Globs.errormsg = pickle.loads(cache_errmsg.content())
1486
1487 debug_records[e_ref] = '%d cached eventrecords are used from %s' % (len(eventrecords), e_ref)
1488
1489 except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1490 dirty = 1
1491 page_content = p.get_raw_body()
1492 eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref)
1493 debug_records[e_ref] = '%d eventrecords are fetched from %s due to pickle error' % (len(eventrecords), e_ref)
1494
1495 cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1496 cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL))
1497 cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL))
1498
1499 eventrecord_list.append(eventrecords)
1500 labelrecord_list.append(labelrecords)
1501
1502 stored_errmsg += Globs.errormsg
1503 Globs.errormsg = ''
1504
1505 debug('Checking event cache: it\'s dirty or requested to refresh')
1506
1507 else:
1508
1509 debug('Checking event cache: still valid')
1510
1511 try:
1512 events = pickle.loads(cache_events.content())
1513 labels = pickle.loads(cache_labels.content())
1514 stored_errmsg = pickle.loads(cache_errmsglist.content())
1515
1516 cached_event_loaded = 1
1517
1518 debug('Cached event information is used: total %d events' % len(events))
1519
1520 except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1521 events = {}
1522 labels = {}
1523 stored_errmsg = ''
1524
1525 debug('Picke error at fetching cached events')
1526
1527 # if it needs refreshed, generate events dictionary
1528 if not cached_event_loaded:
1529
1530 # XXX: just for debugging
1531 debug('Building new event information')
1532 for page_name in eventpages:
1533 debug(debug_records[page_name])
1534
1535 for eventrecords in eventrecord_list:
1536 for evtrecord in eventrecords:
1537 e_id = evtrecord['id']
1538 events[e_id] = evtrecord
1539
1540 for labelrecords in labelrecord_list:
1541 for label in labelrecords:
1542 c_id = label['name']
1543 if not labels.has_key(c_id):
1544 labels[c_id] = label
1545 else:
1546 stored_errmsg += u'<li>%s\n' % geterrormsg('redefined_label', label['refer'], label['name'])
1547
1548 # after generating updated events, update the cache
1549 cache_events.update(pickle.dumps(events, PICKLE_PROTOCOL))
1550 cache_labels.update(pickle.dumps(labels, PICKLE_PROTOCOL))
1551 cache_errmsglist.update(pickle.dumps(stored_errmsg, PICKLE_PROTOCOL))
1552
1553 debug('Event information is newly built: total %d events' % len(events))
1554
1555 Globs.errormsg = stored_errmsg
1556
1557 # end of updating events block
1558
1559 return events, labels
1560
1561
1562
1563 def getEventRecordFromPage(pagecontent, referpage):
1564
1565 request = Globs.request
1566
1567 eventrecords = []
1568 labelrecords = []
1569 page_bgcolor = ''
1570 page_description = ''
1571
1572 e_num = 0
1573
1574 # fetch the page default bgcolor
1575 regex_page_bgcolor = r"""
1576 (?P<req_field>^[ ]+default_bgcolor::[ ]+)
1577 (
1578 (?P<pagebgcolor>\#[0-9a-fA-F]{6})
1579 \s*?
1580 $
1581 )?
1582 """
1583
1584 pattern = re.compile(regex_page_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1585 match = pattern.search(pagecontent)
1586
1587 if match:
1588 if match.group('pagebgcolor'):
1589 page_bgcolor = match.group('pagebgcolor')
1590 else:
1591 errormsg( geterrormsg('invalid_default_bgcolor', referpage) )
1592
1593
1594 # fetch the page default description
1595 regex_page_description = r"""
1596 (?P<req_field>^[ ]+default_description::[ ]+)
1597 (
1598 (?P<pagedescription>.*?)
1599 \s*?
1600 $
1601 )?
1602 """
1603
1604 pattern = re.compile(regex_page_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1605 match = pattern.search(pagecontent)
1606
1607 if match:
1608 if match.group('pagedescription'):
1609 page_description = match.group('pagedescription')
1610 else:
1611 errormsg( geterrormsg('empty_default_description', referpage) )
1612
1613 # fetch the label definition
1614 regex_label_definition = r"""
1615 (?P<reqfield>^[ ]+label_def::[ ]+)
1616 (
1617 (?P<name>[^,^:^\s]+?)
1618 [,: ]+
1619 (?P<bgcolor>\#[0-9a-fA-F]{6})
1620 \s*?
1621 $
1622 )?
1623 """
1624
1625
1626 pattern = re.compile(regex_label_definition, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1627 match = pattern.findall(pagecontent)
1628
1629 if match:
1630
1631 for matchitem in match:
1632
1633 labelitem = {}
1634
1635 label_name = matchitem[2]
1636 label_bgcolor = matchitem[3]
1637
1638 if label_name and label_bgcolor:
1639 labelitem['name'] = label_name
1640 labelitem['bgcolor'] = label_bgcolor
1641 labelitem['refer'] = referpage
1642
1643 labelrecords.append(labelitem)
1644 else:
1645 errormsg( geterrormsg('empty_label_definition', referpage) )
1646 continue
1647
1648
1649 # fetch event item
1650 regex_eventitem = r"""
1651 (?P<eventitem>
1652 (?P<heading>^\s*(?P<hmarker>=+)\s(?P<eventtitle>.*?)\s(?P=hmarker) $)
1653 (?P<eventdetail>
1654 .*?
1655 (?=
1656 ^\s*(?P<nexthmarker>=+)\s(?P<nexteventtitle>.*?)\s(?P=nexthmarker) $
1657 | \Z
1658 )
1659 )
1660 )
1661 """
1662
1663 pattern = re.compile(regex_eventitem, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1664 match = pattern.findall(pagecontent)
1665
1666 if match:
1667
1668 for matchitem in match:
1669
1670 eventitem = {}
1671
1672 eventtitle = matchitem[3]
1673 eventdetail = matchitem[4]
1674
1675 e_headid = getheadingid(request, referpage, eventtitle)
1676
1677 if not eventdetail:
1678 continue
1679
1680 #debug('Examininng "%s" event from %s ..' % (eventtitle, referpage))
1681
1682 try:
1683 e_start_date, e_start_time, e_end_date, e_end_time, e_bgcolor, e_label, e_description, e_recur_freq, e_recur_type, e_recur_until = geteventfield(eventdetail)
1684 except EventcalError, errmsgcode:
1685
1686 if not errmsgcode.value == 'pass':
1687 errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) )
1688
1689 continue
1690
1691 #except TypeError, ValueError:
1692 # errormsg('undefined')
1693 # continue
1694
1695 # set default values
1696 if not e_bgcolor:
1697 e_bgcolor = page_bgcolor
1698
1699 if not e_description:
1700 e_description = page_description
1701
1702 e_num += 1
1703 e_id = 'e_%s_%d' % (referpage, e_num)
1704
1705 eventitem['id'] = e_id
1706 eventitem['title'] = eventtitle
1707 eventitem['startdate'] = e_start_date
1708 eventitem['starttime'] = e_start_time
1709 eventitem['enddate'] = e_end_date
1710 eventitem['endtime'] = e_end_time
1711 eventitem['title'] = eventtitle
1712 eventitem['refer'] = referpage
1713 eventitem['bgcolor'] = e_bgcolor
1714 eventitem['label'] = e_label
1715 eventitem['description'] = e_description
1716 eventitem['recur_freq'] = e_recur_freq
1717 eventitem['recur_type'] = e_recur_type
1718 eventitem['recur_until'] = e_recur_until
1719
1720 try:
1721 eventitem['date_len'] = diffday(e_start_date, e_end_date) + 1
1722 eventitem['clone'] = 0
1723 eventitem['hid'] = e_headid
1724
1725 if eventitem['date_len'] == 1 and e_start_time and e_end_time:
1726 eventitem['time_len'] = difftime(e_start_time, e_end_time) + 1
1727 else:
1728 eventitem['time_len'] = 0
1729
1730 except EventcalError, errmsgcode:
1731 debug('Failed to add "%s" event from %s ..' % (eventtitle, referpage))
1732 errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) )
1733 continue
1734
1735 eventrecords.append(eventitem)
1736
1737 #debug('Added "%s" event from %s ..' % (eventtitle, referpage))
1738
1739 return eventrecords, labelrecords
1740
1741
1742
1743 def geteventfield(detail):
1744
1745
1746 # START DATE REGEX ----------------------------
1747 regex_startdate = r"""
1748 (?P<reqfield>^[ ]+start::(?=[ ]+))
1749 (
1750 (?P<startdate>
1751 [ ]+
1752 (
1753 (?P<startdate1>
1754 (?P<startyear1>19\d{2} | 20\d{2} | \d{2} )
1755 [./-]
1756 (?P<startmonth1>1[012] | 0[1-9] | [1-9])
1757 [./-]
1758 (?P<startday1>3[01] | 0[1-9] | [12]\d | [1-9])
1759 )
1760 |
1761 (?P<startdate2>
1762 (?P<startmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1763 [ ]+
1764 (?P<startday2>3[01] | 0[1-9] | [12]\d | [1-9])
1765 (?: st | nd | rd | th )?
1766 [ ,]+
1767 (?P<startyear2>19\d{2} | 20\d{2} | \d{2})
1768 )
1769 |
1770 (?P<startdate3>
1771 (?P<startyear3>19\d{2} | 20\d{2} | \d{2} )
1772 (?P<startmonth3>1[012] | 0[1-9])
1773 (?P<startday3>3[01] | 0[1-9] | [12]\d)
1774 )
1775 )
1776 )
1777 (?P<starttime>
1778 [ ,]+
1779 (
1780 (?P<starttime1>
1781 (?P<starthour1> 1[0-2] | [0]?[1-9] )
1782 (
1783 (?: [.:])
1784 (?P<startminute1>[0-5]\d{0,1} | [6-9])
1785 )?
1786 [ ]*
1787 (?P<am1> am | pm | p | a )
1788 )
1789 |
1790 (?P<starttime2>
1791 (?P<starthour2> | [01]\d{0,1} | 2[0-3] | [1-9])
1792 (
1793 (?: [.:])
1794 (?P<startminute2>[0-5]\d{0,1} | [6-9])
1795 )?
1796 )
1797 |
1798 (?P<starttime3>
1799 (?P<starthour3> [01]\d | 2[0-3])
1800 (?P<startminute3> [0-5]\d)?
1801 )
1802 |
1803 (?P<starttime4>
1804 (?P<starthour4> 0[1-9] | 1[0-2])
1805 (?P<startminute4> [0-5]\d)?
1806 [ ]*
1807 (?P<am4> am | pm | p | a )
1808 )
1809 )
1810 )?
1811 \s*?
1812 $
1813 )?
1814 """
1815
1816
1817
1818 # END DATE REGEX ----------------------------
1819 regex_enddate = r"""
1820 (?P<reqfield>^[ ]+end::(?=[ ]+))
1821 (
1822 (?P<enddate>
1823 [ ]+
1824 (
1825 (?P<enddate1>
1826 (?P<endyear1>19\d{2} | 20\d{2} | \d{2} )
1827 [./-]
1828 (?P<endmonth1>1[012] | 0[1-9] | [1-9])
1829 [./-]
1830 (?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9])
1831 )
1832 |
1833 (?P<enddate2>
1834 (?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1835 [ ]+
1836 (?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9])
1837 (?: st | nd | rd | th )?
1838 [ ,]+
1839 (?P<endyear2>19\d{2} | 20\d{2} | \d{2})
1840 )
1841 |
1842 (?P<enddate3>
1843 (?P<endyear3>19\d{2} | 20\d{2} | \d{2} )
1844 (?P<endmonth3>1[012] | 0[1-9])
1845 (?P<endday3>3[01] | 0[1-9] | [12]\d)
1846 )
1847 )
1848 )?
1849 (?P<endtime>
1850 [ ,]+
1851 (
1852 (?P<endtime1>
1853 (?P<endhour1> 1[0-2] | [0]?[1-9] )
1854 (
1855 (?: [.:])
1856 (?P<endminute1>[0-5]\d{0,1} | [6-9])
1857 )?
1858 [ ]*
1859 (?P<am1> am | pm | p | a )
1860 )
1861 |
1862 (?P<endtime2>
1863 (?P<endhour2> | [01]\d{0,1} | 2[0-3] | [1-9])
1864 (
1865 (?: [.:])
1866 (?P<endminute2>[0-5]\d{0,1} | [6-9])
1867 )?
1868 )
1869 |
1870 (?P<endtime3>
1871 (?P<endhour3> [01]\d | 2[0-3])
1872 (?P<endminute3> [0-5]\d)?
1873 )
1874 |
1875 (?P<endtime4>
1876 (?P<endhour4> 0[1-9] | 1[0-2])
1877 (?P<endminute4> [0-5]\d)?
1878 [ ]*
1879 (?P<am4> am | pm | p | a )
1880 )
1881 )
1882 )?
1883 \s*?
1884 $
1885 )?
1886 """
1887
1888 regex_bgcolor = r"""
1889 (?P<reqfield>^[ ]+bgcolor::[ ]+)
1890 (
1891 (?P<bgcolor>\#[0-9a-fA-F]{6})?
1892 \s*?
1893 $
1894 )?
1895 """
1896
1897 regex_description = r"""
1898 (?P<reqfield>^[ ]+description::[ ]+)
1899 (
1900 (?P<description>.*?)
1901 \s*?
1902 $
1903 )?
1904 """
1905
1906
1907 regex_recur = r"""
1908 (?P<reqfield>^[ ]+recur::[ ]+)
1909 (
1910 (?P<recur_freq>\d+|last)
1911 \s+
1912 (?P<recur_type>weekday|day|week|month|year)
1913 (
1914 \s+
1915 (?P<recur_until_req>until)
1916 \s+
1917 (?P<recur_until>
1918 (?P<enddate>
1919 (?P<enddate1>
1920 (?P<endyear1>19\d{2} | 20\d{2} | \d{2} )
1921 [./-]
1922 (?P<endmonth1>1[012] | 0[1-9] | [1-9])
1923 [./-]
1924 (?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9])
1925 )
1926 |
1927 (?P<enddate2>
1928 (?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1929 \s+
1930 (?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9])
1931 (?: st | nd | rd | th )?
1932 [\s,]+
1933 (?P<endyear2>19\d{2} | 20\d{2} | \d{2})
1934 )
1935 |
1936 (?P<enddate3>
1937 (?P<endyear3>19\d{2} | 20\d{2} | \d{2} )
1938 (?P<endmonth3>1[012] | 0[1-9])
1939 (?P<endday3>3[01] | 0[1-9] | [12]\d)
1940 )
1941 )?
1942 )?
1943 )?
1944 \s*?
1945 $
1946 )?
1947 """
1948
1949 regex_label = r"""
1950 (?P<reqfield>^[ ]+label::[ ]+)
1951 (
1952 (?P<name>[^,^:^\s]+?)
1953 \s*?
1954 $
1955 )?
1956 """
1957
1958
1959 # need help on regular expressions for more efficient/flexible form
1960
1961 # compile regular expression objects
1962
1963 pattern_startdate = re.compile(regex_startdate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1964 pattern_enddate = re.compile(regex_enddate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1965 pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1966 pattern_label = re.compile(regex_label, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1967 pattern_description = re.compile(regex_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1968 pattern_recur = re.compile(regex_recur, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1969
1970 ##################### retrieve startdate
1971 match = pattern_startdate.search(detail)
1972
1973 if match:
1974
1975 if match.group('startdate'):
1976 passed = 1
1977 # yyyy/mm/dd: 2006/05/10; 06/05/10,
1978 if match.group('startdate1'):
1979 if len(match.group('startyear1')) == 2:
1980 startyear = '20%s' % match.group('startyear1')
1981 else:
1982 startyear = match.group('startyear1')
1983
1984 startmonth = match.group('startmonth1')
1985 startday = match.group('startday1')
1986
1987 # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
1988 elif match.group('startdate2'):
1989 if len(match.group('startyear2')) == 2:
1990 startyear = '20%s' % match.group('startyear2')
1991 else:
1992 startyear = match.group('startyear2')
1993
1994 startmonth = getNumericalMonth(match.group('startmonth2'))
1995 if not startmonth:
1996 raise EventcalError('invalid_startdate')
1997
1998 startday = match.group('startday2')
1999
2000 # yyyymmdd: 20060510, 060510
2001 elif match.group('startdate3'):
2002 if len(match.group('startyear3')) == 2:
2003 startyear = '20%s' % match.group('startyear3')
2004 else:
2005 startyear = match.group('startyear3')
2006
2007 startmonth = match.group('startmonth3')
2008 startday = match.group('startday3')
2009
2010 else:
2011 if len(match.group('startdate').strip()) > 0:
2012 raise EventcalError('invalid_startdate')
2013 else:
2014 passed = 0
2015
2016 if passed:
2017 startdate = '%d/%02d/%02d' % (int(startyear), int(startmonth), int(startday))
2018 else:
2019 startdate = ''
2020
2021 else:
2022 startdate = ''
2023
2024 if match.group('starttime'):
2025 passed = 1
2026 # 12h with ':': 12:00; 9:00pm
2027 if match.group('starttime1'):
2028 starthour = int(match.group('starthour1'))
2029 if match.group('startminute1'):
2030 startmin = int(match.group('startminute1'))
2031 else:
2032 startmin = 0
2033
2034 if starthour < 12 and match.group('am1').lower().startswith('p'):
2035 starthour += 12
2036
2037 # 24h with ':': 12:00; 23:00
2038 elif match.group('starttime2'):
2039 starthour = int(match.group('starthour2'))
2040 if match.group('startminute2'):
2041 startmin = int(match.group('startminute2'))
2042 else:
2043 startmin = 0
2044
2045 # 24h without ':': 1200; 2300
2046 elif match.group('starttime3'):
2047 starthour = int(match.group('starthour3'))
2048 if match.group('startminute3'):
2049 startmin = int(match.group('startminute3'))
2050 else:
2051 startmin = 0
2052
2053 # 12h without ':': 1200; 0900pm
2054 elif match.group('starttime4'):
2055
2056 starthour = int(match.group('starthour4'))
2057 if match.group('startminute4'):
2058 startmin = int(match.group('startminute4'))
2059 else:
2060 startmin = 0
2061
2062 if starthour < 12 and match.group('am4').lower().startswith('p'):
2063 starthour += 12
2064
2065 else:
2066 if len(match.group('starttime').strip()) > 0:
2067 raise EventcalError('invalid_starttime')
2068 else:
2069 passed = 0
2070
2071 if passed:
2072 starttime = '%02d:%02d' % (int(starthour), int(startmin))
2073 else:
2074 starttime = ''
2075
2076 else:
2077 starttime = ''
2078
2079 if not startdate:
2080 raise EventcalError('invalid_start')
2081
2082 else:
2083 raise EventcalError('pass')
2084
2085 ##################### retrieve enddate
2086 match = pattern_enddate.search(detail)
2087
2088 if match:
2089
2090 if match.group('enddate'):
2091 passed = 1
2092 # yyyy/mm/dd: 2006/05/10; 06/05/10,
2093 if match.group('enddate1'):
2094 if len(match.group('endyear1')) == 2:
2095 endyear = '20%s' % match.group('endyear1')
2096 else:
2097 endyear = match.group('endyear1')
2098
2099 endmonth = match.group('endmonth1')
2100 endday = match.group('endday1')
2101
2102 # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2103 elif match.group('enddate2'):
2104 if len(match.group('endyear2')) == 2:
2105 endyear = '20%s' % match.group('endyear2')
2106 else:
2107 endyear = match.group('endyear2')
2108
2109 endmonth = getNumericalMonth(match.group('endmonth2'))
2110 if not endmonth:
2111 raise EventcalError('invalid_enddate')
2112
2113 endday = match.group('endday2')
2114
2115 # yyyymmdd: 20060510, 060510
2116 elif match.group('enddate3'):
2117 if len(match.group('endyear3')) == 2:
2118 endyear = '20%s' % match.group('endyear3')
2119 else:
2120 endyear = match.group('endyear3')
2121
2122 endmonth = match.group('endmonth3')
2123 endday = match.group('endday3')
2124
2125 else:
2126 if len(match.group('enddate').strip()) > 0:
2127 raise EventcalError('invalid_enddate')
2128 else:
2129 passed = 0
2130
2131 if passed:
2132 enddate = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2133 else:
2134 enddate = ''
2135
2136 else:
2137 enddate = ''
2138
2139 if match.group('endtime'):
2140 passed = 1
2141 # 12h with ':': 12:00; 9:00pm
2142 if match.group('endtime1'):
2143 endhour = int(match.group('endhour1'))
2144 if match.group('endminute1'):
2145 endmin = int(match.group('endminute1'))
2146 else:
2147 endmin = 0
2148
2149 if endhour < 12 and match.group('am1').lower() == 'pm':
2150 endhour += 12
2151
2152 # 24h with ':': 12:00; 23:00
2153 elif match.group('endtime2'):
2154 endhour = int(match.group('endhour2'))
2155 if match.group('endminute2'):
2156 endmin = int(match.group('endminute2'))
2157 else:
2158 endmin = 0
2159
2160 # 24h without ':': 1200; 2300
2161 elif match.group('endtime3'):
2162 endhour = int(match.group('endhour3'))
2163 if match.group('endminute3'):
2164 endmin = int(match.group('endminute3'))
2165 else:
2166 endmin = 0
2167
2168 # 12h without ':': 1200; 0900pm
2169 elif match.group('endtime4'):
2170
2171 endhour = int(match.group('endhour4'))
2172 if match.group('endminute4'):
2173 endmin = int(match.group('endminute4'))
2174 else:
2175 endmin = 0
2176
2177 if endhour < 12 and match.group('am4').lower() == 'pm':
2178 endhour += 12
2179
2180 else:
2181 if len(match.group('endtime').strip()) > 0:
2182 raise EventcalError('invalid_endtime')
2183 else:
2184 passed = 0
2185
2186 if passed:
2187 endtime = '%02d:%02d' % (int(endhour), int(endmin))
2188 else:
2189 endtime = ''
2190
2191 else:
2192 endtime = ''
2193
2194 if not (enddate or endtime):
2195 raise EventcalError('invalid_end')
2196
2197 else:
2198 enddate = ''
2199 endtime = ''
2200
2201
2202 ##################### retrieve bgcolor
2203 match = pattern_bgcolor.search(detail)
2204
2205 if match:
2206 if match.group('bgcolor'):
2207 bgcolor = match.group('bgcolor')
2208 else:
2209 errormsgcode('invalid_bgcolor')
2210 bgcolor = ''
2211
2212 else:
2213 bgcolor = ''
2214
2215 ##################### retrieve label
2216 match = pattern_label.search(detail)
2217
2218 if match:
2219 if match.group('name'):
2220 label = match.group('name')
2221 else:
2222 errormsgcode('invalid_label')
2223 label = ''
2224
2225 else:
2226 label = ''
2227
2228 ##################### retrieve description
2229 match = pattern_description.search(detail)
2230
2231 if match:
2232 if match.group('description'):
2233 description = match.group('description')
2234 else:
2235 errormsgcode('empty_description')
2236 description = ''
2237 else:
2238 description = ''
2239
2240 ##################### retrieve recurrence
2241 match = pattern_recur.search(detail)
2242
2243 if match:
2244
2245 if match.group('recur_freq') and match.group('recur_type'):
2246
2247 if match.group('recur_freq') == 'last':
2248 if match.group('recur_type') == 'weekday':
2249 recur_freq = -1
2250 recur_type = match.group('recur_type')
2251 recur_until = match.group('recur_until')
2252 else:
2253 recur_freq = 0
2254 recur_type = ''
2255 recur_until = ''
2256
2257 else:
2258 recur_freq = int(match.group('recur_freq'))
2259 recur_type = match.group('recur_type')
2260
2261 if match.group('recur_until_req'):
2262 if match.group('recur_until'):
2263 # yyyy/mm/dd: 2006/05/10; 06/05/10,
2264 if match.group('enddate1'):
2265 if len(match.group('endyear1')) == 2:
2266 endyear = '20%s' % match.group('endyear1')
2267 else:
2268 endyear = match.group('endyear1')
2269
2270 endmonth = match.group('endmonth1')
2271 endday = match.group('endday1')
2272
2273 # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2274 elif match.group('enddate2'):
2275 if len(match.group('endyear2')) == 2:
2276 endyear = '20%s' % match.group('endyear2')
2277 else:
2278 endyear = match.group('endyear2')
2279
2280 endmonth = getNumericalMonth(match.group('endmonth2'))
2281 if not endmonth:
2282 raise EventcalError('invalid_recur_until')
2283
2284 endday = match.group('endday2')
2285
2286 # yyyymmdd: 20060510, 060510
2287 elif match.group('enddate3'):
2288 if len(match.group('endyear3')) == 2:
2289 endyear = '20%s' % match.group('endyear3')
2290 else:
2291 endyear = match.group('endyear3')
2292
2293 endmonth = match.group('endmonth3')
2294 endday = match.group('endday3')
2295
2296 else:
2297 raise EventcalError('invalid_recur_until')
2298
2299 recur_until = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2300
2301 else:
2302 raise EventcalError('invalid_recur_until')
2303
2304 else:
2305 recur_until = ''
2306
2307 else:
2308 raise EventcalError('invalid_recur')
2309
2310 else:
2311 recur_freq = 0
2312 recur_type = ''
2313 recur_until = ''
2314
2315 # check validity of each fields
2316
2317 if (starttime or endtime):
2318 if not endtime:
2319 endtime = starttime
2320 elif not starttime:
2321 raise EventcalError('need_starttime')
2322
2323
2324 # if no time, it's 1-day event
2325 if not enddate:
2326 enddate = startdate
2327
2328 try:
2329 syear, smonth, sday = getdatefield(startdate)
2330 except (TypeError, ValueError):
2331 raise EventcalError('invalid_startdate')
2332
2333 try:
2334 eyear, emonth, eday = getdatefield(enddate)
2335 except (TypeError, ValueError):
2336 raise EventcalError('invalid_enddate')
2337
2338 if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
2339 raise EventcalError('enddate_precede')
2340
2341 # format date
2342 startdate = formatDate(syear, smonth, sday)
2343 enddate = formatDate(eyear, emonth, eday)
2344
2345 if (starttime and endtime):
2346 try:
2347 shour, smin = gettimefield(starttime)
2348 except (TypeError, ValueError):
2349 raise EventcalError('invalid_starttime')
2350
2351 try:
2352 ehour, emin = gettimefield(endtime)
2353 except (TypeError, ValueError):
2354 raise EventcalError('invalid_endtime')
2355
2356 if startdate == enddate:
2357 if datetime.time(shour, smin) > datetime.time(ehour, emin):
2358 raise EventcalError('endtime_precede')
2359
2360 # format time
2361 starttime = u'%02d%02d' %(shour, smin)
2362 endtime = u'%02d%02d' %(ehour, emin)
2363
2364 # check recurrent data
2365 event_len = diffday(startdate, enddate)
2366 if recur_freq:
2367
2368 if recur_type == 'day':
2369 if event_len > int(recur_freq):
2370 raise EventcalError('len_recur_int')
2371
2372 elif recur_type == 'week':
2373 if event_len > int(recur_freq) * 7:
2374 raise EventcalError('len_recur_int')
2375
2376 elif recur_type == 'weekday':
2377 if event_len > 25:
2378 raise EventcalError('len_recur_int')
2379
2380 elif recur_type == 'month':
2381 if event_len > int(recur_freq) * 25:
2382 raise EventcalError('len_recur_int')
2383
2384 elif recur_type == 'year':
2385 if event_len > int(recur_freq) * 365:
2386 raise EventcalError('len_recur_int')
2387
2388 if recur_until:
2389 try:
2390 ryear, rmonth, rday = getdatefield(recur_until)
2391 except (TypeError, ValueError):
2392 raise EventcalError('invalid_recur_until')
2393
2394 recur_until = formatDate(ryear, rmonth, rday)
2395
2396 if int(recur_until) < int(enddate):
2397 raise EventcalError('recur_until_precede')
2398
2399 return startdate, starttime, enddate, endtime, bgcolor, label, description, recur_freq, recur_type, recur_until
2400
2401
2402
2403 def converttext(targettext):
2404 # Converts some special characters of html to plain-text style
2405 # What else to handle?
2406
2407 targettext = targettext.replace(u'&', '&')
2408 targettext = targettext.replace(u'>', '>')
2409 targettext = targettext.replace(u'<', '<')
2410 targettext = targettext.replace(u'\n', '<br>')
2411 targettext = targettext.replace(u'"', '"')
2412 targettext = targettext.replace(u'\t', '  ')
2413 targettext = targettext.replace(u' ', ' ')
2414
2415 return targettext
2416
2417
2418 # monthly view
2419 def showeventcalendar(year, month):
2420
2421 debug('Show Calendar: Monthly View')
2422
2423 request = Globs.request
2424 formatter = Globs.formatter
2425 _ = request.getText
2426
2427 wkend = Globs.wkend
2428 months= Globs.months
2429 wkdays = Globs.wkdays
2430
2431 # get the calendar
2432 monthcal = calendar.monthcalendar(year, month)
2433
2434 # shows current year & month
2435 html_header_curyearmonth = calhead_yearmonth(year, month, 'head_yearmonth')
2436
2437 r7 = range(7)
2438
2439 # shows header of week days
2440 html_header_weekdays = []
2441
2442 for wkday in r7:
2443 wday = _(wkdays[wkday])
2444 html_header_weekdays.append( calhead_weekday(wday, 'head_weekday') )
2445 html_header_weekdays = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
2446
2447 # pending events for next row
2448 next_pending = []
2449
2450 # gets previous, next month
2451 day_delta = datetime.timedelta(days=-1)
2452 cur_month = datetime.date(year, month, 1)
2453 prev_month = cur_month + day_delta
2454
2455 day_delta = datetime.timedelta(days=15)
2456 cur_month_end = datetime.date(year, month, 25)
2457 next_month = cur_month_end + day_delta
2458
2459 prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
2460 next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
2461
2462 # shows days
2463 html_week_rows = []
2464
2465 # set ranges of events
2466 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2467 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2468
2469 # read all the events
2470 events, cal_events, labels = loadEvents(datefrom, dateto)
2471
2472 #debug(u' events: %s' % events)
2473 #debug(u' cal_events: %s' % cal_events)
2474
2475 for week in monthcal:
2476
2477 # day head rows
2478 html_headday_cols = []
2479 html_events_rows = []
2480
2481 for wkday in r7:
2482
2483 day = week[wkday]
2484
2485 if not day:
2486 if week == monthcal[0]:
2487 nb_day = prev_monthcal[-1][wkday]
2488 else:
2489 nb_day = next_monthcal[0][wkday]
2490
2491 html_headday_cols.append( calhead_day_nbmonth(nb_day) )
2492 else:
2493 html_headday_cols.append( calhead_day(year, month, day, wkday) )
2494
2495 html_headday_row = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
2496 html_week_rows.append(html_headday_row)
2497
2498 # dummy rows
2499 html_headdummy_cols = []
2500
2501 for wkday in r7:
2502 day = week[wkday]
2503 if not day:
2504 html_headdummy_cols.append( calshow_blankbox('head_dummy_nbmonth') )
2505 else:
2506 html_headdummy_cols.append( calshow_blankbox('head_dummy') )
2507
2508 html_headdummy_cols = u'\r\n'.join(html_headdummy_cols)
2509 html_week_rows.append(' <tr>\r\n%s </tr>\r\n' % html_headdummy_cols)
2510
2511 # pending events for next row
2512 pending = next_pending
2513 next_pending = []
2514
2515 # show events
2516 while 1:
2517 event_left = 7
2518 colspan = -1
2519 html_events_cols = []
2520
2521 for wkday in r7:
2522
2523 day = week[wkday]
2524
2525 if not day:
2526 if week == monthcal[0]:
2527 cur_date = formatDate(prev_month.year, prev_month.month, prev_monthcal[-1][wkday])
2528 else:
2529 cur_date = formatDate(next_month.year, next_month.month, next_monthcal[0][wkday])
2530 else:
2531 cur_date = formatDate(year, month, day)
2532
2533 # if an event is already displayed with colspan
2534 if colspan > 0:
2535 colspan -= 1
2536 if cal_events.has_key(cur_date) and lastevent in cal_events[cur_date]:
2537 cal_events[cur_date].remove(lastevent)
2538
2539 continue
2540
2541 # if there is any event for this date
2542 if cal_events.has_key(cur_date):
2543 if len(cal_events[cur_date]) > 0:
2544
2545 # if there is any pending event in the previous week
2546 if wkday == 0 and len(pending) > 0:
2547 todo_event_id = pending.pop(0)
2548 if todo_event_id in cal_events[cur_date]:
2549 cur_event = events[todo_event_id]
2550 temp_len = diffday(cur_date, cur_event['enddate']) + 1
2551
2552 # calculate colspan value
2553 if (7-wkday) < temp_len:
2554 colspan = 7 - wkday
2555 next_pending.append(cur_event['id'])
2556 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
2557
2558 else:
2559 colspan = temp_len
2560 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
2561
2562
2563 cal_events[cur_date].remove(todo_event_id)
2564
2565 colspan -= 1
2566 lastevent = todo_event_id
2567 else:
2568 debug('Warning: no such event in cal_events')
2569
2570 continue
2571
2572 # if there is no pending event in the previous week, start a new event
2573 event_found = 0
2574 for e_id in cal_events[cur_date]:
2575
2576 # if the start date of the event is current date
2577 if events[e_id]['startdate'] == cur_date:
2578
2579 cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2580
2581 # calculate colspan value
2582 if (7-wkday) < cur_event['date_len']:
2583 colspan = 7 - wkday
2584 next_pending.append(cur_event['id'])
2585 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'pending', cur_date) )
2586
2587 else:
2588 colspan = cur_event['date_len']
2589 html_events_cols.append( calshow_eventbox(cur_event, colspan, '', cur_date) )
2590
2591 colspan -= 1
2592 lastevent = cur_event['id']
2593 event_found = 1
2594 break
2595
2596 # if the start date of the event is NOT current date
2597 else:
2598
2599 # pending event from previous month
2600 if wkday == 0 and week == monthcal[0]:
2601
2602 cur_event = events[cal_events[cur_date].pop(0)]
2603 temp_len = diffday(cur_date, cur_event['enddate']) + 1
2604
2605 # calculate colspan value
2606 if (7-wkday) < temp_len:
2607 colspan = 7 - wkday
2608 next_pending.append(cur_event['id'])
2609 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
2610 else:
2611 colspan = temp_len
2612 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
2613
2614 colspan -= 1
2615 lastevent = cur_event['id']
2616 event_found = 1
2617 break
2618
2619 # if there is no event to start
2620 if not event_found:
2621 if not day:
2622 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2623 else:
2624 html_events_cols.append( calshow_blankbox('cal_noevent') )
2625 event_left -= 1
2626
2627 else:
2628 if not day:
2629 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2630 else:
2631 html_events_cols.append( calshow_blankbox('cal_noevent') )
2632
2633 event_left -= 1
2634
2635 # if there is NO event for this date
2636 else:
2637 if not day:
2638 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2639 else:
2640 html_events_cols.append( calshow_blankbox('cal_noevent') )
2641
2642 event_left -= 1
2643
2644 # if no event for this entry
2645 if not event_left:
2646 # ignore the previous entry
2647 break
2648 else:
2649 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2650
2651 # show dummy blank slots for week height
2652 left_blank_rows = 2 - len(html_events_rows)
2653
2654 # remove the followings
2655 if left_blank_rows > 0 and 0:
2656 for i in range(left_blank_rows):
2657 html_events_cols = []
2658 for wkday in r7:
2659 day = week[wkday]
2660 if not day:
2661 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2662 else:
2663 html_events_cols.append( calshow_blankbox('cal_noevent') )
2664
2665 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2666
2667
2668 # close the week slots
2669 html_events_cols = []
2670 for wkday in r7:
2671 day = week[wkday]
2672 if not day:
2673 html_events_cols.append( calshow_blankbox('cal_last_nbmonth') )
2674 else:
2675 html_events_cols.append( calshow_blankbox('cal_last_noevent') )
2676
2677 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2678
2679 html_events_rows = u'\r\n'.join(html_events_rows)
2680 html_week_rows.append(html_events_rows)
2681
2682 html_calendar_rows = u'\r\n'.join(html_week_rows)
2683
2684 html_cal_table = [
2685 u'\r\n<div id="eventcalendar">',
2686 u'<table class="eventcalendar" %s>' % Params.monthlywidth,
2687 u'%s' % html_header_curyearmonth,
2688 u'%s' % html_header_weekdays,
2689 u'%s' % html_calendar_rows,
2690 u'</table>',
2691 u'</div>',
2692 ]
2693 html_cal_table = u'\r\n'.join(html_cal_table)
2694
2695 return html_cal_table
2696
2697
2698
2699 # daily view
2700 def showdailyeventcalendar(year, month, day):
2701
2702 debug('Show Calendar: Daily View')
2703
2704 request = Globs.request
2705 formatter = Globs.formatter
2706 _ = request.getText
2707
2708 wkend = Globs.wkend
2709 months= Globs.months
2710 wkdays = Globs.wkdays
2711
2712 cur_date = formatDate(year, month, day)
2713
2714 # gets previous, next month
2715 day_delta = datetime.timedelta(days=-1)
2716 cur_month = datetime.date(year, month, 1)
2717 prev_month = cur_month + day_delta
2718
2719 day_delta = datetime.timedelta(days=15)
2720 cur_month_end = datetime.date(year, month, 25)
2721 next_month = cur_month_end + day_delta
2722
2723 # set ranges of events
2724 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2725 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2726
2727 # read all the events
2728 events, cal_events, labels = loadEvents(datefrom, dateto)
2729
2730 #debug(u' events: %s' % events)
2731 #debug(u' cal_events: %s' % cal_events)
2732
2733 # calculates hour_events
2734 hour_events = {}
2735
2736 if cal_events.has_key(cur_date):
2737 for e_id in cal_events[cur_date]:
2738 cur_event = events[e_id]
2739
2740 if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2741 start_hour, start_min = gettimefield(cur_event['starttime'])
2742
2743 if not hour_events.has_key(start_hour):
2744 hour_events[start_hour] = []
2745
2746 hour_events[start_hour].append(e_id)
2747
2748 #debug(u'hour_events: %s' % hour_events)
2749
2750 # in-day events
2751 html_calendar_rows = []
2752 html_hour_cols = {}
2753
2754 slot_pending = {}
2755 max_num_slots = 0
2756 hour_max_slots = {}
2757 block_slots = []
2758
2759 start_hour_index = 0
2760
2761 r24 = range(24)
2762
2763 for hour_index in r24:
2764
2765 html_hour_cols[hour_index] = []
2766 hour_max_slots[hour_index] = 1
2767 html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
2768
2769 if len(slot_pending) > 0 or hour_events.has_key(hour_index):
2770
2771 #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2772 if len(slot_pending) == 0:
2773 if max_num_slots < 1:
2774 max_num_slots = 1
2775
2776 for hour_lines in range(start_hour_index, hour_index):
2777 hour_max_slots[hour_lines] = max_num_slots
2778
2779 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2780
2781 block_slots.append(max_num_slots)
2782
2783 max_num_slots = 0
2784 start_hour_index = hour_index
2785
2786 for slot_index in range(max_num_slots):
2787 if slot_pending.has_key(slot_index) and slot_pending[slot_index] > 0:
2788 if slot_pending[slot_index] == 1:
2789 del slot_pending[slot_index]
2790 else:
2791 slot_pending[slot_index] -= 1
2792 html_hour_cols[hour_index].append ( '' )
2793
2794 else:
2795 if hour_events.has_key(hour_index) and len(hour_events[hour_index]) > 0:
2796 e_id = hour_events[hour_index][0]
2797 cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2798 html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2799 slot_pending[slot_index] = cur_event['time_len'] - 1
2800 else:
2801 if not ((len(slot_pending) > 0 and slot_index > max(slot_pending.keys())) or len(slot_pending) == 0):
2802 html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2803
2804 if hour_events.has_key(hour_index):
2805 for tmp_cnt in range(len(hour_events[hour_index])):
2806 e_id = hour_events[hour_index][0]
2807 cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2808 html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2809 slot_pending[max_num_slots] = cur_event['time_len'] - 1
2810 if slot_pending[max_num_slots] == 0:
2811 del slot_pending[max_num_slots]
2812 max_num_slots += 1
2813
2814 else:
2815 html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2816 #hour_max_slots[hour_index] = 1
2817
2818 if max_num_slots < 1:
2819 max_num_slots = 1
2820
2821 for hour_lines in range(start_hour_index, hour_index):
2822 hour_max_slots[hour_lines] = max_num_slots
2823
2824 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2825
2826 block_slots.append(max_num_slots)
2827
2828 max_num_slots = 0
2829 start_hour_index = hour_index
2830
2831
2832 #debug('end: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2833
2834 if max_num_slots < 1:
2835 max_num_slots = 1
2836
2837 for hour_lines in range(start_hour_index, 24):
2838 hour_max_slots[hour_lines] = max_num_slots
2839
2840 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, 23, max_num_slots))
2841
2842 block_slots.append(max_num_slots)
2843
2844 #debug('hour_max_slots: %s' % hour_max_slots)
2845
2846
2847 # calculates global colspan
2848 if len(block_slots):
2849 global_colspan = LCM(block_slots)
2850 else:
2851 global_colspan = 1
2852
2853 for hour_index in r24:
2854
2855 colspan = global_colspan / hour_max_slots[hour_index]
2856 width = 96 / hour_max_slots[hour_index]
2857
2858 left_slots = hour_max_slots[hour_index] - (len(html_hour_cols[hour_index]) - 1)
2859
2860 if left_slots > 0:
2861 #debug('appending left %d slots: %d' % (left_slots, hour_index))
2862 html_hour_cols[hour_index].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
2863
2864 html_cols = u'\r\n'.join(html_hour_cols[hour_index]) % {'colspan': colspan, 'width': u'%d%%' % width}
2865 html_cols = u'<tr>%s</tr>\r\n' % html_cols
2866
2867 html_calendar_rows.append (html_cols)
2868
2869 html_calendar_rows = u'\r\n'.join(html_calendar_rows)
2870
2871 # shows current year & month
2872 html_header_curyearmonthday = calhead_yearmonthday(year, month, day, 'head_yearmonth', global_colspan)
2873
2874 # one-day long events
2875 html_oneday_rows = []
2876
2877 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2878
2879 if cal_events.has_key(cur_date):
2880 if len(cal_events[cur_date]) > 0:
2881 for e_id in cal_events[cur_date]:
2882 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2883 #debug('test events[%s] = %s' % (e_id, events[e_id]))
2884 if events[e_id]['time_len'] <= 0 or events[e_id]['date_len'] > 1:
2885 #cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2886 cur_event = events[e_id]
2887
2888 if cur_event['startdate'] == cur_date:
2889 if cur_event['enddate'] == cur_date:
2890 str_status = ''
2891 else:
2892 str_status = 'pending'
2893 else:
2894 if cur_event['enddate'] == cur_date:
2895 str_status = 'append'
2896 else:
2897 str_status = 'append_pending'
2898
2899 tmp_html = u'<tr><td width="4%%" style="border-width: 0px; "> </td>%s</tr>' % calshow_daily_eventbox2(cur_event, global_colspan, str_status, cur_date)
2900 html_oneday_rows.append( tmp_html )
2901
2902 #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2903 else:
2904 tmp_html = u'<tr><td width="4%%" style="border-width: 0px; "> </td>%s</tr>' % calshow_blankbox2('cal_daily_noevent', global_colspan)
2905 html_oneday_rows.append( tmp_html )
2906
2907 #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2908 #debug('html_oneday_rows = %s' % html_oneday_rows)
2909
2910 html_oneday_rows = u'\r\n'.join(html_oneday_rows)
2911
2912
2913 html_cal_table = [
2914 u'\r\n<div id="eventcalendar">',
2915 u'<table class="eventcalendar" %s>' % Params.dailywidth,
2916 u'<table border="0">',
2917 u'%s' % html_header_curyearmonthday,
2918 u'%s' % html_oneday_rows,
2919 u'%s' % html_calendar_rows,
2920 u'</table>',
2921 u'</td></tr>',
2922 u'</div>',
2923 ]
2924 html_cal_table = u'\r\n'.join(html_cal_table)
2925
2926 return html_cal_table
2927
2928
2929
2930 # weekly view
2931 def showweeklyeventcalendar(year, month, day):
2932
2933 debug('Show Calendar: Weekly View')
2934
2935 request = Globs.request
2936 formatter = Globs.formatter
2937 _ = request.getText
2938
2939 wkend = Globs.wkend
2940 months= Globs.months
2941 wkdays = Globs.wkdays
2942
2943 cur_date = formatDate(year, month, day)
2944
2945 # gets previous, next month
2946 day_delta = datetime.timedelta(days=-1)
2947 cur_month = datetime.date(year, month, 1)
2948 prev_month = cur_month + day_delta
2949
2950 day_delta = datetime.timedelta(days=15)
2951 cur_month_end = datetime.date(year, month, 25)
2952 next_month = cur_month_end + day_delta
2953
2954 # set ranges of events
2955 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2956 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2957
2958 # read all the events
2959 events, cal_events, labels = loadEvents(datefrom, dateto)
2960
2961 #debug(u' events: %s' % events)
2962 #debug(u' cal_events: %s' % cal_events)
2963
2964 # calculates hour_events
2965 hour_events = {}
2966
2967 first_date_week = getFirstDateOfWeek(year, month, day)
2968
2969
2970 for dayindex in range(7):
2971 hour_events[dayindex] = {}
2972
2973 cur_date = first_date_week + datetime.timedelta(dayindex)
2974 cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
2975
2976 if cal_events.has_key(cur_date):
2977 for e_id in cal_events[cur_date]:
2978 cur_event = events[e_id]
2979
2980 if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2981 start_hour, start_min = gettimefield(cur_event['starttime'])
2982
2983 if not hour_events[dayindex].has_key(start_hour):
2984 hour_events[dayindex][start_hour] = []
2985
2986 hour_events[dayindex][start_hour].append(e_id)
2987
2988 #debug(u'hour_events: %s' % hour_events)
2989
2990 # in-day events
2991 html_calendar_rows = []
2992 html_hour_cols = {}
2993
2994 slot_pending = {}
2995 max_num_slots = {}
2996 hour_max_slots = {}
2997 block_slots = {}
2998
2999 start_hour_index = {}
3000
3001 r24 = range(24)
3002
3003 for hour_index in r24:
3004
3005 html_hour_cols[hour_index] = {}
3006 hour_max_slots[hour_index] = {}
3007
3008 #html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
3009
3010 for dayindex in range(7):
3011
3012 if not max_num_slots.has_key(dayindex):
3013 max_num_slots[dayindex] = 0
3014
3015 if not slot_pending.has_key(dayindex):
3016 slot_pending[dayindex] = {}
3017
3018 if not start_hour_index.has_key(dayindex):
3019 start_hour_index[dayindex] = 0
3020
3021 if not block_slots.has_key(dayindex):
3022 block_slots[dayindex] = []
3023
3024 html_hour_cols[hour_index][dayindex] = []
3025 hour_max_slots[hour_index][dayindex] = 1
3026
3027 if len(slot_pending[dayindex]) > 0 or hour_events[dayindex].has_key(hour_index):
3028
3029 #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending[dayindex]))
3030 if len(slot_pending[dayindex]) == 0:
3031 if max_num_slots[dayindex] < 1:
3032 max_num_slots[dayindex] = 1
3033
3034 for hour_lines in range(start_hour_index[dayindex], hour_index):
3035 hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3036
3037 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
3038
3039 block_slots[dayindex].append(max_num_slots[dayindex])
3040
3041 max_num_slots[dayindex] = 0
3042 start_hour_index[dayindex] = hour_index
3043
3044 for slot_index in range(max_num_slots[dayindex]):
3045 if slot_pending[dayindex].has_key(slot_index) and slot_pending[dayindex][slot_index] > 0:
3046 if slot_pending[dayindex][slot_index] == 1:
3047 del slot_pending[dayindex][slot_index]
3048 else:
3049 slot_pending[dayindex][slot_index] -= 1
3050 html_hour_cols[hour_index][dayindex].append ( '' )
3051
3052 else:
3053 if hour_events[dayindex].has_key(hour_index) and len(hour_events[dayindex][hour_index]) > 0:
3054 e_id = hour_events[dayindex][hour_index][0]
3055 cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
3056 html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
3057 slot_pending[dayindex][slot_index] = cur_event['time_len'] - 1
3058 else:
3059 if not ((len(slot_pending[dayindex]) > 0 and slot_index > max(slot_pending[dayindex].keys())) or len(slot_pending[dayindex]) == 0):
3060 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
3061
3062 if hour_events[dayindex].has_key(hour_index):
3063 for tmp_cnt in range(len(hour_events[dayindex][hour_index])):
3064 e_id = hour_events[dayindex][hour_index][0]
3065 cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
3066 html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
3067 slot_pending[dayindex][max_num_slots[dayindex]] = cur_event['time_len'] - 1
3068 if slot_pending[dayindex][max_num_slots[dayindex]] == 0:
3069 del slot_pending[dayindex][max_num_slots[dayindex]]
3070 max_num_slots[dayindex] += 1
3071
3072 else:
3073 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
3074 #hour_max_slots[hour_index][dayindex] = 1
3075
3076 if max_num_slots[dayindex] < 1:
3077 max_num_slots[dayindex] = 1
3078
3079 for hour_lines in range(start_hour_index[dayindex], hour_index):
3080 hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3081
3082 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
3083
3084 block_slots[dayindex].append(max_num_slots[dayindex])
3085
3086 max_num_slots[dayindex] = 0
3087 start_hour_index[dayindex] = hour_index
3088
3089 global_colspan = {}
3090 header_colspan = 0
3091
3092 for dayindex in range(7):
3093 if max_num_slots[dayindex] < 1:
3094 max_num_slots[dayindex] = 1
3095
3096 for hour_lines in range(start_hour_index[dayindex], 24):
3097 hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3098
3099 block_slots[dayindex].append(max_num_slots[dayindex])
3100
3101 # calculates global colspan
3102 if len(block_slots[dayindex]):
3103 global_colspan[dayindex] = LCM(block_slots[dayindex])
3104 else:
3105 global_colspan[dayindex] = 1
3106
3107 header_colspan += global_colspan[dayindex]
3108
3109
3110 for hour_index in r24:
3111
3112 html_cols_days = []
3113
3114 for dayindex in range(7):
3115
3116 colspan = global_colspan[dayindex] / hour_max_slots[hour_index][dayindex]
3117 width = (100 - 2) / 7 / hour_max_slots[hour_index][dayindex]
3118
3119 left_slots = hour_max_slots[hour_index][dayindex] - len(html_hour_cols[hour_index][dayindex])
3120
3121 if left_slots > 0:
3122 #debug('appending left %d slots: %d' % (left_slots, hour_index))
3123 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
3124
3125 html_cols = u'\r\n'.join(html_hour_cols[hour_index][dayindex]) % {'colspan': colspan, 'width': u'%d%%' % width}
3126 html_cols_days.append(html_cols)
3127
3128 html_cols_collected = u'\r\n'.join(html_cols_days)
3129 html_cols = u'<tr>%s\r\n%s</tr>\r\n' % (calshow_weekly_hourhead(hour_index), html_cols_collected)
3130
3131 html_calendar_rows.append (html_cols)
3132
3133 html_calendar_rows = u'\r\n'.join(html_calendar_rows)
3134
3135 # shows current year & month
3136 html_header_curyearmonthday = calhead_yearmonthday2(year, month, day, 'head_yearmonth', header_colspan)
3137
3138 # one-day long events
3139 html_oneday_rows = {}
3140
3141 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
3142
3143 #first_date_week = getFirstDateOfWeek(year, month, day)
3144
3145 html_oneday_rows = []
3146
3147 while 1:
3148 html_oneday_cols = []
3149 cnt_blank_cols = 0
3150 pending = -1
3151
3152 for dayindex in range(7):
3153
3154 if pending > 0:
3155 pending -= 1
3156 html_oneday_cols.append('')
3157 continue
3158 else:
3159 pending = -1
3160
3161 cur_date = first_date_week + datetime.timedelta(dayindex)
3162 cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
3163
3164 if cal_events.has_key(cur_date) and len(cal_events[cur_date]) > 0:
3165
3166 tmpcount = len(cal_events[cur_date])
3167 for tmp_index in range(tmpcount):
3168 cur_event = events[cal_events[cur_date].pop(0)]
3169
3170 #debug('event poped out at %s: %s' % (cur_date, cur_event))
3171
3172 if (cur_event['startdate'] <= cur_date and dayindex == 0) or cur_event['startdate'] == cur_date:
3173 if cur_event['time_len'] <= 0 or cur_event['date_len'] > 1:
3174
3175 temp_len = diffday(cur_date, cur_event['enddate']) + 1
3176
3177 if cur_event['startdate'] == cur_date:
3178 if temp_len <= 7 - dayindex:
3179 str_status = ''
3180 else:
3181 str_status = 'pending'
3182 else:
3183 if temp_len <= 7 - dayindex:
3184 str_status = 'append'
3185 else:
3186 str_status = 'append_pending'
3187
3188 if temp_len > 7 - dayindex:
3189 temp_len = 7 - dayindex
3190
3191 pending = temp_len - 1
3192
3193 tmp_global_colspan = 0
3194 for tmp_index in range(dayindex, dayindex+temp_len):
3195 tmp_global_colspan += global_colspan[tmp_index]
3196
3197 #debug('event appended at %s with pending=%d: %s' % (cur_date, pending, cur_event))
3198
3199 html_oneday_cols.append( calshow_weekly_eventbox2(cur_event, tmp_global_colspan, 14 * temp_len, str_status, cur_date) )
3200 break
3201
3202 if pending < 0:
3203 html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
3204 cnt_blank_cols += 1
3205
3206 else:
3207 html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
3208 cnt_blank_cols += 1
3209
3210 if cnt_blank_cols >= 7:
3211 if len(html_oneday_rows) == 0:
3212 html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
3213 html_oneday_rows.append (html_oneday_cols)
3214 break
3215 else:
3216 html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
3217 html_oneday_rows.append (html_oneday_cols)
3218
3219 html_date_rows = []
3220
3221 for dayindex in range(7):
3222 cur_date = first_date_week + datetime.timedelta(dayindex)
3223 html_date_rows.append(calhead_weeklydate(cur_date.year, cur_date.month, cur_date.day, global_colspan[dayindex]))
3224
3225 html_date_rows = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_date_rows)
3226
3227 html_oneday_rows = u'\r\n'.join(html_oneday_rows)
3228
3229 html_cal_table = [
3230 u'\r\n<div id="eventcalendar">',
3231 u'<table class="eventcalendar" %s>' % Params.weeklywidth,
3232 u'<table border="0">',
3233 u'%s' % html_header_curyearmonthday,
3234 u'%s' % html_date_rows,
3235 u'%s' % html_oneday_rows,
3236 u'%s' % html_calendar_rows,
3237 u'</table>',
3238 u'</td></tr>',
3239 u'</div>',
3240 ]
3241 html_cal_table = u'\r\n'.join(html_cal_table)
3242
3243 return html_cal_table
3244
3245
3246
3247 # simple view
3248 def showsimpleeventcalendar(year, month):
3249
3250 debug('Show Calendar: Simple View')
3251
3252 request = Globs.request
3253 formatter = Globs.formatter
3254 _ = request.getText
3255 monthstyle_us = Globs.month_style_us
3256
3257 wkend = Globs.wkend
3258 months= Globs.months
3259 wkdays = Globs.wkdays
3260
3261 # get the calendar
3262 monthcal = calendar.monthcalendar(year, month)
3263
3264 # shows current year & month
3265 html_header_curyearmonth = calhead_yearmonth(year, month, 'simple_yearmonth')
3266
3267 r7 = range(7)
3268
3269 # shows header of week days
3270 html_header_weekdays = []
3271
3272 for wkday in r7:
3273 wday = wkdays[wkday]
3274 html_header_weekdays.append( calhead_weekday(wday, 'simple_weekday') )
3275 html_header_weekdays = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
3276
3277 # gets previous, next month
3278 day_delta = datetime.timedelta(days=-1)
3279 cur_month = datetime.date(year, month, 1)
3280 prev_month = cur_month + day_delta
3281
3282 day_delta = datetime.timedelta(days=15)
3283 cur_month_end = datetime.date(year, month, 25)
3284 next_month = cur_month_end + day_delta
3285
3286 prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
3287 next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
3288
3289 # shows days
3290 html_week_rows = []
3291
3292 # set ranges of events
3293 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
3294 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
3295
3296 # read all the events
3297 events, cal_events, labels = loadEvents(datefrom, dateto)
3298
3299 maketip_js = []
3300
3301 for week in monthcal:
3302
3303 # day head rows
3304 html_headday_cols = []
3305 html_events_rows = []
3306
3307 for wkday in r7:
3308
3309 day = week[wkday]
3310
3311 if not day:
3312 if week == monthcal[0]:
3313 nb_day = prev_monthcal[-1][wkday]
3314 else:
3315 nb_day = next_monthcal[0][wkday]
3316
3317 html_headday_cols.append( simple_eventbox(year, month, day, nb_day, 'simple_nb') )
3318 else:
3319 cur_date = formatDate(year, month, day)
3320
3321 if cal_events.has_key(cur_date):
3322 html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_event') )
3323
3324 if monthstyle_us:
3325 tiptitle = u'%s %d, %d' % (months[month-1], day, year)
3326 else:
3327 tiptitle = u'%d / %02d / %02d' % (year, month, day)
3328
3329 date_today = datetime.date( year, month, day )
3330 tiptitle = u'%s (%s)' % (tiptitle, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3331
3332 tiptext = []
3333
3334 for e_id in cal_events[cur_date]:
3335 cur_event = events[e_id]
3336 if cur_event['starttime']:
3337 time_string = u'(%s:%s)' % (cur_event['starttime'][:2], cur_event['starttime'][2:])
3338 else:
3339 time_string = ''
3340
3341 title = wikiutil.escape(cur_event['title']).replace("'","\\'")
3342 description = wikiutil.escape(cur_event['description']).replace("'","\\'")
3343
3344 tiptext.append( u'<b>%s</b>%s %s' % (title, time_string, description) )
3345
3346 tiptext = u'<br>'.join(tiptext)
3347
3348 maketip_js.append("maketip('%s','%s','%s');" % (cur_date, tiptitle, tiptext))
3349 else:
3350 html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_noevent') )
3351
3352 html_headday_row = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
3353 html_week_rows.append(html_headday_row)
3354
3355 html_calendar_rows = u'\r\n'.join(html_week_rows)
3356
3357 html_tooltip_result = """\
3358 <script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script>
3359 <div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div>
3360 <script language="JavaScript" type="text/javascript">
3361 <!--
3362 %s
3363 // -->
3364 </script>
3365
3366 """ % (request.cfg.url_prefix, "\n".join(maketip_js))
3367
3368
3369 html_cal_table = [
3370 u'\r\n<div id="eventcalendar">',
3371 u'%s' % html_tooltip_result,
3372 u'<table class="simplecalendar" %s>' % Params.simplewidth,
3373 u'%s' % html_header_curyearmonth,
3374 u'%s' % html_header_weekdays,
3375 u'%s' % html_calendar_rows,
3376 u'</table>',
3377 u'</div>',
3378 ]
3379 html_cal_table = u'\r\n'.join(html_cal_table)
3380
3381 return html_cal_table
3382
3383
3384 # show calendar head (year & month)
3385 def calhead_yearmonth(year, month, headclass):
3386
3387 request = Globs.request
3388
3389 months = Globs.months
3390 monthstyle_us = Globs.month_style_us
3391 cal_action = Globs.cal_action
3392 page_name = Globs.pagename
3393
3394 page_url = Globs.pageurl
3395
3396 nextyear, nextmonth = yearmonthplusoffset(year, month, 1)
3397 prevyear, prevmonth = yearmonthplusoffset(year, month, -1)
3398
3399 prevlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, prevyear, prevmonth, getquerystring(['numcal']) )
3400 nextlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, nextyear, nextmonth, getquerystring(['numcal']))
3401 curlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, year, month, getquerystring(['numcal']))
3402
3403 if monthstyle_us:
3404 stryearmonth = u'%s %d' % (months[month-1], year)
3405 strnextmonth = u'%s %d' % (months[nextmonth-1], nextyear)
3406 strprevmonth = u'%s %d' % (months[prevmonth-1], prevyear)
3407 else:
3408 stryearmonth = u'%d / %02d' % (year, month)
3409 strnextmonth = u'%d / %02d' % (nextyear, nextmonth)
3410 strprevmonth = u'%d / %02d' % (prevyear, prevmonth)
3411
3412 html = [
3413 u' <tr>',
3414 u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth),
3415 u' <td colspan="5" class="%s"><a href="%s" title="Go/Refresh this month">%s</a></td>' % (headclass, curlink, stryearmonth),
3416 u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth),
3417 u' </tr>',
3418 ]
3419
3420 return u'\r\n'.join(html)
3421
3422
3423 # show calendar head (year & month & day)
3424 def calhead_yearmonthday(year, month, day, headclass, colspan):
3425
3426 request = Globs.request
3427 _ = request.getText
3428
3429 months = Globs.months
3430 monthstyle_us = Globs.month_style_us
3431 cal_action = Globs.cal_action
3432 page_name = Globs.pagename
3433 wkdays = Globs.wkdays
3434
3435 page_url = Globs.pageurl
3436
3437 date_today = datetime.date( year, month, day )
3438 prevdate = date_today - datetime.timedelta(days=1)
3439 nextdate = date_today + datetime.timedelta(days=1)
3440
3441 prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
3442 nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
3443 curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
3444
3445 if monthstyle_us:
3446 stryearmonth = u'%s %d, %d' % (months[month-1], day, year)
3447 strnextmonth = u'%s %d, %d' % (months[nextdate.month-1], nextdate.day, nextdate.year)
3448 strprevmonth = u'%s %d, %d' % (months[prevdate.month-1], prevdate.day, prevdate.year)
3449 else:
3450 stryearmonth = u'%d / %02d / %02d' % (year, month, day)
3451 strnextmonth = u'%d / %02d / %02d' % (nextdate.year, nextdate.month, nextdate.day)
3452 strprevmonth = u'%d / %02d / %02d' % (prevdate.year, prevdate.month, prevdate.day)
3453
3454 #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday()]))
3455 stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3456
3457 html = [
3458 u'<tr><td width="4%" style="border: none;"> </td>',
3459 u'<td colspan="%d" style="border: none;">' % colspan,
3460 u'<table width="95%">',
3461 u' <tr>',
3462 u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth),
3463 u' <td class="%s"><a href="%s" title="Go/Refresh this day">%s</a></td>' % (headclass, curlink, stryearmonth),
3464 u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth),
3465 u' </tr>',
3466 u'</table>',
3467 u'</td></tr>',
3468 ]
3469
3470 return u'\r\n'.join(html)
3471
3472 # show calendar head for weekly view (year & month & day)
3473 def calhead_yearmonthday2(year, month, day, headclass, colspan):
3474
3475 request = Globs.request
3476 _ = request.getText
3477
3478 months = Globs.months
3479 monthstyle_us = Globs.month_style_us
3480 cal_action = Globs.cal_action
3481 page_name = Globs.pagename
3482 wkdays = Globs.wkdays
3483
3484 page_url = Globs.pageurl
3485
3486 date_today = datetime.date( year, month, day )
3487 prevdate = date_today - datetime.timedelta(days=7)
3488 nextdate = date_today + datetime.timedelta(days=7)
3489
3490 first_date_week = getFirstDateOfWeek(year, month, day)
3491 prevdate_f = first_date_week - datetime.timedelta(days=7)
3492 nextdate_f = first_date_week + datetime.timedelta(days=7)
3493
3494 last_date_week = first_date_week + datetime.timedelta(days=6)
3495 prevdate_l = last_date_week - datetime.timedelta(days=7)
3496 nextdate_l = last_date_week + datetime.timedelta(days=7)
3497
3498 prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
3499 nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
3500 curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
3501
3502 if monthstyle_us:
3503 stryearmonth = u'%s %d, %d ~ %s %d, %d' % (months[first_date_week.month-1], first_date_week.day, first_date_week.year, months[last_date_week.month-1], last_date_week.day, last_date_week.year)
3504 strnextmonth = u'%s %d, %d ~ %s %d, %d' % (months[nextdate_f.month-1], nextdate_f.day, nextdate_f.year, months[nextdate_l.month-1], nextdate_l.day, nextdate_l.year)
3505 strprevmonth = u'%s %d, %d ~ %s %d, %d' % (months[prevdate_f.month-1], prevdate_f.day, prevdate_f.year, months[prevdate_l.month-1], prevdate_l.day, prevdate_l.year)
3506 else:
3507 stryearmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (first_date_week.year, first_date_week.month, first_date_week.day, last_date_week.year, last_date_week.month, last_date_week.day)
3508 strnextmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (nextdate_f.year, nextdate_f.month, nextdate_f.day, nextdate_l.year, nextdate_l.month, nextdate_l.day)
3509 strprevmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (prevdate_f.year, prevdate_f.month, prevdate_f.day, prevdate_l.year, prevdate_l.month, prevdate_l.day)
3510
3511 #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3512
3513 html = [
3514 u'<tr><td width="2%" style="border: none;"> </td>',
3515 u'<td colspan="%d" style="border: none;">' % colspan,
3516 u'<table width="95%">',
3517 u' <tr>',
3518 u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth),
3519 u' <td class="%s"><a href="%s" title="Go/Refresh this week">%s</a></td>' % (headclass, curlink, stryearmonth),
3520 u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth),
3521 u' </tr>',
3522 u'</table>',
3523 u'</td></tr>',
3524 ]
3525
3526 return u'\r\n'.join(html)
3527
3528
3529 # show calendar head for weekly view (the date)
3530 def calhead_weeklydate(year, month, day, colspan):
3531
3532 request = Globs.request
3533 _ = request.getText
3534
3535 months = Globs.months
3536 monthstyle_us = Globs.month_style_us
3537 cal_action = Globs.cal_action
3538 page_name = Globs.pagename
3539 wkdays = Globs.wkdays
3540
3541 page_url = Globs.pageurl
3542
3543 date_today = datetime.date( year, month, day )
3544
3545 if monthstyle_us:
3546 stryearmonth = u'%s %d' % (months[month-1], day)
3547 else:
3548 stryearmonth = u'%02d / %02d' % (month, day)
3549
3550 stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3551 curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
3552
3553 cyear, cmonth, cday = gettodaydate()
3554 if cyear == year and cmonth == month and cday == day:
3555 bgcolor = 'background-color: #FFFFAA;'
3556 else:
3557 bgcolor = ''
3558
3559 if not Params.changeview:
3560 curlink = '#'
3561
3562 html = [
3563 u'<td colspan="%d" style="border-width: 2px; text-align: center; font-size: 9pt; %s">' % (colspan, bgcolor),
3564 u'<a href="%s">%s</a>' % (curlink, stryearmonth),
3565 u'</td>',
3566 ]
3567
3568 return u'\r\n'.join(html)
3569
3570 # show days in simple
3571 def simple_eventbox(year, month, day, wkday, boxclass):
3572 wkend = Globs.wkend
3573 if wkday == wkend:
3574 html_text = u'<font color="#aa7744">%s</font>' % day
3575 else:
3576 html_text = u'%s' % day
3577
3578 cyear, cmonth, cday = gettodaydate()
3579
3580 page_url = Globs.pageurl
3581 linkkey = u'%d%02d%02d' % (year, month, day)
3582
3583 curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
3584
3585 if not Params.changeview:
3586 curlink = '#'
3587
3588 curlink = u'<a href="%s" onMouseOver="tip(\'%s\')" onMouseOut="untip()" >%s</a>' % (curlink, linkkey, html_text)
3589
3590 if boxclass == 'simple_nb':
3591 html = u' <td class="%s"> </td>\r\n' % boxclass
3592 else:
3593 if cyear == year and cmonth == month and cday == day:
3594 html = u' <td class="%s_today">%s</td>\r\n' % (boxclass, curlink)
3595 else:
3596 html = u' <td class="%s">%s</td>\r\n' % (boxclass, curlink)
3597
3598 return html
3599
3600
3601 # show weekday
3602 def calhead_weekday(wday, headclass):
3603 if headclass == 'simple_weekday':
3604 html = u' <td class="%s">%s</td>\r\n' % (headclass, wday[0])
3605 else:
3606 html = u' <td class="%s">%s</td>\r\n' % (headclass, wday)
3607
3608 return html
3609
3610
3611 # show days of current month
3612 def calhead_day(year, month, day, wkday):
3613
3614 request = Globs.request
3615 page_name = Globs.pagename
3616 wkend = Globs.wkend
3617
3618 if wkday == wkend:
3619 html_text = u'<font color="#FF3300">%s</font>' % day
3620 else:
3621 html_text = u'%s' % day
3622
3623 page_url = Globs.pageurl
3624 html_text = u'<a href="%s?calaction=daily&caldate=%d%02d%02d">%s</a>' % (page_url, year, month, day, html_text)
3625
3626 cyear, cmonth, cday = gettodaydate()
3627
3628 if (not wkday) and Params.showweeknumber:
3629 html_text = u'%s <font size="1" color="#aaaaaa"><i>(%d)</i></font>' % (html_text, (int(datetime.date(year, month, day).strftime('%W')) + 1))
3630
3631 if cyear == year and cmonth == month and cday == day:
3632 html = u' <td class="head_day_today"> %s</td>\r\n' % html_text
3633 else:
3634 html = u' <td class="head_day"> %s</td>\r\n' % html_text
3635
3636 return html
3637
3638
3639 # show days of previous or next month
3640 def calhead_day_nbmonth(day):
3641
3642 html = u' <td class="head_day_nbmonth"> %s</td>\r\n' % day
3643 return html
3644
3645
3646 # show blank calendar box
3647 def calshow_blankbox(classname):
3648 html = u' <td class="%s"> </td>' % classname
3649 return html
3650
3651
3652 def calshow_blankbox2(classname, colspan):
3653 html = u' <td class="%s" colspan="%d"> </td>' % (classname, colspan)
3654 return html
3655
3656
3657 # show eventbox
3658 def calshow_eventbox(event, colspan, status, cur_date):
3659
3660 if status:
3661 status = u'_%s' % status
3662
3663 title = event['title']
3664 eid = event['id']
3665 startdate = event['startdate']
3666 enddate = event['enddate']
3667 starttime = event['starttime']
3668 endtime = event['endtime']
3669 description = event['description']
3670 bgcolor = event['bgcolor']
3671
3672 if not bgcolor:
3673 if Globs.labels:
3674 labels = Globs.labels
3675 # for backward compatibility
3676 if event.has_key('label'):
3677 if labels.has_key(event['label']):
3678 bgcolor = labels[event['label']]['bgcolor']
3679
3680 year, month, day = getdatefield(cur_date)
3681
3682 if bgcolor:
3683 bgcolor = 'background-color: %s;' % bgcolor
3684 else:
3685 bgcolor = 'background-color: %s;' % Params.bgcolor
3686
3687 if (startdate == enddate) and starttime:
3688 shour, smin = gettimefield(starttime)
3689
3690 link = [
3691 u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3692 u'<td nowrap class="cal_eventbox_time">%02d:%02d </td>\r\n' % (shour, smin),
3693 u'<td class="cal_eventbox_time_event">',
3694 u'%s' % showReferPageParsed(event, 'title', 1),
3695 u'</td>\r\n</tr></table>',
3696 ]
3697 link = u''.join(link)
3698 else:
3699 link = u'%s' % showReferPageParsed(event, 'title', 1)
3700
3701
3702 html = [
3703 u' <td class="cal_eventbox" colspan="%d"><table class="cal_event">' % colspan,
3704 u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3705 u' </table></td>',
3706 ]
3707
3708 return u'\r\n'.join(html)
3709
3710
3711 # show eventbox
3712 def calshow_daily_eventbox2(event, colspan, status, cur_date):
3713 if status:
3714 status = u'_%s' % status
3715
3716 title = event['title']
3717 eid = event['id']
3718 startdate = event['startdate']
3719 enddate = event['enddate']
3720 starttime = event['starttime']
3721 endtime = event['endtime']
3722 description = event['description']
3723 bgcolor = event['bgcolor']
3724
3725 if not bgcolor:
3726 labels = Globs.labels
3727 # for backward compatibility
3728 if event.has_key('label'):
3729 if labels.has_key(event['label']):
3730 bgcolor = labels[event['label']]['bgcolor']
3731
3732 year, month, day = getdatefield(cur_date)
3733
3734 if bgcolor:
3735 bgcolor = 'background-color: %s;' % bgcolor
3736 else:
3737 bgcolor = 'background-color: %s;' % Params.bgcolor
3738
3739 if (startdate == enddate) and starttime:
3740 shour, smin = gettimefield(starttime)
3741
3742 link = [
3743 u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3744 u'<td width="10" nowrap style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top; font-size: 7pt; color: #000000;">%02d:%02d </td>\r\n' % (shour, smin),
3745 u'<td style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top;font-size: 8pt;">',
3746 u'%s' % showReferPageParsed(event, 'title', 1),
3747 u'</td>\r\n</tr></table>',
3748 ]
3749 link = u''.join(link)
3750 else:
3751 link = u'%s' % showReferPageParsed(event, 'title', 1)
3752
3753
3754 html = [
3755 u' <td colspan="%d" style="width: 96%%; border-width: 0px; line-height: 11px;"><table class="cal_event">' % colspan,
3756 u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3757 u' </table></td>',
3758 ]
3759
3760 return u'\r\n'.join(html)
3761
3762
3763 # show eventbox
3764 def calshow_daily_eventbox(event):
3765
3766 title = event['title']
3767 eid = event['id']
3768 startdate = event['startdate']
3769 enddate = event['enddate']
3770 starttime = event['starttime']
3771 endtime = event['endtime']
3772 description = event['description']
3773 bgcolor = event['bgcolor']
3774 time_len = event['time_len']
3775
3776 if not bgcolor:
3777 labels = Globs.labels
3778 # for backward compatibility
3779 if event.has_key('label'):
3780 if labels.has_key(event['label']):
3781 bgcolor = labels[event['label']]['bgcolor']
3782
3783 if bgcolor:
3784 bgcolor = 'background-color: %s;' % bgcolor
3785 else:
3786 bgcolor = 'background-color: %s;' % Params.bgcolor
3787
3788 shour, smin = gettimefield(starttime)
3789 ehour, emin = gettimefield(endtime)
3790
3791 html = [
3792 u' <td colspan="%(colspan)d"',
3793 u' style="%s border-width: 2px; border-color: #000000; vertical-align: top; font-size: 9pt; ' % bgcolor,
3794 u' width: %(width)s;" ',
3795 u' rowspan="%(rowspan)d">' % { 'rowspan': time_len },
3796 u' %02d:%02d ~ %02d:%02d<br>%s' % (shour, smin, ehour, emin, showReferPageParsed(event, 'title', 1)),
3797 u' </td>',
3798 ]
3799
3800 return u'\r\n'.join(html)
3801
3802
3803 # show eventbox
3804 def calshow_weekly_eventbox(event):
3805
3806 title = event['title']
3807 eid = event['id']
3808 startdate = event['startdate']
3809 enddate = event['enddate']
3810 starttime = event['starttime']
3811 endtime = event['endtime']
3812 description = event['description']
3813 bgcolor = event['bgcolor']
3814 time_len = event['time_len']
3815
3816 if not bgcolor:
3817 labels = Globs.labels
3818 # for backward compatibility
3819 if event.has_key('label'):
3820 if labels.has_key(event['label']):
3821 bgcolor = labels[event['label']]['bgcolor']
3822
3823 if bgcolor:
3824 bgcolor = 'background-color: %s;' % bgcolor
3825 else:
3826 bgcolor = 'background-color: %s;' % Params.bgcolor
3827
3828 shour, smin = gettimefield(starttime)
3829 ehour, emin = gettimefield(endtime)
3830
3831 html = [
3832 u' <td colspan="%(colspan)d"',
3833 u' style="%s;' % bgcolor,
3834 u' width: %(width)s;" ',
3835 u' rowspan="%(rowspan)d"' % { 'rowspan': time_len },
3836 u' class="cal_weekly_eventbox">',
3837 u' %s' % showReferPageParsed(event, 'title', 1),
3838 u' </td>',
3839 ]
3840
3841 return u'\r\n'.join(html)
3842
3843 # show blank eventbox
3844 def calshow_blankeventbox():
3845
3846 html = [
3847 u' <td colspan="%(colspan)d" style="width: %(width)s;" class="cal_blankeventbox"> </td>',
3848 ]
3849
3850 return u'\r\n'.join(html)
3851
3852
3853 # show eventbox
3854 def calshow_weekly_eventbox2(event, colspan, width, status, cur_date):
3855 if status:
3856 status = u'_%s' % status
3857
3858 title = event['title']
3859 eid = event['id']
3860 startdate = event['startdate']
3861 enddate = event['enddate']
3862 starttime = event['starttime']
3863 endtime = event['endtime']
3864 description = event['description']
3865 bgcolor = event['bgcolor']
3866
3867 year, month, day = getdatefield(cur_date)
3868
3869 if not bgcolor:
3870 labels = Globs.labels
3871 # for backward compatibility
3872 if event.has_key('label'):
3873 if labels.has_key(event['label']):
3874 bgcolor = labels[event['label']]['bgcolor']
3875
3876 if bgcolor:
3877 bgcolor = 'background-color: %s;' % bgcolor
3878 else:
3879 bgcolor = 'background-color: %s;' % Params.bgcolor
3880
3881 link = u'%s' % showReferPageParsed(event, 'title', 1)
3882
3883 html = [
3884 u' <td colspan="%d" style="width: %d%%;" class="cal_weekly_eventbox2"><table class="cal_event">' % (colspan, width),
3885 u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3886 u' </table></td>',
3887 ]
3888
3889 return u'\r\n'.join(html)
3890
3891
3892
3893 # show blank eventbox
3894 def calshow_blankeventbox2(colspan, width):
3895 html = [
3896 u' <td colspan="%(colspan)d"' % { 'colspan': colspan },
3897 u' style="width: %(width)s;" class="cal_blankeventbox"> </td>' % { 'width': '%d%%%%' % width },
3898 ]
3899
3900 return u'\r\n'.join(html)
3901
3902
3903
3904 def calshow_daily_hourhead(hour):
3905
3906 if hour >= Globs.dailystart and hour <= Globs.dailyend:
3907 bgcolor = "#ffffcc"
3908 else:
3909 bgcolor = "#ffeeee"
3910
3911 html = [
3912 u' <td class="cal_hourhead" style="background-color: %s; width: 4%%%%;">%02d</td>' % (bgcolor, hour),
3913 ]
3914
3915 return u'\r\n'.join(html)
3916
3917 def calshow_weekly_hourhead(hour):
3918
3919 if hour >= Globs.dailystart and hour <= Globs.dailyend:
3920 bgcolor = "#ffffcc"
3921 else:
3922 bgcolor = "#ffeeee"
3923
3924 html = [
3925 u' <td class="cal_hourhead" style="width: 2%%%%; background-color: %s; ">%02d</td>' % (bgcolor, hour),
3926 ]
3927
3928 return u'\r\n'.join(html)
3929
3930
3931
3932 def insertcalevents(cal_events, datefrom, dateto, e_id, e_start_date, e_end_date):
3933
3934 if not (int(e_start_date) > dateto or int(e_end_date) < datefrom):
3935
3936 e_start_date = str(max(int(e_start_date), datefrom))
3937 e_end_date = str(min(int(e_end_date), dateto))
3938
3939 day_delta = datetime.timedelta(days=1)
3940 e_start_year, e_start_month, e_start_day = getdatefield(e_start_date)
3941 cur_datetime = datetime.date(e_start_year, e_start_month, e_start_day)
3942
3943 while 1:
3944 tmp_record_date = formatdateobject(cur_datetime)
3945
3946 if not cal_events.has_key(tmp_record_date):
3947 cal_events[tmp_record_date] = []
3948 cal_events[tmp_record_date].append(e_id)
3949
3950 if tmp_record_date == e_end_date:
3951 break
3952
3953 cur_datetime = cur_datetime + day_delta
3954
3955 # date format should be like '20051004' for 2005, Oct., 04
3956 def diffday(date1, date2):
3957
3958 try:
3959 year1, month1, day1 = getdatefield(date1)
3960 year2, month2, day2 = getdatefield(date2)
3961 tmp_diff = datetime.date(year2, month2, day2) - datetime.date(year1, month1, day1)
3962 except (TypeError, ValueError):
3963 raise EventcalError('invalid_date')
3964
3965 return tmp_diff.days
3966
3967
3968 # time format should be like '1700' for 05:00pm
3969 def difftime(time1, time2):
3970
3971 try:
3972 hour1, min1 = gettimefield(time1)
3973 hour2, min2 = gettimefield(time2)
3974
3975 except (TypeError, ValueError):
3976 raise EventcalError('invalid_time')
3977
3978 if min2 == 0 and hour2 != 0 and hour1 != hour2:
3979 hour2 -= 1
3980
3981 tmp_diff = hour2 - hour1
3982
3983 return tmp_diff
3984
3985
3986
3987 def formatDate(year, month, day):
3988 # returns like: '20051004'
3989 return u'%4d%02d%02d' % (year, month, day)
3990
3991 def formatTime(hour, min):
3992 # returns like: '1700'
3993 return u'%2d%02d' % (hour, min)
3994
3995
3996 def formatdateobject(obj_date):
3997
3998 return formatDate(obj_date.year, obj_date.month, obj_date.day)
3999
4000 def formattimeobject(obj_time):
4001
4002 return formatTime(obj_time.hour, obj_time.minute)
4003
4004
4005 def debug(astring):
4006 Globs.debugmsg += u'<li>%s\n' % astring
4007
4008
4009 def geterrormsg(errmsgcode, refer='', title='', hid=''):
4010
4011 if errmsgcode == 'invalid_caldate':
4012 msg = 'Warning: Invalid value for "caldate" parameter. Shows today.'
4013
4014 elif errmsgcode == 'invalid_curdate':
4015 msg = 'Warning: Invalid value for "curdate" parameter. Shows today.'
4016
4017 elif errmsgcode == 'invalid_numcal':
4018 msg = 'Warning: Invalid value of "numcal" parameter. Shows one.'
4019
4020 elif errmsgcode == 'invalid_startdate':
4021 msg = 'Error: Invalid startdate format. Not handled.'
4022
4023 elif errmsgcode == 'invalid_enddate':
4024 msg = 'Error: Invalid enddate format. Not handled.'
4025
4026 elif errmsgcode == 'invalid_start':
4027 msg = 'Error: Invalid start date or time format. Not handled.'
4028
4029 elif errmsgcode == 'invalid_end':
4030 msg = 'Error: Invalid end date or time format. Not handled.'
4031
4032 elif errmsgcode == 'invalid_date':
4033 msg = 'Error: Invalid date format. Not handled.'
4034
4035 elif errmsgcode == 'enddate_precede':
4036 msg = 'Error: Startdate should be earlier than Enddate. Not handled.'
4037
4038 elif errmsgcode == 'invalid_starttime':
4039 msg = 'Error: Invalid starttime format. Not handled.'
4040
4041 elif errmsgcode == 'invalid_endtime':
4042 msg = 'Error: Invalid endtime format. Not handled.'
4043
4044 elif errmsgcode == 'invalid_time':
4045 msg = 'Error: Invalid time format. Not handled.'
4046
4047 elif errmsgcode == 'endtime_precede':
4048 msg = 'Error: Starttime should be earlier than Endtime. Not handled.'
4049
4050 elif errmsgcode == 'len_recur_int':
4051 msg = 'Error: Event length should be smaller than recurrence interval. Not handled.'
4052
4053 elif errmsgcode == 'invalid_bgcolor':
4054 msg = 'Warning: Invalid bgcolor format. Ignored.'
4055
4056 elif errmsgcode == 'invalid_label':
4057 msg = 'Warning: Invalid label format. Ignored.'
4058
4059 elif errmsgcode == 'invalid_recur':
4060 msg = 'Error: Invalid recurrence format. Not handled.'
4061
4062 elif errmsgcode == 'invalid_recur_until':
4063 msg = 'Error: Invalid end date (until) format of the recurrence. Not handled.'
4064
4065 elif errmsgcode == 'empty_description':
4066 msg = 'Warning: Empty description. Ignored.'
4067
4068 elif errmsgcode == 'invalid_default_bgcolor':
4069 msg = 'Warning: Invalid default_bgcolor format. Ignored.'
4070
4071 elif errmsgcode == 'empty_default_description':
4072 msg = 'Warning: Empty default_description. Ignored.'
4073
4074 elif errmsgcode == 'redefined_label':
4075 msg = 'Warning: Redefined label. Ignored.'
4076
4077 elif errmsgcode == 'empty_label_definition':
4078 msg = 'Warning: Invalid label definition. Ignored.'
4079
4080 elif errmsgcode == 'need_starttime':
4081 msg = 'Error: Starttime should be specified. Not handled.'
4082
4083 elif errmsgcode == 'recur_until_precede':
4084 msg = 'Error: Enddate should be earlier than the end date (until) of recurrence. Not handled.'
4085
4086 else:
4087 msg = 'undefined: %s' % errmsgcode
4088
4089 if refer:
4090 msg = '%s (%s)' % (msg, getReferLink(refer, title, hid))
4091
4092 return msg
4093
4094
4095 def errormsgcode(errmsgcode):
4096
4097 errormsg(geterrormsg(errmsgcode))
4098
4099
4100 def errormsg(astring):
4101 Globs.errormsg += u'<li>%s\n' % astring
4102
4103
4104 def yearmonthplusoffset(year, month, offset):
4105 month = month+offset
4106 # handle offset and under/overflows - quick and dirty, yes!
4107 while month < 1:
4108 month = month + 12
4109 year = year - 1
4110 while month > 12:
4111 month = month - 12
4112 year = year + 1
4113 return year, month
4114
4115
4116 def formatcfgdatetime(strdate, strtime=''):
4117
4118 if not strdate:
4119 return ''
4120
4121 request = Globs.request
4122
4123 if request.user.date_fmt:
4124 date_fmt = request.user.date_fmt
4125 else:
4126 date_fmt = request.cfg.date_fmt
4127
4128 if request.user.datetime_fmt:
4129 datetime_fmt = request.user.datetime_fmt
4130 else:
4131 datetime_fmt = request.cfg.datetime_fmt
4132
4133 ## XXX HACK
4134 datetime_fmt = datetime_fmt.replace(':%S', '')
4135
4136 date_fmt = str(date_fmt)
4137 datetime_fmt = str(datetime_fmt)
4138
4139 year, month, day = getdatefield(str(strdate))
4140 if strtime:
4141 hour, min = gettimefield(str(strtime))
4142 objdatetime = datetime.datetime(year, month, day, hour, min)
4143 return objdatetime.strftime(datetime_fmt)
4144 else:
4145 objdate = getdatetimefromstring(strdate)
4146 return objdate.strftime(date_fmt)
4147
4148
4149 def getdatetimefromstring(strdate):
4150 year, month, day = getdatefield(str(strdate))
4151 return datetime.date( year, month, day )
4152
4153
4154 def searchPages(request, needle):
4155 # Search the pages and return the results
4156 query = search.QueryParser().parse_query(needle)
4157 results = search.searchPages(request, query)
4158 #results.sortByPagename()
4159
4160 return results.hits
4161
4162 html = []
4163 for page in results.hits:
4164 html.append(page.page_name)
4165
4166 html = u',<br>'.join(html)
4167 return u'%s<p>%s' % (Params.category, html)
4168
4169
4170 def getFirstDateOfWeek(year, month, day):
4171 orgday = datetime.date(year, month, day)
4172 yearBase, week, weekday = orgday.isocalendar()
4173 baseDate = datetime.date(yearBase, 2, 1)
4174 yearBase, weekBase, dayBase = baseDate.isocalendar()
4175 days = datetime.timedelta(1-dayBase+(week-weekBase)*7)
4176 theday = baseDate + days
4177
4178 theday -= datetime.timedelta(7 - calendar.firstweekday())
4179
4180 if orgday - theday >= datetime.timedelta(7):
4181 theday += datetime.timedelta(7)
4182
4183 return theday
4184
4185 def gcd(a,b):
4186 """Return greatest common divisor using Euclid's Algorithm."""
4187 while b:
4188 a, b = b, a % b
4189
4190 return a
4191
4192 def lcm(a,b):
4193 """
4194 Return lowest common multiple."""
4195 return (a*b)/gcd(a,b)
4196
4197 def LCM(terms):
4198 "Return lcm of a list of numbers."
4199 return reduce(lambda a,b: lcm(a,b), terms)
4200
4201
4202 def getNumericalMonth(strMonth):
4203 months = Globs.months
4204
4205 strMonth = strMonth.lower()
4206
4207 index = 0
4208 for monthitem in months:
4209 index += 1
4210 if monthitem.lower().startswith(strMonth):
4211 return index
4212
4213 return 0
4214
4215
4216 def getReferLink(refer, title='', hid=''):
4217 request = Globs.request
4218
4219 refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
4220
4221 if hid:
4222 refer_url += '#%s' % hid
4223
4224 if title:
4225 refer = '%s: "%s"' % (refer, title)
4226
4227 return '<a href="%s">%s</a>' % (refer_url, refer)
4228
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.