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