Attachment 'EventCalendar-093.py'

Download

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

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.