Attachment 'EventCalendar-099b.py'

Download

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

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-10-31 18:42:02, 65.4 KB) [[attachment:EventCalendar-080.py]]
  • [get | view] (2005-11-22 17:40:26, 55.4 KB) [[attachment:EventCalendar-090.py]]
  • [get | view] (2006-01-15 16:25:08, 57.2 KB) [[attachment:EventCalendar-091.py]]
  • [get | view] (2006-01-17 08:02:06, 75.4 KB) [[attachment:EventCalendar-092.py]]
  • [get | view] (2006-01-18 03:54:33, 75.6 KB) [[attachment:EventCalendar-093.py]]
  • [get | view] (2006-02-25 09:00:17, 74.8 KB) [[attachment:EventCalendar-094-easytime.py]]
  • [get | view] (2006-02-06 04:39:13, 76.2 KB) [[attachment:EventCalendar-094.py]]
  • [get | view] (2006-04-17 13:21:03, 122.7 KB) [[attachment:EventCalendar-096.py]]
  • [get | view] (2006-05-12 15:26:40, 150.6 KB) [[attachment:EventCalendar-098.py]]
  • [get | view] (2008-11-05 16:58:27, 3.2 KB) [[attachment:EventCalendar-099-01.py.patch]]
  • [get | view] (2006-05-23 09:50:33, 152.3 KB) [[attachment:EventCalendar-099.py]]
  • [get | view] (2008-02-14 05:18:57, 1.0 KB) [[attachment:EventCalendar-099.py.patch]]
  • [get | view] (2009-07-15 23:35:13, 151.1 KB) [[attachment:EventCalendar-099a.py]]
  • [get | view] (2013-01-21 02:05:25, 152.4 KB) [[attachment:EventCalendar-099b.py]]
  • [get | view] (2006-11-30 15:51:59, 1.8 KB) [[attachment:defaults-099-01.patch]]
  • [get | view] (2005-10-31 18:35:06, 5.0 KB) [[attachment:eventcal-080.css]]
  • [get | view] (2005-10-31 18:35:01, 11.3 KB) [[attachment:eventcal-080.py]]
  • [get | view] (2005-11-22 17:40:51, 6.8 KB) [[attachment:eventcal-090.css]]
  • [get | view] (2005-11-22 17:40:40, 18.1 KB) [[attachment:eventcal-090.py]]
  • [get | view] (2006-04-17 13:22:09, 8.9 KB) [[attachment:eventcal-096.css]]
  • [get | view] (2006-02-08 02:31:50, 1.4 KB) [[attachment:eventcalendar-094-01.patch]]
  • [get | view] (2006-11-30 15:52:26, 12.2 KB) [[attachment:label_priority-099-01.patch]]
  • [get | view] (2006-11-16 17:06:28, 1.1 KB) [[attachment:pagelinks-099-01.patch]]
  • [get | view] (2006-11-16 17:06:52, 2.9 KB) [[attachment:pagelist-099-01.patch]]
  • [get | view] (2006-03-29 07:37:02, 118.7 KB) [[attachment:snap-daily.jpg]]
  • [get | view] (2006-01-18 03:52:49, 23.2 KB) [[attachment:snap-list.jpg]]
  • [get | view] (2006-01-18 03:52:40, 37.4 KB) [[attachment:snap-monthly.jpg]]
  • [get | view] (2006-03-29 07:35:54, 43.8 KB) [[attachment:snap-simple.jpg]]
  • [get | view] (2006-01-18 03:53:04, 29.4 KB) [[attachment:snap-upcoming.jpg]]
  • [get | view] (2006-03-29 07:36:43, 161.0 KB) [[attachment:snap-weekly.jpg]]
  • [get | view] (2007-06-12 19:51:39, 55.0 KB) [[attachment:time_bug.PNG]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.