Attachment 'EventCalendar-099.py'

Download

   1 """
   2     EventCalendar.py  Version 0.99  May 22, 2006
   3                                                                                                            
   4     This macro gives a list of the events recorded at the sub-pages in the form of various views:
   5         monthly, weekly, daily, simple-month, list, and upcoming.
   6                                                                                                            
   7     @copyright: 2006 by Seungik Lee <seungiklee<at>gmail.com>  http://www.silee.net/
   8     @license: GPL
   9     
  10     For more information, please visit http://moinmoin.wikiwikiweb.de/MacroMarket/EventCalendar
  11     
  12     <Usage>
  13     
  14         * To list the events in a page, just insert [[EventCalendar]]
  15         * To insert an event, insert the event information in any pages of specified category (CategoryEventCalendar by default).
  16         
  17     <Parameters>
  18         
  19         * category: the category of the event data to be used in the calendar. default: 'CategoryEventCalendar'
  20         * menubar: shows menubar or not (1: show, 0: no menubar). default: 1
  21         * monthlywidth: calendar width in pixel or percent (monthly view). default: '600' (pixel)
  22         * simplewidth: calendar width in pixel or percent (simpleview). default: '150' (pixel)
  23         * firstview: initial calendar view: monthly, weekly, daily, list, simple, upcoming. default: 'monthly'
  24         * curdate: initial calendar date (in YYYYMM format). default: current month
  25         * upcomingrange: # of days for the range of upcoming event list. default: 7 (days)
  26         * changeview: enables to change the calendar view or not (1: enalbed, 0: disabled). default: 1
  27         * numcal: # of calendar. default: 1
  28         * showlastweekday: shows the event at the last weekday if the recurred weekday is not available. (1: enalbed, 0: disabled). default: 0
  29         * showerror: shows error messages below the calendar if event data format is invalid. (1: enalbed, 0: disabled). default: 1
  30         * showweeknumber: shows the week number of the year (1: enalbed, 0: disabled). default: 0
  31         
  32     
  33     <Event Data Format>
  34 
  35         * Event data fields:
  36 ...
  37 
  38  [default_description:: [page_default_description_text]]
  39  [default_bgcolor:: [page_default_background_color]]
  40  [label_def:: [label_name], [label_background_color]]
  41 
  42 == <title> ==
  43  start:: <startdate> [starttime]
  44  [end:: [enddate] [endtime]]
  45  [description:: [description_text]]
  46  [bgcolor:: [custom_background_color]]
  47  [recur:: <recur_freq> <recur_type> [until <recur_until>]]
  48  [label:: <label_name>]
  49  
  50 ...
  51 
  52 ----
  53 CategoryEventCalendar
  54 
  55             * default_bgcolor, default_description: default values of bgcolor and description in the page if unavailable. optional
  56             * label_def: label definition with name, bgcolor. optional
  57             
  58             * title: event title. required
  59                 * should be enclosed with heading marker ('='), Title cannot be omitted.
  60 
  61             * startdate: date of start. required
  62                 * should be in date format or date format
  63                 
  64             * starttime: time of start. optional
  65                 * should be in time format
  66                 
  67             * enddate: date of end. optional
  68                 * should be in date format or date format. If omitted, it will be assigned equal to <startdate>.
  69                 
  70             * endtime: time of end. optional
  71                 * should be in time format. Both of start|end Time can be omitted but not either of them.
  72                 
  73             * description: description of the event. optional
  74                 * any text with no markup. should be in a line.
  75                 
  76             * bgcolor: custom background color of the event in monthly view. optional
  77                 * e.g., #abcdef
  78             
  79             * recur: recurrence information of the event. optional
  80                 * recur_freq: how many intervals, digit or 'last' for weekday, required
  81                 * recur_type: [day|week|weekday|month|year], required
  82                     * day: every [recur_freq] days
  83                     * week: every [recur_freq] weeks
  84                     * weekday: on the same weekday of [recur_freq]-th week of the month. or 'last weekday'
  85                     * month: on the same day of [recur_freq]-th month
  86                     * year: on the same day of [recur_freq]-th year
  87                 * recur_until: recurred until when, date format, optional
  88                 
  89                 * e.g., 10 day, 2 week until 2006-06-31, 3 weekday, 6 month until 2007-12-31, 1 year
  90             
  91             * label: custom label for specific name, bgcolor. optional
  92             
  93             * The order of the fields after an event title does not matter.
  94             * Priority of bgcolor: bgcolor > default_bgcolor > label_bgcolor
  95 
  96 
  97         * Datetime format:
  98         
  99             * Date format:
 100                 * YYYY/MM/DD, YYYY-MM-DD, YYYY.MM.DD: 2006/05/12; 2006-05-12; 2006.05.12; 2006-5-12; 06/5/12
 101                 * B DD, YYYY: May 12, 2006; May 5th, 2006; January 1st, 2006; Jan 5, 06
 102                 * YYYYMMDD, YYMMDD: 20060512; 060512
 103                 
 104                 * Year: YY = 20YY. e.g., 06-2-2 = 2006-02-02, allowed 1900 ~ 2099 only.
 105 
 106             * Time format:
 107                 * H:M, HHMM: 12:00; 22:00; 2:00; 2 (= 2 o'clock); 2200; 12:0; 2:0
 108                 * I:M PP, IIMM PP: 12:00 PM; 3:00p; 2a (= 2 o'clock AM); 3:0pm; 0200 am; 10pm
 109 
 110             
 111 
 112     <Event Data Examples>
 113 
 114 == Default values ==
 115  default_bgcolor:: #c0c0c0
 116  default_description:: testing...
 117 
 118 == Labels ==
 119  label_def:: Holiday, #ff0000
 120  label_def:: Meeting, #00ff00
 121 
 122 === Test event ===
 123  start:: 2006-01-10 02:00p
 124  end:: 2006-01-12 17:00
 125  description:: test event
 126  bgcolor:: #cfcfcf
 127   
 128 === Jinah's Birthday ===
 129  start:: 1977-10-20
 130  recur:: 1 year
 131  label:: Holiday
 132  
 133 === Weekly meeting ===
 134  start:: Jan 17, 2006 7:00pm
 135  end:: 21:00
 136  recur:: 1 week until 061231
 137  label:: Meeting
 138 
 139 ----
 140 CategoryEventCalendar  
 141 
 142 
 143     <Notes>
 144     
 145         * It caches all the page list of the specified category and the event information.
 146         * If you added/removed a page into/from a category, you need to do 'Delete cache' in the macro page.
 147 
 148         * 'MonthCalendar.py' developed by Thomas Waldmann <ThomasWaldmann@gmx.de> has inspired this macro.
 149         * Much buggy.. : please report bugs and suggest your ideas.
 150         * If you missed to add css for EventCalender, monthly view may not be readable.
 151             * Insert the EventCalendar css classes into the screen.css of an appropriate theme.
 152 
 153         
 154 
 155 """
 156 
 157 from MoinMoin import wikiutil, config, search, caching
 158 from MoinMoin.Page import Page
 159 from MoinMoin.parser import wiki
 160 import re, calendar, time, datetime
 161 import codecs, os, urllib, sha
 162 
 163 try:
 164     import cPickle as pickle
 165 except ImportError:
 166     import pickle
 167 
 168 # Set pickle protocol, see http://docs.python.org/lib/node64.html
 169 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
 170 
 171 
 172 # The following line sets the calendar to have either Sunday or Monday as
 173 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
 174 # valid here.  All other values will not make good calendars.
 175 # XXX change here ----------------vvvvvv
 176 calendar.setfirstweekday(calendar.SUNDAY)
 177 
 178 
 179 class Globs:
 180     month_style_us = 1  # 1: October 2005; 2: 2005 / 10
 181     defaultcategory = 'CategoryEventCalendar'
 182     upcomingrange = 7   # days
 183     dailystart = 9
 184     dailyend = 18
 185     pagename = ''
 186     baseurl = ''
 187     subname = ''
 188     wkend = ''
 189     months = ''
 190     wkdays = ''
 191     today = ''
 192     now = ''
 193     request = None
 194     formatter = None
 195     cal_action = ''
 196     debugmsg = ''
 197     errormsg = ''
 198     page_action = ''
 199     form_vals = {}
 200     events = None
 201     labels = None
 202 
 203 
 204 class Params:
 205     menubar = 0
 206     monthlywidth = ''
 207     weeklywidth = ''
 208     dailywidth = ''
 209     simplewidth = ''
 210     firstview = ''
 211     curdate = ''
 212     bgcolor = ''
 213     category = ''
 214     upcomingrange = 0
 215     changeview = 0
 216     numcal = 1
 217     showlastweekday = 0
 218     showerror = 1
 219     showweeknumber = 0
 220     debug = 0
 221     
 222 
 223 class EventcalError(Exception):
 224     def __init__(self, value):
 225         self.value = value
 226     
 227     def __str__(self):
 228         return repr(self.value) 
 229 
 230 
 231 def execute(macro, args):
 232     
 233     request = macro.request
 234     formatter = macro.formatter
 235     
 236     # INITIALIZATION ----------------------------------------
 237     setglobalvalues(macro)
 238     getparams(args)
 239     
 240     # allowed actions
 241     allowed_action = ['monthly', 'list', 'simple', 'upcoming', 'daily', 'weekly']
 242     default_action = Params.firstview
 243     
 244     # Internal variables
 245     cal_action = ''
 246     form_vals = {}
 247 
 248     # PROCESSING ARGUEMENTS ----------------------------------------
 249     if args:
 250         args=request.getText(args)
 251 
 252     for item in macro.form.items():
 253         if not form_vals.has_key(item[0]):
 254 	    try:
 255 		    form_vals[item[0]]=item[1][0]
 256 	    except AttributeError:
 257 	        pass
 258     
 259     # PROCESSING ACTIONS ----------------------------------------
 260     cal_action = form_vals.get('calaction', default_action)
 261     page_action = form_vals.get('action', 'show')
 262     
 263     if not cal_action in allowed_action:
 264         cal_action = default_action
 265     
 266     form_vals['calaction'] = cal_action
 267 
 268     Globs.form_vals = form_vals
 269 
 270     # CONTROL FUNCTIONS ----------------------------------------
 271     
 272     html = []
 273     html_result = ''
 274     
 275     Globs.cal_action = cal_action
 276     Globs.page_action = page_action
 277     
 278     
 279     # redirect to the appropriate view
 280     if cal_action == 'monthly':
 281         html_result = showcalendar()
 282         
 283     if cal_action == 'list':
 284         html_result = showeventlist()
 285 
 286     if cal_action == 'simple':
 287         html_result = showsimplecalendar()
 288     
 289     if cal_action == 'upcoming':
 290         html_result = showupcomingeventlist()
 291         
 292     if cal_action == 'daily':
 293         html_result = showdailycalendar()
 294         
 295     if cal_action == 'weekly':
 296         html_result = showweeklycalendar()
 297     
 298     
 299     # format output
 300     html.append( html_result )
 301     html.append( showmenubar() )
 302     
 303     if Params.showerror and Globs.errormsg:
 304         html.append(u'<p><i><font size="2" color="#aa0000"><ol>%s</ol></font></i>' % Globs.errormsg)
 305 
 306     if Params.debug and Globs.debugmsg:
 307         html.append(u'<p><b>Debug messages:</b><font color="#000099"><ol>%s</ol></font>' % Globs.debugmsg)
 308 
 309     return formatter.rawHTML(u''.join(html))
 310 
 311 
 312 
 313 def getparams(args):
 314     # process arguments
 315     
 316     params = {}
 317     if args:
 318         # Arguments are comma delimited key=value pairs
 319         sargs = args.split(',')
 320     
 321         for item in sargs:
 322             sitem = item.split('=')
 323         
 324             if len(sitem) == 2:
 325                 key, value = sitem[0], sitem[1]
 326                 params[key.strip()] = value.strip()
 327 
 328     # category name: 
 329     # default: 'CategoryEventCalendar'
 330     Params.category = params.get('category', Globs.defaultcategory)
 331     
 332     # menu bar: shows menubar or not (1: show, 0: no menubar)
 333     # default: 1
 334     try:
 335         Params.menubar = int(params.get('menubar', 1))
 336     except (TypeError, ValueError):
 337         Params.menubar = 1
 338         
 339     # calendar width in pixel or percent (monthly)
 340     # default: 600px
 341     Params.monthlywidth = params.get('monthlywidth', '600')
 342     if Params.monthlywidth:
 343         Params.monthlywidth = ' width="%s" ' % Params.monthlywidth
 344         
 345     # calendar width in pixel or percent (weekly)
 346     # default: 600px
 347     Params.weeklywidth = params.get('weeklywidth', '600')
 348     if Params.weeklywidth:
 349         Params.weeklywidth = ' width="%s" ' % Params.weeklywidth
 350 
 351     # calendar width in pixel or percent (daily)
 352     # default: 600px
 353     Params.dailywidth = params.get('dailywidth', '600')
 354     if Params.monthlywidth:
 355         Params.dailywidth = ' width="%s" ' % Params.dailywidth
 356 
 357     # calendar width in pixel or percent (simply)
 358     # default: 150px
 359     Params.simplewidth = params.get('simplewidth', '150')
 360     if Params.simplewidth:
 361         # Params.simplewidth = Params.simplewidth.replace('%', '%%')
 362         Params.simplewidth = ' width="%s" ' % Params.simplewidth
 363     
 364     # calendar view: monthly, list, simple
 365     # default: 'monthly'
 366     Params.firstview = params.get('firstview', 'monthly')
 367 
 368     # calendar date: in YYYYMM format (in monthly, simple view)
 369     # default: current month
 370     Params.curdate = params.get('curdate', '')
 371     
 372     # upcoming range: # of days for upcoming event list
 373     # default: 7
 374     try:
 375         Params.upcomingrange = int(params.get('upcomingrange', Globs.upcomingrange))
 376     except (TypeError, ValueError):
 377         Params.upcomingrange = Globs.upcomingrange
 378         
 379     # number of calendar: # of calendar for monthly & simple view
 380     # default: 1
 381     try:
 382         Params.numcal = int(params.get('numcal', '1'))
 383     except (TypeError, ValueError):
 384         Params.numcal = 1
 385 
 386     # change view enabled?
 387     # default: 1
 388     try:
 389         Params.changeview = int(params.get('changeview', '1'))
 390     except (TypeError, ValueError):
 391         Params.changeview = 1
 392         
 393     # shows the event at the last weekday if the recurred weekday is not available.
 394     # default: 0
 395     try:
 396         Params.showlastweekday = int(params.get('showlastweekday', '0'))
 397     except (TypeError, ValueError):
 398         Params.showlastweekday = 0
 399         
 400     # show error message?
 401     # default: 1
 402     try:
 403         Params.showerror = int(params.get('showerror', '1'))
 404     except (TypeError, ValueError):
 405         Params.showerror = 1
 406         
 407     # show week number?
 408     # default: 0
 409     try:
 410         Params.showweeknumber = int(params.get('showweeknumber', '0'))
 411     except (TypeError, ValueError):
 412         Params.showweeknumber = 0
 413 
 414     # default bgcolor
 415     Params.bgcolor = '#ddffdd'
 416     
 417 
 418 def setglobalvalues(macro):
 419     
 420     request = macro.request
 421     formatter = macro.formatter
 422     
 423     # Useful variables
 424     Globs.baseurl = request.getBaseURL() + '/'
 425     Globs.pagename = formatter.page.page_name
 426     Globs.request = request
 427     Globs.formatter = formatter
 428     Globs.pageurl = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(formatter.page.page_name))
 429     
 430     # This fixes the subpages bug. subname is now used instead of pagename when creating certain urls
 431     Globs.subname = Globs.pagename.split('/')[-1]
 432 
 433     pagepath = formatter.page.getPagePath()
 434     Globs.pagepath = formatter.page.getPagePath()
 435     
 436     # european / US differences
 437     months = ('January','February','March','April','May','June','July','August','September','October','November','December')
 438     
 439     # Set things up for Monday or Sunday as the first day of the week
 440     if calendar.firstweekday() == calendar.MONDAY:
 441         wkend = 6
 442         wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
 443     elif calendar.firstweekday() == calendar.SUNDAY:
 444         wkend = 0
 445         wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
 446     
 447     Globs.months = months
 448     Globs.wkdays = wkdays
 449     Globs.wkend = wkend
 450 
 451     year, month, day, h, m, s, wd, yd, ds = request.user.getTime(time.time())
 452     Globs.today = datetime.date(year, month, day)
 453     Globs.now = datetime.time(h, m, s)
 454     
 455     Globs.debugmsg = ''
 456     Globs.errormsg = ''
 457 
 458 
 459 def showReferPageParsed(event, targettext='title', showdesc=0):
 460     request = Globs.request
 461     pagename = Globs.pagename
 462     
 463     refer = event['refer']
 464     targettext = event[targettext]
 465     startdate = event['startdate']
 466     enddate = event['enddate']
 467     description = event['description']
 468     starttime = event['starttime']
 469     endtime = event['endtime']
 470     hid = event['hid']
 471     
 472     refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
 473     
 474     if not Params.changeview:
 475         refer_url = ''
 476         hid = ''
 477     
 478     if showdesc:
 479         if (startdate == enddate) and (starttime and endtime):
 480             timedescription = '(%s:%s ~ %s:%s)' % (starttime[:2], starttime[2:], endtime[:2], endtime[2:])
 481             if description:
 482                 timedescription = '%s ' % timedescription
 483         else:
 484             timedescription = ''
 485         
 486         targetlink = '<a href="%s#%s" title="%s%s">%s</a>' % ( refer_url, hid, timedescription, wikiutil.escape(description), wikiutil.escape(targettext) )
 487             
 488     else:
 489         targetlink = '<a href="%s#%s">%s</a>' % ( refer_url, hid, wikiutil.escape(targettext))
 490     
 491     return targetlink
 492 
 493 
 494 def showReferPageParsedForLabel(thelabel, targettext='name', showdesc=1):
 495     request = Globs.request
 496     pagename = Globs.pagename
 497     
 498     labels = Globs.labels
 499     
 500     label_bgcolor = ''
 501     refer = ''
 502     
 503     if labels and labels.has_key(thelabel):
 504         targettext = labels[thelabel][targettext]
 505         refer = labels[thelabel]['refer']
 506         if showdesc:
 507             label_bgcolor = labels[thelabel]['bgcolor']
 508 
 509     if not refer:
 510         return '<i>%s</i>' % thelabel
 511     
 512     refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
 513     
 514     if showdesc:
 515         targetlink = '<a href="%s" title="%s">%s</a>' % ( refer_url, label_bgcolor, wikiutil.escape(targettext) )
 516     else:
 517         targetlink = '<a href="%s">%s</a>' % ( refer_url, wikiutil.escape(targettext))
 518     
 519     return targetlink
 520 
 521 
 522 def getheadingid(request, referpage, title):
 523 
 524     pntt = (referpage + title).encode(config.charset)
 525     hid = "head-" + sha.new(pntt).hexdigest()
 526     
 527     if not hasattr(request, '_eventcal_headings'):
 528         request._eventcal_headings = {}
 529     
 530     request._eventcal_headings.setdefault(pntt, 0)
 531     request._eventcal_headings[pntt] += 1
 532     if request._eventcal_headings[pntt] > 1:
 533         hid += '-%d'%(request._eventcal_headings[pntt],)
 534     
 535     return hid
 536 
 537 
 538 def getquerystring(req_fields):
 539     
 540     m_query = []
 541     tmp_form_vals = Globs.form_vals
 542     
 543     # format querystring
 544     # action should be poped out
 545     for field in req_fields:
 546         if tmp_form_vals.has_key(field):
 547             m_query.append(u'%s=%s' % (field, tmp_form_vals[field]) )
 548     
 549     if 'prevcalaction' in req_fields:
 550         if not tmp_form_vals.has_key('prevcalaction'):
 551             m_query.append(u'%s=%s' % ('prevcalaction', tmp_form_vals['calaction']) )
 552             
 553     m_query = u'&'.join(m_query)
 554     
 555     if m_query:
 556         m_query = '&%s' % m_query
 557     
 558     return m_query
 559 
 560 
 561 # bottom menu bar
 562 def showmenubar():
 563     
 564     request = Globs.request
 565     cal_action = Globs.cal_action
 566     page_name = Globs.pagename
 567     
 568     page_url = Globs.pageurl
 569     
 570     if not Params.menubar: return ''
 571 
 572     if cal_action == 'simple':
 573         menuwidth = Params.simplewidth
 574     elif cal_action == 'monthly':
 575         menuwidth = Params.monthlywidth
 576     else:
 577         menuwidth = ''
 578     
 579     left_menu_selected = []
 580     right_menu_selected = []
 581     
 582     # Go Today
 583     year, month, day = gettodaydate()
 584     mnu_curmonthcal = u'<a href="%s?calaction=%s&caldate=%d%02d%02d%s" title="Go Today">[Today]</a>' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
 585     
 586     # List View
 587     mnu_listview = u'<a href="%s?calaction=list%s" title="List of all events">[List]</a>' % (page_url, getquerystring(['caldate', 'numcal']))
 588     
 589     # Monthly View
 590     mnu_monthview = u'<a href="%s?calaction=monthly%s" title="Monthly view">[Monthly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 591     
 592     # Simple Calendar View
 593     mnu_simpleview = u'<a href="%s?calaction=simple%s" title="Simple calendar view">[Simple]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 594     
 595     # Upcoming Event List
 596     mnu_upcomingview = u'<a href="%s?calaction=upcoming%s" title="Upcoming event list">[Upcoming]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 597     
 598     # Daily View
 599     mnu_dayview = u'<a href="%s?calaction=daily%s" title="Daily view">[Daily]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 600     
 601     # Weekly View
 602     mnu_weekview = u'<a href="%s?calaction=weekly%s" title="Weekly view">[Weekly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 603     
 604     html = [
 605         u'\r\n',
 606         u'<table class="eventcalendar_menubar" %s>',
 607         u'  <tr>',
 608         u'  <td class="eventcalendar_menubar" align="left">%s</td>',
 609         u'  <td class="eventcalendar_menubar" align="right">%s</td>',
 610         u'  </tr>',
 611         u'</table>',
 612         ]
 613         
 614     if cal_action == 'list':
 615         left_menu_selected.append(mnu_monthview)
 616         left_menu_selected.append(mnu_weekview)
 617         left_menu_selected.append(mnu_dayview)
 618         left_menu_selected.append(mnu_simpleview)
 619         right_menu_selected.append(mnu_upcomingview)
 620 
 621     elif cal_action == 'simple':
 622         left_menu_selected.append(mnu_monthview)
 623         left_menu_selected.append(mnu_weekview)
 624         left_menu_selected.append(mnu_dayview)
 625         right_menu_selected.append(mnu_listview)
 626         right_menu_selected.append(mnu_upcomingview)
 627         right_menu_selected.append(mnu_curmonthcal)
 628     
 629     elif cal_action == 'upcoming':
 630         left_menu_selected.append(mnu_monthview)
 631         left_menu_selected.append(mnu_weekview)
 632         left_menu_selected.append(mnu_dayview)
 633         left_menu_selected.append(mnu_simpleview)
 634         right_menu_selected.append(mnu_listview)
 635 
 636     elif cal_action == 'weekly':
 637         left_menu_selected.append(mnu_monthview)
 638         left_menu_selected.append(mnu_dayview)
 639         left_menu_selected.append(mnu_simpleview)
 640         right_menu_selected.append(mnu_upcomingview)
 641         right_menu_selected.append(mnu_listview)
 642         right_menu_selected.append(mnu_curmonthcal)
 643         
 644     elif cal_action == 'daily':
 645         left_menu_selected.append(mnu_monthview)
 646         left_menu_selected.append(mnu_weekview)
 647         left_menu_selected.append(mnu_simpleview)
 648         right_menu_selected.append(mnu_upcomingview)
 649         right_menu_selected.append(mnu_listview)
 650         right_menu_selected.append(mnu_curmonthcal)
 651 
 652     else:
 653         left_menu_selected.append(mnu_weekview)
 654         left_menu_selected.append(mnu_dayview)
 655         left_menu_selected.append(mnu_simpleview)
 656         right_menu_selected.append(mnu_upcomingview)
 657         right_menu_selected.append(mnu_listview)
 658         right_menu_selected.append(mnu_curmonthcal)
 659 
 660     left_menu_selected = u'\r\n'.join(left_menu_selected)
 661     right_menu_selected = u'\r\n'.join(right_menu_selected)
 662     
 663     html = u'\r\n'.join(html)
 664     html = html % (menuwidth, left_menu_selected, right_menu_selected)
 665 
 666     return html
 667         
 668 
 669 def getdatefield(str_date):
 670     str_year = ''
 671     str_month = ''
 672     str_day = ''
 673     
 674     if len(str_date) == 6:
 675         # year+month
 676         str_year = str_date[:4]
 677         str_month = str_date[4:]
 678         str_day = '1'
 679 
 680     elif len(str_date) == 8:
 681         # year+month+day
 682         str_year = str_date[:4]
 683         str_month = str_date[4:6]
 684         str_day = str_date[6:]
 685     
 686     elif len(str_date) == 10:
 687         # year+?+month+?+day
 688         str_year = str_date[:4]
 689         str_month = str_date[5:7]
 690         str_day = str_date[8:]
 691     
 692     else:
 693         raise ValueError
 694     
 695     # It raises exception if the input date is incorrect
 696     temp = datetime.date(int(str_year), int(str_month), int(str_day))
 697 
 698     return temp.year, temp.month, temp.day
 699 
 700 
 701 def gettimefield(str_time):
 702     str_hour = ''
 703     str_min = ''
 704     
 705     if len(str_time) == 4:
 706         # hour+minute
 707         str_hour = str_time[:2]
 708         str_min = str_time[2:]
 709     
 710     elif len(str_time) == 5:
 711         # hour+?+minute
 712         str_hour = str_time[:2]
 713         str_min = str_time[3:]
 714         
 715     else:
 716         raise ValueError
 717     
 718     # It raises exception if the input date is incorrect
 719     temp = datetime.time(int(str_hour), int(str_min))
 720 
 721     return temp.hour, temp.minute
 722 
 723 
 724 def gettodaydate():
 725     today = Globs.today
 726     return today.year, today.month, today.day    
 727 
 728 
 729 def cal_listhead():
 730 
 731     html = [
 732         u'  <tr>',
 733         u'      <td class="list_head">Title</td>',
 734         u'      <td class="list_head">Start Date</td>',
 735         u'      <td class="list_head">End Date</td>',
 736         u'      <td class="list_head">Recurrence</td>',
 737         u'      <td class="list_head">Label</td>',
 738         u'      <td class="list_head">Description</td>',
 739         u'      <td class="list_head">Reference</td>',
 740         u'  </tr>',
 741         ]
 742         
 743     return u'\r\n'.join(html)
 744 
 745 
 746 def showeventlist():
 747     
 748     debug('Show Calendar: List view')
 749     
 750     request = Globs.request
 751     formatter = Globs.formatter
 752     
 753     html_event_rows = []
 754     html_list_header = cal_listhead()
 755     
 756     # read all the events
 757     events, cal_events, labels = loadEvents()
 758     
 759     # sort events
 760     sorted_eventids = events.keys()
 761     sorted_eventids.sort(comp_list_events)
 762     
 763     for eid in sorted_eventids:
 764         if not events[eid]['clone']:
 765             html_event_rows.append( listshow_event(events[eid]) )
 766     
 767     html_event_rows = u'\r\n'.join(html_event_rows)
 768     
 769     html_list_table = [
 770         u'\r\n<div id="eventlist">',
 771         u'<table class="eventlist">',
 772         u'%s' % html_list_header,
 773         u'%s' % html_event_rows,
 774         u'</table>',
 775         u'</div>',
 776         ]
 777     html_list_table = u'\r\n'.join(html_list_table)
 778         
 779     return html_list_table
 780 
 781 
 782 def listshow_event(event):
 783     
 784     if event['recur_freq']:
 785         if event['recur_freq'] == -1:
 786             recur_desc = 'last %s' % event['recur_type']
 787         else:
 788             recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type'])
 789             
 790         if event['recur_until']:
 791              recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until']))
 792     else:
 793         recur_desc = ''
 794 
 795     html = [
 796         u'  <tr>',
 797         u'  <td class="list_entry">%s</td>' % converttext(event['title']),
 798         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']),
 799         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']),
 800         u'  <td class="list_entry">%s</td>' % recur_desc,
 801         u'  <td class="list_entry">%s</td>' % showReferPageParsedForLabel(event['label']),
 802         u'  <td class="list_entry">%s</td>' % converttext(event['description']),
 803         u'  <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'),
 804         u'  </tr>',
 805         ]
 806     
 807     return u'\r\n'.join(html)
 808 
 809 
 810 def showupcomingeventlist():
 811     
 812     debug('Show Calendar: Upcoming Event View')
 813     
 814     request = Globs.request
 815     formatter = Globs.formatter
 816     
 817     html_event_rows = []
 818     html_list_header = cal_listhead()
 819     
 820     year, month, day = gettodaydate()
 821     day_delta = datetime.timedelta(days=Params.upcomingrange)
 822     cur_date = datetime.date(year, month, day)
 823     next_range = cur_date + day_delta
 824     
 825     # set ranges of events
 826     datefrom = u'%04d%02d%02d' % (year, month, day)
 827     dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day)
 828     
 829     # read all the events (no cache)
 830     events, cal_events, labels = loadEvents(datefrom, dateto, 1)
 831     
 832     nowtime = formattimeobject(Globs.now)
 833     
 834     datefrom = formatcfgdatetime(cur_date, nowtime)
 835     #u'%04d-%02d-%02d %s:%s' % (year, month, day, nowtime[:2], nowtime[2:])
 836     dateto = formatcfgdatetime(formatdateobject(next_range))
 837     #u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day)
 838     
 839     # sort events
 840     sorted_eventids = events.keys()
 841     sorted_eventids.sort(comp_list_events)
 842     
 843     for eid in sorted_eventids:
 844         if events[eid]['enddate'] >= formatdateobject(Globs.today):
 845             if (not events[eid]['endtime']) or events[eid]['endtime'] >= formattimeobject(Globs.now):
 846                 html_event_rows.append( listshow_event(events[eid]) )
 847     
 848     html_event_rows = u'\r\n'.join(html_event_rows)
 849     
 850     html_list_table = [
 851         u'\r\n<div id="eventlist">',
 852         u'<table class="eventlist">',
 853         u'<tr><td colspan="7" class="list_entry" style="border-width: 0px;"><b>Upcoming Event List: %s ~ %s</b><p><br><p></td></tr>' % (datefrom, dateto),
 854         u'%s' % html_list_header,
 855         u'%s' % html_event_rows,
 856         u'</table>',
 857         u'</div>',
 858         ]
 859     html_list_table = u'\r\n'.join(html_list_table)
 860         
 861     return html_list_table
 862 
 863 
 864 
 865 
 866 def showcalendar():
 867     
 868     request = Globs.request
 869     formatter = Globs.formatter
 870     form_vals = Globs.form_vals
 871     
 872     html = []
 873     
 874     if form_vals.has_key('caldate'):
 875         try:
 876             year, month, str_temp = getdatefield(form_vals['caldate'])
 877         except (TypeError, ValueError):
 878             errormsgcode('invalid_caldate')
 879             year, month, dy = gettodaydate()
 880     
 881     elif Params.curdate:
 882         try:
 883             year, month, str_temp = getdatefield(Params.curdate)
 884         except (TypeError, ValueError):
 885             errormsgcode('invalid_curdate')
 886             year, month, dy = gettodaydate()
 887             
 888     else:
 889         year, month, dy = gettodaydate()
 890     
 891     # check number of calendar
 892     numcal = Params.numcal
 893     
 894     if form_vals.has_key('numcal'):
 895         try:
 896             numcal = int(form_vals['numcal'])
 897         except (TypeError, ValueError):
 898             errormsgcode('invalid_numcal')
 899 
 900     if numcal < 1:
 901         numcal = 1
 902     elif numcal > 12:
 903         numcal = 12
 904 
 905     for index in range(numcal):
 906     
 907         cyear, cmonth = yearmonthplusoffset(year, month, index)
 908     
 909         cal_html = showeventcalendar(cyear, cmonth)
 910         html.append(cal_html)
 911     
 912     return u''.join(html)
 913 
 914 
 915 def showdailycalendar():
 916     
 917     request = Globs.request
 918     formatter = Globs.formatter
 919     
 920     form_vals = Globs.form_vals
 921     
 922     if form_vals.has_key('caldate'):
 923         try:
 924             year, month, dy = getdatefield(form_vals['caldate'])
 925             
 926             if len(form_vals['caldate']) <= 6:
 927                 tyear, tmonth, tdy = gettodaydate()
 928                 if tyear == year and month == tmonth:
 929                     dy = tdy
 930                     
 931         except (TypeError, ValueError):
 932             errormsgcode('invalid_caldate')
 933             year, month, dy = gettodaydate()
 934             
 935     elif Params.curdate:
 936         try:
 937             year, month, dy = getdatefield(Params.curdate)
 938         except (TypeError, ValueError):
 939             errormsgcode('invalid_curdate')
 940             year, month, dy = gettodaydate()
 941         
 942     else:
 943         year, month, dy = gettodaydate()
 944     
 945     html = showdailyeventcalendar(year, month, dy)
 946     
 947     return u''.join(html)
 948 
 949 
 950 def showweeklycalendar():
 951     
 952     request = Globs.request
 953     formatter = Globs.formatter
 954     
 955     form_vals = Globs.form_vals
 956     
 957     if form_vals.has_key('caldate'):
 958         try:
 959             year, month, dy = getdatefield(form_vals['caldate'])
 960             
 961             if len(form_vals['caldate']) <= 6:
 962                 tyear, tmonth, tdy = gettodaydate()
 963                 if tyear == year and month == tmonth:
 964                     dy = tdy
 965 
 966         except (TypeError, ValueError):
 967             errormsgcode('invalid_caldate')
 968             year, month, dy = gettodaydate()
 969     
 970     elif Params.curdate:
 971         try:
 972             year, month, dy = getdatefield(Params.curdate)
 973         except (TypeError, ValueError):
 974             errormsgcode('invalid_curdate')
 975             year, month, dy = gettodaydate()
 976     else:
 977         year, month, dy = gettodaydate()
 978     
 979     html = showweeklyeventcalendar(year, month, dy)
 980     
 981     return u''.join(html)
 982 
 983     
 984 def showsimplecalendar():
 985     
 986     request = Globs.request
 987     formatter = Globs.formatter
 988     form_vals = Globs.form_vals
 989     
 990     html = []
 991     
 992     if form_vals.has_key('caldate'):
 993         try:
 994             year, month, str_temp = getdatefield(form_vals['caldate'])
 995         except (TypeError, ValueError):
 996             errormsgcode('invalid_caldate')
 997             year, month, dy = gettodaydate()
 998     elif Params.curdate:
 999         try:
1000             year, month, str_temp = getdatefield(Params.curdate)
1001         except (TypeError, ValueError):
1002             errormsgcode('invalid_curdate')
1003             year, month, dy = gettodaydate()
1004     else:
1005         year, month, dy = gettodaydate()
1006     
1007     # check number of calendar
1008     numcal = Params.numcal
1009     
1010     if form_vals.has_key('numcal'):
1011         try:
1012             numcal = int(form_vals['numcal'])
1013         except (TypeError, ValueError):
1014             errormsgcode('invalid_numcal')
1015             
1016 
1017     if numcal < 1:
1018         numcal = 1
1019     elif numcal > 12:
1020         numcal = 12
1021 
1022     for index in range(numcal):
1023     
1024         cyear, cmonth = yearmonthplusoffset(year, month, index)
1025     
1026         cal_html = showsimpleeventcalendar(cyear, cmonth)
1027         html.append(cal_html)
1028     
1029     return u''.join(html)
1030 
1031 
1032 
1033 # sort events in cal_events by length of days of the event
1034 def comp_cal_events(xid, yid):
1035     events = Globs.events
1036     
1037     if events[xid]['date_len'] > events[yid]['date_len']:
1038         return -1
1039     elif events[xid]['date_len'] == events[yid]['date_len']:
1040         if events[xid]['date_len'] == 1:
1041             if events[xid]['starttime'] == events[yid]['starttime']:
1042                 return cmp(events[yid]['time_len'], events[xid]['time_len'])
1043             else:
1044                 return cmp(events[xid]['starttime'], events[yid]['starttime'])
1045         else:
1046             return 0
1047     else:
1048         return 1
1049 
1050 
1051 # sort events in the list by start date of the event
1052 def comp_list_events(xid, yid):
1053     events = Globs.events
1054     
1055     return cmp(events[xid]['startdate'], events[yid]['startdate'])
1056 
1057 # load events from wiki pages
1058 def loadEvents(datefrom='', dateto='', nocache=0):
1059     
1060     request = Globs.request
1061     
1062     debug('Loading event information.')
1063     
1064     events = {}
1065     labels = {}
1066     cal_events = {}
1067     raw_events = {}
1068     
1069     raw_events, labels = loadEventsFromWikiPages()
1070     
1071     # handling cal_events
1072     if datefrom or dateto:
1073         
1074         # cache configurations
1075         arena = Page(request, Globs.pagename)
1076         eventkey = 'events'
1077         filteredeventkey = 'events_%s-%s' % (datefrom, dateto)
1078         caleventkey = 'calevents_%s-%s' % (datefrom, dateto)
1079         
1080         cache_events = caching.CacheEntry(request, arena, eventkey)
1081         cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey)
1082         cache_calevents = caching.CacheEntry(request, arena, caleventkey)
1083         
1084         dirty = 1
1085         
1086         debug('Checking cal_events cache')
1087         
1088         if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())):
1089         
1090             try:
1091                 events = pickle.loads(cache_filteredevents.content())
1092                 cal_events = pickle.loads(cache_calevents.content())
1093                 debug('Cached event (filtered) information is used: total %d events' % len(events))
1094                 dirty = 0
1095             except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1096                 debug('Picke error at fetching cached events (filtered)')
1097                 events = {}
1098                 cal_events = {}
1099 
1100 
1101         # if cache is dirty, update the cache
1102         if dirty:
1103         
1104             debug('Checking event cache: it\'s dirty or requested to refresh')
1105             debug('Building new cal_event information')
1106         
1107             try:
1108                 datefrom, dateto = int(datefrom), int(dateto)
1109             except (TypeError, ValueError):
1110                 datefrom, dateto = 0, 0
1111         
1112             clone_num = 0
1113             
1114             for e_id in raw_events.keys():
1115                 
1116                 cur_event = raw_events[e_id]
1117                 
1118                 # handling event recurrence
1119                 recur_freq = cur_event['recur_freq']
1120                 
1121                 if recur_freq or recur_freq == -1:
1122                     
1123                     if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto:
1124 
1125                         if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1126                             # generating cal_events for iteself
1127                             events[e_id] = cur_event.copy()
1128                             insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1129                         
1130                         delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 )
1131                         
1132                         if cur_event['recur_type'] == 'day':
1133                         
1134                             day_delta = int(recur_freq)
1135                             startdate = getdatetimefromstring(cur_event['startdate'])
1136                             datefrom_date = getdatetimefromstring(datefrom)
1137                             
1138                             if int(datefrom) > int(cur_event['startdate']):
1139                                 diffs = datefrom_date - startdate
1140                                 q_delta = diffs.days / day_delta
1141                                 if diffs.days % day_delta > 0:
1142                                     q_delta += 1
1143                             else:
1144                                 q_delta = 1
1145                             
1146                             while 1:
1147                                 
1148                                 if q_delta == 0:
1149                                     q_delta += 1
1150                                     continue
1151                                 
1152                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1153                                 recurred_enddate = recurred_startdate + delta_date_len
1154                                 
1155                                 new_startdate = formatdateobject(recurred_startdate)
1156                                 new_enddate = formatdateobject(recurred_enddate)
1157                                 
1158                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1159                                     break
1160                                 
1161                                 clone_num += 1
1162                                 clone_id = 'c%d' % clone_num
1163                                 
1164                                 events[clone_id] = cur_event.copy()
1165                                 events[clone_id]['id'] = clone_id
1166                                 events[clone_id]['startdate'] = new_startdate
1167                                 events[clone_id]['enddate'] = new_enddate
1168                                 events[clone_id]['clone'] = 1
1169                                 
1170                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1171                                 
1172                                 q_delta += 1
1173                         
1174                         elif cur_event['recur_type'] == 'week':
1175                             
1176                             day_delta = int(recur_freq) * 7
1177                             
1178                             startdate = getdatetimefromstring(cur_event['startdate'])
1179                             datefrom_date = getdatetimefromstring(datefrom)
1180                             
1181                             if int(datefrom) > int(cur_event['startdate']):
1182                                 diffs = datefrom_date - startdate
1183                                 q_delta = diffs.days / day_delta
1184                                 if diffs.days % day_delta > 0:
1185                                     q_delta += 1
1186                             else:
1187                                 q_delta = 1
1188                             
1189                             while 1:
1190                                 
1191                                 if q_delta == 0:
1192                                     q_delta += 1
1193                                     continue
1194                                 
1195                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1196                                 recurred_enddate = recurred_startdate + delta_date_len
1197                                 
1198                                 new_startdate = formatdateobject(recurred_startdate)
1199                                 new_enddate = formatdateobject(recurred_enddate)
1200                                 
1201                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1202                                     break
1203                                 
1204                                 clone_num += 1
1205                                 clone_id = 'c%d' % clone_num
1206                                 
1207                                 events[clone_id] = cur_event.copy()
1208                                 events[clone_id]['id'] = clone_id
1209                                 events[clone_id]['startdate'] = new_startdate
1210                                 events[clone_id]['enddate'] = new_enddate
1211                                 events[clone_id]['clone'] = 1
1212                                 
1213                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1214                                 
1215                                 q_delta += 1
1216                         
1217                         
1218                         elif cur_event['recur_type'] == 'weekday':
1219                             
1220                             syear, smonth, sday = getdatefield(cur_event['startdate'])
1221                             cyear, cmonth, cday = getdatefield(str(datefrom))
1222                             
1223                             recur_weekday = calendar.weekday(syear, smonth, sday)
1224 
1225                             while 1:
1226                                 
1227                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1228                                 firstmatch = (recur_weekday - firstweekday) % 7 + 1
1229                                 
1230                                 if recur_freq == -1:
1231                                     therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1232                                 else:
1233                                     #XXX should handle error
1234                                     try:
1235                                         therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1]
1236                                     except IndexError:
1237                                         if Params.showlastweekday:
1238                                             # if no matched weekday, the last weekday will be displayed
1239                                             therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1240                                         else:
1241                                             # if no matched weekday, no event will be displayed
1242                                             cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1243                                             continue
1244                                     
1245                                 
1246                                 recurred_startdate = datetime.date(cyear, cmonth, therecur_day)
1247                                 recurred_enddate = recurred_startdate + delta_date_len
1248                                 
1249                                 new_startdate = formatdateobject(recurred_startdate)
1250                                 new_enddate = formatdateobject(recurred_enddate)
1251                                 
1252                                 if int(new_startdate) < int(datefrom) or new_startdate == cur_event['startdate']:
1253                                     cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1254                                     continue
1255                                 
1256                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1257                                     break
1258                                 
1259                                 clone_num += 1
1260                                 clone_id = 'c%d' % clone_num
1261                                 
1262                                 events[clone_id] = cur_event.copy()
1263                                 events[clone_id]['id'] = clone_id
1264                                 events[clone_id]['startdate'] = new_startdate
1265                                 events[clone_id]['enddate'] = new_enddate
1266                                 events[clone_id]['clone'] = 1
1267     
1268                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1269                                 
1270                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1271                                 
1272                         
1273                         elif cur_event['recur_type'] == 'month':
1274                             
1275                             cyear, cmonth, therecurday = getdatefield(cur_event['startdate'])
1276                             
1277                             while 1:
1278                                 
1279                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq)
1280                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1281                                 recur_day = therecurday 
1282                                 if daysinmonth < recur_day:
1283                                     recur_day = daysinmonth
1284                                 new_startdate = formatDate(cyear, cmonth, recur_day)
1285                                 
1286                                 if int(new_startdate) < int(datefrom):
1287                                     continue
1288                                 
1289                                 recurred_startdate = datetime.date(cyear, cmonth, recur_day)
1290                                 recurred_enddate = recurred_startdate + delta_date_len
1291                                 
1292                                 new_startdate = formatdateobject(recurred_startdate)
1293                                 new_enddate = formatdateobject(recurred_enddate)
1294                                 
1295                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1296                                     break
1297                                 
1298                                 clone_num += 1
1299                                 clone_id = 'c%d' % clone_num
1300                                 
1301                                 events[clone_id] = cur_event.copy()
1302                                 events[clone_id]['id'] = clone_id
1303                                 events[clone_id]['startdate'] = new_startdate
1304                                 events[clone_id]['enddate'] = new_enddate
1305                                 events[clone_id]['clone'] = 1
1306     
1307                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1308                         
1309                         elif cur_event['recur_type'] == 'year':
1310                             
1311                             ryear, rmonth, rday = getdatefield(cur_event['startdate'])
1312                             cyear, cmonth, cday = getdatefield(str(datefrom))
1313                             
1314                             while 1:
1315                                 
1316                                 ryear += recur_freq
1317                                 new_startdate = formatDate(ryear, rmonth, rday)
1318                                 
1319                                 if int(new_startdate) < int(datefrom):
1320                                     continue
1321                                     
1322                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1323                                     break
1324                                 
1325                                 recurred_startdate = datetime.date(ryear, rmonth, rday)
1326                                 recurred_enddate = recurred_startdate + delta_date_len
1327                                 
1328                                 new_startdate = formatdateobject(recurred_startdate)
1329                                 new_enddate = formatdateobject(recurred_enddate)
1330                                 
1331                                 clone_num += 1
1332                                 clone_id = 'c%d' % clone_num
1333                                 
1334                                 events[clone_id] = cur_event.copy()
1335                                 events[clone_id]['id'] = clone_id
1336                                 events[clone_id]['startdate'] = new_startdate
1337                                 events[clone_id]['enddate'] = new_enddate
1338                                 events[clone_id]['clone'] = 1
1339     
1340                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1341                 
1342                 else:
1343                     
1344                     if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1345                         events[e_id] = cur_event.copy()
1346                         insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1347                         
1348             
1349             # sort cal_events
1350             # store event list into global variables in order to sort them
1351             Globs.events = events
1352             
1353             for eachdate in cal_events.keys():
1354                 cal_events[eachdate].sort(comp_cal_events)
1355             
1356             # cache update
1357             if not nocache:
1358                 cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL))
1359                 cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL))
1360         
1361     else:
1362         events = raw_events
1363         
1364         # store event list into global variables in order to sort them
1365         Globs.events = events
1366     
1367     Globs.labels = labels
1368     
1369     debug(u'Total %d events are loaded finally.' % len(events))
1370     debug(u'Total %d labels are loaded finally.' % len(labels))
1371     
1372     return events, cal_events, labels
1373 
1374 
1375 
1376 def loadEventsFromWikiPages():
1377     
1378     events = {}
1379     labels = {}
1380     cached_event_loaded = 0
1381     dirty = 0
1382     
1383     eventrecord_list = []
1384     labelrecord_list = []
1385     eventpages = []
1386     stored_errmsg = ''
1387     
1388     request = Globs.request
1389     category = Params.category
1390     
1391     # cache configurations
1392     arena = Page(request, Globs.pagename)
1393     
1394     eventkey = 'events'
1395     labelkey = 'labels'
1396     pagelistkey = 'eventpages'
1397     errmsglistkey = 'eventcalerrormsglist'
1398     
1399     cache_events = caching.CacheEntry(request, arena, eventkey)
1400     cache_labels = caching.CacheEntry(request, arena, labelkey)
1401     cache_pages = caching.CacheEntry(request, arena, pagelistkey)
1402     cache_errmsglist = caching.CacheEntry(request, arena, errmsglistkey)
1403     
1404     # page list cache
1405 
1406     debug('Checking page list cache')
1407     
1408     # check the time at which page list cache has been created
1409     
1410     cp_mtime = cache_pages.mtime()
1411     timedelta_days = 9999
1412     
1413     if cp_mtime:
1414         cp_date = datetime.datetime.fromtimestamp(cp_mtime)
1415         today = datetime.datetime.fromtimestamp(time.time())
1416         datediff = today - cp_date
1417         timedelta_days = datediff.days
1418         debug('Time from page list cache built = %s' % datediff)
1419 
1420     
1421     if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1:
1422         categorypages = searchPages(request, category)
1423         for page in categorypages:
1424             eventpages.append(page.page_name)
1425         cache_pages.update('\n'.join(eventpages), True)
1426         debug('New page list is built: %d pages' % len(eventpages))
1427     else:
1428         eventpages = cache_pages.content(True).split('\n')
1429         debug('Cached page list is used: %d pages' % len(eventpages))
1430     
1431     if not Globs.page_action == 'refresh':
1432         # check the cache validity
1433         for page_name in eventpages:
1434             
1435             p = Page(request, page_name)
1436             e_ref = page_name
1437             
1438             if cache_events.needsUpdate(p._text_filename()) or cache_labels.needsUpdate(p._text_filename()) or cache_errmsglist.needsUpdate(p._text_filename()):
1439                 dirty = 1
1440                 break
1441     else:
1442         dirty = 1
1443 
1444     if dirty:
1445         # generating events
1446         
1447         dirty_local = 0
1448         debug_records = {}
1449         
1450         eventrecordkey = 'eventrecords'
1451         labelrecordkey = 'labelrecords'
1452         errmsgkey = 'eventcalerrormsg'
1453         
1454         # fetch event records from each page in the category
1455         for page_name in eventpages:
1456             
1457             p = Page(request, page_name)
1458             e_ref = page_name
1459             
1460             cache_errmsg = caching.CacheEntry(request, p, errmsgkey)
1461             cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey)
1462             cache_labelrecords = caching.CacheEntry(request, p, labelrecordkey)
1463             
1464             if cache_eventrecords.needsUpdate(p._text_filename()) or cache_labelrecords.needsUpdate(p._text_filename()) or Globs.page_action == 'refresh':
1465                 page_content = p.get_raw_body()
1466                 eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref)
1467                 
1468                 debug_records[e_ref] = '%d events are fetched from %s' % (len(eventrecords), e_ref)
1469                 
1470                 # XXXXX
1471                 #debug('events: %s' % eventrecords)
1472                 #debug('labels: %s' % labelrecords)
1473                 
1474                 cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1475                 cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL))
1476                 cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL))
1477                 
1478                 stored_errmsg += Globs.errormsg
1479                 Globs.errormsg = ''
1480                 
1481             else:
1482                 try:
1483                     eventrecords = pickle.loads(cache_eventrecords.content())
1484                     labelrecords = pickle.loads(cache_labelrecords.content())
1485                     Globs.errormsg = pickle.loads(cache_errmsg.content())
1486                     
1487                     debug_records[e_ref] = '%d cached eventrecords are used from %s' % (len(eventrecords), e_ref)
1488                     
1489                 except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1490                     dirty = 1
1491                     page_content = p.get_raw_body()
1492                     eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref)
1493                     debug_records[e_ref] = '%d eventrecords are fetched from %s due to pickle error' % (len(eventrecords), e_ref)
1494                     
1495                     cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1496                     cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL))
1497                     cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL))
1498     
1499             eventrecord_list.append(eventrecords)
1500             labelrecord_list.append(labelrecords)
1501             
1502             stored_errmsg += Globs.errormsg
1503             Globs.errormsg = ''
1504 
1505         debug('Checking event cache: it\'s dirty or requested to refresh')
1506 
1507     else:
1508         
1509         debug('Checking event cache: still valid')
1510         
1511         try:
1512             events = pickle.loads(cache_events.content())
1513             labels = pickle.loads(cache_labels.content())
1514             stored_errmsg = pickle.loads(cache_errmsglist.content())
1515             
1516             cached_event_loaded = 1
1517             
1518             debug('Cached event information is used: total %d events' % len(events))
1519             
1520         except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1521             events = {}
1522             labels = {}
1523             stored_errmsg = ''
1524             
1525             debug('Picke error at fetching cached events')
1526     
1527     # if it needs refreshed, generate events dictionary
1528     if not cached_event_loaded:
1529 
1530         # XXX: just for debugging
1531         debug('Building new event information')
1532         for page_name in eventpages:
1533             debug(debug_records[page_name])
1534 
1535         for eventrecords in eventrecord_list:
1536             for evtrecord in eventrecords:
1537                 e_id = evtrecord['id']
1538                 events[e_id] = evtrecord
1539         
1540         for labelrecords in labelrecord_list:
1541             for label in labelrecords:
1542                 c_id = label['name']
1543                 if not labels.has_key(c_id):
1544                     labels[c_id] = label
1545                 else:
1546                     stored_errmsg += u'<li>%s\n' % geterrormsg('redefined_label', label['refer'], label['name'])
1547         
1548         # after generating updated events, update the cache
1549         cache_events.update(pickle.dumps(events, PICKLE_PROTOCOL))
1550         cache_labels.update(pickle.dumps(labels, PICKLE_PROTOCOL))
1551         cache_errmsglist.update(pickle.dumps(stored_errmsg, PICKLE_PROTOCOL))
1552         
1553         debug('Event information is newly built: total %d events' % len(events))
1554 
1555     Globs.errormsg = stored_errmsg
1556     
1557     # end of updating events block    
1558     
1559     return events, labels
1560     
1561 
1562 
1563 def getEventRecordFromPage(pagecontent, referpage):
1564     
1565     request = Globs.request
1566     
1567     eventrecords = []
1568     labelrecords = []
1569     page_bgcolor = ''
1570     page_description = ''
1571     
1572     e_num = 0
1573     
1574     # fetch the page default bgcolor
1575     regex_page_bgcolor = r"""
1576 (?P<req_field>^[ ]+default_bgcolor::[ ]+)
1577 (
1578     (?P<pagebgcolor>\#[0-9a-fA-F]{6})
1579     \s*?
1580     $
1581 )?
1582 """
1583 
1584     pattern = re.compile(regex_page_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1585     match = pattern.search(pagecontent)
1586         
1587     if match:
1588         if match.group('pagebgcolor'):
1589             page_bgcolor = match.group('pagebgcolor')
1590         else:
1591             errormsg( geterrormsg('invalid_default_bgcolor', referpage) )
1592 
1593 
1594     # fetch the page default description
1595     regex_page_description = r"""
1596 (?P<req_field>^[ ]+default_description::[ ]+)
1597 (
1598     (?P<pagedescription>.*?)
1599     \s*?
1600     $
1601 )?
1602 """
1603    
1604     pattern = re.compile(regex_page_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1605     match = pattern.search(pagecontent)
1606         
1607     if match:
1608         if match.group('pagedescription'):
1609             page_description = match.group('pagedescription')
1610         else:
1611             errormsg( geterrormsg('empty_default_description', referpage) )
1612 
1613     # fetch the label definition
1614     regex_label_definition = r"""
1615 (?P<reqfield>^[ ]+label_def::[ ]+)
1616 (
1617 	(?P<name>[^,^:^\s]+?)
1618 	[,: ]+
1619 	(?P<bgcolor>\#[0-9a-fA-F]{6})
1620 	\s*?
1621 	$
1622 )?
1623 """
1624 
1625     
1626     pattern = re.compile(regex_label_definition, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1627     match = pattern.findall(pagecontent)
1628         
1629     if match:
1630     
1631         for matchitem in match:
1632             
1633             labelitem = {}
1634             
1635             label_name = matchitem[2]
1636             label_bgcolor = matchitem[3]
1637         
1638             if label_name and label_bgcolor:
1639                 labelitem['name'] = label_name
1640                 labelitem['bgcolor'] = label_bgcolor
1641                 labelitem['refer'] = referpage
1642                 
1643                 labelrecords.append(labelitem)
1644             else:
1645                 errormsg( geterrormsg('empty_label_definition', referpage) )
1646                 continue
1647 
1648 
1649     # fetch event item
1650     regex_eventitem = r"""
1651 (?P<eventitem>
1652 	(?P<heading>^\s*(?P<hmarker>=+)\s(?P<eventtitle>.*?)\s(?P=hmarker) $)
1653 	(?P<eventdetail>
1654 		.*?
1655 		(?=
1656 			^\s*(?P<nexthmarker>=+)\s(?P<nexteventtitle>.*?)\s(?P=nexthmarker) $
1657 			| \Z
1658         )
1659 	)
1660 )
1661 """
1662     
1663     pattern = re.compile(regex_eventitem, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1664     match = pattern.findall(pagecontent)
1665 
1666     if match:
1667         
1668         for matchitem in match:
1669             
1670             eventitem = {}
1671 
1672             eventtitle = matchitem[3]
1673             eventdetail = matchitem[4]
1674             
1675             e_headid = getheadingid(request, referpage, eventtitle)
1676             
1677             if not eventdetail:
1678                 continue
1679             
1680             #debug('Examininng "%s" event from %s ..' % (eventtitle, referpage))
1681             
1682             try:
1683                 e_start_date, e_start_time, e_end_date, e_end_time, e_bgcolor, e_label, e_description, e_recur_freq, e_recur_type, e_recur_until = geteventfield(eventdetail)
1684             except EventcalError, errmsgcode:
1685 
1686                 if not errmsgcode.value == 'pass':
1687                     errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) )
1688                 
1689                 continue
1690                 
1691             #except TypeError, ValueError:
1692             #    errormsg('undefined')
1693             #    continue
1694             
1695             # set default values
1696             if not e_bgcolor:
1697                 e_bgcolor = page_bgcolor
1698                 
1699             if not e_description:
1700                 e_description = page_description
1701             
1702             e_num += 1
1703             e_id = 'e_%s_%d' % (referpage, e_num)
1704             
1705             eventitem['id'] = e_id
1706             eventitem['title'] = eventtitle
1707             eventitem['startdate'] = e_start_date
1708             eventitem['starttime'] = e_start_time
1709             eventitem['enddate'] = e_end_date
1710             eventitem['endtime'] = e_end_time
1711             eventitem['title'] = eventtitle
1712             eventitem['refer'] = referpage
1713             eventitem['bgcolor'] = e_bgcolor
1714             eventitem['label'] = e_label
1715             eventitem['description'] = e_description
1716             eventitem['recur_freq'] = e_recur_freq
1717             eventitem['recur_type'] = e_recur_type
1718             eventitem['recur_until'] = e_recur_until
1719             
1720             try:
1721                 eventitem['date_len'] = diffday(e_start_date, e_end_date) + 1
1722                 eventitem['clone'] = 0
1723                 eventitem['hid'] = e_headid
1724                 
1725                 if eventitem['date_len'] == 1 and e_start_time and e_end_time:
1726                     eventitem['time_len'] = difftime(e_start_time, e_end_time) + 1
1727                 else:
1728                     eventitem['time_len'] = 0
1729                     
1730             except EventcalError, errmsgcode:
1731                 debug('Failed to add "%s" event from %s ..' % (eventtitle, referpage))
1732                 errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) )
1733                 continue
1734             
1735             eventrecords.append(eventitem)
1736             
1737             #debug('Added "%s" event from %s ..' % (eventtitle, referpage))
1738 
1739     return eventrecords, labelrecords
1740     
1741 
1742 
1743 def geteventfield(detail):
1744     
1745 
1746     # START DATE REGEX ----------------------------
1747     regex_startdate = r"""
1748 (?P<reqfield>^[ ]+start::(?=[ ]+))
1749 (
1750     (?P<startdate>
1751         [ ]+
1752         (
1753             (?P<startdate1>
1754             	(?P<startyear1>19\d{2} | 20\d{2} | \d{2} )
1755             	[./-]
1756             	(?P<startmonth1>1[012] | 0[1-9] | [1-9])
1757             	[./-]
1758             	(?P<startday1>3[01] | 0[1-9] | [12]\d | [1-9])
1759             )
1760             |
1761             (?P<startdate2>
1762             	(?P<startmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1763             	[ ]+
1764             	(?P<startday2>3[01] | 0[1-9] | [12]\d | [1-9])
1765             	(?: st | nd | rd | th )?
1766             	[ ,]+
1767             	(?P<startyear2>19\d{2} | 20\d{2} | \d{2})
1768             )
1769             |
1770             (?P<startdate3>
1771             	(?P<startyear3>19\d{2} | 20\d{2} | \d{2} )
1772             	(?P<startmonth3>1[012] | 0[1-9])
1773             	(?P<startday3>3[01] | 0[1-9] | [12]\d)
1774             )
1775         )
1776     )
1777     (?P<starttime>
1778         [ ,]+
1779         (
1780             (?P<starttime1>
1781             	(?P<starthour1> 1[0-2] | [0]?[1-9] )
1782             	(
1783             		(?: [.:])
1784             		(?P<startminute1>[0-5]\d{0,1} | [6-9])
1785             	)?
1786             	[ ]*
1787             	(?P<am1> am | pm | p | a )
1788             )
1789             |
1790             (?P<starttime2>
1791             	(?P<starthour2> | [01]\d{0,1} | 2[0-3] | [1-9])
1792             	(
1793             		(?: [.:])
1794             		(?P<startminute2>[0-5]\d{0,1} | [6-9])
1795             	)?
1796             )
1797             |
1798             (?P<starttime3>
1799             	(?P<starthour3> [01]\d | 2[0-3])
1800             	(?P<startminute3> [0-5]\d)?
1801             )
1802             |
1803             (?P<starttime4>
1804             	(?P<starthour4> 0[1-9] | 1[0-2])
1805             	(?P<startminute4> [0-5]\d)?
1806             	[ ]*
1807             	(?P<am4> am | pm | p | a )
1808             )
1809         )
1810     )?
1811     \s*?
1812     $
1813 )?
1814 """
1815 
1816     
1817 
1818     # END DATE REGEX ----------------------------
1819     regex_enddate = r"""
1820 (?P<reqfield>^[ ]+end::(?=[ ]+))
1821 (
1822     (?P<enddate>
1823         [ ]+
1824         (
1825             (?P<enddate1>
1826             	(?P<endyear1>19\d{2} | 20\d{2} | \d{2} )
1827             	[./-]
1828             	(?P<endmonth1>1[012] | 0[1-9] | [1-9])
1829             	[./-]
1830             	(?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9])
1831             )
1832             |
1833             (?P<enddate2>
1834             	(?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1835             	[ ]+
1836             	(?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9])
1837             	(?: st | nd | rd | th )?
1838             	[ ,]+
1839             	(?P<endyear2>19\d{2} | 20\d{2} | \d{2})
1840             )
1841             |
1842             (?P<enddate3>
1843             	(?P<endyear3>19\d{2} | 20\d{2} | \d{2} )
1844             	(?P<endmonth3>1[012] | 0[1-9])
1845             	(?P<endday3>3[01] | 0[1-9] | [12]\d)
1846             )
1847         )
1848     )?
1849     (?P<endtime>
1850         [ ,]+
1851         (
1852             (?P<endtime1>
1853             	(?P<endhour1> 1[0-2] | [0]?[1-9] )
1854             	(
1855             		(?: [.:])
1856             		(?P<endminute1>[0-5]\d{0,1} | [6-9])
1857             	)?
1858             	[ ]*
1859             	(?P<am1> am | pm | p | a )
1860             )
1861             |
1862             (?P<endtime2>
1863             	(?P<endhour2> | [01]\d{0,1} | 2[0-3] | [1-9])
1864             	(
1865             		(?: [.:])
1866             		(?P<endminute2>[0-5]\d{0,1} | [6-9])
1867             	)?
1868             )
1869             |
1870             (?P<endtime3>
1871             	(?P<endhour3> [01]\d | 2[0-3])
1872             	(?P<endminute3> [0-5]\d)?
1873             )
1874             |
1875             (?P<endtime4>
1876             	(?P<endhour4> 0[1-9] | 1[0-2])
1877             	(?P<endminute4> [0-5]\d)?
1878             	[ ]*
1879             	(?P<am4> am | pm | p | a )
1880             )
1881         )
1882     )?
1883     \s*?
1884     $
1885 )?
1886 """
1887 
1888     regex_bgcolor = r"""
1889 (?P<reqfield>^[ ]+bgcolor::[ ]+)
1890 (
1891     (?P<bgcolor>\#[0-9a-fA-F]{6})?
1892     \s*?
1893     $
1894 )?
1895 """
1896 
1897     regex_description = r"""
1898 (?P<reqfield>^[ ]+description::[ ]+)
1899 (
1900     (?P<description>.*?)
1901     \s*?
1902     $
1903 )?
1904 """
1905 
1906     
1907     regex_recur = r"""
1908 (?P<reqfield>^[ ]+recur::[ ]+)
1909 (
1910     (?P<recur_freq>\d+|last)
1911     \s+
1912     (?P<recur_type>weekday|day|week|month|year)
1913     (
1914     	\s+
1915     	(?P<recur_until_req>until)
1916     	\s+
1917     	(?P<recur_until>
1918             (?P<enddate>
1919                 (?P<enddate1>
1920                 	(?P<endyear1>19\d{2} | 20\d{2} | \d{2} )
1921                 	[./-]
1922                 	(?P<endmonth1>1[012] | 0[1-9] | [1-9])
1923                 	[./-]
1924                 	(?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9])
1925                 )
1926                 |
1927                 (?P<enddate2>
1928                 	(?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1929                 	\s+
1930                 	(?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9])
1931                 	(?: st | nd | rd | th )?
1932                 	[\s,]+
1933                 	(?P<endyear2>19\d{2} | 20\d{2} | \d{2})
1934                 )
1935                 |
1936                 (?P<enddate3>
1937                 	(?P<endyear3>19\d{2} | 20\d{2} | \d{2} )
1938                 	(?P<endmonth3>1[012] | 0[1-9])
1939                 	(?P<endday3>3[01] | 0[1-9] | [12]\d)
1940                 )
1941             )?
1942         )?
1943     )?
1944     \s*?
1945     $
1946 )?
1947 """
1948 
1949     regex_label = r"""
1950 (?P<reqfield>^[ ]+label::[ ]+)
1951 (
1952 	(?P<name>[^,^:^\s]+?)
1953 	\s*?
1954 	$
1955 )?
1956 """
1957 
1958 
1959     # need help on regular expressions for more efficient/flexible form
1960     
1961     # compile regular expression objects
1962     
1963     pattern_startdate = re.compile(regex_startdate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1964     pattern_enddate = re.compile(regex_enddate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1965     pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1966     pattern_label = re.compile(regex_label, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1967     pattern_description = re.compile(regex_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1968     pattern_recur = re.compile(regex_recur, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1969     
1970     ##################### retrieve startdate
1971     match = pattern_startdate.search(detail)
1972     
1973     if match:
1974     
1975         if match.group('startdate'):
1976             passed = 1
1977             # yyyy/mm/dd: 2006/05/10; 06/05/10, 
1978             if match.group('startdate1'):
1979                 if len(match.group('startyear1')) == 2:
1980                     startyear = '20%s' % match.group('startyear1')
1981                 else:
1982                     startyear = match.group('startyear1')
1983                 
1984                 startmonth = match.group('startmonth1')
1985                 startday = match.group('startday1')
1986                 
1987             # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
1988             elif match.group('startdate2'):
1989                 if len(match.group('startyear2')) == 2:
1990                     startyear = '20%s' % match.group('startyear2')
1991                 else:
1992                     startyear = match.group('startyear2')
1993                 
1994                 startmonth = getNumericalMonth(match.group('startmonth2'))
1995                 if not startmonth:
1996                     raise EventcalError('invalid_startdate')
1997                     
1998                 startday = match.group('startday2')
1999             
2000             # yyyymmdd: 20060510, 060510
2001             elif match.group('startdate3'):
2002                 if len(match.group('startyear3')) == 2:
2003                     startyear = '20%s' % match.group('startyear3')
2004                 else:
2005                     startyear = match.group('startyear3')
2006                 
2007                 startmonth = match.group('startmonth3')
2008                 startday = match.group('startday3')
2009             
2010             else:
2011                 if len(match.group('startdate').strip()) > 0:
2012                     raise EventcalError('invalid_startdate')
2013                 else:
2014                     passed = 0
2015             
2016             if passed:
2017                 startdate = '%d/%02d/%02d' % (int(startyear), int(startmonth), int(startday))
2018             else:
2019                 startdate = ''
2020                 
2021         else:
2022             startdate = ''
2023             
2024         if match.group('starttime'):
2025             passed = 1
2026             # 12h with ':': 12:00; 9:00pm
2027             if match.group('starttime1'):
2028                 starthour = int(match.group('starthour1'))
2029                 if match.group('startminute1'):
2030                     startmin = int(match.group('startminute1'))
2031                 else:
2032                     startmin = 0
2033                 
2034                 if starthour < 12 and match.group('am1').lower().startswith('p'):
2035                     starthour += 12
2036                 
2037             # 24h with ':': 12:00; 23:00
2038             elif match.group('starttime2'):
2039                 starthour = int(match.group('starthour2'))
2040                 if match.group('startminute2'):
2041                     startmin = int(match.group('startminute2'))
2042                 else:
2043                     startmin = 0
2044                 
2045             # 24h without ':': 1200; 2300
2046             elif match.group('starttime3'):
2047                 starthour = int(match.group('starthour3'))
2048                 if match.group('startminute3'):
2049                     startmin = int(match.group('startminute3'))
2050                 else:
2051                     startmin = 0
2052 
2053             # 12h without ':': 1200; 0900pm
2054             elif match.group('starttime4'):
2055                 
2056                 starthour = int(match.group('starthour4'))
2057                 if match.group('startminute4'):
2058                     startmin = int(match.group('startminute4'))
2059                 else:
2060                     startmin = 0
2061                 
2062                 if starthour < 12 and match.group('am4').lower().startswith('p'):
2063                     starthour += 12
2064 
2065             else:
2066                 if len(match.group('starttime').strip()) > 0:
2067                     raise EventcalError('invalid_starttime')
2068                 else:
2069                     passed = 0
2070             
2071             if passed:
2072                 starttime = '%02d:%02d' % (int(starthour), int(startmin))
2073             else:
2074                 starttime = ''
2075         
2076         else:
2077             starttime = ''
2078             
2079         if not startdate:
2080             raise EventcalError('invalid_start')
2081 
2082     else:
2083         raise EventcalError('pass')
2084     
2085     ##################### retrieve enddate
2086     match = pattern_enddate.search(detail)
2087     
2088     if match:
2089     
2090         if match.group('enddate'):
2091             passed = 1
2092             # yyyy/mm/dd: 2006/05/10; 06/05/10, 
2093             if match.group('enddate1'):
2094                 if len(match.group('endyear1')) == 2:
2095                     endyear = '20%s' % match.group('endyear1')
2096                 else:
2097                     endyear = match.group('endyear1')
2098                 
2099                 endmonth = match.group('endmonth1')
2100                 endday = match.group('endday1')
2101                 
2102             # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2103             elif match.group('enddate2'):
2104                 if len(match.group('endyear2')) == 2:
2105                     endyear = '20%s' % match.group('endyear2')
2106                 else:
2107                     endyear = match.group('endyear2')
2108                 
2109                 endmonth = getNumericalMonth(match.group('endmonth2'))
2110                 if not endmonth:
2111                     raise EventcalError('invalid_enddate')
2112                 
2113                 endday = match.group('endday2')
2114             
2115             # yyyymmdd: 20060510, 060510
2116             elif match.group('enddate3'):
2117                 if len(match.group('endyear3')) == 2:
2118                     endyear = '20%s' % match.group('endyear3')
2119                 else:
2120                     endyear = match.group('endyear3')
2121                 
2122                 endmonth = match.group('endmonth3')
2123                 endday = match.group('endday3')
2124             
2125             else:
2126                 if len(match.group('enddate').strip()) > 0:
2127                     raise EventcalError('invalid_enddate')
2128                 else:
2129                     passed = 0
2130             
2131             if passed:
2132                 enddate = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2133             else:
2134                 enddate = ''
2135                 
2136         else:
2137             enddate = ''
2138         
2139         if match.group('endtime'):
2140             passed = 1
2141             # 12h with ':': 12:00; 9:00pm
2142             if match.group('endtime1'):
2143                 endhour = int(match.group('endhour1'))
2144                 if match.group('endminute1'):
2145                     endmin = int(match.group('endminute1'))
2146                 else:
2147                     endmin = 0
2148                 
2149                 if endhour < 12 and match.group('am1').lower() == 'pm':
2150                     endhour += 12
2151                 
2152             # 24h with ':': 12:00; 23:00
2153             elif match.group('endtime2'):
2154                 endhour = int(match.group('endhour2'))
2155                 if match.group('endminute2'):
2156                     endmin = int(match.group('endminute2'))
2157                 else:
2158                     endmin = 0
2159                 
2160             # 24h without ':': 1200; 2300
2161             elif match.group('endtime3'):
2162                 endhour = int(match.group('endhour3'))
2163                 if match.group('endminute3'):
2164                     endmin = int(match.group('endminute3'))
2165                 else:
2166                     endmin = 0
2167 
2168             # 12h without ':': 1200; 0900pm
2169             elif match.group('endtime4'):
2170                 
2171                 endhour = int(match.group('endhour4'))
2172                 if match.group('endminute4'):
2173                     endmin = int(match.group('endminute4'))
2174                 else:
2175                     endmin = 0
2176                 
2177                 if endhour < 12 and match.group('am4').lower() == 'pm':
2178                     endhour += 12
2179             
2180             else:
2181                 if len(match.group('endtime').strip()) > 0:
2182                     raise EventcalError('invalid_endtime')
2183                 else:
2184                     passed = 0
2185                 
2186             if passed:
2187                 endtime = '%02d:%02d' % (int(endhour), int(endmin))
2188             else:
2189                 endtime = ''
2190                 
2191         else:
2192             endtime = ''
2193 
2194         if not (enddate or endtime):
2195             raise EventcalError('invalid_end')
2196 
2197     else:
2198         enddate = ''
2199         endtime = '' 
2200 
2201 
2202     ##################### retrieve bgcolor
2203     match = pattern_bgcolor.search(detail)
2204     
2205     if match:
2206         if match.group('bgcolor'):
2207             bgcolor = match.group('bgcolor')
2208         else:
2209             errormsgcode('invalid_bgcolor')
2210             bgcolor = ''
2211             
2212     else:
2213         bgcolor = ''
2214 
2215     ##################### retrieve label
2216     match = pattern_label.search(detail)
2217     
2218     if match:
2219         if match.group('name'):
2220             label = match.group('name')
2221         else:
2222             errormsgcode('invalid_label')
2223             label = ''
2224             
2225     else:
2226         label = ''
2227 
2228     ##################### retrieve description
2229     match = pattern_description.search(detail)
2230     
2231     if match:
2232         if match.group('description'):
2233             description = match.group('description')
2234         else:
2235             errormsgcode('empty_description')
2236             description = ''
2237     else:
2238         description = ''
2239         
2240     ##################### retrieve recurrence
2241     match = pattern_recur.search(detail)
2242     
2243     if match:
2244     
2245         if match.group('recur_freq') and match.group('recur_type'):
2246     
2247             if match.group('recur_freq') == 'last':
2248                 if match.group('recur_type') == 'weekday':
2249                     recur_freq = -1
2250                     recur_type = match.group('recur_type')
2251                     recur_until = match.group('recur_until')
2252                 else:
2253                     recur_freq = 0
2254                     recur_type = ''
2255                     recur_until = ''
2256                     
2257             else:
2258                 recur_freq = int(match.group('recur_freq'))
2259                 recur_type = match.group('recur_type')
2260                 
2261                 if match.group('recur_until_req'):
2262                     if match.group('recur_until'):
2263                         # yyyy/mm/dd: 2006/05/10; 06/05/10, 
2264                         if match.group('enddate1'):
2265                             if len(match.group('endyear1')) == 2:
2266                                 endyear = '20%s' % match.group('endyear1')
2267                             else:
2268                                 endyear = match.group('endyear1')
2269                             
2270                             endmonth = match.group('endmonth1')
2271                             endday = match.group('endday1')
2272                             
2273                         # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2274                         elif match.group('enddate2'):
2275                             if len(match.group('endyear2')) == 2:
2276                                 endyear = '20%s' % match.group('endyear2')
2277                             else:
2278                                 endyear = match.group('endyear2')
2279                             
2280                             endmonth = getNumericalMonth(match.group('endmonth2'))
2281                             if not endmonth:
2282                                 raise EventcalError('invalid_recur_until')
2283                             
2284                             endday = match.group('endday2')
2285                         
2286                         # yyyymmdd: 20060510, 060510
2287                         elif match.group('enddate3'):
2288                             if len(match.group('endyear3')) == 2:
2289                                 endyear = '20%s' % match.group('endyear3')
2290                             else:
2291                                 endyear = match.group('endyear3')
2292                             
2293                             endmonth = match.group('endmonth3')
2294                             endday = match.group('endday3')
2295                             
2296                         else:
2297                             raise EventcalError('invalid_recur_until')
2298                             
2299                         recur_until = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2300 
2301                     else:
2302                         raise EventcalError('invalid_recur_until')
2303                         
2304                 else:
2305                     recur_until = ''
2306             
2307         else:
2308             raise EventcalError('invalid_recur')
2309                     
2310     else:
2311         recur_freq = 0
2312         recur_type = ''
2313         recur_until = ''
2314         
2315     # check validity of each fields
2316     
2317     if (starttime or endtime):
2318         if not endtime:
2319             endtime = starttime
2320         elif not starttime:
2321             raise EventcalError('need_starttime')
2322             
2323 
2324     # if no time, it's 1-day event
2325     if not enddate:
2326         enddate = startdate
2327     
2328     try:
2329         syear, smonth, sday = getdatefield(startdate)
2330     except (TypeError, ValueError):
2331         raise EventcalError('invalid_startdate')
2332 
2333     try:
2334         eyear, emonth, eday = getdatefield(enddate)
2335     except (TypeError, ValueError):
2336         raise EventcalError('invalid_enddate')
2337     
2338     if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
2339         raise EventcalError('enddate_precede')
2340     
2341     # format date
2342     startdate = formatDate(syear, smonth, sday)
2343     enddate = formatDate(eyear, emonth, eday)
2344     
2345     if (starttime and endtime):
2346         try:
2347             shour, smin = gettimefield(starttime)
2348         except (TypeError, ValueError):
2349             raise EventcalError('invalid_starttime')
2350         
2351         try:
2352             ehour, emin = gettimefield(endtime)
2353         except (TypeError, ValueError):
2354             raise EventcalError('invalid_endtime')
2355         
2356         if startdate == enddate:
2357             if datetime.time(shour, smin) > datetime.time(ehour, emin):
2358                 raise EventcalError('endtime_precede')
2359                 
2360         # format time
2361         starttime = u'%02d%02d' %(shour, smin)
2362         endtime = u'%02d%02d' %(ehour, emin)
2363     
2364     # check recurrent data
2365     event_len = diffday(startdate, enddate)
2366     if recur_freq:
2367         
2368         if recur_type == 'day':
2369             if event_len > int(recur_freq):
2370                 raise EventcalError('len_recur_int')
2371         
2372         elif recur_type == 'week':
2373             if event_len > int(recur_freq) * 7:
2374                 raise EventcalError('len_recur_int')
2375         
2376         elif recur_type == 'weekday':
2377             if event_len > 25:
2378                 raise EventcalError('len_recur_int')
2379         
2380         elif recur_type == 'month':
2381             if event_len > int(recur_freq) * 25:
2382                 raise EventcalError('len_recur_int')
2383         
2384         elif recur_type == 'year':
2385             if event_len > int(recur_freq) * 365:
2386                 raise EventcalError('len_recur_int')
2387         
2388         if recur_until:
2389             try:
2390                 ryear, rmonth, rday = getdatefield(recur_until)
2391             except (TypeError, ValueError):
2392                 raise EventcalError('invalid_recur_until')
2393             
2394             recur_until = formatDate(ryear, rmonth, rday)
2395             
2396             if int(recur_until) < int(enddate):
2397                 raise EventcalError('recur_until_precede')
2398     
2399     return startdate, starttime, enddate, endtime, bgcolor, label, description, recur_freq, recur_type, recur_until
2400 
2401 
2402 
2403 def converttext(targettext):
2404     # Converts some special characters of html to plain-text style
2405     # What else to handle?
2406 
2407     targettext = targettext.replace(u'&', '&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.