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

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.