Attachment 'EventCalendar-098.py'
Download 1 """
2 EventCalendar.py Version 0.98 May 12, 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
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 startdate = '%d/%02d/%02d' % (int(startyear), int(startmonth), int(startday))
2011
2012 else:
2013 startdate = ''
2014
2015 if match.group('starttime'):
2016
2017 # 12h with ':': 12:00; 9:00pm
2018 if match.group('starttime1'):
2019 starthour = int(match.group('starthour1'))
2020 if match.group('startminute1'):
2021 startmin = int(match.group('startminute1'))
2022 else:
2023 startmin = 0
2024
2025 if starthour < 12 and match.group('am1').lower().startswith('p'):
2026 starthour += 12
2027
2028 # 24h with ':': 12:00; 23:00
2029 elif match.group('starttime2'):
2030 starthour = int(match.group('starthour2'))
2031 if match.group('startminute2'):
2032 startmin = int(match.group('startminute2'))
2033 else:
2034 startmin = 0
2035
2036 # 24h without ':': 1200; 2300
2037 elif match.group('starttime3'):
2038 starthour = int(match.group('starthour3'))
2039 if match.group('startminute3'):
2040 startmin = int(match.group('startminute3'))
2041 else:
2042 startmin = 0
2043
2044 # 12h without ':': 1200; 0900pm
2045 elif match.group('starttime4'):
2046
2047 starthour = int(match.group('starthour4'))
2048 if match.group('startminute4'):
2049 startmin = int(match.group('startminute4'))
2050 else:
2051 startmin = 0
2052
2053 if starthour < 12 and match.group('am4').lower().startswith('p'):
2054 starthour += 12
2055
2056 starttime = '%02d:%02d' % (int(starthour), int(startmin))
2057
2058 else:
2059 starttime = ''
2060
2061 if not startdate:
2062 raise EventcalError('invalid_start')
2063
2064 else:
2065 raise EventcalError('pass')
2066
2067 ##################### retrieve enddate
2068 match = pattern_enddate.search(detail)
2069
2070 if match:
2071
2072 if match.group('enddate'):
2073 # yyyy/mm/dd: 2006/05/10; 06/05/10,
2074 if match.group('enddate1'):
2075 if len(match.group('endyear1')) == 2:
2076 endyear = '20%s' % match.group('endyear1')
2077 else:
2078 endyear = match.group('endyear1')
2079
2080 endmonth = match.group('endmonth1')
2081 endday = match.group('endday1')
2082
2083 # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2084 elif match.group('enddate2'):
2085 if len(match.group('endyear2')) == 2:
2086 endyear = '20%s' % match.group('endyear2')
2087 else:
2088 endyear = match.group('endyear2')
2089
2090 endmonth = getNumericalMonth(match.group('endmonth2'))
2091 if not endmonth:
2092 raise EventcalError('invalid_enddate')
2093
2094 endday = match.group('endday2')
2095
2096 # yyyymmdd: 20060510, 060510
2097 elif match.group('enddate3'):
2098 if len(match.group('endyear3')) == 2:
2099 endyear = '20%s' % match.group('endyear3')
2100 else:
2101 endyear = match.group('endyear3')
2102
2103 endmonth = match.group('endmonth3')
2104 endday = match.group('endday3')
2105
2106 enddate = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2107 else:
2108 enddate = ''
2109
2110 if match.group('endtime'):
2111
2112 # 12h with ':': 12:00; 9:00pm
2113 if match.group('endtime1'):
2114 endhour = int(match.group('endhour1'))
2115 if match.group('endminute1'):
2116 endmin = int(match.group('endminute1'))
2117 else:
2118 endmin = 0
2119
2120 if endhour < 12 and match.group('am1').lower() == 'pm':
2121 endhour += 12
2122
2123 # 24h with ':': 12:00; 23:00
2124 elif match.group('endtime2'):
2125 endhour = int(match.group('endhour2'))
2126 if match.group('endminute2'):
2127 endmin = int(match.group('endminute2'))
2128 else:
2129 endmin = 0
2130
2131 # 24h without ':': 1200; 2300
2132 elif match.group('endtime3'):
2133 endhour = int(match.group('endhour3'))
2134 if match.group('endminute3'):
2135 endmin = int(match.group('endminute3'))
2136 else:
2137 endmin = 0
2138
2139 # 12h without ':': 1200; 0900pm
2140 elif match.group('endtime4'):
2141
2142 endhour = int(match.group('endhour4'))
2143 if match.group('endminute4'):
2144 endmin = int(match.group('endminute4'))
2145 else:
2146 endmin = 0
2147
2148 if endhour < 12 and match.group('am4').lower() == 'pm':
2149 endhour += 12
2150
2151 endtime = '%02d:%02d' % (int(endhour), int(endmin))
2152
2153 else:
2154 endtime = ''
2155
2156 if not (enddate or endtime):
2157 raise EventcalError('invalid_end')
2158
2159 else:
2160 enddate = ''
2161 endtime = ''
2162
2163
2164 ##################### retrieve bgcolor
2165 match = pattern_bgcolor.search(detail)
2166
2167 if match:
2168 if match.group('bgcolor'):
2169 bgcolor = match.group('bgcolor')
2170 else:
2171 errormsgcode('invalid_bgcolor')
2172 bgcolor = ''
2173
2174 else:
2175 bgcolor = ''
2176
2177 ##################### retrieve label
2178 match = pattern_label.search(detail)
2179
2180 if match:
2181 if match.group('name'):
2182 label = match.group('name')
2183 else:
2184 errormsgcode('invalid_label')
2185 label = ''
2186
2187 else:
2188 label = ''
2189
2190 ##################### retrieve description
2191 match = pattern_description.search(detail)
2192
2193 if match:
2194 if match.group('description'):
2195 description = match.group('description')
2196 else:
2197 errormsgcode('empty_description')
2198 description = ''
2199 else:
2200 description = ''
2201
2202 ##################### retrieve recurrence
2203 match = pattern_recur.search(detail)
2204
2205 if match:
2206
2207 if match.group('recur_freq') and match.group('recur_type'):
2208
2209 if match.group('recur_freq') == 'last':
2210 if match.group('recur_type') == 'weekday':
2211 recur_freq = -1
2212 recur_type = match.group('recur_type')
2213 recur_until = match.group('recur_until')
2214 else:
2215 recur_freq = 0
2216 recur_type = ''
2217 recur_until = ''
2218
2219 else:
2220 recur_freq = int(match.group('recur_freq'))
2221 recur_type = match.group('recur_type')
2222
2223 if match.group('recur_until_req'):
2224 if match.group('recur_until'):
2225 # yyyy/mm/dd: 2006/05/10; 06/05/10,
2226 if match.group('enddate1'):
2227 if len(match.group('endyear1')) == 2:
2228 endyear = '20%s' % match.group('endyear1')
2229 else:
2230 endyear = match.group('endyear1')
2231
2232 endmonth = match.group('endmonth1')
2233 endday = match.group('endday1')
2234
2235 # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2236 elif match.group('enddate2'):
2237 if len(match.group('endyear2')) == 2:
2238 endyear = '20%s' % match.group('endyear2')
2239 else:
2240 endyear = match.group('endyear2')
2241
2242 endmonth = getNumericalMonth(match.group('endmonth2'))
2243 if not endmonth:
2244 raise EventcalError('invalid_recur_until')
2245
2246 endday = match.group('endday2')
2247
2248 # yyyymmdd: 20060510, 060510
2249 elif match.group('enddate3'):
2250 if len(match.group('endyear3')) == 2:
2251 endyear = '20%s' % match.group('endyear3')
2252 else:
2253 endyear = match.group('endyear3')
2254
2255 endmonth = match.group('endmonth3')
2256 endday = match.group('endday3')
2257
2258 recur_until = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2259 else:
2260 raise EventcalError('invalid_recur_until')
2261
2262 else:
2263 recur_until = ''
2264
2265 else:
2266 raise EventcalError('invalid_recur')
2267
2268 else:
2269 recur_freq = 0
2270 recur_type = ''
2271 recur_until = ''
2272
2273 # check validity of each fields
2274
2275 if (starttime or endtime):
2276 if not endtime:
2277 endtime = starttime
2278 elif not starttime:
2279 raise EventcalError('invalid_starttime')
2280
2281
2282 # if no time, it's 1-day event
2283 if not enddate:
2284 enddate = startdate
2285
2286 try:
2287 syear, smonth, sday = getdatefield(startdate)
2288 except (TypeError, ValueError):
2289 raise EventcalError('invalid_startdate')
2290
2291 try:
2292 eyear, emonth, eday = getdatefield(enddate)
2293 except (TypeError, ValueError):
2294 raise EventcalError('invalid_enddate')
2295
2296 if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
2297 raise EventcalError('enddate_precede')
2298
2299 # format date
2300 startdate = formatDate(syear, smonth, sday)
2301 enddate = formatDate(eyear, emonth, eday)
2302
2303 if (starttime and endtime):
2304 try:
2305 shour, smin = gettimefield(starttime)
2306 except (TypeError, ValueError):
2307 raise EventcalError('invalid_starttime')
2308
2309 try:
2310 ehour, emin = gettimefield(endtime)
2311 except (TypeError, ValueError):
2312 raise EventcalError('invalid_endtime')
2313
2314 if startdate == enddate:
2315 if datetime.time(shour, smin) > datetime.time(ehour, emin):
2316 raise EventcalError('endtime_precede')
2317
2318 # format time
2319 starttime = u'%02d%02d' %(shour, smin)
2320 endtime = u'%02d%02d' %(ehour, emin)
2321
2322 # check recurrent data
2323 event_len = diffday(startdate, enddate)
2324 if recur_freq:
2325
2326 if recur_type == 'day':
2327 if event_len > int(recur_freq):
2328 raise EventcalError('len_recur_int')
2329
2330 elif recur_type == 'week':
2331 if event_len > int(recur_freq) * 7:
2332 raise EventcalError('len_recur_int')
2333
2334 elif recur_type == 'weekday':
2335 if event_len > 25:
2336 raise EventcalError('len_recur_int')
2337
2338 elif recur_type == 'month':
2339 if event_len > int(recur_freq) * 25:
2340 raise EventcalError('len_recur_int')
2341
2342 elif recur_type == 'year':
2343 if event_len > int(recur_freq) * 365:
2344 raise EventcalError('len_recur_int')
2345
2346 if recur_until:
2347 try:
2348 ryear, rmonth, rday = getdatefield(recur_until)
2349 except (TypeError, ValueError):
2350 raise EventcalError('invalid_date')
2351
2352 recur_until = formatDate(ryear, rmonth, rday)
2353
2354 if int(recur_until) < int(enddate):
2355 raise EventcalError('invalid_date')
2356
2357 return startdate, starttime, enddate, endtime, bgcolor, label, description, recur_freq, recur_type, recur_until
2358
2359
2360
2361 def converttext(targettext):
2362 # Converts some special characters of html to plain-text style
2363 # What else to handle?
2364
2365 targettext = targettext.replace(u'&', '&')
2366 targettext = targettext.replace(u'>', '>')
2367 targettext = targettext.replace(u'<', '<')
2368 targettext = targettext.replace(u'\n', '<br>')
2369 targettext = targettext.replace(u'"', '"')
2370 targettext = targettext.replace(u'\t', '  ')
2371 targettext = targettext.replace(u' ', ' ')
2372
2373 return targettext
2374
2375
2376 # monthly view
2377 def showeventcalendar(year, month):
2378
2379 debug('Show Calendar: Monthly View')
2380
2381 request = Globs.request
2382 formatter = Globs.formatter
2383 _ = request.getText
2384
2385 wkend = Globs.wkend
2386 months= Globs.months
2387 wkdays = Globs.wkdays
2388
2389 # get the calendar
2390 monthcal = calendar.monthcalendar(year, month)
2391
2392 # shows current year & month
2393 html_header_curyearmonth = calhead_yearmonth(year, month, 'head_yearmonth')
2394
2395 r7 = range(7)
2396
2397 # shows header of week days
2398 html_header_weekdays = []
2399
2400 for wkday in r7:
2401 wday = _(wkdays[wkday])
2402 html_header_weekdays.append( calhead_weekday(wday, 'head_weekday') )
2403 html_header_weekdays = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
2404
2405 # pending events for next row
2406 next_pending = []
2407
2408 # gets previous, next month
2409 day_delta = datetime.timedelta(days=-1)
2410 cur_month = datetime.date(year, month, 1)
2411 prev_month = cur_month + day_delta
2412
2413 day_delta = datetime.timedelta(days=15)
2414 cur_month_end = datetime.date(year, month, 25)
2415 next_month = cur_month_end + day_delta
2416
2417 prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
2418 next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
2419
2420 # shows days
2421 html_week_rows = []
2422
2423 # set ranges of events
2424 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2425 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2426
2427 # read all the events
2428 events, cal_events, labels = loadEvents(datefrom, dateto)
2429
2430 #debug(u' events: %s' % events)
2431 #debug(u' cal_events: %s' % cal_events)
2432
2433 for week in monthcal:
2434
2435 # day head rows
2436 html_headday_cols = []
2437 html_events_rows = []
2438
2439 for wkday in r7:
2440
2441 day = week[wkday]
2442
2443 if not day:
2444 if week == monthcal[0]:
2445 nb_day = prev_monthcal[-1][wkday]
2446 else:
2447 nb_day = next_monthcal[0][wkday]
2448
2449 html_headday_cols.append( calhead_day_nbmonth(nb_day) )
2450 else:
2451 html_headday_cols.append( calhead_day(year, month, day, wkday) )
2452
2453 html_headday_row = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
2454 html_week_rows.append(html_headday_row)
2455
2456 # dummy rows
2457 html_headdummy_cols = []
2458
2459 for wkday in r7:
2460 day = week[wkday]
2461 if not day:
2462 html_headdummy_cols.append( calshow_blankbox('head_dummy_nbmonth') )
2463 else:
2464 html_headdummy_cols.append( calshow_blankbox('head_dummy') )
2465
2466 html_headdummy_cols = u'\r\n'.join(html_headdummy_cols)
2467 html_week_rows.append(' <tr>\r\n%s </tr>\r\n' % html_headdummy_cols)
2468
2469 # pending events for next row
2470 pending = next_pending
2471 next_pending = []
2472
2473 # show events
2474 while 1:
2475 event_left = 7
2476 colspan = -1
2477 html_events_cols = []
2478
2479 for wkday in r7:
2480
2481 day = week[wkday]
2482
2483 if not day:
2484 if week == monthcal[0]:
2485 cur_date = formatDate(prev_month.year, prev_month.month, prev_monthcal[-1][wkday])
2486 else:
2487 cur_date = formatDate(next_month.year, next_month.month, next_monthcal[0][wkday])
2488 else:
2489 cur_date = formatDate(year, month, day)
2490
2491 # if an event is already displayed with colspan
2492 if colspan > 0:
2493 colspan -= 1
2494 if cal_events.has_key(cur_date) and lastevent in cal_events[cur_date]:
2495 cal_events[cur_date].remove(lastevent)
2496
2497 continue
2498
2499 # if there is any event for this date
2500 if cal_events.has_key(cur_date):
2501 if len(cal_events[cur_date]) > 0:
2502
2503 # if there is any pending event in the previous week
2504 if wkday == 0 and len(pending) > 0:
2505 todo_event_id = pending.pop(0)
2506 if todo_event_id in cal_events[cur_date]:
2507 cur_event = events[todo_event_id]
2508 temp_len = diffday(cur_date, cur_event['enddate']) + 1
2509
2510 # calculate colspan value
2511 if (7-wkday) < temp_len:
2512 colspan = 7 - wkday
2513 next_pending.append(cur_event['id'])
2514 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
2515
2516 else:
2517 colspan = temp_len
2518 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
2519
2520
2521 cal_events[cur_date].remove(todo_event_id)
2522
2523 colspan -= 1
2524 lastevent = todo_event_id
2525 else:
2526 debug('Warning: no such event in cal_events')
2527
2528 continue
2529
2530 # if there is no pending event in the previous week, start a new event
2531 event_found = 0
2532 for e_id in cal_events[cur_date]:
2533
2534 # if the start date of the event is current date
2535 if events[e_id]['startdate'] == cur_date:
2536
2537 cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2538
2539 # calculate colspan value
2540 if (7-wkday) < cur_event['date_len']:
2541 colspan = 7 - wkday
2542 next_pending.append(cur_event['id'])
2543 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'pending', cur_date) )
2544
2545 else:
2546 colspan = cur_event['date_len']
2547 html_events_cols.append( calshow_eventbox(cur_event, colspan, '', cur_date) )
2548
2549 colspan -= 1
2550 lastevent = cur_event['id']
2551 event_found = 1
2552 break
2553
2554 # if the start date of the event is NOT current date
2555 else:
2556
2557 # pending event from previous month
2558 if wkday == 0 and week == monthcal[0]:
2559
2560 cur_event = events[cal_events[cur_date].pop(0)]
2561 temp_len = diffday(cur_date, cur_event['enddate']) + 1
2562
2563 # calculate colspan value
2564 if (7-wkday) < temp_len:
2565 colspan = 7 - wkday
2566 next_pending.append(cur_event['id'])
2567 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
2568 else:
2569 colspan = temp_len
2570 html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
2571
2572 colspan -= 1
2573 lastevent = cur_event['id']
2574 event_found = 1
2575 break
2576
2577 # if there is no event to start
2578 if not event_found:
2579 if not day:
2580 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2581 else:
2582 html_events_cols.append( calshow_blankbox('cal_noevent') )
2583 event_left -= 1
2584
2585 else:
2586 if not day:
2587 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2588 else:
2589 html_events_cols.append( calshow_blankbox('cal_noevent') )
2590
2591 event_left -= 1
2592
2593 # if there is NO event for this date
2594 else:
2595 if not day:
2596 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2597 else:
2598 html_events_cols.append( calshow_blankbox('cal_noevent') )
2599
2600 event_left -= 1
2601
2602 # if no event for this entry
2603 if not event_left:
2604 # ignore the previous entry
2605 break
2606 else:
2607 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2608
2609 # show dummy blank slots for week height
2610 left_blank_rows = 2 - len(html_events_rows)
2611
2612 # remove the followings
2613 if left_blank_rows > 0 and 0:
2614 for i in range(left_blank_rows):
2615 html_events_cols = []
2616 for wkday in r7:
2617 day = week[wkday]
2618 if not day:
2619 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2620 else:
2621 html_events_cols.append( calshow_blankbox('cal_noevent') )
2622
2623 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2624
2625
2626 # close the week slots
2627 html_events_cols = []
2628 for wkday in r7:
2629 day = week[wkday]
2630 if not day:
2631 html_events_cols.append( calshow_blankbox('cal_last_nbmonth') )
2632 else:
2633 html_events_cols.append( calshow_blankbox('cal_last_noevent') )
2634
2635 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2636
2637 html_events_rows = u'\r\n'.join(html_events_rows)
2638 html_week_rows.append(html_events_rows)
2639
2640 html_calendar_rows = u'\r\n'.join(html_week_rows)
2641
2642 html_cal_table = [
2643 u'\r\n<div id="eventcalendar">',
2644 u'<table class="eventcalendar" %s>' % Params.monthlywidth,
2645 u'%s' % html_header_curyearmonth,
2646 u'%s' % html_header_weekdays,
2647 u'%s' % html_calendar_rows,
2648 u'</table>',
2649 u'</div>',
2650 ]
2651 html_cal_table = u'\r\n'.join(html_cal_table)
2652
2653 return html_cal_table
2654
2655
2656
2657 # daily view
2658 def showdailyeventcalendar(year, month, day):
2659
2660 debug('Show Calendar: Daily View')
2661
2662 request = Globs.request
2663 formatter = Globs.formatter
2664 _ = request.getText
2665
2666 wkend = Globs.wkend
2667 months= Globs.months
2668 wkdays = Globs.wkdays
2669
2670 cur_date = formatDate(year, month, day)
2671
2672 # gets previous, next month
2673 day_delta = datetime.timedelta(days=-1)
2674 cur_month = datetime.date(year, month, 1)
2675 prev_month = cur_month + day_delta
2676
2677 day_delta = datetime.timedelta(days=15)
2678 cur_month_end = datetime.date(year, month, 25)
2679 next_month = cur_month_end + day_delta
2680
2681 # set ranges of events
2682 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2683 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2684
2685 # read all the events
2686 events, cal_events, labels = loadEvents(datefrom, dateto)
2687
2688 #debug(u' events: %s' % events)
2689 #debug(u' cal_events: %s' % cal_events)
2690
2691 # calculates hour_events
2692 hour_events = {}
2693
2694 if cal_events.has_key(cur_date):
2695 for e_id in cal_events[cur_date]:
2696 cur_event = events[e_id]
2697
2698 if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2699 start_hour, start_min = gettimefield(cur_event['starttime'])
2700
2701 if not hour_events.has_key(start_hour):
2702 hour_events[start_hour] = []
2703
2704 hour_events[start_hour].append(e_id)
2705
2706 #debug(u'hour_events: %s' % hour_events)
2707
2708 # in-day events
2709 html_calendar_rows = []
2710 html_hour_cols = {}
2711
2712 slot_pending = {}
2713 max_num_slots = 0
2714 hour_max_slots = {}
2715 block_slots = []
2716
2717 start_hour_index = 0
2718
2719 r24 = range(24)
2720
2721 for hour_index in r24:
2722
2723 html_hour_cols[hour_index] = []
2724 hour_max_slots[hour_index] = 1
2725 html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
2726
2727 if len(slot_pending) > 0 or hour_events.has_key(hour_index):
2728
2729 #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2730 if len(slot_pending) == 0:
2731 if max_num_slots < 1:
2732 max_num_slots = 1
2733
2734 for hour_lines in range(start_hour_index, hour_index):
2735 hour_max_slots[hour_lines] = max_num_slots
2736
2737 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2738
2739 block_slots.append(max_num_slots)
2740
2741 max_num_slots = 0
2742 start_hour_index = hour_index
2743
2744 for slot_index in range(max_num_slots):
2745 if slot_pending.has_key(slot_index) and slot_pending[slot_index] > 0:
2746 if slot_pending[slot_index] == 1:
2747 del slot_pending[slot_index]
2748 else:
2749 slot_pending[slot_index] -= 1
2750 html_hour_cols[hour_index].append ( '' )
2751
2752 else:
2753 if hour_events.has_key(hour_index) and len(hour_events[hour_index]) > 0:
2754 e_id = hour_events[hour_index][0]
2755 cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2756 html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2757 slot_pending[slot_index] = cur_event['time_len'] - 1
2758 else:
2759 if not ((len(slot_pending) > 0 and slot_index > max(slot_pending.keys())) or len(slot_pending) == 0):
2760 html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2761
2762 if hour_events.has_key(hour_index):
2763 for tmp_cnt in range(len(hour_events[hour_index])):
2764 e_id = hour_events[hour_index][0]
2765 cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2766 html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2767 slot_pending[max_num_slots] = cur_event['time_len'] - 1
2768 if slot_pending[max_num_slots] == 0:
2769 del slot_pending[max_num_slots]
2770 max_num_slots += 1
2771
2772 else:
2773 html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2774 #hour_max_slots[hour_index] = 1
2775
2776 if max_num_slots < 1:
2777 max_num_slots = 1
2778
2779 for hour_lines in range(start_hour_index, hour_index):
2780 hour_max_slots[hour_lines] = max_num_slots
2781
2782 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2783
2784 block_slots.append(max_num_slots)
2785
2786 max_num_slots = 0
2787 start_hour_index = hour_index
2788
2789
2790 #debug('end: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2791
2792 if max_num_slots < 1:
2793 max_num_slots = 1
2794
2795 for hour_lines in range(start_hour_index, 24):
2796 hour_max_slots[hour_lines] = max_num_slots
2797
2798 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, 23, max_num_slots))
2799
2800 block_slots.append(max_num_slots)
2801
2802 #debug('hour_max_slots: %s' % hour_max_slots)
2803
2804
2805 # calculates global colspan
2806 if len(block_slots):
2807 global_colspan = LCM(block_slots)
2808 else:
2809 global_colspan = 1
2810
2811 for hour_index in r24:
2812
2813 colspan = global_colspan / hour_max_slots[hour_index]
2814 width = 96 / hour_max_slots[hour_index]
2815
2816 left_slots = hour_max_slots[hour_index] - (len(html_hour_cols[hour_index]) - 1)
2817
2818 if left_slots > 0:
2819 #debug('appending left %d slots: %d' % (left_slots, hour_index))
2820 html_hour_cols[hour_index].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
2821
2822 html_cols = u'\r\n'.join(html_hour_cols[hour_index]) % {'colspan': colspan, 'width': u'%d%%' % width}
2823 html_cols = u'<tr>%s</tr>\r\n' % html_cols
2824
2825 html_calendar_rows.append (html_cols)
2826
2827 html_calendar_rows = u'\r\n'.join(html_calendar_rows)
2828
2829 # shows current year & month
2830 html_header_curyearmonthday = calhead_yearmonthday(year, month, day, 'head_yearmonth', global_colspan)
2831
2832 # one-day long events
2833 html_oneday_rows = []
2834
2835 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2836
2837 if cal_events.has_key(cur_date):
2838 if len(cal_events[cur_date]) > 0:
2839 for e_id in cal_events[cur_date]:
2840 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2841 #debug('test events[%s] = %s' % (e_id, events[e_id]))
2842 if events[e_id]['time_len'] <= 0 or events[e_id]['date_len'] > 1:
2843 #cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2844 cur_event = events[e_id]
2845
2846 if cur_event['startdate'] == cur_date:
2847 if cur_event['enddate'] == cur_date:
2848 str_status = ''
2849 else:
2850 str_status = 'pending'
2851 else:
2852 if cur_event['enddate'] == cur_date:
2853 str_status = 'append'
2854 else:
2855 str_status = 'append_pending'
2856
2857 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)
2858 html_oneday_rows.append( tmp_html )
2859
2860 #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2861 else:
2862 tmp_html = u'<tr><td width="4%%" style="border-width: 0px; "> </td>%s</tr>' % calshow_blankbox2('cal_daily_noevent', global_colspan)
2863 html_oneday_rows.append( tmp_html )
2864
2865 #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2866 #debug('html_oneday_rows = %s' % html_oneday_rows)
2867
2868 html_oneday_rows = u'\r\n'.join(html_oneday_rows)
2869
2870
2871 html_cal_table = [
2872 u'\r\n<div id="eventcalendar">',
2873 u'<table class="eventcalendar" %s>' % Params.dailywidth,
2874 u'<table border="0">',
2875 u'%s' % html_header_curyearmonthday,
2876 u'%s' % html_oneday_rows,
2877 u'%s' % html_calendar_rows,
2878 u'</table>',
2879 u'</td></tr>',
2880 u'</div>',
2881 ]
2882 html_cal_table = u'\r\n'.join(html_cal_table)
2883
2884 return html_cal_table
2885
2886
2887
2888 # weekly view
2889 def showweeklyeventcalendar(year, month, day):
2890
2891 debug('Show Calendar: Weekly View')
2892
2893 request = Globs.request
2894 formatter = Globs.formatter
2895 _ = request.getText
2896
2897 wkend = Globs.wkend
2898 months= Globs.months
2899 wkdays = Globs.wkdays
2900
2901 cur_date = formatDate(year, month, day)
2902
2903 # gets previous, next month
2904 day_delta = datetime.timedelta(days=-1)
2905 cur_month = datetime.date(year, month, 1)
2906 prev_month = cur_month + day_delta
2907
2908 day_delta = datetime.timedelta(days=15)
2909 cur_month_end = datetime.date(year, month, 25)
2910 next_month = cur_month_end + day_delta
2911
2912 # set ranges of events
2913 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2914 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2915
2916 # read all the events
2917 events, cal_events, labels = loadEvents(datefrom, dateto)
2918
2919 #debug(u' events: %s' % events)
2920 #debug(u' cal_events: %s' % cal_events)
2921
2922 # calculates hour_events
2923 hour_events = {}
2924
2925 first_date_week = getFirstDateOfWeek(year, month, day)
2926
2927
2928 for dayindex in range(7):
2929 hour_events[dayindex] = {}
2930
2931 cur_date = first_date_week + datetime.timedelta(dayindex)
2932 cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
2933
2934 if cal_events.has_key(cur_date):
2935 for e_id in cal_events[cur_date]:
2936 cur_event = events[e_id]
2937
2938 if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2939 start_hour, start_min = gettimefield(cur_event['starttime'])
2940
2941 if not hour_events[dayindex].has_key(start_hour):
2942 hour_events[dayindex][start_hour] = []
2943
2944 hour_events[dayindex][start_hour].append(e_id)
2945
2946 #debug(u'hour_events: %s' % hour_events)
2947
2948 # in-day events
2949 html_calendar_rows = []
2950 html_hour_cols = {}
2951
2952 slot_pending = {}
2953 max_num_slots = {}
2954 hour_max_slots = {}
2955 block_slots = {}
2956
2957 start_hour_index = {}
2958
2959 r24 = range(24)
2960
2961 for hour_index in r24:
2962
2963 html_hour_cols[hour_index] = {}
2964 hour_max_slots[hour_index] = {}
2965
2966 #html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
2967
2968 for dayindex in range(7):
2969
2970 if not max_num_slots.has_key(dayindex):
2971 max_num_slots[dayindex] = 0
2972
2973 if not slot_pending.has_key(dayindex):
2974 slot_pending[dayindex] = {}
2975
2976 if not start_hour_index.has_key(dayindex):
2977 start_hour_index[dayindex] = 0
2978
2979 if not block_slots.has_key(dayindex):
2980 block_slots[dayindex] = []
2981
2982 html_hour_cols[hour_index][dayindex] = []
2983 hour_max_slots[hour_index][dayindex] = 1
2984
2985 if len(slot_pending[dayindex]) > 0 or hour_events[dayindex].has_key(hour_index):
2986
2987 #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending[dayindex]))
2988 if len(slot_pending[dayindex]) == 0:
2989 if max_num_slots[dayindex] < 1:
2990 max_num_slots[dayindex] = 1
2991
2992 for hour_lines in range(start_hour_index[dayindex], hour_index):
2993 hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
2994
2995 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
2996
2997 block_slots[dayindex].append(max_num_slots[dayindex])
2998
2999 max_num_slots[dayindex] = 0
3000 start_hour_index[dayindex] = hour_index
3001
3002 for slot_index in range(max_num_slots[dayindex]):
3003 if slot_pending[dayindex].has_key(slot_index) and slot_pending[dayindex][slot_index] > 0:
3004 if slot_pending[dayindex][slot_index] == 1:
3005 del slot_pending[dayindex][slot_index]
3006 else:
3007 slot_pending[dayindex][slot_index] -= 1
3008 html_hour_cols[hour_index][dayindex].append ( '' )
3009
3010 else:
3011 if hour_events[dayindex].has_key(hour_index) and len(hour_events[dayindex][hour_index]) > 0:
3012 e_id = hour_events[dayindex][hour_index][0]
3013 cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
3014 html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
3015 slot_pending[dayindex][slot_index] = cur_event['time_len'] - 1
3016 else:
3017 if not ((len(slot_pending[dayindex]) > 0 and slot_index > max(slot_pending[dayindex].keys())) or len(slot_pending[dayindex]) == 0):
3018 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
3019
3020 if hour_events[dayindex].has_key(hour_index):
3021 for tmp_cnt in range(len(hour_events[dayindex][hour_index])):
3022 e_id = hour_events[dayindex][hour_index][0]
3023 cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
3024 html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
3025 slot_pending[dayindex][max_num_slots[dayindex]] = cur_event['time_len'] - 1
3026 if slot_pending[dayindex][max_num_slots[dayindex]] == 0:
3027 del slot_pending[dayindex][max_num_slots[dayindex]]
3028 max_num_slots[dayindex] += 1
3029
3030 else:
3031 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
3032 #hour_max_slots[hour_index][dayindex] = 1
3033
3034 if max_num_slots[dayindex] < 1:
3035 max_num_slots[dayindex] = 1
3036
3037 for hour_lines in range(start_hour_index[dayindex], hour_index):
3038 hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3039
3040 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
3041
3042 block_slots[dayindex].append(max_num_slots[dayindex])
3043
3044 max_num_slots[dayindex] = 0
3045 start_hour_index[dayindex] = hour_index
3046
3047 global_colspan = {}
3048 header_colspan = 0
3049
3050 for dayindex in range(7):
3051 if max_num_slots[dayindex] < 1:
3052 max_num_slots[dayindex] = 1
3053
3054 for hour_lines in range(start_hour_index[dayindex], 24):
3055 hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3056
3057 block_slots[dayindex].append(max_num_slots[dayindex])
3058
3059 # calculates global colspan
3060 if len(block_slots[dayindex]):
3061 global_colspan[dayindex] = LCM(block_slots[dayindex])
3062 else:
3063 global_colspan[dayindex] = 1
3064
3065 header_colspan += global_colspan[dayindex]
3066
3067
3068 for hour_index in r24:
3069
3070 html_cols_days = []
3071
3072 for dayindex in range(7):
3073
3074 colspan = global_colspan[dayindex] / hour_max_slots[hour_index][dayindex]
3075 width = (100 - 2) / 7 / hour_max_slots[hour_index][dayindex]
3076
3077 left_slots = hour_max_slots[hour_index][dayindex] - len(html_hour_cols[hour_index][dayindex])
3078
3079 if left_slots > 0:
3080 #debug('appending left %d slots: %d' % (left_slots, hour_index))
3081 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
3082
3083 html_cols = u'\r\n'.join(html_hour_cols[hour_index][dayindex]) % {'colspan': colspan, 'width': u'%d%%' % width}
3084 html_cols_days.append(html_cols)
3085
3086 html_cols_collected = u'\r\n'.join(html_cols_days)
3087 html_cols = u'<tr>%s\r\n%s</tr>\r\n' % (calshow_weekly_hourhead(hour_index), html_cols_collected)
3088
3089 html_calendar_rows.append (html_cols)
3090
3091 html_calendar_rows = u'\r\n'.join(html_calendar_rows)
3092
3093 # shows current year & month
3094 html_header_curyearmonthday = calhead_yearmonthday2(year, month, day, 'head_yearmonth', header_colspan)
3095
3096 # one-day long events
3097 html_oneday_rows = {}
3098
3099 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
3100
3101 #first_date_week = getFirstDateOfWeek(year, month, day)
3102
3103 html_oneday_rows = []
3104
3105 while 1:
3106 html_oneday_cols = []
3107 cnt_blank_cols = 0
3108 pending = -1
3109
3110 for dayindex in range(7):
3111
3112 if pending > 0:
3113 pending -= 1
3114 html_oneday_cols.append('')
3115 continue
3116 else:
3117 pending = -1
3118
3119 cur_date = first_date_week + datetime.timedelta(dayindex)
3120 cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
3121
3122 if cal_events.has_key(cur_date) and len(cal_events[cur_date]) > 0:
3123
3124 tmpcount = len(cal_events[cur_date])
3125 for tmp_index in range(tmpcount):
3126 cur_event = events[cal_events[cur_date].pop(0)]
3127
3128 #debug('event poped out at %s: %s' % (cur_date, cur_event))
3129
3130 if (cur_event['startdate'] <= cur_date and dayindex == 0) or cur_event['startdate'] == cur_date:
3131 if cur_event['time_len'] <= 0 or cur_event['date_len'] > 1:
3132
3133 temp_len = diffday(cur_date, cur_event['enddate']) + 1
3134
3135 if cur_event['startdate'] == cur_date:
3136 if temp_len <= 7 - dayindex:
3137 str_status = ''
3138 else:
3139 str_status = 'pending'
3140 else:
3141 if temp_len <= 7 - dayindex:
3142 str_status = 'append'
3143 else:
3144 str_status = 'append_pending'
3145
3146 if temp_len > 7 - dayindex:
3147 temp_len = 7 - dayindex
3148
3149 pending = temp_len - 1
3150
3151 tmp_global_colspan = 0
3152 for tmp_index in range(dayindex, dayindex+temp_len):
3153 tmp_global_colspan += global_colspan[tmp_index]
3154
3155 #debug('event appended at %s with pending=%d: %s' % (cur_date, pending, cur_event))
3156
3157 html_oneday_cols.append( calshow_weekly_eventbox2(cur_event, tmp_global_colspan, 14 * temp_len, str_status, cur_date) )
3158 break
3159
3160 if pending < 0:
3161 html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
3162 cnt_blank_cols += 1
3163
3164 else:
3165 html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
3166 cnt_blank_cols += 1
3167
3168 if cnt_blank_cols >= 7:
3169 if len(html_oneday_rows) == 0:
3170 html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
3171 html_oneday_rows.append (html_oneday_cols)
3172 break
3173 else:
3174 html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
3175 html_oneday_rows.append (html_oneday_cols)
3176
3177 html_date_rows = []
3178
3179 for dayindex in range(7):
3180 cur_date = first_date_week + datetime.timedelta(dayindex)
3181 html_date_rows.append(calhead_weeklydate(cur_date.year, cur_date.month, cur_date.day, global_colspan[dayindex]))
3182
3183 html_date_rows = u'<tr><td width="2%%" style="border-width: 0px; "> </td>%s</tr>' % u'\r\n'.join(html_date_rows)
3184
3185 html_oneday_rows = u'\r\n'.join(html_oneday_rows)
3186
3187 html_cal_table = [
3188 u'\r\n<div id="eventcalendar">',
3189 u'<table class="eventcalendar" %s>' % Params.weeklywidth,
3190 u'<table border="0">',
3191 u'%s' % html_header_curyearmonthday,
3192 u'%s' % html_date_rows,
3193 u'%s' % html_oneday_rows,
3194 u'%s' % html_calendar_rows,
3195 u'</table>',
3196 u'</td></tr>',
3197 u'</div>',
3198 ]
3199 html_cal_table = u'\r\n'.join(html_cal_table)
3200
3201 return html_cal_table
3202
3203
3204
3205 # simple view
3206 def showsimpleeventcalendar(year, month):
3207
3208 debug('Show Calendar: Simple View')
3209
3210 request = Globs.request
3211 formatter = Globs.formatter
3212 _ = request.getText
3213 monthstyle_us = Globs.month_style_us
3214
3215 wkend = Globs.wkend
3216 months= Globs.months
3217 wkdays = Globs.wkdays
3218
3219 # get the calendar
3220 monthcal = calendar.monthcalendar(year, month)
3221
3222 # shows current year & month
3223 html_header_curyearmonth = calhead_yearmonth(year, month, 'simple_yearmonth')
3224
3225 r7 = range(7)
3226
3227 # shows header of week days
3228 html_header_weekdays = []
3229
3230 for wkday in r7:
3231 wday = wkdays[wkday]
3232 html_header_weekdays.append( calhead_weekday(wday, 'simple_weekday') )
3233 html_header_weekdays = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
3234
3235 # gets previous, next month
3236 day_delta = datetime.timedelta(days=-1)
3237 cur_month = datetime.date(year, month, 1)
3238 prev_month = cur_month + day_delta
3239
3240 day_delta = datetime.timedelta(days=15)
3241 cur_month_end = datetime.date(year, month, 25)
3242 next_month = cur_month_end + day_delta
3243
3244 prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
3245 next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
3246
3247 # shows days
3248 html_week_rows = []
3249
3250 # set ranges of events
3251 datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
3252 dateto = u'%04d%02d06' % (next_month.year, next_month.month)
3253
3254 # read all the events
3255 events, cal_events, labels = loadEvents(datefrom, dateto)
3256
3257 maketip_js = []
3258
3259 for week in monthcal:
3260
3261 # day head rows
3262 html_headday_cols = []
3263 html_events_rows = []
3264
3265 for wkday in r7:
3266
3267 day = week[wkday]
3268
3269 if not day:
3270 if week == monthcal[0]:
3271 nb_day = prev_monthcal[-1][wkday]
3272 else:
3273 nb_day = next_monthcal[0][wkday]
3274
3275 html_headday_cols.append( simple_eventbox(year, month, day, nb_day, 'simple_nb') )
3276 else:
3277 cur_date = formatDate(year, month, day)
3278
3279 if cal_events.has_key(cur_date):
3280 html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_event') )
3281
3282 if monthstyle_us:
3283 tiptitle = u'%s %d, %d' % (months[month-1], day, year)
3284 else:
3285 tiptitle = u'%d / %02d / %02d' % (year, month, day)
3286
3287 date_today = datetime.date( year, month, day )
3288 tiptitle = u'%s (%s)' % (tiptitle, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3289
3290 tiptext = []
3291
3292 for e_id in cal_events[cur_date]:
3293 cur_event = events[e_id]
3294 if cur_event['starttime']:
3295 time_string = u'(%s:%s)' % (cur_event['starttime'][:2], cur_event['starttime'][2:])
3296 else:
3297 time_string = ''
3298
3299 title = wikiutil.escape(cur_event['title']).replace("'","\\'")
3300 description = wikiutil.escape(cur_event['description']).replace("'","\\'")
3301
3302 tiptext.append( u'<b>%s</b>%s %s' % (title, time_string, description) )
3303
3304 tiptext = u'<br>'.join(tiptext)
3305
3306 maketip_js.append("maketip('%s','%s','%s');" % (cur_date, tiptitle, tiptext))
3307 else:
3308 html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_noevent') )
3309
3310 html_headday_row = ' <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
3311 html_week_rows.append(html_headday_row)
3312
3313 html_calendar_rows = u'\r\n'.join(html_week_rows)
3314
3315 html_tooltip_result = """\
3316 <script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script>
3317 <div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div>
3318 <script language="JavaScript" type="text/javascript">
3319 <!--
3320 %s
3321 // -->
3322 </script>
3323
3324 """ % (request.cfg.url_prefix, "\n".join(maketip_js))
3325
3326
3327 html_cal_table = [
3328 u'\r\n<div id="eventcalendar">',
3329 u'%s' % html_tooltip_result,
3330 u'<table class="simplecalendar" %s>' % Params.simplewidth,
3331 u'%s' % html_header_curyearmonth,
3332 u'%s' % html_header_weekdays,
3333 u'%s' % html_calendar_rows,
3334 u'</table>',
3335 u'</div>',
3336 ]
3337 html_cal_table = u'\r\n'.join(html_cal_table)
3338
3339 return html_cal_table
3340
3341
3342 # show calendar head (year & month)
3343 def calhead_yearmonth(year, month, headclass):
3344
3345 request = Globs.request
3346
3347 months = Globs.months
3348 monthstyle_us = Globs.month_style_us
3349 cal_action = Globs.cal_action
3350 page_name = Globs.pagename
3351
3352 page_url = Globs.pageurl
3353
3354 nextyear, nextmonth = yearmonthplusoffset(year, month, 1)
3355 prevyear, prevmonth = yearmonthplusoffset(year, month, -1)
3356
3357 prevlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, prevyear, prevmonth, getquerystring(['numcal']) )
3358 nextlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, nextyear, nextmonth, getquerystring(['numcal']))
3359 curlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, year, month, getquerystring(['numcal']))
3360
3361 if monthstyle_us:
3362 stryearmonth = u'%s %d' % (months[month-1], year)
3363 strnextmonth = u'%s %d' % (months[nextmonth-1], nextyear)
3364 strprevmonth = u'%s %d' % (months[prevmonth-1], prevyear)
3365 else:
3366 stryearmonth = u'%d / %02d' % (year, month)
3367 strnextmonth = u'%d / %02d' % (nextyear, nextmonth)
3368 strprevmonth = u'%d / %02d' % (prevyear, prevmonth)
3369
3370 html = [
3371 u' <tr>',
3372 u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth),
3373 u' <td colspan="5" class="%s"><a href="%s" title="Go/Refresh this month">%s</a></td>' % (headclass, curlink, stryearmonth),
3374 u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth),
3375 u' </tr>',
3376 ]
3377
3378 return u'\r\n'.join(html)
3379
3380
3381 # show calendar head (year & month & day)
3382 def calhead_yearmonthday(year, month, day, headclass, colspan):
3383
3384 request = Globs.request
3385 _ = request.getText
3386
3387 months = Globs.months
3388 monthstyle_us = Globs.month_style_us
3389 cal_action = Globs.cal_action
3390 page_name = Globs.pagename
3391 wkdays = Globs.wkdays
3392
3393 page_url = Globs.pageurl
3394
3395 date_today = datetime.date( year, month, day )
3396 prevdate = date_today - datetime.timedelta(days=1)
3397 nextdate = date_today + datetime.timedelta(days=1)
3398
3399 prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
3400 nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
3401 curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
3402
3403 if monthstyle_us:
3404 stryearmonth = u'%s %d, %d' % (months[month-1], day, year)
3405 strnextmonth = u'%s %d, %d' % (months[nextdate.month-1], nextdate.day, nextdate.year)
3406 strprevmonth = u'%s %d, %d' % (months[prevdate.month-1], prevdate.day, prevdate.year)
3407 else:
3408 stryearmonth = u'%d / %02d / %02d' % (year, month, day)
3409 strnextmonth = u'%d / %02d / %02d' % (nextdate.year, nextdate.month, nextdate.day)
3410 strprevmonth = u'%d / %02d / %02d' % (prevdate.year, prevdate.month, prevdate.day)
3411
3412 #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday()]))
3413 stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3414
3415 html = [
3416 u'<tr><td width="4%" style="border: none;"> </td>',
3417 u'<td colspan="%d" style="border: none;">' % colspan,
3418 u'<table width="95%">',
3419 u' <tr>',
3420 u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth),
3421 u' <td class="%s"><a href="%s" title="Go/Refresh this day">%s</a></td>' % (headclass, curlink, stryearmonth),
3422 u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth),
3423 u' </tr>',
3424 u'</table>',
3425 u'</td></tr>',
3426 ]
3427
3428 return u'\r\n'.join(html)
3429
3430 # show calendar head for weekly view (year & month & day)
3431 def calhead_yearmonthday2(year, month, day, headclass, colspan):
3432
3433 request = Globs.request
3434 _ = request.getText
3435
3436 months = Globs.months
3437 monthstyle_us = Globs.month_style_us
3438 cal_action = Globs.cal_action
3439 page_name = Globs.pagename
3440 wkdays = Globs.wkdays
3441
3442 page_url = Globs.pageurl
3443
3444 date_today = datetime.date( year, month, day )
3445 prevdate = date_today - datetime.timedelta(days=7)
3446 nextdate = date_today + datetime.timedelta(days=7)
3447
3448 first_date_week = getFirstDateOfWeek(year, month, day)
3449 prevdate_f = first_date_week - datetime.timedelta(days=7)
3450 nextdate_f = first_date_week + datetime.timedelta(days=7)
3451
3452 last_date_week = first_date_week + datetime.timedelta(days=6)
3453 prevdate_l = last_date_week - datetime.timedelta(days=7)
3454 nextdate_l = last_date_week + datetime.timedelta(days=7)
3455
3456 prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
3457 nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
3458 curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
3459
3460 if monthstyle_us:
3461 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)
3462 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)
3463 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)
3464 else:
3465 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)
3466 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)
3467 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)
3468
3469 #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3470
3471 html = [
3472 u'<tr><td width="2%" style="border: none;"> </td>',
3473 u'<td colspan="%d" style="border: none;">' % colspan,
3474 u'<table width="95%">',
3475 u' <tr>',
3476 u' <td class="%s"><a href="%s" title="%s"><</a></td>' % (headclass, prevlink, strprevmonth),
3477 u' <td class="%s"><a href="%s" title="Go/Refresh this week">%s</a></td>' % (headclass, curlink, stryearmonth),
3478 u' <td class="%s"><a href="%s" title="%s">></a></td>' % (headclass, nextlink, strnextmonth),
3479 u' </tr>',
3480 u'</table>',
3481 u'</td></tr>',
3482 ]
3483
3484 return u'\r\n'.join(html)
3485
3486
3487 # show calendar head for weekly view (the date)
3488 def calhead_weeklydate(year, month, day, colspan):
3489
3490 request = Globs.request
3491 _ = request.getText
3492
3493 months = Globs.months
3494 monthstyle_us = Globs.month_style_us
3495 cal_action = Globs.cal_action
3496 page_name = Globs.pagename
3497 wkdays = Globs.wkdays
3498
3499 page_url = Globs.pageurl
3500
3501 date_today = datetime.date( year, month, day )
3502
3503 if monthstyle_us:
3504 stryearmonth = u'%s %d' % (months[month-1], day)
3505 else:
3506 stryearmonth = u'%02d / %02d' % (month, day)
3507
3508 stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3509 curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
3510
3511 cyear, cmonth, cday = gettodaydate()
3512 if cyear == year and cmonth == month and cday == day:
3513 bgcolor = 'background-color: #FFFFAA;'
3514 else:
3515 bgcolor = ''
3516
3517 if not Params.changeview:
3518 curlink = '#'
3519
3520 html = [
3521 u'<td colspan="%d" style="border-width: 2px; text-align: center; font-size: 9pt; %s">' % (colspan, bgcolor),
3522 u'<a href="%s">%s</a>' % (curlink, stryearmonth),
3523 u'</td>',
3524 ]
3525
3526 return u'\r\n'.join(html)
3527
3528 # show days in simple
3529 def simple_eventbox(year, month, day, wkday, boxclass):
3530 wkend = Globs.wkend
3531 if wkday == wkend:
3532 html_text = u'<font color="#aa7744">%s</font>' % day
3533 else:
3534 html_text = u'%s' % day
3535
3536 cyear, cmonth, cday = gettodaydate()
3537
3538 page_url = Globs.pageurl
3539 linkkey = u'%d%02d%02d' % (year, month, day)
3540
3541 curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
3542
3543 if not Params.changeview:
3544 curlink = '#'
3545
3546 curlink = u'<a href="%s" onMouseOver="tip(\'%s\')" onMouseOut="untip()" >%s</a>' % (curlink, linkkey, html_text)
3547
3548 if boxclass == 'simple_nb':
3549 html = u' <td class="%s"> </td>\r\n' % boxclass
3550 else:
3551 if cyear == year and cmonth == month and cday == day:
3552 html = u' <td class="%s_today">%s</td>\r\n' % (boxclass, curlink)
3553 else:
3554 html = u' <td class="%s">%s</td>\r\n' % (boxclass, curlink)
3555
3556 return html
3557
3558
3559 # show weekday
3560 def calhead_weekday(wday, headclass):
3561 if headclass == 'simple_weekday':
3562 html = u' <td class="%s">%s</td>\r\n' % (headclass, wday[0])
3563 else:
3564 html = u' <td class="%s">%s</td>\r\n' % (headclass, wday)
3565
3566 return html
3567
3568
3569 # show days of current month
3570 def calhead_day(year, month, day, wkday):
3571
3572 request = Globs.request
3573 page_name = Globs.pagename
3574 wkend = Globs.wkend
3575
3576 if wkday == wkend:
3577 html_text = u'<font color="#FF3300">%s</font>' % day
3578 else:
3579 html_text = u'%s' % day
3580
3581 page_url = Globs.pageurl
3582 html_text = u'<a href="%s?calaction=daily&caldate=%d%02d%02d">%s</a>' % (page_url, year, month, day, html_text)
3583
3584 cyear, cmonth, cday = gettodaydate()
3585
3586 if (not wkday) and Params.showweeknumber:
3587 html_text = u'%s <font size="1" color="#aaaaaa"><i>(%d)</i></font>' % (html_text, (int(datetime.date(year, month, day).strftime('%W')) + 1))
3588
3589 if cyear == year and cmonth == month and cday == day:
3590 html = u' <td class="head_day_today"> %s</td>\r\n' % html_text
3591 else:
3592 html = u' <td class="head_day"> %s</td>\r\n' % html_text
3593
3594 return html
3595
3596
3597 # show days of previous or next month
3598 def calhead_day_nbmonth(day):
3599
3600 html = u' <td class="head_day_nbmonth"> %s</td>\r\n' % day
3601 return html
3602
3603
3604 # show blank calendar box
3605 def calshow_blankbox(classname):
3606 html = u' <td class="%s"> </td>' % classname
3607 return html
3608
3609
3610 def calshow_blankbox2(classname, colspan):
3611 html = u' <td class="%s" colspan="%d"> </td>' % (classname, colspan)
3612 return html
3613
3614
3615 # show eventbox
3616 def calshow_eventbox(event, colspan, status, cur_date):
3617
3618 if status:
3619 status = u'_%s' % status
3620
3621 title = event['title']
3622 eid = event['id']
3623 startdate = event['startdate']
3624 enddate = event['enddate']
3625 starttime = event['starttime']
3626 endtime = event['endtime']
3627 description = event['description']
3628 bgcolor = event['bgcolor']
3629
3630 if not bgcolor:
3631 if Globs.labels:
3632 labels = Globs.labels
3633 # for backward compatibility
3634 if event.has_key('label'):
3635 if labels.has_key(event['label']):
3636 bgcolor = labels[event['label']]['bgcolor']
3637
3638 year, month, day = getdatefield(cur_date)
3639
3640 if bgcolor:
3641 bgcolor = 'background-color: %s;' % bgcolor
3642 else:
3643 bgcolor = 'background-color: %s;' % Params.bgcolor
3644
3645 if (startdate == enddate) and starttime:
3646 shour, smin = gettimefield(starttime)
3647
3648 link = [
3649 u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3650 u'<td nowrap class="cal_eventbox_time">%02d:%02d </td>\r\n' % (shour, smin),
3651 u'<td class="cal_eventbox_time_event">',
3652 u'%s' % showReferPageParsed(event, 'title', 1),
3653 u'</td>\r\n</tr></table>',
3654 ]
3655 link = u''.join(link)
3656 else:
3657 link = u'%s' % showReferPageParsed(event, 'title', 1)
3658
3659
3660 html = [
3661 u' <td class="cal_eventbox" colspan="%d"><table class="cal_event">' % colspan,
3662 u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3663 u' </table></td>',
3664 ]
3665
3666 return u'\r\n'.join(html)
3667
3668
3669 # show eventbox
3670 def calshow_daily_eventbox2(event, colspan, status, cur_date):
3671 if status:
3672 status = u'_%s' % status
3673
3674 title = event['title']
3675 eid = event['id']
3676 startdate = event['startdate']
3677 enddate = event['enddate']
3678 starttime = event['starttime']
3679 endtime = event['endtime']
3680 description = event['description']
3681 bgcolor = event['bgcolor']
3682
3683 if not bgcolor:
3684 labels = Globs.labels
3685 # for backward compatibility
3686 if event.has_key('label'):
3687 if labels.has_key(event['label']):
3688 bgcolor = labels[event['label']]['bgcolor']
3689
3690 year, month, day = getdatefield(cur_date)
3691
3692 if bgcolor:
3693 bgcolor = 'background-color: %s;' % bgcolor
3694 else:
3695 bgcolor = 'background-color: %s;' % Params.bgcolor
3696
3697 if (startdate == enddate) and starttime:
3698 shour, smin = gettimefield(starttime)
3699
3700 link = [
3701 u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3702 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),
3703 u'<td style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top;font-size: 8pt;">',
3704 u'%s' % showReferPageParsed(event, 'title', 1),
3705 u'</td>\r\n</tr></table>',
3706 ]
3707 link = u''.join(link)
3708 else:
3709 link = u'%s' % showReferPageParsed(event, 'title', 1)
3710
3711
3712 html = [
3713 u' <td colspan="%d" style="width: 96%%; border-width: 0px; line-height: 11px;"><table class="cal_event">' % colspan,
3714 u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3715 u' </table></td>',
3716 ]
3717
3718 return u'\r\n'.join(html)
3719
3720
3721 # show eventbox
3722 def calshow_daily_eventbox(event):
3723
3724 title = event['title']
3725 eid = event['id']
3726 startdate = event['startdate']
3727 enddate = event['enddate']
3728 starttime = event['starttime']
3729 endtime = event['endtime']
3730 description = event['description']
3731 bgcolor = event['bgcolor']
3732 time_len = event['time_len']
3733
3734 if not bgcolor:
3735 labels = Globs.labels
3736 # for backward compatibility
3737 if event.has_key('label'):
3738 if labels.has_key(event['label']):
3739 bgcolor = labels[event['label']]['bgcolor']
3740
3741 if bgcolor:
3742 bgcolor = 'background-color: %s;' % bgcolor
3743 else:
3744 bgcolor = 'background-color: %s;' % Params.bgcolor
3745
3746 shour, smin = gettimefield(starttime)
3747 ehour, emin = gettimefield(endtime)
3748
3749 html = [
3750 u' <td colspan="%(colspan)d"',
3751 u' style="%s border-width: 2px; border-color: #000000; vertical-align: top; font-size: 9pt; ' % bgcolor,
3752 u' width: %(width)s;" ',
3753 u' rowspan="%(rowspan)d">' % { 'rowspan': time_len },
3754 u' %02d:%02d ~ %02d:%02d<br>%s' % (shour, smin, ehour, emin, showReferPageParsed(event, 'title', 1)),
3755 u' </td>',
3756 ]
3757
3758 return u'\r\n'.join(html)
3759
3760
3761 # show eventbox
3762 def calshow_weekly_eventbox(event):
3763
3764 title = event['title']
3765 eid = event['id']
3766 startdate = event['startdate']
3767 enddate = event['enddate']
3768 starttime = event['starttime']
3769 endtime = event['endtime']
3770 description = event['description']
3771 bgcolor = event['bgcolor']
3772 time_len = event['time_len']
3773
3774 if not bgcolor:
3775 labels = Globs.labels
3776 # for backward compatibility
3777 if event.has_key('label'):
3778 if labels.has_key(event['label']):
3779 bgcolor = labels[event['label']]['bgcolor']
3780
3781 if bgcolor:
3782 bgcolor = 'background-color: %s;' % bgcolor
3783 else:
3784 bgcolor = 'background-color: %s;' % Params.bgcolor
3785
3786 shour, smin = gettimefield(starttime)
3787 ehour, emin = gettimefield(endtime)
3788
3789 html = [
3790 u' <td colspan="%(colspan)d"',
3791 u' style="%s;' % bgcolor,
3792 u' width: %(width)s;" ',
3793 u' rowspan="%(rowspan)d"' % { 'rowspan': time_len },
3794 u' class="cal_weekly_eventbox">',
3795 u' %s' % showReferPageParsed(event, 'title', 1),
3796 u' </td>',
3797 ]
3798
3799 return u'\r\n'.join(html)
3800
3801 # show blank eventbox
3802 def calshow_blankeventbox():
3803
3804 html = [
3805 u' <td colspan="%(colspan)d" style="width: %(width)s;" class="cal_blankeventbox"> </td>',
3806 ]
3807
3808 return u'\r\n'.join(html)
3809
3810
3811 # show eventbox
3812 def calshow_weekly_eventbox2(event, colspan, width, status, cur_date):
3813 if status:
3814 status = u'_%s' % status
3815
3816 title = event['title']
3817 eid = event['id']
3818 startdate = event['startdate']
3819 enddate = event['enddate']
3820 starttime = event['starttime']
3821 endtime = event['endtime']
3822 description = event['description']
3823 bgcolor = event['bgcolor']
3824
3825 year, month, day = getdatefield(cur_date)
3826
3827 if not bgcolor:
3828 labels = Globs.labels
3829 # for backward compatibility
3830 if event.has_key('label'):
3831 if labels.has_key(event['label']):
3832 bgcolor = labels[event['label']]['bgcolor']
3833
3834 if bgcolor:
3835 bgcolor = 'background-color: %s;' % bgcolor
3836 else:
3837 bgcolor = 'background-color: %s;' % Params.bgcolor
3838
3839 link = u'%s' % showReferPageParsed(event, 'title', 1)
3840
3841 html = [
3842 u' <td colspan="%d" style="width: %d%%;" class="cal_weekly_eventbox2"><table class="cal_event">' % (colspan, width),
3843 u' <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3844 u' </table></td>',
3845 ]
3846
3847 return u'\r\n'.join(html)
3848
3849
3850
3851 # show blank eventbox
3852 def calshow_blankeventbox2(colspan, width):
3853 html = [
3854 u' <td colspan="%(colspan)d"' % { 'colspan': colspan },
3855 u' style="width: %(width)s;" class="cal_blankeventbox"> </td>' % { 'width': '%d%%%%' % width },
3856 ]
3857
3858 return u'\r\n'.join(html)
3859
3860
3861
3862 def calshow_daily_hourhead(hour):
3863
3864 if hour >= Globs.dailystart and hour <= Globs.dailyend:
3865 bgcolor = "#ffffcc"
3866 else:
3867 bgcolor = "#ffeeee"
3868
3869 html = [
3870 u' <td class="cal_hourhead" style="background-color: %s; width: 4%%%%;">%02d</td>' % (bgcolor, hour),
3871 ]
3872
3873 return u'\r\n'.join(html)
3874
3875 def calshow_weekly_hourhead(hour):
3876
3877 if hour >= Globs.dailystart and hour <= Globs.dailyend:
3878 bgcolor = "#ffffcc"
3879 else:
3880 bgcolor = "#ffeeee"
3881
3882 html = [
3883 u' <td class="cal_hourhead" style="width: 2%%%%; background-color: %s; ">%02d</td>' % (bgcolor, hour),
3884 ]
3885
3886 return u'\r\n'.join(html)
3887
3888
3889
3890 def insertcalevents(cal_events, datefrom, dateto, e_id, e_start_date, e_end_date):
3891
3892 if not (int(e_start_date) > dateto or int(e_end_date) < datefrom):
3893
3894 e_start_date = str(max(int(e_start_date), datefrom))
3895 e_end_date = str(min(int(e_end_date), dateto))
3896
3897 day_delta = datetime.timedelta(days=1)
3898 e_start_year, e_start_month, e_start_day = getdatefield(e_start_date)
3899 cur_datetime = datetime.date(e_start_year, e_start_month, e_start_day)
3900
3901 while 1:
3902 tmp_record_date = formatdateobject(cur_datetime)
3903
3904 if not cal_events.has_key(tmp_record_date):
3905 cal_events[tmp_record_date] = []
3906 cal_events[tmp_record_date].append(e_id)
3907
3908 if tmp_record_date == e_end_date:
3909 break
3910
3911 cur_datetime = cur_datetime + day_delta
3912
3913 # date format should be like '20051004' for 2005, Oct., 04
3914 def diffday(date1, date2):
3915
3916 try:
3917 year1, month1, day1 = getdatefield(date1)
3918 year2, month2, day2 = getdatefield(date2)
3919 tmp_diff = datetime.date(year2, month2, day2) - datetime.date(year1, month1, day1)
3920 except (TypeError, ValueError):
3921 raise EventcalError('invalid_date')
3922
3923 return tmp_diff.days
3924
3925
3926 # time format should be like '1700' for 05:00pm
3927 def difftime(time1, time2):
3928
3929 try:
3930 hour1, min1 = gettimefield(time1)
3931 hour2, min2 = gettimefield(time2)
3932
3933 except (TypeError, ValueError):
3934 raise EventcalError('invalid_time')
3935
3936 if min2 == 0 and hour2 != 0 and hour1 != hour2:
3937 hour2 -= 1
3938
3939 tmp_diff = hour2 - hour1
3940
3941 return tmp_diff
3942
3943
3944
3945 def formatDate(year, month, day):
3946 # returns like: '20051004'
3947 return u'%4d%02d%02d' % (year, month, day)
3948
3949 def formatTime(hour, min):
3950 # returns like: '1700'
3951 return u'%2d%02d' % (hour, min)
3952
3953
3954 def formatdateobject(obj_date):
3955
3956 return formatDate(obj_date.year, obj_date.month, obj_date.day)
3957
3958 def formattimeobject(obj_time):
3959
3960 return formatTime(obj_time.hour, obj_time.minute)
3961
3962
3963 def debug(astring):
3964 Globs.debugmsg += u'<li>%s\n' % astring
3965
3966
3967 def geterrormsg(errmsgcode, refer='', title='', hid=''):
3968
3969 if errmsgcode == 'invalid_caldate':
3970 msg = 'Warning: Invalid value for "caldate" parameter. Shows today.'
3971
3972 elif errmsgcode == 'invalid_curdate':
3973 msg = 'Warning: Invalid value for "curdate" parameter. Shows today.'
3974
3975 elif errmsgcode == 'invalid_numcal':
3976 msg = 'Warning: Invalid value of "numcal" parameter. Shows one.'
3977
3978 elif errmsgcode == 'invalid_startdate':
3979 msg = 'Error: Invalid startdate format. Not handled.'
3980
3981 elif errmsgcode == 'invalid_enddate':
3982 msg = 'Error: Invalid enddate format. Not handled.'
3983
3984 elif errmsgcode == 'invalid_start':
3985 msg = 'Error: Invalid start date or time format. Not handled.'
3986
3987 elif errmsgcode == 'invalid_end':
3988 msg = 'Error: Invalid end date or time format. Not handled.'
3989
3990 elif errmsgcode == 'invalid_date':
3991 msg = 'Error: Invalid date format. Not handled.'
3992
3993 elif errmsgcode == 'enddate_precede':
3994 msg = 'Error: Enddate precedes startdate. Not handled.'
3995
3996 elif errmsgcode == 'invalid_starttime':
3997 msg = 'Error: Invalid starttime format. Not handled.'
3998
3999 elif errmsgcode == 'invalid_endtime':
4000 msg = 'Error: Invalid endtime format. Not handled.'
4001
4002 elif errmsgcode == 'invalid_time':
4003 msg = 'Error: Invalid time format. Not handled.'
4004
4005 elif errmsgcode == 'endtime_precede':
4006 msg = 'Error: Enddate precedes startdate. Not handled.'
4007
4008 elif errmsgcode == 'len_recur_int':
4009 msg = 'Error: Event length should be smaller than recurrence interval. Not handled.'
4010
4011 elif errmsgcode == 'invalid_bgcolor':
4012 msg = 'Warning: Invalid bgcolor format. Ignored.'
4013
4014 elif errmsgcode == 'invalid_label':
4015 msg = 'Warning: Invalid label format. Ignored.'
4016
4017 elif errmsgcode == 'invalid_recur':
4018 msg = 'Error: Invalid recurrence format. Not handled.'
4019
4020 elif errmsgcode == 'invalid_recur_until':
4021 msg = 'Error: Invalid end date (until) format of the recurrence. Not handled.'
4022
4023 elif errmsgcode == 'empty_description':
4024 msg = 'Warning: Empty description. Ignored.'
4025
4026 elif errmsgcode == 'invalid_default_bgcolor':
4027 msg = 'Warning: Invalid default_bgcolor format. Ignored.'
4028
4029 elif errmsgcode == 'empty_default_description':
4030 msg = 'Warning: Empty default_description. Ignored.'
4031
4032 elif errmsgcode == 'redefined_label':
4033 msg = 'Warning: Redefined label. Ignored.'
4034
4035 elif errmsgcode == 'empty_label_definition':
4036 msg = 'Warning: Invalid label definition. Ignored.'
4037
4038 else:
4039 msg = 'undefined: %s' % errmsgcode
4040
4041 if refer:
4042 msg = '%s (%s)' % (msg, getReferLink(refer, title, hid))
4043
4044 return msg
4045
4046
4047 def errormsgcode(errmsgcode):
4048
4049 errormsg(geterrormsg(errmsgcode))
4050
4051
4052 def errormsg(astring):
4053 Globs.errormsg += u'<li>%s\n' % astring
4054
4055
4056 def yearmonthplusoffset(year, month, offset):
4057 month = month+offset
4058 # handle offset and under/overflows - quick and dirty, yes!
4059 while month < 1:
4060 month = month + 12
4061 year = year - 1
4062 while month > 12:
4063 month = month - 12
4064 year = year + 1
4065 return year, month
4066
4067
4068 def formatcfgdatetime(strdate, strtime=''):
4069
4070 if not strdate:
4071 return ''
4072
4073 request = Globs.request
4074
4075 if request.user.date_fmt:
4076 date_fmt = request.user.date_fmt
4077 else:
4078 date_fmt = request.cfg.date_fmt
4079
4080 if request.user.datetime_fmt:
4081 datetime_fmt = request.user.datetime_fmt
4082 else:
4083 datetime_fmt = request.cfg.datetime_fmt
4084
4085 ## XXX HACK
4086 datetime_fmt = datetime_fmt.replace(':%S', '')
4087
4088 date_fmt = str(date_fmt)
4089 datetime_fmt = str(datetime_fmt)
4090
4091 year, month, day = getdatefield(str(strdate))
4092 if strtime:
4093 hour, min = gettimefield(str(strtime))
4094 objdatetime = datetime.datetime(year, month, day, hour, min)
4095 return objdatetime.strftime(datetime_fmt)
4096 else:
4097 objdate = getdatetimefromstring(strdate)
4098 return objdate.strftime(date_fmt)
4099
4100
4101 def getdatetimefromstring(strdate):
4102 year, month, day = getdatefield(str(strdate))
4103 return datetime.date( year, month, day )
4104
4105
4106 def searchPages(request, needle):
4107 # Search the pages and return the results
4108 query = search.QueryParser().parse_query(needle)
4109 results = search.searchPages(request, query)
4110 #results.sortByPagename()
4111
4112 return results.hits
4113
4114 html = []
4115 for page in results.hits:
4116 html.append(page.page_name)
4117
4118 html = u',<br>'.join(html)
4119 return u'%s<p>%s' % (Params.category, html)
4120
4121
4122 def getFirstDateOfWeek(year, month, day):
4123 orgday = datetime.date(year, month, day)
4124 yearBase, week, weekday = orgday.isocalendar()
4125 baseDate = datetime.date(yearBase, 2, 1)
4126 yearBase, weekBase, dayBase = baseDate.isocalendar()
4127 days = datetime.timedelta(1-dayBase+(week-weekBase)*7)
4128 theday = baseDate + days
4129
4130 theday -= datetime.timedelta(7 - calendar.firstweekday())
4131
4132 if orgday - theday >= datetime.timedelta(7):
4133 theday += datetime.timedelta(7)
4134
4135 return theday
4136
4137 def gcd(a,b):
4138 """Return greatest common divisor using Euclid's Algorithm."""
4139 while b:
4140 a, b = b, a % b
4141
4142 return a
4143
4144 def lcm(a,b):
4145 """
4146 Return lowest common multiple."""
4147 return (a*b)/gcd(a,b)
4148
4149 def LCM(terms):
4150 "Return lcm of a list of numbers."
4151 return reduce(lambda a,b: lcm(a,b), terms)
4152
4153
4154 def getNumericalMonth(strMonth):
4155 months = Globs.months
4156
4157 strMonth = strMonth.lower()
4158
4159 index = 0
4160 for monthitem in months:
4161 index += 1
4162 if monthitem.lower().startswith(strMonth):
4163 return index
4164
4165 return 0
4166
4167
4168 def getReferLink(refer, title='', hid=''):
4169 request = Globs.request
4170
4171 refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
4172
4173 if hid:
4174 refer_url += '#%s' % hid
4175
4176 if title:
4177 refer = '%s: "%s"' % (refer, title)
4178
4179 return '<a href="%s">%s</a>' % (refer_url, refer)
4180
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.