Attachment 'EventCalendar-099.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 from MoinMoin.parser import wiki
160 import re, calendar, time, datetime
161 import codecs, os, urllib, sha
162
163 try:
164 import cPickle as pickle
165 except ImportError:
166 import pickle
167
168 # Set pickle protocol, see http://docs.python.org/lib/node64.html
169 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
170
171
172 # The following line sets the calendar to have either Sunday or Monday as
173 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
174 # valid here. All other values will not make good calendars.
175 # XXX change here ----------------vvvvvv
176 calendar.setfirstweekday(calendar.SUNDAY)
177
178
179 class Globs:
180 month_style_us = 1 # 1: October 2005; 2: 2005 / 10
181 defaultcategory = 'CategoryEventCalendar'
182 upcomingrange = 7 # days
183 dailystart = 9
184 dailyend = 18
185 pagename = ''
186 baseurl = ''
187 subname = ''
188 wkend = ''
189 months = ''
190 wkdays = ''
191 today = ''
192 now = ''
193 request = None
194 formatter = None
195 cal_action = ''
196 debugmsg = ''
197 errormsg = ''
198 page_action = ''
199 form_vals = {}
200 events = None
201 labels = None
202
203
204 class Params:
205 menubar = 0
206 monthlywidth = ''
207 weeklywidth = ''
208 dailywidth = ''
209 simplewidth = ''
210 firstview = ''
211 curdate = ''
212 bgcolor = ''
213 category = ''
214 upcomingrange = 0
215 changeview = 0
216 numcal = 1
217 showlastweekday = 0
218 showerror = 1
219 showweeknumber = 0
220 debug = 0
221
222
223 class EventcalError(Exception):
224 def __init__(self, value):
225 self.value = value
226
227 def __str__(self):
228 return repr(self.value)
229
230
231 def execute(macro, args):
232
233 request = macro.request
234 formatter = macro.formatter
235
236 # INITIALIZATION ----------------------------------------
237 setglobalvalues(macro)
238 getparams(args)
239
240 # allowed actions
241 allowed_action = ['monthly', 'list', 'simple', 'upcoming', 'daily', 'weekly']
242 default_action = Params.firstview
243
244 # Internal variables
245 cal_action = ''
246 form_vals = {}
247
248 # PROCESSING ARGUEMENTS ----------------------------------------
249 if args:
250 args=request.getText(args)
251
252 for item in macro.form.items():
253 if not form_vals.has_key(item[0]):
254 try:
255 form_vals[item[0]]=item[1][0]
256 except AttributeError:
257 pass
258
259 # PROCESSING ACTIONS ----------------------------------------
260 cal_action = form_vals.get('calaction', default_action)
261 page_action = form_vals.get('action', 'show')
262
263 if not cal_action in allowed_action:
264 cal_action = default_action
265
266 form_vals['calaction'] = cal_action
267
268 Globs.form_vals = form_vals
269
270 # CONTROL FUNCTIONS ----------------------------------------
271
272 html = []
273 html_result = ''
274
275 Globs.cal_action = cal_action
276 Globs.page_action = page_action
277
278
279 # redirect to the appropriate view
280 if cal_action == 'monthly':
281 html_result = showcalendar()
282
283 if cal_action == 'list':
284 html_result = showeventlist()
285
286 if cal_action == 'simple':
287 html_result = showsimplecalendar()
288
289 if cal_action == 'upcoming':
290 html_result = showupcomingeventlist()
291
292 if cal_action == 'daily':
293 html_result = showdailycalendar()
294
295 if cal_action == 'weekly':
296 html_result = showweeklycalendar()
297
298
299 # format output
300 html.append( html_result )
301 html.append( showmenubar() )
302
303 if Params.showerror and Globs.errormsg:
304 html.append(u'<p><i><font size="2" color="#aa0000"><ol>%s</ol></font></i>' % Globs.errormsg)
305
306 if Params.debug and Globs.debugmsg:
307 html.append(u'<p><b>Debug messages:</b><font color="#000099"><ol>%s</ol></font>' % Globs.debugmsg)
308
309 return formatter.rawHTML(u''.join(html))
310
311
312
313 def getparams(args):
314 # process arguments
315
316 params = {}
317 if args:
318 # Arguments are comma delimited key=value pairs
319 sargs = args.split(',')
320
321 for item in sargs:
322 sitem = item.split('=')
323
324 if len(sitem) == 2:
325 key, value = sitem[0], sitem[1]
326 params[key.strip()] = value.strip()
327
328 # category name:
329 # default: 'CategoryEventCalendar'
330 Params.category = params.get('category', Globs.defaultcategory)
331
332 # menu bar: shows menubar or not (1: show, 0: no menubar)
333 # default: 1
334 try:
335 Params.menubar = int(params.get('menubar', 1))
336 except (TypeError, ValueError):
337 Params.menubar = 1
338
339 # calendar width in pixel or percent (monthly)
340 # default: 600px
341 Params.monthlywidth = params.get('monthlywidth', '600')
342 if Params.monthlywidth:
343 Params.monthlywidth = ' width="%s" ' % Params.monthlywidth
344
345 # calendar width in pixel or percent (weekly)
346 # default: 600px
347 Params.weeklywidth = params.get('weeklywidth', '600')
348 if Params.weeklywidth:
349 Params.weeklywidth = ' width="%s" ' % Params.weeklywidth
350
351 # calendar width in pixel or percent (daily)
352 # default: 600px
353 Params.dailywidth = params.get('dailywidth', '600')
354 if Params.monthlywidth:
355 Params.dailywidth = ' width="%s" ' % Params.dailywidth
356
357 # calendar width in pixel or percent (simply)
358 # default: 150px
359 Params.simplewidth = params.get('simplewidth', '150')
360 if Params.simplewidth:
361 # Params.simplewidth = Params.simplewidth.replace('%', '%%')
362 Params.simplewidth = ' width="%s" ' % Params.simplewidth
363
364 # calendar view: monthly, list, simple
365 # default: 'monthly'
366 Params.firstview = params.get('firstview', 'monthly')
367
368 # calendar date: in YYYYMM format (in monthly, simple view)
369 # default: current month
370 Params.curdate = params.get('curdate', '')
371
372 # upcoming range: # of days for upcoming event list
373 # default: 7
374 try:
375 Params.upcomingrange = int(params.get('upcomingrange', Globs.upcomingrange))
376 except (TypeError, ValueError):
377 Params.upcomingrange = Globs.upcomingrange
378
379 # number of calendar: # of calendar for monthly & simple view
380 # default: 1
381 try:
382 Params.numcal = int(params.get('numcal', '1'))
383 except (TypeError, ValueError):
384 Params.numcal = 1
385
386 # change view enabled?
387 # default: 1
388 try:
389 Params.changeview = int(params.get('changeview', '1'))
390 except (TypeError, ValueError):
391 Params.changeview = 1
392
393 # shows the event at the last weekday if the recurred weekday is not available.
394 # default: 0
395 try:
396 Params.showlastweekday = int(params.get('showlastweekday', '0'))
397 except (TypeError, ValueError):
398 Params.showlastweekday = 0
399
400 # show error message?
401 # default: 1
402 try:
403 Params.showerror = int(params.get('showerror', '1'))
404 except (TypeError, ValueError):
405 Params.showerror = 1
406
407 # show week number?
408 # default: 0
409 try:
410 Params.showweeknumber = int(params.get('showweeknumber', '0'))
411 except (TypeError, ValueError):
412 Params.showweeknumber = 0
413
414 # default bgcolor
415 Params.bgcolor = '#ddffdd'
416
417
418 def setglobalvalues(macro):
419
420 request = macro.request
421 formatter = macro.formatter
422
423 # Useful variables
424 Globs.baseurl = request.getBaseURL() + '/'
425 Globs.pagename = formatter.page.page_name
426 Globs.request = request
427 Globs.formatter = formatter
428 Globs.pageurl = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(formatter.page.page_name))
429
430 # This fixes the subpages bug. subname is now used instead of pagename when creating certain urls
431 Globs.subname = Globs.pagename.split('/')[-1]
432
433 pagepath = formatter.page.getPagePath()
434 Globs.pagepath = formatter.page.getPagePath()
435
436 # european / US differences
437 months = ('January','February','March','April','May','June','July','August','September','October','November','December')
438
439 # Set things up for Monday or Sunday as the first day of the week
440 if calendar.firstweekday() == calendar.MONDAY:
441 wkend = 6
442 wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
443 elif calendar.firstweekday() == calendar.SUNDAY:
444 wkend = 0
445 wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
446
447 Globs.months = months
448 Globs.wkdays = wkdays
449 Globs.wkend = wkend
450
451 year, month, day, h, m, s, wd, yd, ds = request.user.getTime(time.time())
452 Globs.today = datetime.date(year, month, day)
453 Globs.now = datetime.time(h, m, s)
454
455 Globs.debugmsg = ''
456 Globs.errormsg = ''
457
458
459 def showReferPageParsed(event, targettext='title', showdesc=0):
460 request = Globs.request
461 pagename = Globs.pagename
462
463 refer = event['refer']
464 targettext = event[targettext]
465 startdate = event['startdate']
466 enddate = event['enddate']
467 description = event['description']
468 starttime = event['starttime']
469 endtime = event['endtime']
470 hid = event['hid']
471
472 refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
473
474 if not Params.changeview:
475 refer_url = ''
476 hid = ''
477
478 if showdesc:
479 if (startdate == enddate) and (starttime and endtime):
480 timedescription = '(%s:%s ~ %s:%s)' % (starttime[:2], starttime[2:], endtime[:2], endtime[2:])
481 if description:
482 timedescription = '%s ' % timedescription
483 else:
484 timedescription = ''
485
486 targetlink = '<a href="%s#%s" title="%s%s">%s</a>' % ( refer_url, hid, timedescription, wikiutil.escape(description), wikiutil.escape(targettext) )
487
488 else:
489 targetlink = '<a href="%s#%s">%s</a>' % ( refer_url, hid, wikiutil.escape(targettext))
490
491 return targetlink
492
493
494 def showReferPageParsedForLabel(thelabel, targettext='name', showdesc=1):
495 request = Globs.request
496 pagename = Globs.pagename
497
498 labels = Globs.labels
499
500 label_bgcolor = ''
501 refer = ''
502
503 if labels and labels.has_key(thelabel):
504 targettext = labels[thelabel][targettext]
505 refer = labels[thelabel]['refer']
506 if showdesc:
507 label_bgcolor = labels[thelabel]['bgcolor']
508
509 if not refer:
510 return '<i>%s</i>' % thelabel
511
512 refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
513
514 if showdesc:
515 targetlink = '<a href="%s" title="%s">%s</a>' % ( refer_url, label_bgcolor, wikiutil.escape(targettext) )
516 else:
517 targetlink = '<a href="%s">%s</a>' % ( refer_url, wikiutil.escape(targettext))
518
519 return targetlink
520
521
522 def getheadingid(request, referpage, title):
523
524 pntt = (referpage + title).encode(config.charset)
525 hid = "head-" + sha.new(pntt).hexdigest()
526
527 if not hasattr(request, '_eventcal_headings'):
528 request._eventcal_headings = {}
529
530 request._eventcal_headings.setdefault(pntt, 0)
531 request._eventcal_headings[pntt] += 1
532 if request._eventcal_headings[pntt] > 1:
533 hid += '-%d'%(request._eventcal_headings[pntt],)
534
535 return hid
536
537
538 def getquerystring(req_fields):
539
540 m_query = []
541 tmp_form_vals = Globs.form_vals
542
543 # format querystring
544 # action should be poped out
545 for field in req_fields:
546 if tmp_form_vals.has_key(field):
547 m_query.append(u'%s=%s' % (field, tmp_form_vals[field]) )
548
549 if 'prevcalaction' in req_fields:
550 if not tmp_form_vals.has_key('prevcalaction'):
551 m_query.append(u'%s=%s' % ('prevcalaction', tmp_form_vals['calaction']) )
552
553 m_query = u'&'.join(m_query)
554
555 if m_query:
556 m_query = '&%s' % m_query
557
558 return m_query
559
560
561 # bottom menu bar
562 def showmenubar():
563
564 request = Globs.request
565 cal_action = Globs.cal_action
566 page_name = Globs.pagename
567
568 page_url = Globs.pageurl
569
570 if not Params.menubar: return ''
571
572 if cal_action == 'simple':
573 menuwidth = Params.simplewidth
574 elif cal_action == 'monthly':
575 menuwidth = Params.monthlywidth
576 else:
577 menuwidth = ''
578
579 left_menu_selected = []
580 right_menu_selected = []
581
582 # Go Today
583 year, month, day = gettodaydate()
584 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']))
585
586 # List View
587 mnu_listview = u'<a href="%s?calaction=list%s" title="List of all events">[List]</a>' % (page_url, getquerystring(['caldate', 'numcal']))
588
589 # Monthly View
590 mnu_monthview = u'<a href="%s?calaction=monthly%s" title="Monthly view">[Monthly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
591
592 # Simple Calendar View
593 mnu_simpleview = u'<a href="%s?calaction=simple%s" title="Simple calendar view">[Simple]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
594
595 # Upcoming Event List
596 mnu_upcomingview = u'<a href="%s?calaction=upcoming%s" title="Upcoming event list">[Upcoming]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
597
598 # Daily View
599 mnu_dayview = u'<a href="%s?calaction=daily%s" title="Daily view">[Daily]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
600
601 # Weekly View
602 mnu_weekview = u'<a href="%s?calaction=weekly%s" title="Weekly view">[Weekly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
603
604 html = [
605 u'\r\n',
606 u'<table class="eventcalendar_menubar" %s>',
607 u' <tr>',
608 u' <td class="eventcalendar_menubar" align="left">%s</td>',
609 u' <td class="eventcalendar_menubar" align="right">%s</td>',
610 u' </tr>',
611 u'</table>',
612 ]
613
614 if cal_action == 'list':
615 left_menu_selected.append(mnu_monthview)
616 left_menu_selected.append(mnu_weekview)
617 left_menu_selected.append(mnu_dayview)
618 left_menu_selected.append(mnu_simpleview)
619 right_menu_selected.append(mnu_upcomingview)
620
621 elif cal_action == 'simple':
622 left_menu_selected.append(mnu_monthview)
623 left_menu_selected.append(mnu_weekview)
624 left_menu_selected.append(mnu_dayview)
625 right_menu_selected.append(mnu_listview)
626 right_menu_selected.append(mnu_upcomingview)
627 right_menu_selected.append(mnu_curmonthcal)
628
629 elif cal_action == 'upcoming':
630 left_menu_selected.append(mnu_monthview)
631 left_menu_selected.append(mnu_weekview)
632 left_menu_selected.append(mnu_dayview)
633 left_menu_selected.append(mnu_simpleview)
634 right_menu_selected.append(mnu_listview)
635
636 elif cal_action == 'weekly':
637 left_menu_selected.append(mnu_monthview)
638 left_menu_selected.append(mnu_dayview)
639 left_menu_selected.append(mnu_simpleview)
640 right_menu_selected.append(mnu_upcomingview)
641 right_menu_selected.append(mnu_listview)
642 right_menu_selected.append(mnu_curmonthcal)
643
644 elif cal_action == 'daily':
645 left_menu_selected.append(mnu_monthview)
646 left_menu_selected.append(mnu_weekview)
647 left_menu_selected.append(mnu_simpleview)
648 right_menu_selected.append(mnu_upcomingview)
649 right_menu_selected.append(mnu_listview)
650 right_menu_selected.append(mnu_curmonthcal)
651
652 else:
653 left_menu_selected.append(mnu_weekview)
654 left_menu_selected.append(mnu_dayview)
655 left_menu_selected.append(mnu_simpleview)
656 right_menu_selected.append(mnu_upcomingview)
657 right_menu_selected.append(mnu_listview)
658 right_menu_selected.append(mnu_curmonthcal)
659
660 left_menu_selected = u'\r\n'.join(left_menu_selected)
661 right_menu_selected = u'\r\n'.join(right_menu_selected)
662
663 html = u'\r\n'.join(html)
664 html = html % (menuwidth, left_menu_selected, right_menu_selected)
665
666 return html
667
668
669 def getdatefield(str_date):
670 str_year = ''
671 str_month = ''
672 str_day = ''
673
674 if len(str_date) == 6:
675 # year+month
676 str_year = str_date[:4]
677 str_month = str_date[4:]
678 str_day = '1'
679
680 elif len(str_date) == 8:
681 # year+month+day
682 str_year = str_date[:4]
683 str_month = str_date[4:6]
684 str_day = str_date[6:]
685
686 elif len(str_date) == 10:
687 # year+?+month+?+day
688 str_year = str_date[:4]
689 str_month = str_date[5:7]
690 str_day = str_date[8:]
691
692 else:
693 raise ValueError
694
695 # It raises exception if the input date is incorrect
696 temp = datetime.date(int(str_year), int(str_month), int(str_day))
697
698 return temp.year, temp.month, temp.day
699
700
701 def gettimefield(str_time):
702 str_hour = ''
703 str_min = ''
704
705 if len(str_time) == 4:
706 # hour+minute
707 str_hour = str_time[:2]
708 str_min = str_time[2:]
709
710 elif len(str_time) == 5:
711 # hour+?+minute
712 str_hour = str_time[:2]
713 str_min = str_time[3:]
714
715 else:
716 raise ValueError
717
718 # It raises exception if the input date is incorrect
719 temp = datetime.time(int(str_hour), int(str_min))
720
721 return temp.hour, temp.minute
722
723
724 def gettodaydate():
725 today = Globs.today
726 return today.year, today.month, today.day
727
728
729 def cal_listhead():
730
731 html = [
732 u' <tr>',
733 u' <td class="list_head">Title</td>',
734 u' <td class="list_head">Start Date</td>',
735 u' <td class="list_head">End Date</td>',
736 u' <td class="list_head">Recurrence</td>',
737 u' <td class="list_head">Label</td>',
738 u' <td class="list_head">Description</td>',
739 u' <td class="list_head">Reference</td>',
740 u' </tr>',
741 ]
742
743 return u'\r\n'.join(html)
744
745
746 def showeventlist():
747
748 debug('Show Calendar: List view')
749
750 request = Globs.request
751 formatter = Globs.formatter
752
753 html_event_rows = []
754 html_list_header = cal_listhead()
755
756 # read all the events
757 events, cal_events, labels = loadEvents()
758
759 # sort events
760 sorted_eventids = events.keys()
761 sorted_eventids.sort(comp_list_events)
762
763 for eid in sorted_eventids:
764 if not events[eid]['clone']:
765 html_event_rows.append( listshow_event(events[eid]) )
766
767 html_event_rows = u'\r\n'.join(html_event_rows)
768
769 html_list_table = [
770 u'\r\n<div id="eventlist">',
771 u'<table class="eventlist">',
772 u'%s' % html_list_header,
773 u'%s' % html_event_rows,
774 u'</table>',
775 u'</div>',
776 ]
777 html_list_table = u'\r\n'.join(html_list_table)
778
779 return html_list_table
780
781
782 def listshow_event(event):
783
784 if event['recur_freq']:
785 if event['recur_freq'] == -1:
786 recur_desc = 'last %s' % event['recur_type']
787 else:
788 recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type'])
789
790 if event['recur_until']:
791 recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until']))
792 else:
793 recur_desc = ''
794
795 html = [
796 u' <tr>',
797 u' <td class="list_entry">%s</td>' % converttext(event['title']),
798 u' <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']),
799 u' <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']),
800 u' <td class="list_entry">%s</td>' % recur_desc,
801 u' <td class="list_entry">%s</td>' % showReferPageParsedForLabel(event['label']),
802 u' <td class="list_entry">%s</td>' % converttext(event['description']),
803 u' <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'),
804 u' </tr>',
805 ]
806
807 return u'\r\n'.join(html)
808
809
810 def showupcomingeventlist():
811
812 debug('Show Calendar: Upcoming Event View')
813
814 request = Globs.request
815 formatter = Globs.formatter
816
817 html_event_rows = []
818 html_list_header = cal_listhead()
819
820 year, month, day = gettodaydate()
821 day_delta = datetime.timedelta(days=Params.upcomingrange)
822 cur_date = datetime.date(year, month, day)
823 next_range = cur_date + day_delta
824
825 # set ranges of events
826 datefrom = u'%04d%02d%02d' % (year, month, day)
827 dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day)
828
829 # read all the events (no cache)
830 events, cal_events, labels = loadEvents(datefrom, dateto, 1)
831
832 nowtime = formattimeobject(Globs.now)
833
834 datefrom = formatcfgdatetime(cur_date, nowtime)
835 #u'%04d-%02d-%02d %s:%s' % (year, month, day, nowtime[:2], nowtime[2:])
836 dateto = formatcfgdatetime(formatdateobject(next_range))
837 #u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day)
838
839 # sort events
840 sorted_eventids = events.keys()
841 sorted_eventids.sort(comp_list_events)
842
843 for eid in sorted_eventids:
844 if events[eid]['enddate'] >= formatdateobject(Globs.today):
845 if (not events[eid]['endtime']) or events[eid]['endtime'] >= formattimeobject(Globs.now):
846 html_event_rows.append( listshow_event(events[eid]) )
847
848 html_event_rows = u'\r\n'.join(html_event_rows)
849
850 html_list_table = [
851 u'\r\n<div id="eventlist">',
852 u'<table class="eventlist">',
853 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),
854 u'%s' % html_list_header,
855 u'%s' % html_event_rows,
856 u'</table>',
857 u'</div>',
858 ]
859 html_list_table = u'\r\n'.join(html_list_table)
860
861 return html_list_table
862
863
864
865
866 def showcalendar():
867
868 request = Globs.request
869 formatter = Globs.formatter
870 form_vals = Globs.form_vals
871
872 html = []
873
874 if form_vals.has_key('caldate'):
875 try:
876 year, month, str_temp = getdatefield(form_vals['caldate'])
877 except (TypeError, ValueError):
878 errormsgcode('invalid_caldate')
879 year, month, dy = gettodaydate()
880
881 elif Params.curdate:
882 try:
883 year, month, str_temp = getdatefield(Params.curdate)
884 except (TypeError, ValueError):
885 errormsgcode('invalid_curdate')
886 year, month, dy = gettodaydate()
887
888 else:
889 year, month, dy = gettodaydate()
890
891 # check number of calendar
892 numcal = Params.numcal
893
894 if form_vals.has_key('numcal'):
895 try:
896 numcal = int(form_vals['numcal'])
897 except (TypeError, ValueError):
898 errormsgcode('invalid_numcal')
899
900 if numcal < 1:
901 numcal = 1
902 elif numcal > 12:
903 numcal = 12
904
905 for index in range(numcal):
906
907 cyear, cmonth = yearmonthplusoffset(year, month, index)
908
909 cal_html = showeventcalendar(cyear, cmonth)
910 html.append(cal_html)
911
912 return u''.join(html)
913
914
915 def showdailycalendar():
916
917 request = Globs.request
918 formatter = Globs.formatter
919
920 form_vals = Globs.form_vals
921
922 if form_vals.has_key('caldate'):
923 try:
924 year, month, dy = getdatefield(form_vals['caldate'])
925
926 if len(form_vals['caldate']) <= 6:
927 tyear, tmonth, tdy = gettodaydate()
928 if tyear == year and month == tmonth:
929 dy = tdy
930
931 except (TypeError, ValueError):
932 errormsgcode('invalid_caldate')
933 year, month, dy = gettodaydate()
934
935 elif Params.curdate:
936 try:
937 year, month, dy = getdatefield(Params.curdate)
938 except (TypeError, ValueError):
939 errormsgcode('invalid_curdate')
940 year, month, dy = gettodaydate()
941
942 else:
943 year, month, dy = gettodaydate()
944
945 html = showdailyeventcalendar(year, month, dy)
946
947 return u''.join(html)
948
949
950 def showweeklycalendar():
951
952 request = Globs.request
953 formatter = Globs.formatter
954
955 form_vals = Globs.form_vals
956
957 if form_vals.has_key('caldate'):
958 try:
959 year, month, dy = getdatefield(form_vals['caldate'])
960
961 if len(form_vals['caldate']) <= 6:
962 tyear, tmonth, tdy = gettodaydate()
963 if tyear == year and month == tmonth:
964 dy = tdy
965
966 except (TypeError, ValueError):
967 errormsgcode('invalid_caldate')
968 year, month, dy = gettodaydate()
969
970 elif Params.curdate:
971 try:
972 year, month, dy = getdatefield(Params.curdate)
973 except (TypeError, ValueError):
974 errormsgcode('invalid_curdate')
975 year, month, dy = gettodaydate()
976 else:
977 year, month, dy = gettodaydate()
978
979 html = showweeklyeventcalendar(year, month, dy)
980
981 return u''.join(html)
982
983
984 def showsimplecalendar():
985
986 request = Globs.request
987 formatter = Globs.formatter
988 form_vals = Globs.form_vals
989
990 html = []
991
992 if form_vals.has_key('caldate'):
993 try:
994 year, month, str_temp = getdatefield(form_vals['caldate'])
995 except (TypeError, ValueError):
996 errormsgcode('invalid_caldate')
997 year, month, dy = gettodaydate()
998 elif Params.curdate:
999 try:
1000 year, month, str_temp = getdatefield(Params.curdate)
1001 except (TypeError, ValueError):
1002 errormsgcode('invalid_curdate')
1003 year, month, dy = gettodaydate()
1004 else:
1005 year, month, dy = gettodaydate()
1006
1007 # check number of calendar
1008 numcal = Params.numcal
1009
1010 if form_vals.has_key('numcal'):
1011 try:
1012 numcal = int(form_vals['numcal'])
1013 except (TypeError, ValueError):
1014 errormsgcode('invalid_numcal')
1015
1016
1017 if numcal < 1:
1018 numcal = 1
1019 elif numcal > 12:
1020 numcal = 12
1021
1022 for index in range(numcal):
1023
1024 cyear, cmonth = yearmonthplusoffset(year, month, index)
1025
1026 cal_html = showsimpleeventcalendar(cyear, cmonth)
1027 html.append(cal_html)
1028
1029 return u''.join(html)
1030
1031
1032
1033 # sort events in cal_events by length of days of the event
1034 def comp_cal_events(xid, yid):
1035 events = Globs.events
1036
1037 if events[xid]['date_len'] > events[yid]['date_len']:
1038 return -1
1039 elif events[xid]['date_len'] == events[yid]['date_len']:
1040 if events[xid]['date_len'] == 1:
1041 if events[xid]['starttime'] == events[yid]['starttime']:
1042 return cmp(events[yid]['time_len'], events[xid]['time_len'])
1043 else:
1044 return cmp(events[xid]['starttime'], events[yid]['starttime'])
1045 else:
1046 return 0
1047 else:
1048 return 1
1049
1050
1051 # sort events in the list by start date of the event
1052 def comp_list_events(xid, yid):
1053 events = Globs.events
1054
1055 return cmp(events[xid]['startdate'], events[yid]['startdate'])
1056
1057 # load events from wiki pages
1058 def loadEvents(datefrom='', dateto='', nocache=0):
1059
1060 request = Globs.request
1061
1062 debug('Loading event information.')
1063
1064 events = {}
1065 labels = {}
1066 cal_events = {}
1067 raw_events = {}
1068
1069 raw_events, labels = loadEventsFromWikiPages()
1070
1071 # handling cal_events
1072 if datefrom or dateto:
1073
1074 # cache configurations
1075 arena = Page(request, Globs.pagename)
1076 eventkey = 'events'
1077 filteredeventkey = 'events_%s-%s' % (datefrom, dateto)
1078 caleventkey = 'calevents_%s-%s' % (datefrom, dateto)
1079
1080 cache_events = caching.CacheEntry(request, arena, eventkey)
1081 cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey)
1082 cache_calevents = caching.CacheEntry(request, arena, caleventkey)
1083
1084 dirty = 1
1085
1086 debug('Checking cal_events cache')
1087
1088 if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())):
1089
1090 try:
1091 events = pickle.loads(cache_filteredevents.content())
1092 cal_events = pickle.loads(cache_calevents.content())
1093 debug('Cached event (filtered) information is used: total %d events' % len(events))
1094 dirty = 0
1095 except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1096 debug('Picke error at fetching cached events (filtered)')
1097 events = {}
1098 cal_events = {}
1099
1100
1101 # if cache is dirty, update the cache
1102 if dirty:
1103
1104 debug('Checking event cache: it\'s dirty or requested to refresh')
1105 debug('Building new cal_event information')
1106
1107 try:
1108 datefrom, dateto = int(datefrom), int(dateto)
1109 except (TypeError, ValueError):
1110 datefrom, dateto = 0, 0
1111
1112 clone_num = 0
1113
1114 for e_id in raw_events.keys():
1115
1116 cur_event = raw_events[e_id]
1117
1118 # handling event recurrence
1119 recur_freq = cur_event['recur_freq']
1120
1121 if recur_freq or recur_freq == -1:
1122
1123 if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto:
1124
1125 if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1126 # generating cal_events for iteself
1127 events[e_id] = cur_event.copy()
1128 insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1129
1130 delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 )
1131
1132 if cur_event['recur_type'] == 'day':
1133
1134 day_delta = int(recur_freq)
1135 startdate = getdatetimefromstring(cur_event['startdate'])
1136 datefrom_date = getdatetimefromstring(datefrom)
1137
1138 if int(datefrom) > int(cur_event['startdate']):
1139 diffs = datefrom_date - startdate
1140 q_delta = diffs.days / day_delta
1141 if diffs.days % day_delta > 0:
1142 q_delta += 1
1143 else:
1144 q_delta = 1
1145
1146 while 1:
1147
1148 if q_delta == 0:
1149 q_delta += 1
1150 continue
1151
1152 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1153 recurred_enddate = recurred_startdate + delta_date_len
1154
1155 new_startdate = formatdateobject(recurred_startdate)
1156 new_enddate = formatdateobject(recurred_enddate)
1157
1158 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1159 break
1160
1161 clone_num += 1
1162 clone_id = 'c%d' % clone_num
1163
1164 events[clone_id] = cur_event.copy()
1165 events[clone_id]['id'] = clone_id
1166 events[clone_id]['startdate'] = new_startdate
1167 events[clone_id]['enddate'] = new_enddate
1168 events[clone_id]['clone'] = 1
1169
1170 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1171
1172 q_delta += 1
1173
1174 elif cur_event['recur_type'] == 'week':
1175
1176 day_delta = int(recur_freq) * 7
1177
1178 startdate = getdatetimefromstring(cur_event['startdate'])
1179 datefrom_date = getdatetimefromstring(datefrom)
1180
1181 if int(datefrom) > int(cur_event['startdate']):
1182 diffs = datefrom_date - startdate
1183 q_delta = diffs.days / day_delta
1184 if diffs.days % day_delta > 0:
1185 q_delta += 1
1186 else:
1187 q_delta = 1
1188
1189 while 1:
1190
1191 if q_delta == 0:
1192 q_delta += 1
1193 continue
1194
1195 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1196 recurred_enddate = recurred_startdate + delta_date_len
1197
1198 new_startdate = formatdateobject(recurred_startdate)
1199 new_enddate = formatdateobject(recurred_enddate)
1200
1201 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1202 break
1203
1204 clone_num += 1
1205 clone_id = 'c%d' % clone_num
1206
1207 events[clone_id] = cur_event.copy()
1208 events[clone_id]['id'] = clone_id
1209 events[clone_id]['startdate'] = new_startdate
1210 events[clone_id]['enddate'] = new_enddate
1211 events[clone_id]['clone'] = 1
1212
1213 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1214
1215 q_delta += 1
1216
1217
1218 elif cur_event['recur_type'] == 'weekday':
1219
1220 syear, smonth, sday = getdatefield(cur_event['startdate'])
1221 cyear, cmonth, cday = getdatefield(str(datefrom))
1222
1223 recur_weekday = calendar.weekday(syear, smonth, sday)
1224
1225 while 1:
1226
1227 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1228 firstmatch = (recur_weekday - firstweekday) % 7 + 1
1229
1230 if recur_freq == -1:
1231 therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1232 else:
1233 #XXX should handle error
1234 try:
1235 therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1]
1236 except IndexError:
1237 if Params.showlastweekday:
1238 # if no matched weekday, the last weekday will be displayed
1239 therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1240 else:
1241 # if no matched weekday, no event will be displayed
1242 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1243 continue
1244
1245
1246 recurred_startdate = datetime.date(cyear, cmonth, therecur_day)
1247 recurred_enddate = recurred_startdate + delta_date_len
1248
1249 new_startdate = formatdateobject(recurred_startdate)
1250 new_enddate = formatdateobject(recurred_enddate)
1251
1252 if int(new_startdate) < int(datefrom) or new_startdate == cur_event['startdate']:
1253 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1254 continue
1255
1256 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1257 break
1258
1259 clone_num += 1
1260 clone_id = 'c%d' % clone_num
1261
1262 events[clone_id] = cur_event.copy()
1263 events[clone_id]['id'] = clone_id
1264 events[clone_id]['startdate'] = new_startdate
1265 events[clone_id]['enddate'] = new_enddate
1266 events[clone_id]['clone'] = 1
1267
1268 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1269
1270 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1271
1272
1273 elif cur_event['recur_type'] == 'month':
1274
1275 cyear, cmonth, therecurday = getdatefield(cur_event['startdate'])
1276
1277 while 1:
1278
1279 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq)
1280 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1281 recur_day = therecurday
1282 if daysinmonth < recur_day:
1283 recur_day = daysinmonth
1284 new_startdate = formatDate(cyear, cmonth, recur_day)
1285
1286 if int(new_startdate) < int(datefrom):
1287 continue
1288
1289 recurred_startdate = datetime.date(cyear, cmonth, recur_day)
1290 recurred_enddate = recurred_startdate + delta_date_len
1291
1292 new_startdate = formatdateobject(recurred_startdate)
1293 new_enddate = formatdateobject(recurred_enddate)
1294
1295 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1296 break
1297
1298 clone_num += 1
1299 clone_id = 'c%d' % clone_num
1300
1301 events[clone_id] = cur_event.copy()
1302 events[clone_id]['id'] = clone_id
1303 events[clone_id]['startdate'] = new_startdate
1304 events[clone_id]['enddate'] = new_enddate
1305 events[clone_id]['clone'] = 1
1306
1307 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1308
1309 elif cur_event['recur_type'] == 'year':
1310
1311 ryear, rmonth, rday = getdatefield(cur_event['startdate'])
1312 cyear, cmonth, cday = getdatefield(str(datefrom))
1313
1314 while 1:
1315
1316 ryear += recur_freq
1317 new_startdate = formatDate(ryear, rmonth, rday)
1318
1319 if int(new_startdate) < int(datefrom):
1320 continue
1321
1322 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1323 break
1324
1325 recurred_startdate = datetime.date(ryear, rmonth, rday)
1326 recurred_enddate = recurred_startdate + delta_date_len
1327
1328 new_startdate = formatdateobject(recurred_startdate)
1329 new_enddate = formatdateobject(recurred_enddate)
1330
1331 clone_num += 1
1332 clone_id = 'c%d' % clone_num
1333
1334 events[clone_id] = cur_event.copy()
1335 events[clone_id]['id'] = clone_id
1336 events[clone_id]['startdate'] = new_startdate
1337 events[clone_id]['enddate'] = new_enddate
1338 events[clone_id]['clone'] = 1
1339
1340 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1341
1342 else:
1343
1344 if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1345 events[e_id] = cur_event.copy()
1346 insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1347
1348
1349 # sort cal_events
1350 # store event list into global variables in order to sort them
1351 Globs.events = events
1352
1353 for eachdate in cal_events.keys():
1354 cal_events[eachdate].sort(comp_cal_events)
1355
1356 # cache update
1357 if not nocache:
1358 cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL))
1359 cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL))
1360
1361 else:
1362 events = raw_events
1363
1364 # store event list into global variables in order to sort them
1365 Globs.events = events
1366
1367 Globs.labels = labels
1368
1369 debug(u'Total %d events are loaded finally.' % len(events))
1370 debug(u'Total %d labels are loaded finally.' % len(labels))
1371
1372 return events, cal_events, labels
1373
1374
1375
1376 def loadEventsFromWikiPages():
1377
1378 events = {}
1379 labels = {}
1380 cached_event_loaded = 0
1381 dirty = 0
1382
1383 eventrecord_list = []
1384 labelrecord_list = []
1385 eventpages = []
1386 stored_errmsg = ''
1387
1388 request = Globs.request
1389 category = Params.category
1390
1391 # cache configurations
1392 arena = Page(request, Globs.pagename)
1393
1394 eventkey = 'events'
1395 labelkey = 'labels'
1396 pagelistkey = 'eventpages'
1397 errmsglistkey = 'eventcalerrormsglist'
1398
1399 cache_events = caching.CacheEntry(request, arena, eventkey)
1400 cache_labels = caching.CacheEntry(request, arena, labelkey)
1401 cache_pages = caching.CacheEntry(request, arena, pagelistkey)
1402 cache_errmsglist = caching.CacheEntry(request, arena, errmsglistkey)
1403
1404 # page list cache
1405
1406 debug('Checking page list cache')
1407
1408 # check the time at which page list cache has been created
1409
1410 cp_mtime = cache_pages.mtime()
1411 timedelta_days = 9999
1412
1413 if cp_mtime:
1414 cp_date = datetime.datetime.fromtimestamp(cp_mtime)
1415 today = datetime.datetime.fromtimestamp(time.time())
1416 datediff = today - cp_date
1417 timedelta_days = datediff.days
1418 debug('Time from page list cache built = %s' % datediff)
1419
1420
1421 if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1:
1422 categorypages = searchPages(request, category)
1423 for page in categorypages:
1424 eventpages.append(page.page_name)
1425 cache_pages.update('\n'.join(eventpages), True)
1426 debug('New page list is built: %d pages' % len(eventpages))
1427 else:
1428 eventpages = cache_pages.content(True).split('\n')
1429 debug('Cached page list is used: %d pages' % len(eventpages))
1430
1431 if not Globs.page_action == 'refresh':
1432 # check the cache validity
1433 for page_name in eventpages:
1434
1435 p = Page(request, page_name)
1436 e_ref = page_name
1437
1438 if cache_events.needsUpdate(p._text_filename()) or cache_labels.needsUpdate(p._text_filename()) or cache_errmsglist.needsUpdate(p._text_filename()):
1439 dirty = 1
1440 break
1441 else:
1442 dirty = 1
1443
1444 if dirty:
1445 # generating events
1446
1447 dirty_local = 0
1448 debug_records = {}
1449
1450 eventrecordkey = 'eventrecords'
1451 labelrecordkey = 'labelrecords'
1452 errmsgkey = 'eventcalerrormsg'
1453
1454 # fetch event records from each page in the category
1455 for page_name in eventpages:
1456
1457 p = Page(request, page_name)
1458 e_ref = page_name
1459
1460 cache_errmsg = caching.CacheEntry(request, p, errmsgkey)
1461 cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey)
1462 cache_labelrecords = caching.CacheEntry(request, p, labelrecordkey)
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.