Attachment 'EventCalendar-092.py'

Download

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

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.