Attachment 'EventCalendar-easytime2.py'

Download

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

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] (2006-02-25 08:59:09, 2.8 KB) [[attachment:EventCalendar-easytime.patch]]
  • [get | view] (2006-02-25 09:30:01, 2.9 KB) [[attachment:EventCalendar-easytime2.patch]]
  • [get | view] (2006-02-25 09:30:39, 74.9 KB) [[attachment:EventCalendar-easytime2.py]]
 All files | Selected Files: delete move to page copy to page

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