Attachment 'EventCalendar-094-easytime.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<meridian_p>[pP][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_meridian_p = match.group('meridian_p')
 521         
 522     else:
 523         raise ValueError
 524     
 525     int_hour = int(str_hour)
 526     
 527     # convert to 24 hour format
 528     if int_hour == 12:
 529         int_hour = 0
 530 	
 531     # check for pm
 532     if str_meridian_p:
 533         int_hour = int_hour + 12
 534     
 535     #handle null minutes
 536     try:
 537         int_min = int(str_min)
 538     except (TypeError, ValueError):
 539         int_min = 0
 540     
 541     # It raises exception if the input date is incorrect
 542     temp = datetime.time(int_hour, int_min)
 543 
 544     return temp.hour, temp.minute
 545 
 546 
 547 def gettodaydate():
 548     today = Globs.today
 549     return today.year, today.month, today.day    
 550 
 551 
 552 def cal_listhead():
 553 
 554     html = [
 555         u'  <tr>',
 556         u'      <td class="list_head">Title</td>',
 557         u'      <td class="list_head">Start Date</td>',
 558         u'      <td class="list_head">End Date</td>',
 559         u'      <td class="list_head">Recurrence</td>',
 560         u'      <td class="list_head">Description</td>',
 561         u'      <td class="list_head">Reference</td>',
 562         u'  </tr>',
 563         ]
 564         
 565     return u'\r\n'.join(html)
 566 
 567 
 568 def showeventlist(form_vals):
 569     
 570     debug('Show Calendar: List view')
 571     
 572     request = Globs.request
 573     formatter = Globs.formatter
 574     
 575     html_event_rows = []
 576     html_list_header = cal_listhead()
 577     
 578     # read all the events
 579     events, cal_events = loadEvents()
 580     
 581     # sort events
 582     sorted_eventids = events.keys()
 583     sorted_eventids.sort(cmp=lambda x,y: cmp(events[x]['startdate'], events[y]['startdate']))
 584     
 585     for eid in sorted_eventids:
 586         if not events[eid]['clone']:
 587             html_event_rows.append( listshow_event(events[eid], form_vals) )
 588     
 589     html_event_rows = u'\r\n'.join(html_event_rows)
 590     
 591     html_list_table = [
 592         u'\r\n<div id="eventlist">',
 593         u'<table class="eventlist">',
 594         u'%s' % html_list_header,
 595         u'%s' % html_event_rows,
 596         u'</table>',
 597         u'</div>',
 598         ]
 599     html_list_table = u'\r\n'.join(html_list_table)
 600         
 601     return html_list_table
 602 
 603 
 604 def listshow_event(event, form_vals):
 605     
 606     if event['recur_freq']:
 607         recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type'])
 608         if event['recur_until']:
 609              recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until']))
 610     else:
 611         recur_desc = ''
 612 
 613     html = [
 614         u'  <tr>',
 615         u'  <td class="list_entry">%s</td>' % converttext(event['title']),
 616         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']),
 617         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']),
 618         u'  <td class="list_entry">%s</td>' % recur_desc,
 619         u'  <td class="list_entry">%s</td>' % converttext(event['description']),
 620         u'  <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'),
 621         u'  </tr>',
 622         ]
 623     
 624     return u'\r\n'.join(html)
 625 
 626 
 627 def showupcomingeventlist(form_vals):
 628     
 629     debug('Show Calendar: Upcoming Event View')
 630     
 631     request = Globs.request
 632     formatter = Globs.formatter
 633     
 634     html_event_rows = []
 635     html_list_header = cal_listhead()
 636     
 637     year, month, day = gettodaydate()
 638     day_delta = datetime.timedelta(days=Params.upcomingrange)
 639     cur_date = datetime.date(year, month, day)
 640     next_range = cur_date + day_delta
 641     
 642     # set ranges of events
 643     datefrom = u'%04d%02d%02d' % (year, month, day)
 644     dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day)
 645     
 646     # read all the events (no cache)
 647     events, cal_events = loadEvents(datefrom, dateto, 1)
 648     
 649     datefrom = u'%04d-%02d-%02d' % (year, month, day)
 650     dateto = u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day)
 651     
 652     # sort events
 653     sorted_eventids = events.keys()
 654     sorted_eventids.sort(cmp=lambda x,y: cmp(events[x]['startdate'], events[y]['startdate']))
 655     
 656     for eid in sorted_eventids:
 657         html_event_rows.append( listshow_event(events[eid], form_vals) )
 658     
 659     html_event_rows = u'\r\n'.join(html_event_rows)
 660     
 661     html_list_table = [
 662         u'\r\n<div id="eventlist">',
 663         u'<table class="eventlist">',
 664         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),
 665         u'%s' % html_list_header,
 666         u'%s' % html_event_rows,
 667         u'</table>',
 668         u'</div>',
 669         ]
 670     html_list_table = u'\r\n'.join(html_list_table)
 671         
 672     return html_list_table
 673 
 674 
 675 
 676 
 677 def showcalendar(form_vals):
 678     
 679     request = Globs.request
 680     formatter = Globs.formatter
 681     
 682     if form_vals.has_key('caldate'):
 683         try:
 684             year, month, str_temp = getdatefield(form_vals['caldate'])
 685         except (TypeError, ValueError):
 686             debug('Invalid target date: e.g., "200510"')
 687             year, month, dy = gettodaydate()
 688     elif Params.curdate:
 689         try:
 690             year, month, str_temp = getdatefield(Params.curdate)
 691         except (TypeError, ValueError):
 692             debug('Invalid target date: e.g., "200510"')
 693             year, month, dy = gettodaydate()
 694             
 695     else:
 696         year, month, dy = gettodaydate()
 697     
 698     html = showeventcalendar(year, month)
 699     
 700     return u''.join(html)
 701 
 702 
 703 
 704     
 705 def showsimplecalendar(form_vals):
 706     
 707     request = Globs.request
 708     formatter = Globs.formatter
 709     
 710     if form_vals.has_key('caldate'):
 711         try:
 712             year, month, str_temp = getdatefield(form_vals['caldate'])
 713         except (TypeError, ValueError):
 714             debug('Invalid target date: e.g., "200510"')
 715             year, month, dy = gettodaydate()
 716     elif Params.curdate:
 717         try:
 718             year, month, str_temp = getdatefield(Params.curdate)
 719         except (TypeError, ValueError):
 720             debug('Invalid target date: e.g., "200510"')
 721             year, month, dy = gettodaydate()
 722     else:
 723         year, month, dy = gettodaydate()
 724     
 725     html = showsimpleeventcalendar(year, month)
 726     
 727     return u''.join(html)
 728 
 729 
 730 
 731 # sort events in cal_events by length of days of the event
 732 def comp_cal_events(xid, yid):
 733     events = Globs.events
 734     
 735     if events[xid]['date_len'] > events[yid]['date_len']:
 736         return -1
 737     elif events[xid]['date_len'] == events[yid]['date_len']:
 738         if events[xid]['date_len'] == 1:
 739             return cmp(events[xid]['starttime'], events[yid]['starttime'])
 740         else:
 741             return 0
 742     else:
 743         return 1
 744 
 745 
 746 # load events from wiki pages
 747 def loadEvents(datefrom='', dateto='', nocache=0):
 748     
 749     request = Globs.request
 750     
 751     debug('Loading event information.')
 752     
 753     events = {}
 754     cal_events = {}
 755     raw_events = loadEventsFromWikiPages()
 756     
 757     # handling cal_events
 758     if datefrom or dateto:
 759         
 760         # cache configurations
 761         arena = Page(request, Globs.pagename)
 762         eventkey = 'events'
 763         filteredeventkey = 'events_%s-%s' % (datefrom, dateto)
 764         caleventkey = 'calevents_%s-%s' % (datefrom, dateto)
 765         
 766         cache_events = caching.CacheEntry(request, arena, eventkey)
 767         cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey)
 768         cache_calevents = caching.CacheEntry(request, arena, caleventkey)
 769         
 770         dirty = 1
 771         
 772         debug('Checking cal_events cache')
 773         
 774         if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())):
 775         
 776             try:
 777                 events = pickle.loads(cache_filteredevents.content())
 778                 cal_events = pickle.loads(cache_calevents.content())
 779                 debug('Cached event (filtered) information is used: total %d events' % len(events))
 780                 dirty = 0
 781             except (pickle.UnpicklingError, IOError, EOFError, ValueError):
 782                 debug('Picke error at fetching cached events (filtered)')
 783                 events = {}
 784                 cal_events = {}
 785 
 786 
 787         # if cache is dirty, update the cache
 788         if dirty:
 789         
 790             debug('Checking event cache: it\'s dirty or requested to refresh')
 791             debug('Building new cal_event information')
 792         
 793             try:
 794                 datefrom, dateto = int(datefrom), int(dateto)
 795             except (TypeError, ValueError):
 796                 datefrom, dateto = 0, 0
 797         
 798             clone_num = 0
 799             
 800             for e_id in raw_events.keys():
 801                 
 802                 cur_event = raw_events[e_id]
 803                 
 804                 # handling event recurrence
 805                 recur_freq = cur_event['recur_freq']
 806                 
 807                 if recur_freq:
 808                     
 809                     if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto:
 810 
 811                         if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
 812                             # generating cal_events for iteself
 813                             events[e_id] = cur_event.copy()
 814                             insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
 815                         
 816                         delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 )
 817                         
 818                         if cur_event['recur_type'] == 'day':
 819                         
 820                             day_delta = int(recur_freq)
 821                             startdate = getdatetimefromstring(cur_event['startdate'])
 822                             datefrom_date = getdatetimefromstring(datefrom)
 823                             
 824                             if int(datefrom) > int(cur_event['startdate']):
 825                                 diffs = datefrom_date - startdate
 826                                 q_delta = diffs.days / day_delta
 827                                 if diffs.days % day_delta > 0:
 828                                     q_delta += 1
 829                             else:
 830                                 q_delta = 1
 831                             
 832                             while 1:
 833                                 
 834                                 if q_delta == 0:
 835                                     q_delta += 1
 836                                     continue
 837                                 
 838                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
 839                                 recurred_enddate = recurred_startdate + delta_date_len
 840                                 
 841                                 new_startdate = formatdateobject(recurred_startdate)
 842                                 new_enddate = formatdateobject(recurred_enddate)
 843                                 
 844                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
 845                                     break
 846                                 
 847                                 clone_num += 1
 848                                 clone_id = 'c%d' % clone_num
 849                                 
 850                                 events[clone_id] = cur_event.copy()
 851                                 events[clone_id]['id'] = clone_id
 852                                 events[clone_id]['startdate'] = new_startdate
 853                                 events[clone_id]['enddate'] = new_enddate
 854                                 events[clone_id]['clone'] = 1
 855                                 
 856                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
 857                                 
 858                                 q_delta += 1
 859                         
 860                         elif cur_event['recur_type'] == 'week':
 861                             
 862                             day_delta = int(recur_freq) * 7
 863                             
 864                             startdate = getdatetimefromstring(cur_event['startdate'])
 865                             datefrom_date = getdatetimefromstring(datefrom)
 866                             
 867                             if int(datefrom) > int(cur_event['startdate']):
 868                                 diffs = datefrom_date - startdate
 869                                 q_delta = diffs.days / day_delta
 870                                 if diffs.days % day_delta > 0:
 871                                     q_delta += 1
 872                             else:
 873                                 q_delta = 1
 874                             
 875                             while 1:
 876                                 
 877                                 if q_delta == 0:
 878                                     q_delta += 1
 879                                     continue
 880                                 
 881                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
 882                                 recurred_enddate = recurred_startdate + delta_date_len
 883                                 
 884                                 new_startdate = formatdateobject(recurred_startdate)
 885                                 new_enddate = formatdateobject(recurred_enddate)
 886                                 
 887                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
 888                                     break
 889                                 
 890                                 clone_num += 1
 891                                 clone_id = 'c%d' % clone_num
 892                                 
 893                                 events[clone_id] = cur_event.copy()
 894                                 events[clone_id]['id'] = clone_id
 895                                 events[clone_id]['startdate'] = new_startdate
 896                                 events[clone_id]['enddate'] = new_enddate
 897                                 events[clone_id]['clone'] = 1
 898                                 
 899                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
 900                                 
 901                                 q_delta += 1
 902                         
 903                         
 904                         elif cur_event['recur_type'] == 'weekday':
 905                             
 906                             syear, smonth, sday = getdatefield(cur_event['startdate'])
 907                             cyear, cmonth, cday = getdatefield(str(datefrom))
 908                             
 909                             recur_weekday = calendar.weekday(syear, smonth, sday)
 910                             
 911                             
 912                             while 1:
 913                                 
 914                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
 915                                 firstmatch = (recur_weekday - firstweekday) % 7 + 1
 916                                 
 917                                 #XXX should handle error
 918                                 try:
 919                                     therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1]
 920                                 except IndexError:
 921                                     therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
 922                                 
 923                                 recurred_startdate = datetime.date(cyear, cmonth, therecur_day)
 924                                 recurred_enddate = recurred_startdate + delta_date_len
 925                                 
 926                                 new_startdate = formatdateobject(recurred_startdate)
 927                                 new_enddate = formatdateobject(recurred_enddate)
 928                                 
 929                                 if int(new_startdate) < int(datefrom):
 930                                     cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
 931                                     continue
 932                                 
 933                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
 934                                     break
 935                                 
 936                                 clone_num += 1
 937                                 clone_id = 'c%d' % clone_num
 938                                 
 939                                 events[clone_id] = cur_event.copy()
 940                                 events[clone_id]['id'] = clone_id
 941                                 events[clone_id]['startdate'] = new_startdate
 942                                 events[clone_id]['enddate'] = new_enddate
 943                                 events[clone_id]['clone'] = 1
 944     
 945                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
 946                                 
 947                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
 948                                 
 949                         
 950                         elif cur_event['recur_type'] == 'month':
 951                             
 952                             cyear, cmonth, therecurday = getdatefield(cur_event['startdate'])
 953                             
 954                             while 1:
 955                                 
 956                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq)
 957                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
 958                                 recur_day = therecurday 
 959                                 if daysinmonth < recur_day:
 960                                     recur_day = daysinmonth
 961                                 new_startdate = formatDate(cyear, cmonth, recur_day)
 962                                 
 963                                 if int(new_startdate) < int(datefrom):
 964                                     continue
 965                                 
 966                                 recurred_startdate = datetime.date(cyear, cmonth, recur_day)
 967                                 recurred_enddate = recurred_startdate + delta_date_len
 968                                 
 969                                 new_startdate = formatdateobject(recurred_startdate)
 970                                 new_enddate = formatdateobject(recurred_enddate)
 971                                 
 972                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
 973                                     break
 974                                 
 975                                 clone_num += 1
 976                                 clone_id = 'c%d' % clone_num
 977                                 
 978                                 events[clone_id] = cur_event.copy()
 979                                 events[clone_id]['id'] = clone_id
 980                                 events[clone_id]['startdate'] = new_startdate
 981                                 events[clone_id]['enddate'] = new_enddate
 982                                 events[clone_id]['clone'] = 1
 983     
 984                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
 985                         
 986                         elif cur_event['recur_type'] == 'year':
 987                             
 988                             ryear, rmonth, rday = getdatefield(cur_event['startdate'])
 989                             cyear, cmonth, cday = getdatefield(str(datefrom))
 990                             
 991                             while 1:
 992                                 
 993                                 ryear += recur_freq
 994                                 new_startdate = formatDate(ryear, rmonth, rday)
 995                                 
 996                                 if int(new_startdate) < int(datefrom):
 997                                     continue
 998                                     
 999                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1000                                     break
1001                                 
1002                                 recurred_startdate = datetime.date(ryear, rmonth, rday)
1003                                 recurred_enddate = recurred_startdate + delta_date_len
1004                                 
1005                                 new_startdate = formatdateobject(recurred_startdate)
1006                                 new_enddate = formatdateobject(recurred_enddate)
1007                                 
1008                                 clone_num += 1
1009                                 clone_id = 'c%d' % clone_num
1010                                 
1011                                 events[clone_id] = cur_event.copy()
1012                                 events[clone_id]['id'] = clone_id
1013                                 events[clone_id]['startdate'] = new_startdate
1014                                 events[clone_id]['enddate'] = new_enddate
1015                                 events[clone_id]['clone'] = 1
1016     
1017                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1018                 
1019                 else:
1020                     
1021                     if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1022                         events[e_id] = cur_event.copy()
1023                         insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1024             
1025             # sort cal_events
1026             # store event list into global variables in order to sort them
1027             Globs.events = events
1028         
1029             for eachdate in cal_events.keys():
1030                 cal_events[eachdate].sort(comp_cal_events)
1031             
1032             # cache update
1033             if not nocache:
1034                 cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL))
1035                 cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL))
1036         
1037     else:
1038         events = raw_events
1039 
1040     debug(u'Total %d of events are loaded finally.' % len(events))
1041     
1042     #debug('Events:')
1043     #for key in events.keys():
1044     #    debug('__ %s' % events[key])
1045     
1046     return events, cal_events
1047 
1048 
1049 
1050 def loadEventsFromWikiPages():
1051     
1052     events = {}
1053     
1054     eventrecord_list = []
1055     eventpages = []
1056     
1057     request = Globs.request
1058     category = Params.category
1059     
1060     # cache configurations
1061     arena = Page(request, Globs.pagename)
1062     eventkey = 'events'
1063     pagelistkey = 'eventpages'
1064     
1065     cache_events = caching.CacheEntry(request, arena, eventkey)
1066     cache_pages = caching.CacheEntry(request, arena, pagelistkey)
1067     
1068     
1069     # page list cache
1070 
1071     debug('Checking page list cache')
1072     
1073     # check the time at which page list cache has been created
1074     
1075     cp_mtime = cache_pages.mtime()
1076     timedelta_days = 9999
1077     
1078     if cp_mtime:
1079         cp_date = datetime.datetime.fromtimestamp(cp_mtime)
1080         today = datetime.datetime.fromtimestamp(time.time())
1081         datediff = today - cp_date
1082         timedelta_days = datediff.days
1083         debug('Time from page list cache built = %s' % datediff)
1084 
1085     
1086     if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1:
1087         categorypages = searchPages(request, category)
1088         for page in categorypages:
1089             eventpages.append(page.page_name)
1090         cache_pages.update('\n'.join(eventpages), True)
1091         debug('New page list is built: %d pages' % len(eventpages))
1092     else:
1093         eventpages = cache_pages.content(True).split('\n')
1094         debug('Cached page list is used: %d pages' % len(eventpages))
1095     
1096 
1097     # generating events
1098     
1099     e_num = 0
1100     dirty = 0
1101     debug_records = {}
1102     
1103     # fetch event records from each page in the category
1104     for page_name in eventpages:
1105         
1106         p = Page(request, page_name)
1107         e_ref = page_name
1108         
1109         eventrecordkey = 'eventrecords'
1110         cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey)
1111         
1112         if cache_eventrecords.needsUpdate(p._text_filename()) or Globs.page_action == 'refresh':
1113             dirty = 1
1114             page_content = p.get_raw_body()
1115             eventrecords, e_num = getEventRecordFromPage(page_content, e_ref, e_num)
1116             debug_records[e_ref] = '%d eventrecords are fetched from %s' % (len(eventrecords), e_ref)
1117             cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1118         else:
1119             try:
1120                 eventrecords = pickle.loads(cache_eventrecords.content())
1121                 debug_records[e_ref] = '%d cached eventrecords are used from %s' % (len(eventrecords), e_ref)
1122             except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1123                 dirty = 1
1124                 page_content = p.get_raw_body()
1125                 eventrecords, e_num = getEventRecordFromPage(page_content, e_ref, e_num)
1126                 debug_records[e_ref] = '%d eventrecords are fetched from %s due to pickle error' % (len(eventrecords), e_ref)
1127                 cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1128 
1129         eventrecord_list.append(eventrecords)
1130 
1131     # if no dirty, just fetch the cache
1132     if not (dirty or Globs.page_action == 'refresh'):
1133         
1134         debug('Checking event cache: still valid')
1135         
1136         try:
1137             events = pickle.loads(cache_events.content())
1138             debug('Cached event information is used: total %d events' % len(events))
1139         except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1140             debug('Picke error at fetching cached events')
1141             events = {}
1142 
1143     else:
1144         
1145         debug('Checking event cache: it\'s dirty or requested to refresh')
1146     
1147     # if there is no events (if it needs refreshed), generate events dictionary
1148     if not len(events.keys()):
1149 
1150         # XXX: just debugging
1151         debug('Bulding new event information')
1152         for page_name in eventpages:
1153             debug(debug_records[page_name])
1154 
1155             
1156         day_delta = datetime.timedelta(days=1)
1157         
1158         for eventrecords in eventrecord_list:
1159         
1160             for evtrecord in eventrecords:
1161                 
1162                 e_id = evtrecord['id']
1163                 
1164                 # generating events
1165                 events[e_id] = evtrecord
1166                 #debug('event %s: %s' % (evtrecord['id'], evtrecord))
1167 
1168         # after generating updated events, update the cache
1169         cache_events.update(pickle.dumps(events, PICKLE_PROTOCOL))
1170         
1171         debug('Event information is newly built: total %d events' % len(events))
1172 
1173     # end of updating events block    
1174     
1175     
1176     return events
1177     
1178 
1179 
1180 def getEventRecordFromPage(pagecontent, referpage, e_num):
1181     
1182     request = Globs.request
1183     
1184     eventrecords = []
1185     page_bgcolor = ''
1186     page_description = ''
1187     
1188     # fetch the page default bgcolor
1189     regex_page_bgcolor = r"""
1190 ^\s+default_bgcolor::\s*
1191 (?P<pagebgcolor>\#[0-9a-fA-F]{6})
1192 \s*
1193 $
1194 """
1195 
1196     pattern = re.compile(regex_page_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1197     match = pattern.search(pagecontent)
1198         
1199     if match:
1200         page_bgcolor = match.group('pagebgcolor')
1201 
1202     # fetch the page default description
1203     regex_page_description = r"""
1204 ^\s+default_description::\s*
1205 (?P<pagedescription>.*?)
1206 $
1207 """
1208    
1209     pattern = re.compile(regex_page_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1210     match = pattern.search(pagecontent)
1211         
1212     if match:
1213         page_description = match.group('pagedescription')
1214     
1215 
1216     # fetch event item
1217     regex_eventitem = r"""
1218 (?P<eventitem>
1219 	(?P<heading>^\s*(?P<hmarker>=+)\s(?P<eventtitle>.*?)\s(?P=hmarker) $)
1220 	(?P<eventdetail>.*?
1221 		(?=
1222 			^\s*(?P<nexthmarker>=+)\s(?P<nexteventtitle>.*?)\s(?P=nexthmarker) $
1223 			| \Z
1224         )
1225 	)
1226 )
1227 """
1228     
1229     pattern = re.compile(regex_eventitem, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1230     match = pattern.findall(pagecontent)
1231         
1232     if match:
1233         
1234         for matchitem in match:
1235             
1236             eventitem = {}
1237             
1238             eventtitle = matchitem[3]
1239             eventdetail = matchitem[4]
1240             
1241             try:
1242                 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)
1243             except (TypeError, ValueError):
1244                 #debug('An event data is corrupted: invalid event format')
1245                 continue
1246             
1247             # set default values
1248             if not e_bgcolor:
1249                 e_bgcolor = page_bgcolor
1250                 
1251             if not e_description:
1252                 e_description = page_description
1253             
1254             e_num += 1
1255             e_id = 'e%d' % e_num
1256             
1257             eventitem['id'] = e_id
1258             eventitem['title'] = eventtitle
1259             eventitem['startdate'] = e_start_date
1260             eventitem['starttime'] = e_start_time
1261             eventitem['enddate'] = e_end_date
1262             eventitem['endtime'] = e_end_time
1263             eventitem['title'] = eventtitle
1264             eventitem['refer'] = referpage
1265             eventitem['bgcolor'] = e_bgcolor
1266             eventitem['description'] = e_description
1267             eventitem['recur_freq'] = e_recur_freq
1268             eventitem['recur_type'] = e_recur_type
1269             eventitem['recur_until'] = e_recur_until
1270             
1271             eventitem['date_len'] = diffday(e_start_date, e_end_date) + 1
1272             eventitem['clone'] = 0
1273             eventitem['hid'] = getheadingid(request, referpage, eventtitle)
1274             
1275             eventrecords.append(eventitem)
1276 
1277     #debug('matched records: %d' % len(match))
1278 
1279     return eventrecords, e_num
1280     
1281 
1282 
1283 def geteventfield(detail):
1284     
1285     regex_startdate = r"""
1286 ^\s+start::\s*
1287 (?P<startdate>\d{4}[/-]\d{2}[/-]\d{2})
1288 \s*
1289 (?P<starttime>\d{1,2}[:]?\d{0,2}([AP][M]?)?)*
1290 \s*
1291 $
1292 """
1293 
1294     regex_enddate = r"""
1295 ^\s+end::\s*
1296 (?P<enddate>\d{4}[/-]\d{2}[/-]\d{2})*
1297 \s*
1298 (?P<endtime>\d{1,2}[:]?\d{0,2}([AP][M]?)?)*
1299 \s*
1300 $
1301 """
1302 
1303     regex_bgcolor = r"""
1304 ^\s+bgcolor::\s*
1305 (?P<bgcolor>\#[0-9a-fA-F]{6})
1306 \s*
1307 $
1308 """
1309 
1310     regex_description = r"""
1311 ^\s+description::\s*
1312 (?P<description>.*?)
1313 $
1314 """
1315 
1316     regex_recur = r"""
1317 ^\s+recur::\s*
1318 (?P<recur_freq>\d+)
1319 \s*
1320 (?P<recur_type>day|week|weekday|month|year)
1321 \s*
1322 (
1323 	until
1324 	\s*
1325 	(?P<recur_until>\d{4}[/-]\d{2}[/-]\d{2})
1326 )*
1327 $
1328 """
1329 
1330     # need help on regular expressions for more efficient/flexible form
1331     
1332     # compile regular expression objects
1333     
1334     pattern_startdate = re.compile(regex_startdate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1335     pattern_enddate = re.compile(regex_enddate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1336     pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1337     pattern_description = re.compile(regex_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1338     pattern_recur = re.compile(regex_recur, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1339     
1340     ##################### retrieve startdate
1341     match = pattern_startdate.search(detail)
1342     
1343     if match:
1344         startdate = match.group('startdate')
1345         starttime = match.group('starttime')
1346     else:
1347         startdate = ''
1348         starttime = '' 
1349     
1350     ##################### retrieve enddate
1351     match = pattern_enddate.search(detail)
1352     
1353     if match:
1354         enddate = match.group('enddate')
1355         endtime = match.group('endtime')
1356     else:
1357         enddate = ''
1358         endtime = ''
1359 
1360     ##################### retrieve bgcolor
1361     match = pattern_bgcolor.search(detail)
1362     
1363     if match:
1364         bgcolor = match.group('bgcolor')
1365     else:
1366         bgcolor = ''
1367         
1368     ##################### retrieve description
1369     match = pattern_description.search(detail)
1370     
1371     if match:
1372         description = match.group('description')
1373     else:
1374         description = ''
1375         
1376     ##################### retrieve recurrence
1377     match = pattern_recur.search(detail)
1378     
1379     if match:
1380         recur_freq = int(match.group('recur_freq'))
1381         recur_type = match.group('recur_type')
1382         recur_until = match.group('recur_until')
1383         
1384     else:
1385         recur_freq = 0
1386         recur_type = ''
1387         recur_until = ''
1388         
1389 
1390     # check validity of each fields
1391 
1392     if not startdate:
1393         #debug('start date is not specified')
1394         # self.printoutput('Parse Error', msg, '')
1395         # ERROR
1396         return '','','','','','','','','',''
1397     
1398     if (endtime) and not (starttime):
1399         #debug('endtime without starttime')
1400         # ERROR
1401         return '','','','','','','','','',''
1402 
1403     # if no time, it's 1-day event
1404     if not enddate:
1405         enddate = startdate
1406     
1407     try:
1408         syear, smonth, sday = getdatefield(startdate)
1409         eyear, emonth, eday = getdatefield(enddate)
1410     except (TypeError, ValueError):
1411         #debug('invalid date format: %s, %s' % (startdate, enddate))
1412         return '','','','','','','','','',''
1413     
1414     if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
1415         #debug('startdate should precede enddate')
1416         return '','','','','','','','','',''
1417     
1418     # format date
1419     startdate = formatDate(syear, smonth, sday)
1420     enddate = formatDate(eyear, emonth, eday)
1421     
1422     if (starttime and endtime):
1423         try:
1424             shour, smin = gettimefield(starttime)
1425             ehour, emin = gettimefield(endtime)
1426         except (TypeError, ValueError):
1427             #debug('invalid time format: %s, %s' % (startdate, enddate))
1428             return '','','','','','','','','',''
1429         
1430         if startdate == enddate:
1431             if datetime.time(shour, smin) > datetime.time(ehour, emin):
1432                 #debug('starttime should precede endtime')
1433                 return '','','','','','','','','',''
1434                 
1435         # format time
1436         starttime = u'%02d%02d' %(shour, smin)
1437         endtime = u'%02d%02d' %(ehour, emin)
1438     elif (starttime):
1439         try:
1440             shour, smin = gettimefield(starttime)
1441         except (TypeError, ValueError):
1442             #debug('invalid time format: %s, %s' % (startdate, enddate))
1443             return '','','','','','','','','',''
1444 
1445         starttime = u'%02d%02d' %(shour, smin)
1446         endtime = u''
1447     
1448     # check recurrent data
1449     event_len = diffday(startdate, enddate)
1450     if recur_freq:
1451         
1452         if recur_type == 'day':
1453             if event_len > int(recur_freq):
1454                 debug('event length should be smaller than recurrence interval')
1455                 return '','','','','','','','','',''
1456         
1457         elif recur_type == 'week':
1458             if event_len > int(recur_freq) * 7:
1459                 debug('event length should be smaller than recurrence interval')
1460                 return '','','','','','','','','',''
1461         
1462         elif recur_type == 'weekday':
1463             if event_len > 25:
1464                 debug('event length should be smaller than recurrence interval')
1465                 return '','','','','','','','','',''
1466         
1467         elif recur_type == 'month':
1468             if event_len > int(recur_freq) * 25:
1469                 debug('event length should be smaller than recurrence interval')
1470                 return '','','','','','','','','',''
1471         
1472         elif recur_type == 'year':
1473             if event_len > int(recur_freq) * 365:
1474                 debug('event length should be smaller than recurrence interval')
1475                 return '','','','','','','','','',''
1476         
1477         if recur_until:
1478             try:
1479                 ryear, rmonth, rday = getdatefield(recur_until)
1480             except (TypeError, ValueError):
1481                 debug('invalid date format: %s' % recur_until)
1482                 return '','','','','','','','','',''
1483             
1484             recur_until = formatDate(ryear, rmonth, rday)
1485             
1486             if int(recur_until) < int(enddate):
1487                 debug('recur_until should precede enddate')
1488                 return '','','','','','','','','',''
1489 
1490     
1491     return startdate, starttime, enddate, endtime, bgcolor, description, recur_freq, recur_type, recur_until
1492 
1493 
1494 
1495 def converttext(targettext):
1496     # Converts some special characters of html to plain-text style
1497     # What else to handle?
1498 
1499     targettext = targettext.replace(u'&', '&amp')
1500     targettext = targettext.replace(u'>', '&gt;')
1501     targettext = targettext.replace(u'<', '&lt;')
1502     targettext = targettext.replace(u'\n', '<br>')
1503     targettext = targettext.replace(u'"', '&quot;')
1504     targettext = targettext.replace(u'\t', '&nbsp;&nbsp;&nbsp;&nbsp')
1505     targettext = targettext.replace(u'  ', '&nbsp;&nbsp;')
1506         
1507     return targettext
1508 
1509 
1510 # monthly view
1511 def showeventcalendar(year, month):
1512     
1513     debug('Show Calendar: Monthly View')
1514     
1515     request = Globs.request
1516     formatter = Globs.formatter
1517     _ = request.getText
1518     
1519     wkend = Globs.wkend
1520     months= Globs.months
1521     wkdays = Globs.wkdays
1522     
1523     # get the calendar
1524     monthcal = calendar.monthcalendar(year, month)
1525 
1526     # shows current year & month
1527     html_header_curyearmonth = calhead_yearmonth(year, month, 'head_yearmonth')
1528     
1529     r7 = range(7)
1530     
1531     # shows header of week days
1532     html_header_weekdays = []
1533     
1534     for wkday in r7:
1535         wday = _(wkdays[wkday])
1536         html_header_weekdays.append( calhead_weekday(wday, 'head_weekday') )
1537     html_header_weekdays = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
1538  
1539     # pending events for next row
1540     next_pending = []
1541     
1542     # gets previous, next month
1543     day_delta = datetime.timedelta(days=-1)
1544     cur_month = datetime.date(year, month, 1)
1545     prev_month = cur_month + day_delta
1546     
1547     day_delta = datetime.timedelta(days=15)
1548     cur_month_end = datetime.date(year, month, 25)
1549     next_month = cur_month_end + day_delta
1550     
1551     prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
1552     next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
1553     
1554     # shows days
1555     html_week_rows = []
1556     
1557     # set ranges of events
1558     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
1559     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
1560     
1561     # read all the events
1562     events, cal_events = loadEvents(datefrom, dateto)
1563     
1564     #debug(u'  events: %s' % events)
1565     #debug(u'  cal_events: %s' % cal_events)
1566     
1567     for week in monthcal:
1568         
1569         # day head rows
1570         html_headday_cols = []
1571         html_events_rows = []
1572         
1573         for wkday in r7:
1574              
1575             day = week[wkday]
1576             
1577             if not day:
1578                 if week == monthcal[0]:
1579                     nb_day = prev_monthcal[-1][wkday]
1580                 else:
1581                     nb_day = next_monthcal[0][wkday]
1582                     
1583                 html_headday_cols.append( calhead_day_nbmonth(nb_day) )
1584             else:
1585                 html_headday_cols.append( calhead_day(year, month, day, wkday) )
1586         
1587         html_headday_row = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
1588         html_week_rows.append(html_headday_row)
1589         
1590         # dummy rows
1591         html_headdummy_cols = []
1592         
1593         for wkday in r7:
1594             day = week[wkday]
1595             if not day:
1596                 html_headdummy_cols.append( calshow_blankbox('head_dummy_nbmonth') )
1597             else:
1598                 html_headdummy_cols.append( calshow_blankbox('head_dummy') )
1599         
1600         html_headdummy_cols = u'\r\n'.join(html_headdummy_cols)
1601         html_week_rows.append(' <tr>\r\n%s </tr>\r\n' % html_headdummy_cols)
1602         
1603         # pending events for next row
1604         pending = next_pending
1605         next_pending = []
1606         
1607         # show events
1608         while 1: 
1609             event_left = 7
1610             colspan = -1
1611             html_events_cols = []
1612 
1613             for wkday in r7:
1614              
1615                 day = week[wkday]
1616                 
1617                 if not day:
1618                     if week == monthcal[0]:
1619                         cur_date = formatDate(prev_month.year, prev_month.month, prev_monthcal[-1][wkday])
1620                     else:
1621                         cur_date = formatDate(next_month.year, next_month.month, next_monthcal[0][wkday])
1622                 else:
1623                     cur_date = formatDate(year, month, day)
1624 
1625                 # if an event is already displayed with colspan
1626                 if colspan > 0:
1627                     colspan -= 1
1628                     if cal_events.has_key(cur_date) and lastevent in cal_events[cur_date]:
1629                         cal_events[cur_date].remove(lastevent)
1630                     
1631                     continue
1632                     
1633                 # if there is any event for this date
1634                 if cal_events.has_key(cur_date):
1635                     if len(cal_events[cur_date]) > 0:
1636                         
1637                         # if there is any pending event in the previous week
1638                         if wkday == 0 and len(pending) > 0:
1639                             todo_event_id = pending.pop(0)
1640                             if todo_event_id in cal_events[cur_date]:
1641                                 cur_event = events[todo_event_id]
1642                                 temp_len = diffday(cur_date, cur_event['enddate']) + 1
1643                                 
1644                                 # calculate colspan value
1645                                 if (7-wkday) < temp_len:
1646                                     colspan = 7 - wkday
1647                                     next_pending.append(cur_event['id'])
1648                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
1649 
1650                                 else:
1651                                     colspan = temp_len
1652                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
1653                                 
1654                                 
1655                                 cal_events[cur_date].remove(todo_event_id)
1656 
1657                                 colspan -= 1
1658                                 lastevent = todo_event_id
1659                             else:
1660                                 debug('Warning: no such event in cal_events')
1661                             
1662                             continue
1663                         
1664                         # if there is no pending event in the previous week, start a new event
1665                         event_found = 0
1666                         for e_id in cal_events[cur_date]:
1667                             
1668                             # if the start date of the event is current date    
1669                             if events[e_id]['startdate'] == cur_date:
1670                                 
1671                                 cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
1672                                 
1673                                 # calculate colspan value
1674                                 if (7-wkday) < cur_event['date_len']:
1675                                     colspan = 7 - wkday
1676                                     next_pending.append(cur_event['id'])
1677                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'pending', cur_date) )
1678 
1679                                 else:
1680                                     colspan = cur_event['date_len']
1681                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, '', cur_date) )
1682                                 
1683                                 colspan -= 1
1684                                 lastevent = cur_event['id']
1685                                 event_found = 1
1686                                 break
1687                             
1688                             # if the start date of the event is NOT current date
1689                             else:
1690                                 
1691                                 # pending event from previous month
1692                                 if wkday == 0 and week == monthcal[0]:
1693                                     
1694                                     cur_event = events[cal_events[cur_date].pop(0)]
1695                                     temp_len = diffday(cur_date, cur_event['enddate']) + 1
1696                                     
1697                                     # calculate colspan value
1698                                     if (7-wkday) < temp_len:
1699                                         colspan = 7 - wkday
1700                                         next_pending.append(cur_event['id'])
1701                                         html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
1702                                     else:
1703                                         colspan = temp_len
1704                                         html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
1705                                     
1706                                     colspan -= 1
1707                                     lastevent = cur_event['id']
1708                                     event_found = 1
1709                                     break
1710                                 
1711                         # if there is no event to start
1712                         if not event_found:
1713                             if not day:
1714                                 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1715                             else:
1716                                 html_events_cols.append( calshow_blankbox('cal_noevent') )
1717                             event_left -= 1
1718                                 
1719                     else:
1720                         if not day:
1721                             html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1722                         else:
1723                             html_events_cols.append( calshow_blankbox('cal_noevent') )
1724                         
1725                         event_left -= 1        
1726                 
1727                 # if there is NO event for this date
1728                 else:
1729                     if not day:
1730                         html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1731                     else:
1732                         html_events_cols.append( calshow_blankbox('cal_noevent') )
1733                         
1734                     event_left -= 1
1735             
1736             # if no event for this entry
1737             if not event_left:
1738                 # ignore the previous entry
1739                 break
1740             else:
1741                 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
1742             
1743         # show dummy blank slots for week height
1744         left_blank_rows = 2 - len(html_events_rows)
1745         
1746         # remove the followings
1747         if left_blank_rows > 0 and 0:
1748             for i in range(left_blank_rows):
1749                 html_events_cols = []
1750                 for wkday in r7:
1751                     day = week[wkday]
1752                     if not day:
1753                         html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1754                     else:
1755                         html_events_cols.append( calshow_blankbox('cal_noevent') )
1756                 
1757                 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
1758         
1759         
1760         # close the week slots
1761         html_events_cols = []
1762         for wkday in r7:
1763             day = week[wkday]
1764             if not day:
1765                 html_events_cols.append( calshow_blankbox('cal_last_nbmonth') )
1766             else:
1767                 html_events_cols.append( calshow_blankbox('cal_last_noevent') )
1768     
1769         html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
1770         
1771         html_events_rows = u'\r\n'.join(html_events_rows)
1772         html_week_rows.append(html_events_rows)
1773             
1774     html_calendar_rows = u'\r\n'.join(html_week_rows)
1775     
1776     html_cal_table = [
1777         u'\r\n<div id="eventcalendar">',
1778         u'<table class="eventcalendar" %s>' % Params.monthlywidth,
1779         u'%s' % html_header_curyearmonth,
1780         u'%s' % html_header_weekdays,
1781         u'%s' % html_calendar_rows,
1782         u'</table>',
1783         u'</div>',
1784         ]
1785     html_cal_table = u'\r\n'.join(html_cal_table)
1786         
1787     return html_cal_table
1788 
1789 # simple view
1790 def showsimpleeventcalendar(year, month):
1791     
1792     debug('Show Calendar: Simple View')
1793     
1794     request = Globs.request
1795     formatter = Globs.formatter
1796     _ = request.getText
1797     
1798     wkend = Globs.wkend
1799     months= Globs.months
1800     wkdays = Globs.wkdays
1801     
1802     # get the calendar
1803     monthcal = calendar.monthcalendar(year, month)
1804 
1805     # shows current year & month
1806     html_header_curyearmonth = calhead_yearmonth(year, month, 'simple_yearmonth')
1807     
1808     r7 = range(7)
1809     
1810     # shows header of week days
1811     html_header_weekdays = []
1812     
1813     for wkday in r7:
1814         wday = wkdays[wkday]
1815         html_header_weekdays.append( calhead_weekday(wday, 'simple_weekday') )
1816     html_header_weekdays = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
1817  
1818     # gets previous, next month
1819     day_delta = datetime.timedelta(days=-1)
1820     cur_month = datetime.date(year, month, 1)
1821     prev_month = cur_month + day_delta
1822     
1823     day_delta = datetime.timedelta(days=15)
1824     cur_month_end = datetime.date(year, month, 25)
1825     next_month = cur_month_end + day_delta
1826     
1827     prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
1828     next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
1829     
1830     # shows days
1831     html_week_rows = []
1832 
1833     # set ranges of events
1834     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
1835     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
1836     
1837     # read all the events
1838     events, cal_events = loadEvents(datefrom, dateto)
1839     
1840     for week in monthcal:
1841         
1842         # day head rows
1843         html_headday_cols = []
1844         html_events_rows = []
1845         
1846         for wkday in r7:
1847              
1848             day = week[wkday]
1849             
1850             if not day:
1851                 if week == monthcal[0]:
1852                     nb_day = prev_monthcal[-1][wkday]
1853                 else:
1854                     nb_day = next_monthcal[0][wkday]
1855                     
1856                 html_headday_cols.append( simple_eventbox(year, month, day, nb_day, 'simple_nb') )
1857             else:
1858                 cur_date = formatDate(year, month, day)
1859                 if cal_events.has_key(cur_date):
1860                     html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_event') )
1861                 else:
1862                     html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_noevent') )
1863         
1864         html_headday_row = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
1865         html_week_rows.append(html_headday_row)
1866             
1867     html_calendar_rows = u'\r\n'.join(html_week_rows)
1868     
1869     html_cal_table = [
1870         u'\r\n<div id="eventcalendar">',
1871         u'<table class="simplecalendar" %s>' % Params.simplewidth,
1872         u'%s' % html_header_curyearmonth,
1873         u'%s' % html_header_weekdays,
1874         u'%s' % html_calendar_rows,
1875         u'</table>',
1876         u'</div>',
1877         ]
1878     html_cal_table = u'\r\n'.join(html_cal_table)
1879         
1880     return html_cal_table
1881 
1882 
1883 # show weekday
1884 def calhead_yearmonth(year, month, headclass):
1885     
1886     months = Globs.months
1887     monthstyle_us = Globs.month_style_us
1888     cal_action = Globs.cal_action
1889     page_name = Globs.pagename
1890     
1891     nextyear, nextmonth = yearmonthplusoffset(year, month, 1)
1892     prevyear, prevmonth = yearmonthplusoffset(year, month, -1)
1893     
1894     prevlink = u'%s?calaction=%s&caldate=%d%02d' % (page_name, cal_action, prevyear, prevmonth)
1895     nextlink = u'%s?calaction=%s&caldate=%d%02d' % (page_name, cal_action, nextyear, nextmonth)
1896     curlink = u'%s?calaction=%s&caldate=%d%02d' % (page_name, cal_action, year, month)
1897     
1898     if monthstyle_us:
1899         stryearmonth = u'%s %d' % (months[month-1], year)
1900         strnextmonth = u'%s %d' % (months[nextmonth-1], nextyear)
1901         strprevmonth = u'%s %d' % (months[prevmonth-1], prevyear)
1902     else:
1903         stryearmonth = u'%d / %02d' % (year, month)
1904         strnextmonth = u'%d / %02d' % (nextyear, nextmonth)
1905         strprevmonth = u'%d / %02d' % (prevyear, prevmonth)
1906     
1907     html = [
1908         u'  <tr>',
1909         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
1910         u'      <td colspan="5" class="%s"><a href="%s" title="Refresh">%s</a></td>' % (headclass, curlink, stryearmonth),
1911         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
1912         u'  </tr>',
1913         ]
1914         
1915     return u'\r\n'.join(html)
1916 
1917 # show days in simple
1918 def simple_eventbox(year, month, day, wkday, boxclass):
1919     wkend = Globs.wkend
1920     if wkday == wkend:
1921         html_text = u'<font color="#aa7744">%s</font>' % day
1922     else:
1923         html_text = u'%s' % day
1924     
1925     cyear, cmonth, cday = gettodaydate()
1926     
1927     if boxclass == 'simple_nb':
1928         html = u'  <td class="%s">&nbsp;</td>\r\n' % boxclass
1929     else:
1930         if cyear == year and cmonth == month and cday == day:
1931             html = u'  <td class="%s_today">%s</td>\r\n' % (boxclass, html_text)
1932         else:
1933             html = u'  <td class="%s">%s</td>\r\n' % (boxclass, html_text)
1934        
1935     return html
1936 
1937 
1938 # show weekday
1939 def calhead_weekday(wday, headclass):
1940     if headclass == 'simple_weekday':
1941         html = u'       <td class="%s">%s</td>\r\n' % (headclass, wday[0])
1942     else:
1943         html = u'       <td class="%s">%s</td>\r\n' % (headclass, wday)
1944 
1945     return html
1946 
1947 
1948 # show days of current month
1949 def calhead_day(year, month, day, wkday):
1950     wkend = Globs.wkend
1951     if wkday == wkend:
1952         html_text = u'<font color="#FF3300">%s</font>' % day
1953     else:
1954         html_text = u'%s' % day
1955     
1956     cyear, cmonth, cday = gettodaydate()
1957     
1958     if cyear == year and cmonth == month and cday == day:
1959         html = u'  <td class="head_day_today">&nbsp;%s</td>\r\n' % html_text
1960     else:
1961         html = u'  <td class="head_day">&nbsp;%s</td>\r\n' % html_text
1962        
1963     return html
1964 
1965 
1966 # show days of previous or next month
1967 def calhead_day_nbmonth(day):
1968     html = u'  <td class="head_day_nbmonth">&nbsp;%s</td>\r\n' % day
1969     return html
1970 
1971     
1972 # show blank calendar box
1973 def calshow_blankbox(classname):
1974     html = u'  <td class="%s">&nbsp;</td>' % classname
1975     return html
1976 
1977 # show eventbox
1978 def calshow_eventbox(event, colspan, status, cur_date):
1979     if status:
1980         status = u'_%s' % status
1981     
1982     title = event['title']
1983     eid = event['id']
1984     startdate = event['startdate']
1985     enddate = event['enddate']
1986     starttime = event['starttime']
1987     endtime = event['endtime']
1988     description = event['description']
1989     bgcolor = event['bgcolor']
1990     
1991     year, month, day = getdatefield(cur_date)
1992     
1993     if bgcolor:
1994         bgcolor = 'background-color: %s;' % bgcolor
1995     else:
1996         bgcolor = 'background-color: %s;' % Params.bgcolor
1997     
1998     if (startdate == enddate) and starttime:
1999         shour, smin = gettimefield(starttime)
2000         
2001         link = [
2002             u'<table width="100%%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
2003             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),
2004             u'<td style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top;font-size: 8pt;">',
2005             u'%s' % showReferPageParsed(event, 'title', 1),
2006             u'</td>\r\n</tr></table>',
2007             ]
2008         link = u''.join(link)
2009     else:
2010         link = u'%s' % showReferPageParsed(event, 'title', 1)
2011     
2012     
2013     html = [
2014         u'  <td class="cal_eventbox" colspan="%d"><table class="cal_event">' % colspan,
2015         u'      <tr><td id="cal_event_%s" class="cal_event%s" style="%s">%s</td></tr>' % (eid, status, bgcolor, link),
2016         u'      </table></td>',
2017         ]
2018         
2019     return u'\r\n'.join(html)
2020         
2021 
2022 def insertcalevents(cal_events, datefrom, dateto, e_id, e_start_date, e_end_date):
2023     
2024     
2025     if not (int(e_start_date) > dateto or int(e_end_date) < datefrom):
2026         
2027         e_start_date = str(max(int(e_start_date), datefrom))
2028         e_end_date = str(min(int(e_end_date), dateto))
2029         
2030         day_delta = datetime.timedelta(days=1)
2031         e_start_year, e_start_month, e_start_day = getdatefield(e_start_date)
2032         cur_datetime = datetime.date(e_start_year, e_start_month, e_start_day)
2033         
2034         while 1:
2035             tmp_record_date = formatdateobject(cur_datetime)
2036             
2037             if not cal_events.has_key(tmp_record_date):
2038                 cal_events[tmp_record_date] = []
2039             cal_events[tmp_record_date].append(e_id)
2040             
2041             if tmp_record_date == e_end_date:
2042                 break
2043             
2044             cur_datetime = cur_datetime + day_delta   
2045 
2046 
2047 # date format should be like '20051004' for 2005, Oct., 04
2048 def diffday(date1, date2):
2049     
2050     try:
2051         year1, month1, day1 = getdatefield(date1)
2052         year2, month2, day2 = getdatefield(date2)
2053         tmp_diff = datetime.date(year2, month2, day2) - datetime.date(year1, month1, day1)
2054     except (TypeError, ValueError):
2055         debug('An event data is corrupted: invalid date format')
2056         return 0
2057 
2058     return tmp_diff.days
2059 
2060 
2061 def formatDate(year, month, day):
2062     # returns like: '20051004'
2063     return u'%4d%02d%02d' % (year, month, day)
2064 
2065 def formatdateobject(obj_date):
2066 
2067     return formatDate(obj_date.year, obj_date.month, obj_date.day)
2068 
2069 
2070 def cliprgb(r,g,b): # don't use 255!
2071     if r < 0:   r=0
2072     if r > 254: r=254
2073     if b < 0:   b=0
2074     if b > 254: b=254
2075     if g < 0:   g=0
2076     if g > 254: g=254
2077     return r, g, b
2078 
2079 
2080 def debug(astring):
2081     Globs.debugmsg += u'<li>%s\n' % astring
2082 
2083 
2084 def yearmonthplusoffset(year, month, offset):
2085     month = month+offset
2086     # handle offset and under/overflows - quick and dirty, yes!
2087     while month < 1:
2088         month = month + 12
2089         year = year - 1
2090     while month > 12:
2091         month = month - 12
2092         year = year + 1
2093     return year, month
2094 
2095 
2096 def formatcfgdatetime(strdate, strtime=''):
2097     
2098     if not strdate:
2099         return ''
2100     
2101     request = Globs.request
2102     
2103     if request.user.date_fmt:
2104         date_fmt = request.user.date_fmt
2105     else:
2106         date_fmt = request.cfg.date_fmt
2107     
2108     if request.user.datetime_fmt:
2109         datetime_fmt = request.user.datetime_fmt
2110     else:
2111         datetime_fmt = request.cfg.datetime_fmt
2112     
2113     ## XXX HACK
2114     datetime_fmt = datetime_fmt.replace(':%S', '')
2115     
2116     date_fmt = str(date_fmt)
2117     datetime_fmt = str(datetime_fmt)
2118     
2119     year, month, day = getdatefield(str(strdate))
2120     if strtime:
2121         hour, min = gettimefield(str(strtime))
2122         objdatetime = datetime.datetime(year, month, day, hour, min)
2123         return objdatetime.strftime(datetime_fmt)
2124     else:
2125         objdate = getdatetimefromstring(strdate)
2126         return objdate.strftime(date_fmt)
2127     
2128 
2129 def getdatetimefromstring(strdate):
2130     year, month, day = getdatefield(str(strdate))
2131     return datetime.date( year, month, day )
2132 
2133 
2134 def searchPages(request, needle):
2135     # Search the pages and return the results
2136     query = search.QueryParser().parse_query(needle)
2137     results = search.searchPages(request, query)
2138     #results.sortByPagename()
2139     
2140     return results.hits
2141     
2142     html = []
2143     for page in results.hits:
2144         html.append(page.page_name)
2145     
2146     html = u',<br>'.join(html)
2147     return u'%s<p>%s' % (Params.category, html)
2148     

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.