Attachment 'EventCalendar-096.py'

Download

   1 """
   2     EventCalendar.py  Version 0.96  April 17, 2006
   3                                                                                                            
   4     This macro gives a list of the events recorded at the sub-pages in the form of various views:
   5         monthly, weekly, daily, simple-month, list, and upcoming.
   6                                                                                                            
   7     @copyright: 2006 by Seungik Lee <seungiklee<at>gmail.com>  http://www.silee.net/
   8     @license: GPL
   9     
  10     For more information, please visit http://moinmoin.wikiwikiweb.de/MacroMarket/EventCalendar
  11     
  12     <Usage>
  13     
  14         * To list the events in a page, just insert [[EventCalendar]]
  15         * To insert an event, insert the event information in any pages of specified category (CategoryEventCalendar by default).
  16         
  17     <Parameters>
  18         
  19         * category: the category of the event data to be used in the calendar. default: 'CategoryEventCalendar'
  20         * menubar: shows menubar or not (1: show, 0: no menubar). default: 1
  21         * monthlywidth: calendar width in pixel or percent (monthly view). default: '600' (pixel)
  22         * simplewidth: calendar width in pixel or percent (simpleview). default: '150' (pixel)
  23         * firstview: initial calendar view: monthly, weekly, daily, list, simple, upcoming. default: 'monthly'
  24         * curdate: initial calendar date (in YYYYMM format). default: current month
  25         * upcomingrange: # of days for the range of upcoming event list. default: 7 (days)
  26         * changeview: enables to change the calendar view or not (1: enalbed, 0: disabled). default: 1
  27         * numcal: # of calendar. default: 1
  28         
  29     
  30     <Event Data Format>
  31 
  32         * Example:
  33         
  34 [default_description:: [default_description_text]]
  35 [default_bgcolor:: [default_custom_background_color]]
  36 
  37 == <title> ==
  38  start:: <startdate> [starttime]
  39  [end:: [enddate] [endtime]]
  40  [description:: [description_text]]
  41  [bgcolor:: [custom_background_color]]
  42  [recur:: <recur_freq> <recur_type> [until <recur_until>]]
  43 
  44 ...
  45 
  46 ----
  47 CategoryEventCalendar
  48 
  49 
  50             * title: event title. required
  51                 * should be enclosed with heading marker ('='), Title cannot be omitted.
  52 
  53             * startdate: date of start. required
  54                 * should be in YYYY/MM/DD or YYYY-MM-DD
  55                 
  56             * starttime: time of start. optional
  57                 * should be in HH:MM in 24-hour format
  58                 
  59             * enddate: date of end. optional
  60                 * should be in YYYY/MM/DD or YYYY-MM-DD. If omitted, it will be assigned equal to <startdate>.
  61                 
  62             * endtime: time of end. optional
  63                 * should be in HH:MM in 24-hour format. Both of start|end Time can be omitted but not either of them.
  64                 
  65             * description: description of the event. optional
  66                 * any text with no markup. should be in a line.
  67                 
  68             * bgcolor: custom background color of the event in monthly view. optional
  69                 * e.g., #abcdef
  70             
  71             * recur: recurrence information of the event, optional
  72                 * recur_freq: how many intervals, digit, required
  73                 * recur_type: [day|week|weekday|month|year], required
  74                     * day: every [recur_freq] days
  75                     * week: every [recur_freq] weeks
  76                     * weekday: on the same weekday of [recur_freq]-th week of the month
  77                     * month: on the same day of [recur_freq]-th month
  78                     * year: on the same day of [recur_freq]-th year
  79                 * recur_until: recurred until when, YYYY/MM/DD or YYYY-MM-DD, optional
  80                 
  81                 * e.g., 10 day, 2 week until 2006-06-31, 3 weekday, 6 month until 2007-12-31, 1 year
  82 
  83             * default_bgcolor, default_description: default values of bgcolor and description in the page if unavailable
  84             
  85             * The order of the fields after an event title does not matter.
  86 
  87     <Event Data Examples>
  88 
  89 = Default values =
  90  default_bgcolor:: #c0c0c0
  91  default_description:: testing...
  92 
  93 === Test event ===
  94  start:: 2006-01-10 14:00
  95  end:: 2006-01-12 17:00
  96  description:: test event
  97  bgcolor:: #cfcfcf
  98   
  99 === Jinah's Birthday ===
 100  start:: 1977-10-20
 101  recur:: 1 year
 102  
 103 === Weekly meeting ===
 104  start:: 2006-01-17 19:00
 105  end:: 21:00
 106  recur:: 1 week until 2006-12-31
 107 
 108 ----
 109 CategoryEventCalendar  
 110 
 111 
 112     <Notes>
 113     
 114         * It caches all the page list of the specified category and the event information.
 115         * If you added/removed a page into/from a category, you need to do 'Delete cache' in the macro page.
 116 
 117         * 'MonthCalendar.py' developed by Thomas Waldmann <ThomasWaldmann@gmx.de> has inspired this macro.
 118         * Much buggy.. : please report bugs and suggest your ideas.
 119         * If you missed to add css for EventCalender, monthly view may not be readable.
 120             * Insert the EventCalendar css classes into the screen.css of an appropriate theme.
 121 
 122         
 123 
 124 """
 125 
 126 from MoinMoin import wikiutil, config, search, caching
 127 from MoinMoin.Page import Page
 128 from MoinMoin.parser import wiki
 129 import re, calendar, time, datetime
 130 import codecs, os, urllib, sha
 131 
 132 try:
 133     import cPickle as pickle
 134 except ImportError:
 135     import pickle
 136 
 137 # Set pickle protocol, see http://docs.python.org/lib/node64.html
 138 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
 139 
 140 
 141 # The following line sets the calendar to have either Sunday or Monday as
 142 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
 143 # valid here.  All other values will not make good calendars.
 144 # XXX change here ----------------vvvvvv
 145 calendar.setfirstweekday(calendar.SUNDAY)
 146 
 147 
 148 class Globs:
 149     month_style_us = 1  # 1: October 2005; 2: 2005 / 10
 150     defaultcategory = 'CategoryEventCalendar'
 151     upcomingrange = 7   # days
 152     dailystart = 9
 153     dailyend = 18
 154     pagename = ''
 155     baseurl = ''
 156     subname = ''
 157     wkend = ''
 158     months = ''
 159     wkdays = ''
 160     today = ''
 161     now = ''
 162     request = None
 163     formatter = None
 164     cal_action = ''
 165     debugmsg = ''
 166     page_action = ''
 167     form_vals = {}
 168     events = None
 169 
 170 
 171 class Params:
 172     menubar = 0
 173     monthlywidth = ''
 174     weeklywidth = ''
 175     dailywidth = ''
 176     simplewidth = ''
 177     firstview = ''
 178     curdate = ''
 179     bgcolor = ''
 180     category = ''
 181     upcomingrange = 0
 182     changeview = 0
 183     numcal = 1
 184     debug = 0
 185     
 186 
 187 def execute(macro, args):
 188     
 189     request = macro.request
 190     formatter = macro.formatter
 191     
 192     # INITIALIZATION ----------------------------------------
 193     setglobalvalues(macro)
 194     getparams(args)
 195     
 196     # allowed actions
 197     allowed_action = ['monthly', 'list', 'simple', 'upcoming', 'daily', 'weekly']
 198     default_action = Params.firstview
 199     
 200     # Internal variables
 201     cal_action = ''
 202     form_vals = {}
 203 
 204     # PROCESSING ARGUEMENTS ----------------------------------------
 205     if args:
 206         args=request.getText(args)
 207 
 208     for item in macro.form.items():
 209         if not form_vals.has_key(item[0]):
 210 	    try:
 211 		    form_vals[item[0]]=item[1][0]
 212 	    except AttributeError:
 213 	        pass
 214     
 215     # PROCESSING ACTIONS ----------------------------------------
 216     cal_action = form_vals.get('calaction', default_action)
 217     page_action = form_vals.get('action', 'show')
 218     
 219     if not cal_action in allowed_action:
 220         cal_action = default_action
 221     
 222     form_vals['calaction'] = cal_action
 223 
 224     Globs.form_vals = form_vals
 225 
 226     # CONTROL FUNCTIONS ----------------------------------------
 227     
 228     html = []
 229     html_result = ''
 230     
 231     Globs.cal_action = cal_action
 232     Globs.page_action = page_action
 233     
 234     
 235     # redirect to the appropriate view
 236     if cal_action == 'monthly':
 237         html_result = showcalendar()
 238         
 239     if cal_action == 'list':
 240         html_result = showeventlist()
 241 
 242     if cal_action == 'simple':
 243         html_result = showsimplecalendar()
 244     
 245     if cal_action == 'upcoming':
 246         html_result = showupcomingeventlist()
 247         
 248     if cal_action == 'daily':
 249         html_result = showdailycalendar()
 250         
 251     if cal_action == 'weekly':
 252         html_result = showweeklycalendar()
 253     
 254     
 255     # format output
 256     html.append( html_result )
 257     html.append( showmenubar() )
 258     
 259     if Params.debug and Globs.debugmsg:
 260         html.append(u'<p><b>Debug messages:</b><font color="#aa0000"><ol>%s</ol></font>' % Globs.debugmsg)
 261         
 262     return formatter.rawHTML(u''.join(html))
 263 
 264 
 265 
 266 def getparams(args):
 267     # process arguments
 268     
 269     params = {}
 270     if args:
 271         # Arguments are comma delimited key=value pairs
 272         sargs = args.split(',')
 273     
 274         for item in sargs:
 275             sitem = item.split('=')
 276         
 277             if len(sitem) == 2:
 278                 key, value = sitem[0], sitem[1]
 279                 params[key.strip()] = value.strip()
 280 
 281     # category name: 
 282     # default: 'CategoryEventCalendar'
 283     Params.category = params.get('category', Globs.defaultcategory)
 284     
 285     # menu bar: shows menubar or not (1: show, 0: no menubar)
 286     # default: 1
 287     try:
 288         Params.menubar = int(params.get('menubar', 1))
 289     except (TypeError, ValueError):
 290         Params.menubar = 1
 291         
 292     # calendar width in pixel or percent (monthly)
 293     # default: 600px
 294     Params.monthlywidth = params.get('monthlywidth', '600')
 295     if Params.monthlywidth:
 296         Params.monthlywidth = ' width="%s" ' % Params.monthlywidth
 297         
 298     # calendar width in pixel or percent (weekly)
 299     # default: 600px
 300     Params.weeklywidth = params.get('weeklywidth', '600')
 301     if Params.weeklywidth:
 302         Params.weeklywidth = ' width="%s" ' % Params.weeklywidth
 303 
 304     # calendar width in pixel or percent (daily)
 305     # default: 600px
 306     Params.dailywidth = params.get('dailywidth', '600')
 307     if Params.monthlywidth:
 308         Params.dailywidth = ' width="%s" ' % Params.dailywidth
 309 
 310     # calendar width in pixel or percent (simply)
 311     # default: 150px
 312     Params.simplewidth = params.get('simplewidth', '150')
 313     if Params.simplewidth:
 314         # Params.simplewidth = Params.simplewidth.replace('%', '%%')
 315         Params.simplewidth = ' width="%s" ' % Params.simplewidth
 316     
 317     # calendar view: monthly, list, simple
 318     # default: 'monthly'
 319     Params.firstview = params.get('firstview', 'monthly')
 320 
 321     # calendar date: in YYYYMM format (in monthly, simple view)
 322     # default: current month
 323     Params.curdate = params.get('curdate', '')
 324     
 325     # upcoming range: # of days for upcoming event list
 326     # default: 7
 327     try:
 328         Params.upcomingrange = int(params.get('upcomingrange', Globs.upcomingrange))
 329     except (TypeError, ValueError):
 330         Params.upcomingrange = Globs.upcomingrange
 331         
 332     # number of calendar: # of calendar for monthly & simple view
 333     # default: 1
 334     try:
 335         Params.numcal = int(params.get('numcal', '1'))
 336     except (TypeError, ValueError):
 337         Params.numcal = 1
 338 
 339     # change view enabled?
 340     # default: 1
 341     try:
 342         Params.changeview = int(params.get('changeview', '1'))
 343     except (TypeError, ValueError):
 344         Params.changeview = 1
 345 
 346     # default bgcolor
 347     Params.bgcolor = '#ddffdd'
 348     
 349 
 350 def setglobalvalues(macro):
 351     
 352     request = macro.request
 353     formatter = macro.formatter
 354     
 355     # Useful variables
 356     Globs.baseurl = request.getBaseURL() + '/'
 357     Globs.pagename = formatter.page.page_name
 358     Globs.request = request
 359     Globs.formatter = formatter
 360     Globs.pageurl = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(formatter.page.page_name))
 361     
 362     # This fixes the subpages bug. subname is now used instead of pagename when creating certain urls
 363     Globs.subname = Globs.pagename.split('/')[-1]
 364 
 365     pagepath = formatter.page.getPagePath()
 366     Globs.pagepath = formatter.page.getPagePath()
 367     
 368     # european / US differences
 369     months = ('January','February','March','April','May','June','July','August','September','October','November','December')
 370     
 371     # Set things up for Monday or Sunday as the first day of the week
 372     if calendar.firstweekday() == calendar.MONDAY:
 373         wkend = 6
 374         wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
 375     elif calendar.firstweekday() == calendar.SUNDAY:
 376         wkend = 0
 377         wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
 378     
 379     Globs.months = months
 380     Globs.wkdays = wkdays
 381     Globs.wkend = wkend
 382 
 383     year, month, day, h, m, s, wd, yd, ds = request.user.getTime(time.time())
 384     Globs.today = datetime.date(year, month, day)
 385     Globs.now = datetime.time(h, m, s)
 386     
 387     Globs.debugmsg = ''
 388 
 389 
 390 def showReferPageParsed(event, targettext='title', showdesc=0):
 391     request = Globs.request
 392     pagename = Globs.pagename
 393     
 394     refer = event['refer']
 395     targettext = event[targettext]
 396     startdate = event['startdate']
 397     enddate = event['enddate']
 398     description = event['description']
 399     starttime = event['starttime']
 400     endtime = event['endtime']
 401     hid = event['hid']
 402     
 403     refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
 404     
 405     if not Params.changeview:
 406         refer_url = ''
 407         hid = ''
 408     
 409     if showdesc:
 410         if (startdate == enddate) and (starttime and endtime):
 411             timedescription = '(%s:%s ~ %s:%s)' % (starttime[:2], starttime[2:], endtime[:2], endtime[2:])
 412             if description:
 413                 timedescription = '%s ' % timedescription
 414         else:
 415             timedescription = ''
 416         
 417         targetlink = '<a href="%s#%s" title="%s%s">%s</a>' % ( refer_url, hid, timedescription, wikiutil.escape(description), wikiutil.escape(targettext) )
 418             
 419     else:
 420         targetlink = '<a href="%s#%s">%s</a>' % ( refer_url, hid, wikiutil.escape(targettext))
 421     
 422     return targetlink
 423 
 424 
 425 def getheadingid(request, referpage, title):
 426 
 427     pntt = (referpage + title).encode(config.charset)
 428     hid = "head-" + sha.new(pntt).hexdigest()
 429     request._page_headings.setdefault(pntt, 0)
 430     request._page_headings[pntt] += 1
 431     if request._page_headings[pntt] > 1:
 432         hid += '-%d'%(request._page_headings[pntt],)
 433     
 434     return hid
 435 
 436 
 437 def getquerystring(req_fields):
 438     
 439     m_query = []
 440     tmp_form_vals = Globs.form_vals
 441     
 442     # format querystring
 443     # action should be poped out
 444     for field in req_fields:
 445         if tmp_form_vals.has_key(field):
 446             m_query.append(u'%s=%s' % (field, tmp_form_vals[field]) )
 447     
 448     if 'prevcalaction' in req_fields:
 449         if not tmp_form_vals.has_key('prevcalaction'):
 450             m_query.append(u'%s=%s' % ('prevcalaction', tmp_form_vals['calaction']) )
 451             
 452     m_query = u'&'.join(m_query)
 453     
 454     if m_query:
 455         m_query = '&%s' % m_query
 456     
 457     return m_query
 458 
 459 
 460 # bottom menu bar
 461 def showmenubar():
 462     
 463     request = Globs.request
 464     cal_action = Globs.cal_action
 465     page_name = Globs.pagename
 466     
 467     page_url = Globs.pageurl
 468     
 469     if not Params.menubar: return ''
 470 
 471     if cal_action == 'simple':
 472         menuwidth = Params.simplewidth
 473     elif cal_action == 'monthly':
 474         menuwidth = Params.monthlywidth
 475     else:
 476         menuwidth = ''
 477     
 478     left_menu_selected = []
 479     right_menu_selected = []
 480     
 481     # Go Today
 482     year, month, day = gettodaydate()
 483     mnu_curmonthcal = u'<a href="%s?calaction=%s&caldate=%d%02d%02d%s" title="Go Today">[Today]</a>' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
 484     
 485     # List View
 486     mnu_listview = u'<a href="%s?calaction=list%s" title="List of all events">[List]</a>' % (page_url, getquerystring(['caldate', 'numcal']))
 487     
 488     # Monthly View
 489     mnu_monthview = u'<a href="%s?calaction=monthly%s" title="Monthly view">[Monthly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 490     
 491     # Simple Calendar View
 492     mnu_simpleview = u'<a href="%s?calaction=simple%s" title="Simple calendar view">[Simple]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 493     
 494     # Upcoming Event List
 495     mnu_upcomingview = u'<a href="%s?calaction=upcoming%s" title="Upcoming event list">[Upcoming]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 496     
 497     # Daily View
 498     mnu_dayview = u'<a href="%s?calaction=daily%s" title="Daily view">[Daily]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 499     
 500     # Weekly View
 501     mnu_weekview = u'<a href="%s?calaction=weekly%s" title="Weekly view">[Weekly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 502     
 503     html = [
 504         u'\r\n',
 505         u'<table class="eventcalendar_menubar" %s>',
 506         u'  <tr>',
 507         u'  <td class="eventcalendar_menubar" align="left">%s</td>',
 508         u'  <td class="eventcalendar_menubar" align="right">%s</td>',
 509         u'  </tr>',
 510         u'</table>',
 511         ]
 512         
 513     if cal_action == 'list':
 514         left_menu_selected.append(mnu_monthview)
 515         left_menu_selected.append(mnu_weekview)
 516         left_menu_selected.append(mnu_dayview)
 517         left_menu_selected.append(mnu_simpleview)
 518         right_menu_selected.append(mnu_upcomingview)
 519 
 520     elif cal_action == 'simple':
 521         left_menu_selected.append(mnu_monthview)
 522         left_menu_selected.append(mnu_weekview)
 523         left_menu_selected.append(mnu_dayview)
 524         right_menu_selected.append(mnu_listview)
 525         right_menu_selected.append(mnu_upcomingview)
 526         right_menu_selected.append(mnu_curmonthcal)
 527     
 528     elif cal_action == 'upcoming':
 529         left_menu_selected.append(mnu_monthview)
 530         left_menu_selected.append(mnu_weekview)
 531         left_menu_selected.append(mnu_dayview)
 532         left_menu_selected.append(mnu_simpleview)
 533         right_menu_selected.append(mnu_listview)
 534 
 535     elif cal_action == 'weekly':
 536         left_menu_selected.append(mnu_monthview)
 537         left_menu_selected.append(mnu_dayview)
 538         left_menu_selected.append(mnu_simpleview)
 539         right_menu_selected.append(mnu_upcomingview)
 540         right_menu_selected.append(mnu_listview)
 541         right_menu_selected.append(mnu_curmonthcal)
 542         
 543     elif cal_action == 'daily':
 544         left_menu_selected.append(mnu_monthview)
 545         left_menu_selected.append(mnu_weekview)
 546         left_menu_selected.append(mnu_simpleview)
 547         right_menu_selected.append(mnu_upcomingview)
 548         right_menu_selected.append(mnu_listview)
 549         right_menu_selected.append(mnu_curmonthcal)
 550 
 551     else:
 552         left_menu_selected.append(mnu_weekview)
 553         left_menu_selected.append(mnu_dayview)
 554         left_menu_selected.append(mnu_simpleview)
 555         right_menu_selected.append(mnu_upcomingview)
 556         right_menu_selected.append(mnu_listview)
 557         right_menu_selected.append(mnu_curmonthcal)
 558 
 559     left_menu_selected = u'\r\n'.join(left_menu_selected)
 560     right_menu_selected = u'\r\n'.join(right_menu_selected)
 561     
 562     html = u'\r\n'.join(html)
 563     html = html % (menuwidth, left_menu_selected, right_menu_selected)
 564 
 565     return html
 566         
 567 
 568 def getdatefield(str_date):
 569     str_year = ''
 570     str_month = ''
 571     str_day = ''
 572     
 573     if len(str_date) == 6:
 574         # year+month
 575         str_year = str_date[:4]
 576         str_month = str_date[4:]
 577         str_day = '1'
 578 
 579     elif len(str_date) == 8:
 580         # year+month+day
 581         str_year = str_date[:4]
 582         str_month = str_date[4:6]
 583         str_day = str_date[6:]
 584     
 585     elif len(str_date) == 10:
 586         # year+?+month+?+day
 587         str_year = str_date[:4]
 588         str_month = str_date[5:7]
 589         str_day = str_date[8:]
 590     
 591     else:
 592         raise ValueError
 593     
 594     # It raises exception if the input date is incorrect
 595     temp = datetime.date(int(str_year), int(str_month), int(str_day))
 596 
 597     return temp.year, temp.month, temp.day
 598 
 599 
 600 def gettimefield(str_time):
 601     str_hour = ''
 602     str_min = ''
 603     
 604     if len(str_time) == 4:
 605         # hour+minute
 606         str_hour = str_time[:2]
 607         str_min = str_time[2:]
 608     
 609     elif len(str_time) == 5:
 610         # hour+?+minute
 611         str_hour = str_time[:2]
 612         str_min = str_time[3:]
 613         
 614     else:
 615         raise ValueError
 616     
 617     # It raises exception if the input date is incorrect
 618     temp = datetime.time(int(str_hour), int(str_min))
 619 
 620     return temp.hour, temp.minute
 621 
 622 
 623 def gettodaydate():
 624     today = Globs.today
 625     return today.year, today.month, today.day    
 626 
 627 
 628 def cal_listhead():
 629 
 630     html = [
 631         u'  <tr>',
 632         u'      <td class="list_head">Title</td>',
 633         u'      <td class="list_head">Start Date</td>',
 634         u'      <td class="list_head">End Date</td>',
 635         u'      <td class="list_head">Recurrence</td>',
 636         u'      <td class="list_head">Description</td>',
 637         u'      <td class="list_head">Reference</td>',
 638         u'  </tr>',
 639         ]
 640         
 641     return u'\r\n'.join(html)
 642 
 643 
 644 def showeventlist():
 645     
 646     debug('Show Calendar: List view')
 647     
 648     request = Globs.request
 649     formatter = Globs.formatter
 650     
 651     html_event_rows = []
 652     html_list_header = cal_listhead()
 653     
 654     # read all the events
 655     events, cal_events = loadEvents()
 656     
 657     # sort events
 658     sorted_eventids = events.keys()
 659     sorted_eventids.sort(comp_list_events)
 660     
 661     for eid in sorted_eventids:
 662         if not events[eid]['clone']:
 663             html_event_rows.append( listshow_event(events[eid]) )
 664     
 665     html_event_rows = u'\r\n'.join(html_event_rows)
 666     
 667     html_list_table = [
 668         u'\r\n<div id="eventlist">',
 669         u'<table class="eventlist">',
 670         u'%s' % html_list_header,
 671         u'%s' % html_event_rows,
 672         u'</table>',
 673         u'</div>',
 674         ]
 675     html_list_table = u'\r\n'.join(html_list_table)
 676         
 677     return html_list_table
 678 
 679 
 680 def listshow_event(event):
 681     
 682     if event['recur_freq']:
 683         recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type'])
 684         if event['recur_until']:
 685              recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until']))
 686     else:
 687         recur_desc = ''
 688 
 689     html = [
 690         u'  <tr>',
 691         u'  <td class="list_entry">%s</td>' % converttext(event['title']),
 692         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']),
 693         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']),
 694         u'  <td class="list_entry">%s</td>' % recur_desc,
 695         u'  <td class="list_entry">%s</td>' % converttext(event['description']),
 696         u'  <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'),
 697         u'  </tr>',
 698         ]
 699     
 700     return u'\r\n'.join(html)
 701 
 702 
 703 def showupcomingeventlist():
 704     
 705     debug('Show Calendar: Upcoming Event View')
 706     
 707     request = Globs.request
 708     formatter = Globs.formatter
 709     
 710     html_event_rows = []
 711     html_list_header = cal_listhead()
 712     
 713     year, month, day = gettodaydate()
 714     day_delta = datetime.timedelta(days=Params.upcomingrange)
 715     cur_date = datetime.date(year, month, day)
 716     next_range = cur_date + day_delta
 717     
 718     # set ranges of events
 719     datefrom = u'%04d%02d%02d' % (year, month, day)
 720     dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day)
 721     
 722     # read all the events (no cache)
 723     events, cal_events = loadEvents(datefrom, dateto, 1)
 724     
 725     nowtime = formattimeobject(Globs.now)
 726     
 727     datefrom = formatcfgdatetime(cur_date, nowtime)
 728     #u'%04d-%02d-%02d %s:%s' % (year, month, day, nowtime[:2], nowtime[2:])
 729     dateto = formatcfgdatetime(formatdateobject(next_range))
 730     #u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day)
 731     
 732     # sort events
 733     sorted_eventids = events.keys()
 734     sorted_eventids.sort(comp_list_events)
 735     
 736     for eid in sorted_eventids:
 737         if events[eid]['enddate'] >= formatdateobject(Globs.today):
 738             if (not events[eid]['endtime']) or events[eid]['endtime'] >= formattimeobject(Globs.now):
 739                 html_event_rows.append( listshow_event(events[eid]) )
 740     
 741     html_event_rows = u'\r\n'.join(html_event_rows)
 742     
 743     html_list_table = [
 744         u'\r\n<div id="eventlist">',
 745         u'<table class="eventlist">',
 746         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),
 747         u'%s' % html_list_header,
 748         u'%s' % html_event_rows,
 749         u'</table>',
 750         u'</div>',
 751         ]
 752     html_list_table = u'\r\n'.join(html_list_table)
 753         
 754     return html_list_table
 755 
 756 
 757 
 758 
 759 def showcalendar():
 760     
 761     request = Globs.request
 762     formatter = Globs.formatter
 763     form_vals = Globs.form_vals
 764     
 765     html = []
 766     
 767     if form_vals.has_key('caldate'):
 768         try:
 769             year, month, str_temp = getdatefield(form_vals['caldate'])
 770         except (TypeError, ValueError):
 771             debug('Invalid target date: e.g., "200510"')
 772             year, month, dy = gettodaydate()
 773     elif Params.curdate:
 774         try:
 775             year, month, str_temp = getdatefield(Params.curdate)
 776         except (TypeError, ValueError):
 777             debug('Invalid target date: e.g., "200510"')
 778             year, month, dy = gettodaydate()
 779             
 780     else:
 781         year, month, dy = gettodaydate()
 782     
 783     # check number of calendar
 784     numcal = Params.numcal
 785     
 786     if form_vals.has_key('numcal'):
 787         try:
 788             numcal = int(form_vals['numcal'])
 789         except (TypeError, ValueError):
 790             debug('Invalid number of calendar: e.g., 3')
 791 
 792     if numcal < 1:
 793         numcal = 1
 794     elif numcal > 12:
 795         numcal = 12
 796 
 797     for index in range(numcal):
 798     
 799         cyear, cmonth = yearmonthplusoffset(year, month, index)
 800     
 801         cal_html = showeventcalendar(cyear, cmonth)
 802         html.append(cal_html)
 803     
 804     return u''.join(html)
 805 
 806 
 807 def showdailycalendar():
 808     
 809     request = Globs.request
 810     formatter = Globs.formatter
 811     
 812     form_vals = Globs.form_vals
 813     
 814     if form_vals.has_key('caldate'):
 815         try:
 816             year, month, dy = getdatefield(form_vals['caldate'])
 817             
 818             if len(form_vals['caldate']) <= 6:
 819                 tyear, tmonth, tdy = gettodaydate()
 820                 if tyear == year and month == tmonth:
 821                     dy = tdy
 822                     
 823         except (TypeError, ValueError):
 824             debug('Invalid target date: e.g., "20051020"')
 825             year, month, dy = gettodaydate()
 826             
 827     elif Params.curdate:
 828         try:
 829             year, month, dy = getdatefield(Params.curdate)
 830         except (TypeError, ValueError):
 831             debug('Invalid target date: e.g., "200510"')
 832             year, month, dy = gettodaydate()
 833         
 834     else:
 835         year, month, dy = gettodaydate()
 836     
 837     html = showdailyeventcalendar(year, month, dy)
 838     
 839     return u''.join(html)
 840 
 841 
 842 def showweeklycalendar():
 843     
 844     request = Globs.request
 845     formatter = Globs.formatter
 846     
 847     form_vals = Globs.form_vals
 848     
 849     if form_vals.has_key('caldate'):
 850         try:
 851             year, month, dy = getdatefield(form_vals['caldate'])
 852             
 853             if len(form_vals['caldate']) <= 6:
 854                 tyear, tmonth, tdy = gettodaydate()
 855                 if tyear == year and month == tmonth:
 856                     dy = tdy
 857 
 858         except (TypeError, ValueError):
 859             debug('Invalid target date: e.g., "20051020"')
 860             year, month, dy = gettodaydate()
 861     
 862     elif Params.curdate:
 863         try:
 864             year, month, dy = getdatefield(Params.curdate)
 865         except (TypeError, ValueError):
 866             debug('Invalid target date: e.g., "200510"')
 867             year, month, dy = gettodaydate()
 868     else:
 869         year, month, dy = gettodaydate()
 870     
 871     html = showweeklyeventcalendar(year, month, dy)
 872     
 873     return u''.join(html)
 874 
 875     
 876 def showsimplecalendar():
 877     
 878     request = Globs.request
 879     formatter = Globs.formatter
 880     form_vals = Globs.form_vals
 881     
 882     html = []
 883     
 884     if form_vals.has_key('caldate'):
 885         try:
 886             year, month, str_temp = getdatefield(form_vals['caldate'])
 887         except (TypeError, ValueError):
 888             debug('Invalid target date: e.g., "200510"')
 889             year, month, dy = gettodaydate()
 890     elif Params.curdate:
 891         try:
 892             year, month, str_temp = getdatefield(Params.curdate)
 893         except (TypeError, ValueError):
 894             debug('Invalid target date: e.g., "200510"')
 895             year, month, dy = gettodaydate()
 896     else:
 897         year, month, dy = gettodaydate()
 898     
 899     # check number of calendar
 900     numcal = Params.numcal
 901     
 902     if form_vals.has_key('numcal'):
 903         try:
 904             numcal = int(form_vals['numcal'])
 905         except (TypeError, ValueError):
 906             debug('Invalid number of calendar: e.g., 3')
 907 
 908     if numcal < 1:
 909         numcal = 1
 910     elif numcal > 12:
 911         numcal = 12
 912 
 913     for index in range(numcal):
 914     
 915         cyear, cmonth = yearmonthplusoffset(year, month, index)
 916     
 917         cal_html = showsimpleeventcalendar(cyear, cmonth)
 918         html.append(cal_html)
 919     
 920     return u''.join(html)
 921 
 922 
 923 
 924 # sort events in cal_events by length of days of the event
 925 def comp_cal_events(xid, yid):
 926     events = Globs.events
 927     
 928     if events[xid]['date_len'] > events[yid]['date_len']:
 929         return -1
 930     elif events[xid]['date_len'] == events[yid]['date_len']:
 931         if events[xid]['date_len'] == 1:
 932             if events[xid]['starttime'] == events[yid]['starttime']:
 933                 return cmp(events[yid]['time_len'], events[xid]['time_len'])
 934             else:
 935                 return cmp(events[xid]['starttime'], events[yid]['starttime'])
 936         else:
 937             return 0
 938     else:
 939         return 1
 940 
 941 
 942 # sort events in the list by start date of the event
 943 def comp_list_events(xid, yid):
 944     events = Globs.events
 945     
 946     return cmp(events[xid]['startdate'], events[yid]['startdate'])
 947 
 948 # load events from wiki pages
 949 def loadEvents(datefrom='', dateto='', nocache=0):
 950     
 951     request = Globs.request
 952     
 953     debug('Loading event information.')
 954     
 955     events = {}
 956     cal_events = {}
 957     raw_events = {}
 958     
 959     raw_events = loadEventsFromWikiPages()
 960     
 961     # handling cal_events
 962     if datefrom or dateto:
 963         
 964         # cache configurations
 965         arena = Page(request, Globs.pagename)
 966         eventkey = 'events'
 967         filteredeventkey = 'events_%s-%s' % (datefrom, dateto)
 968         caleventkey = 'calevents_%s-%s' % (datefrom, dateto)
 969         
 970         cache_events = caching.CacheEntry(request, arena, eventkey)
 971         cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey)
 972         cache_calevents = caching.CacheEntry(request, arena, caleventkey)
 973         
 974         dirty = 1
 975         
 976         debug('Checking cal_events cache')
 977         
 978         if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())):
 979         
 980             try:
 981                 events = pickle.loads(cache_filteredevents.content())
 982                 cal_events = pickle.loads(cache_calevents.content())
 983                 debug('Cached event (filtered) information is used: total %d events' % len(events))
 984                 dirty = 0
 985             except (pickle.UnpicklingError, IOError, EOFError, ValueError):
 986                 debug('Picke error at fetching cached events (filtered)')
 987                 events = {}
 988                 cal_events = {}
 989 
 990 
 991         # if cache is dirty, update the cache
 992         if dirty:
 993         
 994             debug('Checking event cache: it\'s dirty or requested to refresh')
 995             debug('Building new cal_event information')
 996         
 997             try:
 998                 datefrom, dateto = int(datefrom), int(dateto)
 999             except (TypeError, ValueError):
1000                 datefrom, dateto = 0, 0
1001         
1002             clone_num = 0
1003             
1004             for e_id in raw_events.keys():
1005                 
1006                 cur_event = raw_events[e_id]
1007                 
1008                 # handling event recurrence
1009                 recur_freq = cur_event['recur_freq']
1010                 
1011                 if recur_freq:
1012                     
1013                     if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto:
1014 
1015                         if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1016                             # generating cal_events for iteself
1017                             events[e_id] = cur_event.copy()
1018                             insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1019                         
1020                         delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 )
1021                         
1022                         if cur_event['recur_type'] == 'day':
1023                         
1024                             day_delta = int(recur_freq)
1025                             startdate = getdatetimefromstring(cur_event['startdate'])
1026                             datefrom_date = getdatetimefromstring(datefrom)
1027                             
1028                             if int(datefrom) > int(cur_event['startdate']):
1029                                 diffs = datefrom_date - startdate
1030                                 q_delta = diffs.days / day_delta
1031                                 if diffs.days % day_delta > 0:
1032                                     q_delta += 1
1033                             else:
1034                                 q_delta = 1
1035                             
1036                             while 1:
1037                                 
1038                                 if q_delta == 0:
1039                                     q_delta += 1
1040                                     continue
1041                                 
1042                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1043                                 recurred_enddate = recurred_startdate + delta_date_len
1044                                 
1045                                 new_startdate = formatdateobject(recurred_startdate)
1046                                 new_enddate = formatdateobject(recurred_enddate)
1047                                 
1048                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1049                                     break
1050                                 
1051                                 clone_num += 1
1052                                 clone_id = 'c%d' % clone_num
1053                                 
1054                                 events[clone_id] = cur_event.copy()
1055                                 events[clone_id]['id'] = clone_id
1056                                 events[clone_id]['startdate'] = new_startdate
1057                                 events[clone_id]['enddate'] = new_enddate
1058                                 events[clone_id]['clone'] = 1
1059                                 
1060                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1061                                 
1062                                 q_delta += 1
1063                         
1064                         elif cur_event['recur_type'] == 'week':
1065                             
1066                             day_delta = int(recur_freq) * 7
1067                             
1068                             startdate = getdatetimefromstring(cur_event['startdate'])
1069                             datefrom_date = getdatetimefromstring(datefrom)
1070                             
1071                             if int(datefrom) > int(cur_event['startdate']):
1072                                 diffs = datefrom_date - startdate
1073                                 q_delta = diffs.days / day_delta
1074                                 if diffs.days % day_delta > 0:
1075                                     q_delta += 1
1076                             else:
1077                                 q_delta = 1
1078                             
1079                             while 1:
1080                                 
1081                                 if q_delta == 0:
1082                                     q_delta += 1
1083                                     continue
1084                                 
1085                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1086                                 recurred_enddate = recurred_startdate + delta_date_len
1087                                 
1088                                 new_startdate = formatdateobject(recurred_startdate)
1089                                 new_enddate = formatdateobject(recurred_enddate)
1090                                 
1091                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1092                                     break
1093                                 
1094                                 clone_num += 1
1095                                 clone_id = 'c%d' % clone_num
1096                                 
1097                                 events[clone_id] = cur_event.copy()
1098                                 events[clone_id]['id'] = clone_id
1099                                 events[clone_id]['startdate'] = new_startdate
1100                                 events[clone_id]['enddate'] = new_enddate
1101                                 events[clone_id]['clone'] = 1
1102                                 
1103                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1104                                 
1105                                 q_delta += 1
1106                         
1107                         
1108                         elif cur_event['recur_type'] == 'weekday':
1109                             
1110                             syear, smonth, sday = getdatefield(cur_event['startdate'])
1111                             cyear, cmonth, cday = getdatefield(str(datefrom))
1112                             
1113                             recur_weekday = calendar.weekday(syear, smonth, sday)
1114                             
1115                             
1116                             while 1:
1117                                 
1118                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1119                                 firstmatch = (recur_weekday - firstweekday) % 7 + 1
1120                                 
1121                                 #XXX should handle error
1122                                 try:
1123                                     therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1]
1124                                 except IndexError:
1125                                     therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1126                                 
1127                                 recurred_startdate = datetime.date(cyear, cmonth, therecur_day)
1128                                 recurred_enddate = recurred_startdate + delta_date_len
1129                                 
1130                                 new_startdate = formatdateobject(recurred_startdate)
1131                                 new_enddate = formatdateobject(recurred_enddate)
1132                                 
1133                                 if int(new_startdate) < int(datefrom):
1134                                     cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1135                                     continue
1136                                 
1137                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1138                                     break
1139                                 
1140                                 clone_num += 1
1141                                 clone_id = 'c%d' % clone_num
1142                                 
1143                                 events[clone_id] = cur_event.copy()
1144                                 events[clone_id]['id'] = clone_id
1145                                 events[clone_id]['startdate'] = new_startdate
1146                                 events[clone_id]['enddate'] = new_enddate
1147                                 events[clone_id]['clone'] = 1
1148     
1149                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1150                                 
1151                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1152                                 
1153                         
1154                         elif cur_event['recur_type'] == 'month':
1155                             
1156                             cyear, cmonth, therecurday = getdatefield(cur_event['startdate'])
1157                             
1158                             while 1:
1159                                 
1160                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq)
1161                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1162                                 recur_day = therecurday 
1163                                 if daysinmonth < recur_day:
1164                                     recur_day = daysinmonth
1165                                 new_startdate = formatDate(cyear, cmonth, recur_day)
1166                                 
1167                                 if int(new_startdate) < int(datefrom):
1168                                     continue
1169                                 
1170                                 recurred_startdate = datetime.date(cyear, cmonth, recur_day)
1171                                 recurred_enddate = recurred_startdate + delta_date_len
1172                                 
1173                                 new_startdate = formatdateobject(recurred_startdate)
1174                                 new_enddate = formatdateobject(recurred_enddate)
1175                                 
1176                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1177                                     break
1178                                 
1179                                 clone_num += 1
1180                                 clone_id = 'c%d' % clone_num
1181                                 
1182                                 events[clone_id] = cur_event.copy()
1183                                 events[clone_id]['id'] = clone_id
1184                                 events[clone_id]['startdate'] = new_startdate
1185                                 events[clone_id]['enddate'] = new_enddate
1186                                 events[clone_id]['clone'] = 1
1187     
1188                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1189                         
1190                         elif cur_event['recur_type'] == 'year':
1191                             
1192                             ryear, rmonth, rday = getdatefield(cur_event['startdate'])
1193                             cyear, cmonth, cday = getdatefield(str(datefrom))
1194                             
1195                             while 1:
1196                                 
1197                                 ryear += recur_freq
1198                                 new_startdate = formatDate(ryear, rmonth, rday)
1199                                 
1200                                 if int(new_startdate) < int(datefrom):
1201                                     continue
1202                                     
1203                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1204                                     break
1205                                 
1206                                 recurred_startdate = datetime.date(ryear, rmonth, rday)
1207                                 recurred_enddate = recurred_startdate + delta_date_len
1208                                 
1209                                 new_startdate = formatdateobject(recurred_startdate)
1210                                 new_enddate = formatdateobject(recurred_enddate)
1211                                 
1212                                 clone_num += 1
1213                                 clone_id = 'c%d' % clone_num
1214                                 
1215                                 events[clone_id] = cur_event.copy()
1216                                 events[clone_id]['id'] = clone_id
1217                                 events[clone_id]['startdate'] = new_startdate
1218                                 events[clone_id]['enddate'] = new_enddate
1219                                 events[clone_id]['clone'] = 1
1220     
1221                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1222                 
1223                 else:
1224                     
1225                     if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1226                         events[e_id] = cur_event.copy()
1227                         insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1228             
1229             # sort cal_events
1230             # store event list into global variables in order to sort them
1231             Globs.events = events
1232         
1233             for eachdate in cal_events.keys():
1234                 cal_events[eachdate].sort(comp_cal_events)
1235             
1236             # cache update
1237             if not nocache:
1238                 cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL))
1239                 cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL))
1240         
1241     else:
1242         events = raw_events
1243         
1244         # store event list into global variables in order to sort them
1245         Globs.events = events
1246 
1247     debug(u'Total %d of events are loaded finally.' % len(events))
1248     
1249     return events, cal_events
1250 
1251 
1252 
1253 def loadEventsFromWikiPages():
1254     
1255     events = {}
1256     
1257     eventrecord_list = []
1258     eventpages = []
1259     
1260     request = Globs.request
1261     category = Params.category
1262     
1263     # cache configurations
1264     arena = Page(request, Globs.pagename)
1265     eventkey = 'events'
1266     pagelistkey = 'eventpages'
1267     
1268     cache_events = caching.CacheEntry(request, arena, eventkey)
1269     cache_pages = caching.CacheEntry(request, arena, pagelistkey)
1270     
1271     
1272     # page list cache
1273 
1274     debug('Checking page list cache')
1275     
1276     # check the time at which page list cache has been created
1277     
1278     cp_mtime = cache_pages.mtime()
1279     timedelta_days = 9999
1280     
1281     if cp_mtime:
1282         cp_date = datetime.datetime.fromtimestamp(cp_mtime)
1283         today = datetime.datetime.fromtimestamp(time.time())
1284         datediff = today - cp_date
1285         timedelta_days = datediff.days
1286         debug('Time from page list cache built = %s' % datediff)
1287 
1288     
1289     if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1:
1290         categorypages = searchPages(request, category)
1291         for page in categorypages:
1292             eventpages.append(page.page_name)
1293         cache_pages.update('\n'.join(eventpages), True)
1294         debug('New page list is built: %d pages' % len(eventpages))
1295     else:
1296         eventpages = cache_pages.content(True).split('\n')
1297         debug('Cached page list is used: %d pages' % len(eventpages))
1298     
1299 
1300     # generating events
1301     
1302     dirty = 0
1303     dirty_local = 0
1304     debug_records = {}
1305     
1306     # fetch event records from each page in the category
1307     for page_name in eventpages:
1308         
1309         p = Page(request, page_name)
1310         e_ref = page_name
1311         
1312         eventrecordkey = 'eventrecords'
1313         cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey)
1314         
1315         if cache_eventrecords.needsUpdate(p._text_filename()) or Globs.page_action == 'refresh':
1316             dirty = 1
1317             page_content = p.get_raw_body()
1318             eventrecords = getEventRecordFromPage(page_content, e_ref)
1319             debug_records[e_ref] = '%d eventrecords are fetched from %s' % (len(eventrecords), e_ref)
1320             cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1321         else:
1322             try:
1323                 eventrecords = pickle.loads(cache_eventrecords.content())
1324                 
1325                 debug_records[e_ref] = '%d cached eventrecords are used from %s' % (len(eventrecords), e_ref)
1326                 
1327                 if cache_events.needsUpdate(p._text_filename()):
1328                     dirty_local = 1
1329                 
1330             except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1331                 dirty = 1
1332                 page_content = p.get_raw_body()
1333                 eventrecords = getEventRecordFromPage(page_content, e_ref)
1334                 debug_records[e_ref] = '%d eventrecords are fetched from %s due to pickle error' % (len(eventrecords), e_ref)
1335                 cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1336 
1337         eventrecord_list.append(eventrecords)
1338 
1339     # if no dirty, just fetch the cache
1340     if not (dirty or dirty_local or Globs.page_action == 'refresh'):
1341         
1342         debug('Checking event cache: still valid')
1343         
1344         try:
1345             events = pickle.loads(cache_events.content())
1346             debug('Cached event information is used: total %d events' % len(events))
1347         except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1348             debug('Picke error at fetching cached events')
1349             events = {}
1350 
1351     else:
1352         
1353         debug('Checking event cache: it\'s dirty or requested to refresh')
1354     
1355     # if there is no events (if it needs refreshed), generate events dictionary
1356     if not len(events.keys()):
1357 
1358         # XXX: just debugging
1359         debug('Building new event information')
1360         for page_name in eventpages:
1361             debug(debug_records[page_name])
1362 
1363         day_delta = datetime.timedelta(days=1)
1364         
1365         for eventrecords in eventrecord_list:
1366         
1367             for evtrecord in eventrecords:
1368                 
1369                 e_id = evtrecord['id']
1370                 
1371                 # generating events
1372                 events[e_id] = evtrecord
1373 
1374         # after generating updated events, update the cache
1375         cache_events.update(pickle.dumps(events, PICKLE_PROTOCOL))
1376         
1377         debug('Event information is newly built: total %d events' % len(events))
1378 
1379     # end of updating events block    
1380     
1381     
1382     return events
1383     
1384 
1385 
1386 def getEventRecordFromPage(pagecontent, referpage):
1387     
1388     request = Globs.request
1389     
1390     eventrecords = []
1391     page_bgcolor = ''
1392     page_description = ''
1393     
1394     e_num = 0
1395     
1396     # fetch the page default bgcolor
1397     regex_page_bgcolor = r"""
1398 ^\s+default_bgcolor::\s*
1399 (?P<pagebgcolor>\#[0-9a-fA-F]{6})
1400 \s*
1401 $
1402 """
1403 
1404     pattern = re.compile(regex_page_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1405     match = pattern.search(pagecontent)
1406         
1407     if match:
1408         page_bgcolor = match.group('pagebgcolor')
1409 
1410     # fetch the page default description
1411     regex_page_description = r"""
1412 ^\s+default_description::\s*
1413 (?P<pagedescription>.*?)
1414 $
1415 """
1416    
1417     pattern = re.compile(regex_page_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1418     match = pattern.search(pagecontent)
1419         
1420     if match:
1421         page_description = match.group('pagedescription')
1422     
1423 
1424     # fetch event item
1425     regex_eventitem = r"""
1426 (?P<eventitem>
1427 	(?P<heading>^\s*(?P<hmarker>=+)\s(?P<eventtitle>.*?)\s(?P=hmarker) $)
1428 	(?P<eventdetail>.*?
1429 		(?=
1430 			^\s*(?P<nexthmarker>=+)\s(?P<nexteventtitle>.*?)\s(?P=nexthmarker) $
1431 			| \Z
1432         )
1433 	)
1434 )
1435 """
1436     
1437     pattern = re.compile(regex_eventitem, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1438     match = pattern.findall(pagecontent)
1439 
1440     if match:
1441         
1442         for matchitem in match:
1443             
1444             eventitem = {}
1445             
1446             eventtitle = matchitem[3]
1447             eventdetail = matchitem[4]
1448             
1449             try:
1450                 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)
1451             except (TypeError, ValueError):
1452                 #debug('An event data is corrupted: invalid event format')
1453                 continue
1454             
1455             # set default values
1456             if not e_bgcolor:
1457                 e_bgcolor = page_bgcolor
1458                 
1459             if not e_description:
1460                 e_description = page_description
1461             
1462             e_num += 1
1463             e_id = 'e_%s_%d' % (referpage, e_num)
1464             
1465             eventitem['id'] = e_id
1466             eventitem['title'] = eventtitle
1467             eventitem['startdate'] = e_start_date
1468             eventitem['starttime'] = e_start_time
1469             eventitem['enddate'] = e_end_date
1470             eventitem['endtime'] = e_end_time
1471             eventitem['title'] = eventtitle
1472             eventitem['refer'] = referpage
1473             eventitem['bgcolor'] = e_bgcolor
1474             eventitem['description'] = e_description
1475             eventitem['recur_freq'] = e_recur_freq
1476             eventitem['recur_type'] = e_recur_type
1477             eventitem['recur_until'] = e_recur_until
1478             
1479             eventitem['date_len'] = diffday(e_start_date, e_end_date) + 1
1480             eventitem['clone'] = 0
1481             eventitem['hid'] = getheadingid(request, referpage, eventtitle)
1482             
1483             if eventitem['date_len'] == 1 and e_start_time and e_end_time:
1484                 eventitem['time_len'] = difftime(e_start_time, e_end_time) + 1
1485             else:
1486                 eventitem['time_len'] = 0
1487             
1488             eventrecords.append(eventitem)
1489 
1490     return eventrecords
1491     
1492 
1493 
1494 def geteventfield(detail):
1495     
1496     regex_startdate = r"""
1497 ^\s+start::\s*
1498 (?P<startdate>\d{4}[/-]\d{2}[/-]\d{2})
1499 \s*
1500 (?P<starttime>\d{2}[:]\d{2})*
1501 \s*
1502 $
1503 """
1504 
1505     regex_enddate = r"""
1506 ^\s+end::\s*
1507 (?P<enddate>\d{4}[/-]\d{2}[/-]\d{2})*
1508 \s*
1509 (?P<endtime>\d{2}[:]\d{2})*
1510 \s*
1511 $
1512 """
1513 
1514     regex_bgcolor = r"""
1515 ^\s+bgcolor::\s*
1516 (?P<bgcolor>\#[0-9a-fA-F]{6})
1517 \s*
1518 $
1519 """
1520 
1521     regex_description = r"""
1522 ^\s+description::\s*
1523 (?P<description>.*?)
1524 $
1525 """
1526 
1527     regex_recur = r"""
1528 ^\s+recur::\s*
1529 (?P<recur_freq>\d+)
1530 \s*
1531 (?P<recur_type>day|week|weekday|month|year)
1532 \s*
1533 (
1534 	until
1535 	\s*
1536 	(?P<recur_until>\d{4}[/-]\d{2}[/-]\d{2})
1537 )*
1538 $
1539 """
1540 
1541     # need help on regular expressions for more efficient/flexible form
1542     
1543     # compile regular expression objects
1544     
1545     pattern_startdate = re.compile(regex_startdate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1546     pattern_enddate = re.compile(regex_enddate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1547     pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1548     pattern_description = re.compile(regex_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1549     pattern_recur = re.compile(regex_recur, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1550     
1551     ##################### retrieve startdate
1552     match = pattern_startdate.search(detail)
1553     
1554     if match:
1555         startdate = match.group('startdate')
1556         starttime = match.group('starttime')
1557     else:
1558         startdate = ''
1559         starttime = '' 
1560     
1561     ##################### retrieve enddate
1562     match = pattern_enddate.search(detail)
1563     
1564     if match:
1565         enddate = match.group('enddate')
1566         endtime = match.group('endtime')
1567     else:
1568         enddate = ''
1569         endtime = ''
1570 
1571     ##################### retrieve bgcolor
1572     match = pattern_bgcolor.search(detail)
1573     
1574     if match:
1575         bgcolor = match.group('bgcolor')
1576     else:
1577         bgcolor = ''
1578         
1579     ##################### retrieve description
1580     match = pattern_description.search(detail)
1581     
1582     if match:
1583         description = match.group('description')
1584     else:
1585         description = ''
1586         
1587     ##################### retrieve recurrence
1588     match = pattern_recur.search(detail)
1589     
1590     if match:
1591         recur_freq = int(match.group('recur_freq'))
1592         recur_type = match.group('recur_type')
1593         recur_until = match.group('recur_until')
1594         
1595     else:
1596         recur_freq = 0
1597         recur_type = ''
1598         recur_until = ''
1599         
1600 
1601     # check validity of each fields
1602     
1603     if not startdate:
1604         #debug('start date is not specified')
1605         # self.printoutput('Parse Error', msg, '')
1606         # ERROR
1607         return '','','','','','','','','',''
1608     
1609     #if (starttime or endtime) and not (starttime and endtime):
1610         #debug('no or 2 time field should be specified')
1611         # ERROR
1612         #return '','','','','','','','','',''
1613 
1614     if (starttime or endtime):
1615         if not endtime:
1616             endtime = starttime
1617         elif not starttime:
1618             #debug('endtime field should be specified')
1619             # ERROR
1620             return '','','','','','','','','',''
1621             
1622 
1623     # if no time, it's 1-day event
1624     if not enddate:
1625         enddate = startdate
1626     
1627     try:
1628         syear, smonth, sday = getdatefield(startdate)
1629         eyear, emonth, eday = getdatefield(enddate)
1630     except (TypeError, ValueError):
1631         #debug('invalid date format: %s, %s' % (startdate, enddate))
1632         return '','','','','','','','','',''
1633     
1634     if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
1635         #debug('startdate should precede enddate')
1636         return '','','','','','','','','',''
1637     
1638     # format date
1639     startdate = formatDate(syear, smonth, sday)
1640     enddate = formatDate(eyear, emonth, eday)
1641     
1642     if (starttime and endtime):
1643         try:
1644             shour, smin = gettimefield(starttime)
1645             ehour, emin = gettimefield(endtime)
1646         except (TypeError, ValueError):
1647             #debug('invalid time format: %s, %s' % (startdate, enddate))
1648             return '','','','','','','','','',''
1649         
1650         if startdate == enddate:
1651             if datetime.time(shour, smin) > datetime.time(ehour, emin):
1652                 #debug('starttime should precede endtime')
1653                 return '','','','','','','','','',''
1654                 
1655         # format time
1656         starttime = u'%02d%02d' %(shour, smin)
1657         endtime = u'%02d%02d' %(ehour, emin)
1658     
1659     # check recurrent data
1660     event_len = diffday(startdate, enddate)
1661     if recur_freq:
1662         
1663         if recur_type == 'day':
1664             if event_len > int(recur_freq):
1665                 debug('event length should be smaller than recurrence interval')
1666                 return '','','','','','','','','',''
1667         
1668         elif recur_type == 'week':
1669             if event_len > int(recur_freq) * 7:
1670                 debug('event length should be smaller than recurrence interval')
1671                 return '','','','','','','','','',''
1672         
1673         elif recur_type == 'weekday':
1674             if event_len > 25:
1675                 debug('event length should be smaller than recurrence interval')
1676                 return '','','','','','','','','',''
1677         
1678         elif recur_type == 'month':
1679             if event_len > int(recur_freq) * 25:
1680                 debug('event length should be smaller than recurrence interval')
1681                 return '','','','','','','','','',''
1682         
1683         elif recur_type == 'year':
1684             if event_len > int(recur_freq) * 365:
1685                 debug('event length should be smaller than recurrence interval')
1686                 return '','','','','','','','','',''
1687         
1688         if recur_until:
1689             try:
1690                 ryear, rmonth, rday = getdatefield(recur_until)
1691             except (TypeError, ValueError):
1692                 debug('invalid date format: %s' % recur_until)
1693                 return '','','','','','','','','',''
1694             
1695             recur_until = formatDate(ryear, rmonth, rday)
1696             
1697             if int(recur_until) < int(enddate):
1698                 debug('recur_until should precede enddate')
1699                 return '','','','','','','','','',''
1700     
1701     return startdate, starttime, enddate, endtime, bgcolor, description, recur_freq, recur_type, recur_until
1702 
1703 
1704 
1705 def converttext(targettext):
1706     # Converts some special characters of html to plain-text style
1707     # What else to handle?
1708 
1709     targettext = targettext.replace(u'&', '&amp')
1710     targettext = targettext.replace(u'>', '&gt;')
1711     targettext = targettext.replace(u'<', '&lt;')
1712     targettext = targettext.replace(u'\n', '<br>')
1713     targettext = targettext.replace(u'"', '&quot;')
1714     targettext = targettext.replace(u'\t', '&nbsp;&nbsp;&nbsp;&nbsp')
1715     targettext = targettext.replace(u'  ', '&nbsp;&nbsp;')
1716         
1717     return targettext
1718 
1719 
1720 # monthly view
1721 def showeventcalendar(year, month):
1722     
1723     debug('Show Calendar: Monthly View')
1724     
1725     request = Globs.request
1726     formatter = Globs.formatter
1727     _ = request.getText
1728     
1729     wkend = Globs.wkend
1730     months= Globs.months
1731     wkdays = Globs.wkdays
1732     
1733     # get the calendar
1734     monthcal = calendar.monthcalendar(year, month)
1735 
1736     # shows current year & month
1737     html_header_curyearmonth = calhead_yearmonth(year, month, 'head_yearmonth')
1738     
1739     r7 = range(7)
1740     
1741     # shows header of week days
1742     html_header_weekdays = []
1743     
1744     for wkday in r7:
1745         wday = _(wkdays[wkday])
1746         html_header_weekdays.append( calhead_weekday(wday, 'head_weekday') )
1747     html_header_weekdays = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
1748  
1749     # pending events for next row
1750     next_pending = []
1751     
1752     # gets previous, next month
1753     day_delta = datetime.timedelta(days=-1)
1754     cur_month = datetime.date(year, month, 1)
1755     prev_month = cur_month + day_delta
1756     
1757     day_delta = datetime.timedelta(days=15)
1758     cur_month_end = datetime.date(year, month, 25)
1759     next_month = cur_month_end + day_delta
1760     
1761     prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
1762     next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
1763     
1764     # shows days
1765     html_week_rows = []
1766     
1767     # set ranges of events
1768     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
1769     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
1770     
1771     # read all the events
1772     events, cal_events = loadEvents(datefrom, dateto)
1773     
1774     #debug(u'  events: %s' % events)
1775     #debug(u'  cal_events: %s' % cal_events)
1776     
1777     for week in monthcal:
1778         
1779         # day head rows
1780         html_headday_cols = []
1781         html_events_rows = []
1782         
1783         for wkday in r7:
1784              
1785             day = week[wkday]
1786             
1787             if not day:
1788                 if week == monthcal[0]:
1789                     nb_day = prev_monthcal[-1][wkday]
1790                 else:
1791                     nb_day = next_monthcal[0][wkday]
1792                     
1793                 html_headday_cols.append( calhead_day_nbmonth(nb_day) )
1794             else:
1795                 html_headday_cols.append( calhead_day(year, month, day, wkday) )
1796         
1797         html_headday_row = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
1798         html_week_rows.append(html_headday_row)
1799         
1800         # dummy rows
1801         html_headdummy_cols = []
1802         
1803         for wkday in r7:
1804             day = week[wkday]
1805             if not day:
1806                 html_headdummy_cols.append( calshow_blankbox('head_dummy_nbmonth') )
1807             else:
1808                 html_headdummy_cols.append( calshow_blankbox('head_dummy') )
1809         
1810         html_headdummy_cols = u'\r\n'.join(html_headdummy_cols)
1811         html_week_rows.append(' <tr>\r\n%s </tr>\r\n' % html_headdummy_cols)
1812         
1813         # pending events for next row
1814         pending = next_pending
1815         next_pending = []
1816         
1817         # show events
1818         while 1: 
1819             event_left = 7
1820             colspan = -1
1821             html_events_cols = []
1822 
1823             for wkday in r7:
1824              
1825                 day = week[wkday]
1826                 
1827                 if not day:
1828                     if week == monthcal[0]:
1829                         cur_date = formatDate(prev_month.year, prev_month.month, prev_monthcal[-1][wkday])
1830                     else:
1831                         cur_date = formatDate(next_month.year, next_month.month, next_monthcal[0][wkday])
1832                 else:
1833                     cur_date = formatDate(year, month, day)
1834 
1835                 # if an event is already displayed with colspan
1836                 if colspan > 0:
1837                     colspan -= 1
1838                     if cal_events.has_key(cur_date) and lastevent in cal_events[cur_date]:
1839                         cal_events[cur_date].remove(lastevent)
1840                     
1841                     continue
1842                     
1843                 # if there is any event for this date
1844                 if cal_events.has_key(cur_date):
1845                     if len(cal_events[cur_date]) > 0:
1846                         
1847                         # if there is any pending event in the previous week
1848                         if wkday == 0 and len(pending) > 0:
1849                             todo_event_id = pending.pop(0)
1850                             if todo_event_id in cal_events[cur_date]:
1851                                 cur_event = events[todo_event_id]
1852                                 temp_len = diffday(cur_date, cur_event['enddate']) + 1
1853                                 
1854                                 # calculate colspan value
1855                                 if (7-wkday) < temp_len:
1856                                     colspan = 7 - wkday
1857                                     next_pending.append(cur_event['id'])
1858                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
1859 
1860                                 else:
1861                                     colspan = temp_len
1862                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
1863                                 
1864                                 
1865                                 cal_events[cur_date].remove(todo_event_id)
1866 
1867                                 colspan -= 1
1868                                 lastevent = todo_event_id
1869                             else:
1870                                 debug('Warning: no such event in cal_events')
1871                             
1872                             continue
1873                         
1874                         # if there is no pending event in the previous week, start a new event
1875                         event_found = 0
1876                         for e_id in cal_events[cur_date]:
1877                             
1878                             # if the start date of the event is current date    
1879                             if events[e_id]['startdate'] == cur_date:
1880                                 
1881                                 cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
1882                                 
1883                                 # calculate colspan value
1884                                 if (7-wkday) < cur_event['date_len']:
1885                                     colspan = 7 - wkday
1886                                     next_pending.append(cur_event['id'])
1887                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'pending', cur_date) )
1888 
1889                                 else:
1890                                     colspan = cur_event['date_len']
1891                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, '', cur_date) )
1892                                 
1893                                 colspan -= 1
1894                                 lastevent = cur_event['id']
1895                                 event_found = 1
1896                                 break
1897                             
1898                             # if the start date of the event is NOT current date
1899                             else:
1900                                 
1901                                 # pending event from previous month
1902                                 if wkday == 0 and week == monthcal[0]:
1903                                     
1904                                     cur_event = events[cal_events[cur_date].pop(0)]
1905                                     temp_len = diffday(cur_date, cur_event['enddate']) + 1
1906                                     
1907                                     # calculate colspan value
1908                                     if (7-wkday) < temp_len:
1909                                         colspan = 7 - wkday
1910                                         next_pending.append(cur_event['id'])
1911                                         html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
1912                                     else:
1913                                         colspan = temp_len
1914                                         html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
1915                                     
1916                                     colspan -= 1
1917                                     lastevent = cur_event['id']
1918                                     event_found = 1
1919                                     break
1920                                 
1921                         # if there is no event to start
1922                         if not event_found:
1923                             if not day:
1924                                 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1925                             else:
1926                                 html_events_cols.append( calshow_blankbox('cal_noevent') )
1927                             event_left -= 1
1928                                 
1929                     else:
1930                         if not day:
1931                             html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1932                         else:
1933                             html_events_cols.append( calshow_blankbox('cal_noevent') )
1934                         
1935                         event_left -= 1        
1936                 
1937                 # if there is NO event for this date
1938                 else:
1939                     if not day:
1940                         html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1941                     else:
1942                         html_events_cols.append( calshow_blankbox('cal_noevent') )
1943                         
1944                     event_left -= 1
1945             
1946             # if no event for this entry
1947             if not event_left:
1948                 # ignore the previous entry
1949                 break
1950             else:
1951                 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
1952             
1953         # show dummy blank slots for week height
1954         left_blank_rows = 2 - len(html_events_rows)
1955         
1956         # remove the followings
1957         if left_blank_rows > 0 and 0:
1958             for i in range(left_blank_rows):
1959                 html_events_cols = []
1960                 for wkday in r7:
1961                     day = week[wkday]
1962                     if not day:
1963                         html_events_cols.append( calshow_blankbox('cal_nbmonth') )
1964                     else:
1965                         html_events_cols.append( calshow_blankbox('cal_noevent') )
1966                 
1967                 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
1968         
1969         
1970         # close the week slots
1971         html_events_cols = []
1972         for wkday in r7:
1973             day = week[wkday]
1974             if not day:
1975                 html_events_cols.append( calshow_blankbox('cal_last_nbmonth') )
1976             else:
1977                 html_events_cols.append( calshow_blankbox('cal_last_noevent') )
1978     
1979         html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
1980         
1981         html_events_rows = u'\r\n'.join(html_events_rows)
1982         html_week_rows.append(html_events_rows)
1983             
1984     html_calendar_rows = u'\r\n'.join(html_week_rows)
1985     
1986     html_cal_table = [
1987         u'\r\n<div id="eventcalendar">',
1988         u'<table class="eventcalendar" %s>' % Params.monthlywidth,
1989         u'%s' % html_header_curyearmonth,
1990         u'%s' % html_header_weekdays,
1991         u'%s' % html_calendar_rows,
1992         u'</table>',
1993         u'</div>',
1994         ]
1995     html_cal_table = u'\r\n'.join(html_cal_table)
1996         
1997     return html_cal_table
1998 
1999 
2000 
2001 # daily view
2002 def showdailyeventcalendar(year, month, day):
2003     
2004     debug('Show Calendar: Daily View')
2005     
2006     request = Globs.request
2007     formatter = Globs.formatter
2008     _ = request.getText
2009     
2010     wkend = Globs.wkend
2011     months= Globs.months
2012     wkdays = Globs.wkdays
2013     
2014     cur_date = formatDate(year, month, day)
2015     
2016     # gets previous, next month
2017     day_delta = datetime.timedelta(days=-1)
2018     cur_month = datetime.date(year, month, 1)
2019     prev_month = cur_month + day_delta
2020     
2021     day_delta = datetime.timedelta(days=15)
2022     cur_month_end = datetime.date(year, month, 25)
2023     next_month = cur_month_end + day_delta
2024     
2025     # set ranges of events
2026     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2027     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2028     
2029     # read all the events
2030     events, cal_events = loadEvents(datefrom, dateto)
2031     
2032     #debug(u'  events: %s' % events)
2033     #debug(u'  cal_events: %s' % cal_events)
2034     
2035     # calculates hour_events
2036     hour_events = {}
2037     
2038     if cal_events.has_key(cur_date):
2039         for e_id in cal_events[cur_date]:
2040             cur_event = events[e_id]
2041             
2042             if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2043                 start_hour, start_min = gettimefield(cur_event['starttime'])
2044                 
2045                 if not hour_events.has_key(start_hour):
2046                     hour_events[start_hour] = []
2047                 
2048                 hour_events[start_hour].append(e_id)
2049 
2050     #debug(u'hour_events: %s' % hour_events)
2051 
2052     # in-day events
2053     html_calendar_rows = []
2054     html_hour_cols = {}
2055     
2056     slot_pending = {}
2057     max_num_slots = 0
2058     hour_max_slots = {}
2059     block_slots = []
2060     
2061     start_hour_index = 0
2062     
2063     r24 = range(24)
2064     
2065     for hour_index in r24:
2066         
2067         html_hour_cols[hour_index] = []
2068         hour_max_slots[hour_index] = 1
2069         html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
2070         
2071         if len(slot_pending) > 0 or hour_events.has_key(hour_index):
2072             
2073             #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2074             if len(slot_pending) == 0:
2075                 if max_num_slots < 1:
2076                     max_num_slots = 1
2077                 
2078                 for hour_lines in range(start_hour_index, hour_index):
2079                     hour_max_slots[hour_lines] = max_num_slots
2080                 
2081                 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2082                 
2083                 block_slots.append(max_num_slots)
2084                 
2085                 max_num_slots = 0
2086                 start_hour_index = hour_index
2087             
2088             for slot_index in range(max_num_slots):
2089                 if slot_pending.has_key(slot_index) and slot_pending[slot_index] > 0:
2090                     if slot_pending[slot_index] == 1:
2091                         del slot_pending[slot_index]
2092                     else:
2093                         slot_pending[slot_index] -= 1
2094                     html_hour_cols[hour_index].append ( '' )
2095                     
2096                 else:
2097                     if hour_events.has_key(hour_index) and len(hour_events[hour_index]) > 0:
2098                         e_id = hour_events[hour_index][0]
2099                         cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2100                         html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2101                         slot_pending[slot_index] = cur_event['time_len'] - 1
2102                     else:
2103                         if not ((len(slot_pending) > 0 and slot_index > max(slot_pending.keys())) or len(slot_pending) == 0):
2104                             html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2105 
2106             if hour_events.has_key(hour_index):
2107                 for tmp_cnt in range(len(hour_events[hour_index])):
2108                     e_id = hour_events[hour_index][0]
2109                     cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2110                     html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2111                     slot_pending[max_num_slots] = cur_event['time_len'] - 1
2112                     if slot_pending[max_num_slots] == 0:
2113                         del slot_pending[max_num_slots]
2114                     max_num_slots += 1
2115 
2116         else:
2117             html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2118             #hour_max_slots[hour_index] = 1
2119             
2120             if max_num_slots < 1:
2121                 max_num_slots = 1
2122             
2123             for hour_lines in range(start_hour_index, hour_index):
2124                 hour_max_slots[hour_lines] = max_num_slots
2125             
2126             #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2127             
2128             block_slots.append(max_num_slots)
2129             
2130             max_num_slots = 0
2131             start_hour_index = hour_index
2132             
2133         
2134         #debug('end: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2135         
2136     if max_num_slots < 1:
2137         max_num_slots = 1
2138     
2139     for hour_lines in range(start_hour_index, 24):
2140         hour_max_slots[hour_lines] = max_num_slots
2141     
2142     #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, 23, max_num_slots))
2143     
2144     block_slots.append(max_num_slots)
2145     
2146     #debug('hour_max_slots: %s' % hour_max_slots)
2147     
2148     
2149     # calculates global colspan
2150     if len(block_slots):
2151         global_colspan = LCM(block_slots)
2152     else:
2153         global_colspan = 1
2154 
2155     for hour_index in r24:
2156         
2157         colspan = global_colspan / hour_max_slots[hour_index]
2158         width = 96 / hour_max_slots[hour_index]
2159         
2160         left_slots = hour_max_slots[hour_index] - (len(html_hour_cols[hour_index]) - 1)
2161         
2162         if left_slots > 0:
2163             #debug('appending left %d slots: %d' % (left_slots, hour_index))
2164             html_hour_cols[hour_index].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
2165         
2166         html_cols = u'\r\n'.join(html_hour_cols[hour_index]) % {'colspan': colspan, 'width': u'%d%%' % width}
2167         html_cols = u'<tr>%s</tr>\r\n' % html_cols
2168         
2169         html_calendar_rows.append (html_cols)
2170 
2171     html_calendar_rows = u'\r\n'.join(html_calendar_rows)
2172     
2173     # shows current year & month
2174     html_header_curyearmonthday = calhead_yearmonthday(year, month, day, 'head_yearmonth', global_colspan)
2175     
2176     # one-day long events
2177     html_oneday_rows = []
2178     
2179     #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2180     
2181     if cal_events.has_key(cur_date):
2182         if len(cal_events[cur_date]) > 0:
2183             for e_id in cal_events[cur_date]:
2184                 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2185                 #debug('test events[%s] = %s' % (e_id, events[e_id]))
2186                 if events[e_id]['time_len'] <= 0 or events[e_id]['date_len'] > 1:
2187                     #cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2188                     cur_event = events[e_id]
2189                     
2190                     if cur_event['startdate'] == cur_date:
2191                         if cur_event['enddate'] == cur_date:
2192                             str_status = ''
2193                         else:
2194                             str_status = 'pending'
2195                     else:
2196                         if cur_event['enddate'] == cur_date:
2197                             str_status = 'append'
2198                         else:
2199                             str_status = 'append_pending'
2200                     
2201                     tmp_html = u'<tr><td width="4%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % calshow_daily_eventbox2(cur_event, global_colspan, str_status, cur_date)
2202                     html_oneday_rows.append( tmp_html )
2203                     
2204                 #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2205     else:
2206         tmp_html = u'<tr><td width="4%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % calshow_blankbox2('cal_daily_noevent', global_colspan)
2207         html_oneday_rows.append( tmp_html )
2208     
2209     #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2210     #debug('html_oneday_rows = %s' % html_oneday_rows)
2211     
2212     html_oneday_rows = u'\r\n'.join(html_oneday_rows)
2213     
2214    
2215     html_cal_table = [
2216         u'\r\n<div id="eventcalendar">',
2217         u'<table class="eventcalendar" %s>' % Params.dailywidth,
2218         u'<table border="0">',
2219         u'%s' % html_header_curyearmonthday,
2220         u'%s' % html_oneday_rows,
2221         u'%s' % html_calendar_rows,
2222         u'</table>',
2223         u'</td></tr>',
2224         u'</div>',
2225         ]
2226     html_cal_table = u'\r\n'.join(html_cal_table)
2227         
2228     return html_cal_table
2229 
2230 
2231 
2232 # weekly view
2233 def showweeklyeventcalendar(year, month, day):
2234     
2235     debug('Show Calendar: Weekly View')
2236     
2237     request = Globs.request
2238     formatter = Globs.formatter
2239     _ = request.getText
2240     
2241     wkend = Globs.wkend
2242     months= Globs.months
2243     wkdays = Globs.wkdays
2244     
2245     cur_date = formatDate(year, month, day)
2246     
2247     # gets previous, next month
2248     day_delta = datetime.timedelta(days=-1)
2249     cur_month = datetime.date(year, month, 1)
2250     prev_month = cur_month + day_delta
2251     
2252     day_delta = datetime.timedelta(days=15)
2253     cur_month_end = datetime.date(year, month, 25)
2254     next_month = cur_month_end + day_delta
2255     
2256     # set ranges of events
2257     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2258     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2259     
2260     # read all the events
2261     events, cal_events = loadEvents(datefrom, dateto)
2262     
2263     #debug(u'  events: %s' % events)
2264     #debug(u'  cal_events: %s' % cal_events)
2265     
2266     # calculates hour_events
2267     hour_events = {}
2268     
2269     first_date_week = getFirstDateOfWeek(year, month, day)
2270     
2271     
2272     for dayindex in range(7):
2273         hour_events[dayindex] = {}
2274         
2275         cur_date = first_date_week + datetime.timedelta(dayindex)
2276         cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
2277         
2278         if cal_events.has_key(cur_date):
2279             for e_id in cal_events[cur_date]:
2280                 cur_event = events[e_id]
2281                 
2282                 if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2283                     start_hour, start_min = gettimefield(cur_event['starttime'])
2284                     
2285                     if not hour_events[dayindex].has_key(start_hour):
2286                         hour_events[dayindex][start_hour] = []
2287                     
2288                     hour_events[dayindex][start_hour].append(e_id)
2289 
2290     #debug(u'hour_events: %s' % hour_events)
2291 
2292     # in-day events
2293     html_calendar_rows = []
2294     html_hour_cols = {}
2295     
2296     slot_pending = {}
2297     max_num_slots = {}
2298     hour_max_slots = {}
2299     block_slots = {}
2300     
2301     start_hour_index = {}
2302     
2303     r24 = range(24)
2304     
2305     for hour_index in r24:
2306         
2307         html_hour_cols[hour_index] = {}
2308         hour_max_slots[hour_index] = {}
2309             
2310         #html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
2311         
2312         for dayindex in range(7):
2313             
2314             if not max_num_slots.has_key(dayindex):
2315                 max_num_slots[dayindex] = 0
2316                
2317             if not slot_pending.has_key(dayindex):
2318                 slot_pending[dayindex] = {}
2319             
2320             if not start_hour_index.has_key(dayindex):
2321                 start_hour_index[dayindex] = 0
2322                 
2323             if not block_slots.has_key(dayindex):
2324                 block_slots[dayindex] = []
2325             
2326             html_hour_cols[hour_index][dayindex] = []
2327             hour_max_slots[hour_index][dayindex] = 1
2328         
2329             if len(slot_pending[dayindex]) > 0 or hour_events[dayindex].has_key(hour_index):
2330                 
2331                 #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending[dayindex]))
2332                 if len(slot_pending[dayindex]) == 0:
2333                     if max_num_slots[dayindex] < 1:
2334                         max_num_slots[dayindex] = 1
2335                     
2336                     for hour_lines in range(start_hour_index[dayindex], hour_index):
2337                         hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
2338                     
2339                     #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
2340                     
2341                     block_slots[dayindex].append(max_num_slots[dayindex])
2342                     
2343                     max_num_slots[dayindex] = 0
2344                     start_hour_index[dayindex] = hour_index
2345                 
2346                 for slot_index in range(max_num_slots[dayindex]):
2347                     if slot_pending[dayindex].has_key(slot_index) and slot_pending[dayindex][slot_index] > 0:
2348                         if slot_pending[dayindex][slot_index] == 1:
2349                             del slot_pending[dayindex][slot_index]
2350                         else:
2351                             slot_pending[dayindex][slot_index] -= 1
2352                         html_hour_cols[hour_index][dayindex].append ( '' )
2353                         
2354                     else:
2355                         if hour_events[dayindex].has_key(hour_index) and len(hour_events[dayindex][hour_index]) > 0:
2356                             e_id = hour_events[dayindex][hour_index][0]
2357                             cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
2358                             html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
2359                             slot_pending[dayindex][slot_index] = cur_event['time_len'] - 1
2360                         else:
2361                             if not ((len(slot_pending[dayindex]) > 0 and slot_index > max(slot_pending[dayindex].keys())) or len(slot_pending[dayindex]) == 0):
2362                                 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
2363     
2364                 if hour_events[dayindex].has_key(hour_index):
2365                     for tmp_cnt in range(len(hour_events[dayindex][hour_index])):
2366                         e_id = hour_events[dayindex][hour_index][0]
2367                         cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
2368                         html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
2369                         slot_pending[dayindex][max_num_slots[dayindex]] = cur_event['time_len'] - 1
2370                         if slot_pending[dayindex][max_num_slots[dayindex]] == 0:
2371                             del slot_pending[dayindex][max_num_slots[dayindex]]
2372                         max_num_slots[dayindex] += 1
2373     
2374             else:
2375                 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
2376                 #hour_max_slots[hour_index][dayindex] = 1
2377                 
2378                 if max_num_slots[dayindex] < 1:
2379                     max_num_slots[dayindex] = 1
2380                 
2381                 for hour_lines in range(start_hour_index[dayindex], hour_index):
2382                     hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
2383                 
2384                 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
2385                 
2386                 block_slots[dayindex].append(max_num_slots[dayindex])
2387                 
2388                 max_num_slots[dayindex] = 0
2389                 start_hour_index[dayindex] = hour_index
2390             
2391     global_colspan = {}
2392     header_colspan = 0
2393 
2394     for dayindex in range(7):
2395         if max_num_slots[dayindex] < 1:
2396             max_num_slots[dayindex] = 1
2397         
2398         for hour_lines in range(start_hour_index[dayindex], 24):
2399             hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
2400         
2401         block_slots[dayindex].append(max_num_slots[dayindex])
2402         
2403         # calculates global colspan
2404         if len(block_slots[dayindex]):
2405             global_colspan[dayindex] = LCM(block_slots[dayindex])
2406         else:
2407             global_colspan[dayindex] = 1
2408         
2409         header_colspan += global_colspan[dayindex]
2410 
2411 
2412     for hour_index in r24:
2413         
2414         html_cols_days = []
2415         
2416         for dayindex in range(7):
2417         
2418             colspan = global_colspan[dayindex] / hour_max_slots[hour_index][dayindex]
2419             width = (100 - 2) / 7 / hour_max_slots[hour_index][dayindex]
2420             
2421             left_slots = hour_max_slots[hour_index][dayindex] - len(html_hour_cols[hour_index][dayindex])
2422             
2423             if left_slots > 0:
2424                 #debug('appending left %d slots: %d' % (left_slots, hour_index))
2425                 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
2426             
2427             html_cols = u'\r\n'.join(html_hour_cols[hour_index][dayindex]) % {'colspan': colspan, 'width': u'%d%%' % width}
2428             html_cols_days.append(html_cols)
2429             
2430         html_cols_collected = u'\r\n'.join(html_cols_days)
2431         html_cols = u'<tr>%s\r\n%s</tr>\r\n' % (calshow_weekly_hourhead(hour_index), html_cols_collected)
2432         
2433         html_calendar_rows.append (html_cols)
2434 
2435     html_calendar_rows = u'\r\n'.join(html_calendar_rows)
2436     
2437     # shows current year & month
2438     html_header_curyearmonthday = calhead_yearmonthday2(year, month, day, 'head_yearmonth', header_colspan)
2439     
2440     # one-day long events
2441     html_oneday_rows = {}
2442     
2443     #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2444     
2445     #first_date_week = getFirstDateOfWeek(year, month, day)
2446     
2447     html_oneday_rows = []
2448     
2449     while 1:
2450         html_oneday_cols = []
2451         cnt_blank_cols = 0
2452         pending = -1
2453         
2454         for dayindex in range(7):
2455             
2456             if pending > 0:
2457                 pending -= 1
2458                 html_oneday_cols.append('')
2459                 continue
2460             else:
2461                 pending = -1
2462             
2463             cur_date = first_date_week + datetime.timedelta(dayindex)
2464             cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
2465             
2466             if cal_events.has_key(cur_date) and len(cal_events[cur_date]) > 0:
2467                 
2468                 tmpcount = len(cal_events[cur_date])
2469                 for tmp_index in range(tmpcount):
2470                     cur_event = events[cal_events[cur_date].pop(0)]
2471                     
2472                     #debug('event poped out at %s: %s' % (cur_date, cur_event))
2473                     
2474                     if (cur_event['startdate'] <= cur_date and dayindex == 0) or cur_event['startdate'] == cur_date:
2475                         if cur_event['time_len'] <= 0 or cur_event['date_len'] > 1:
2476                         
2477                             temp_len = diffday(cur_date, cur_event['enddate']) + 1
2478                             
2479                             if cur_event['startdate'] == cur_date:
2480                                 if temp_len <= 7 - dayindex:
2481                                     str_status = ''
2482                                 else:
2483                                     str_status = 'pending'
2484                             else:
2485                                 if temp_len <= 7 - dayindex:
2486                                     str_status = 'append'
2487                                 else:
2488                                     str_status = 'append_pending'
2489                             
2490                             if temp_len > 7 - dayindex:
2491                                 temp_len = 7 - dayindex
2492                             
2493                             pending = temp_len - 1
2494                             
2495                             tmp_global_colspan = 0
2496                             for tmp_index in range(dayindex, dayindex+temp_len):
2497                                 tmp_global_colspan += global_colspan[tmp_index]
2498                             
2499                             #debug('event appended at %s with pending=%d: %s' % (cur_date, pending, cur_event))
2500                             
2501                             html_oneday_cols.append( calshow_weekly_eventbox2(cur_event, tmp_global_colspan, 14 * temp_len, str_status, cur_date) )
2502                             break
2503                             
2504                 if pending < 0:
2505                     html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
2506                     cnt_blank_cols += 1
2507 
2508             else:
2509                 html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
2510                 cnt_blank_cols += 1
2511                 
2512         if cnt_blank_cols >= 7:
2513             if len(html_oneday_rows) == 0:
2514                 html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
2515                 html_oneday_rows.append (html_oneday_cols)
2516             break
2517         else:
2518             html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
2519             html_oneday_rows.append (html_oneday_cols)
2520         
2521     html_date_rows = []
2522     
2523     for dayindex in range(7):
2524         cur_date = first_date_week + datetime.timedelta(dayindex)
2525         html_date_rows.append(calhead_weeklydate(cur_date.year, cur_date.month, cur_date.day, global_colspan[dayindex]))
2526 
2527     html_date_rows = u'<tr><td width="2%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % u'\r\n'.join(html_date_rows)
2528 
2529     html_oneday_rows = u'\r\n'.join(html_oneday_rows)
2530    
2531     html_cal_table = [
2532         u'\r\n<div id="eventcalendar">',
2533         u'<table class="eventcalendar" %s>' % Params.weeklywidth,
2534         u'<table border="0">',
2535         u'%s' % html_header_curyearmonthday,
2536         u'%s' % html_date_rows,
2537         u'%s' % html_oneday_rows,
2538         u'%s' % html_calendar_rows,
2539         u'</table>',
2540         u'</td></tr>',
2541         u'</div>',
2542         ]
2543     html_cal_table = u'\r\n'.join(html_cal_table)
2544         
2545     return html_cal_table
2546 
2547 
2548 
2549 # simple view
2550 def showsimpleeventcalendar(year, month):
2551     
2552     debug('Show Calendar: Simple View')
2553     
2554     request = Globs.request
2555     formatter = Globs.formatter
2556     _ = request.getText
2557     monthstyle_us = Globs.month_style_us
2558     
2559     wkend = Globs.wkend
2560     months= Globs.months
2561     wkdays = Globs.wkdays
2562     
2563     # get the calendar
2564     monthcal = calendar.monthcalendar(year, month)
2565 
2566     # shows current year & month
2567     html_header_curyearmonth = calhead_yearmonth(year, month, 'simple_yearmonth')
2568     
2569     r7 = range(7)
2570     
2571     # shows header of week days
2572     html_header_weekdays = []
2573     
2574     for wkday in r7:
2575         wday = wkdays[wkday]
2576         html_header_weekdays.append( calhead_weekday(wday, 'simple_weekday') )
2577     html_header_weekdays = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
2578  
2579     # gets previous, next month
2580     day_delta = datetime.timedelta(days=-1)
2581     cur_month = datetime.date(year, month, 1)
2582     prev_month = cur_month + day_delta
2583     
2584     day_delta = datetime.timedelta(days=15)
2585     cur_month_end = datetime.date(year, month, 25)
2586     next_month = cur_month_end + day_delta
2587     
2588     prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
2589     next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
2590     
2591     # shows days
2592     html_week_rows = []
2593 
2594     # set ranges of events
2595     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2596     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2597     
2598     # read all the events
2599     events, cal_events = loadEvents(datefrom, dateto)
2600     
2601     maketip_js = []
2602     
2603     for week in monthcal:
2604         
2605         # day head rows
2606         html_headday_cols = []
2607         html_events_rows = []
2608         
2609         for wkday in r7:
2610              
2611             day = week[wkday]
2612             
2613             if not day:
2614                 if week == monthcal[0]:
2615                     nb_day = prev_monthcal[-1][wkday]
2616                 else:
2617                     nb_day = next_monthcal[0][wkday]
2618                     
2619                 html_headday_cols.append( simple_eventbox(year, month, day, nb_day, 'simple_nb') )
2620             else:
2621                 cur_date = formatDate(year, month, day)
2622                 
2623                 if cal_events.has_key(cur_date):
2624                     html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_event') )
2625                     
2626                     if monthstyle_us:
2627                         tiptitle = u'%s %d, %d' % (months[month-1], day, year)
2628                     else:
2629                         tiptitle = u'%d / %02d / %02d' % (year, month, day)
2630 
2631                     date_today = datetime.date( year, month, day )                    
2632                     tiptitle = u'%s (%s)' % (tiptitle, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
2633                     
2634                     tiptext = []
2635                     
2636                     for e_id in cal_events[cur_date]:
2637                         cur_event = events[e_id]
2638                         if cur_event['starttime']:
2639                             time_string = u'(%s:%s)' % (cur_event['starttime'][:2], cur_event['starttime'][2:])
2640                         else:
2641                             time_string = ''
2642 
2643                         title = wikiutil.escape(cur_event['title']).replace("'","\\'")
2644                         description = wikiutil.escape(cur_event['description']).replace("'","\\'")
2645                         
2646                         tiptext.append( u'<b>%s</b>%s %s' % (title, time_string, description) )
2647                     
2648                     tiptext = u'<br>'.join(tiptext)
2649                     
2650                     maketip_js.append("maketip('%s','%s','%s');" % (cur_date, tiptitle, tiptext))
2651                 else:
2652                     html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_noevent') )
2653         
2654         html_headday_row = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
2655         html_week_rows.append(html_headday_row)
2656             
2657     html_calendar_rows = u'\r\n'.join(html_week_rows)
2658     
2659     html_tooltip_result = """\
2660 <script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script>
2661 <div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div>
2662 <script language="JavaScript" type="text/javascript">
2663 <!--
2664 %s
2665 // -->
2666 </script>
2667 
2668 """ % (request.cfg.url_prefix, "\n".join(maketip_js))
2669     
2670     
2671     html_cal_table = [
2672         u'\r\n<div id="eventcalendar">',
2673         u'%s' % html_tooltip_result,
2674         u'<table class="simplecalendar" %s>' % Params.simplewidth,
2675         u'%s' % html_header_curyearmonth,
2676         u'%s' % html_header_weekdays,
2677         u'%s' % html_calendar_rows,
2678         u'</table>',
2679         u'</div>',
2680         ]
2681     html_cal_table = u'\r\n'.join(html_cal_table)
2682         
2683     return html_cal_table
2684 
2685 
2686 # show calendar head (year & month)
2687 def calhead_yearmonth(year, month, headclass):
2688     
2689     request = Globs.request
2690     
2691     months = Globs.months
2692     monthstyle_us = Globs.month_style_us
2693     cal_action = Globs.cal_action
2694     page_name = Globs.pagename
2695     
2696     page_url = Globs.pageurl
2697     
2698     nextyear, nextmonth = yearmonthplusoffset(year, month, 1)
2699     prevyear, prevmonth = yearmonthplusoffset(year, month, -1)
2700     
2701     prevlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, prevyear, prevmonth, getquerystring(['numcal']) )
2702     nextlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, nextyear, nextmonth, getquerystring(['numcal']))
2703     curlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, year, month, getquerystring(['numcal']))
2704     
2705     if monthstyle_us:
2706         stryearmonth = u'%s %d' % (months[month-1], year)
2707         strnextmonth = u'%s %d' % (months[nextmonth-1], nextyear)
2708         strprevmonth = u'%s %d' % (months[prevmonth-1], prevyear)
2709     else:
2710         stryearmonth = u'%d / %02d' % (year, month)
2711         strnextmonth = u'%d / %02d' % (nextyear, nextmonth)
2712         strprevmonth = u'%d / %02d' % (prevyear, prevmonth)
2713     
2714     html = [
2715         u'  <tr>',
2716         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
2717         u'      <td colspan="5" class="%s"><a href="%s" title="Go/Refresh this month">%s</a></td>' % (headclass, curlink, stryearmonth),
2718         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
2719         u'  </tr>',
2720         ]
2721         
2722     return u'\r\n'.join(html)
2723 
2724 
2725 # show calendar head (year & month & day)
2726 def calhead_yearmonthday(year, month, day, headclass, colspan):
2727     
2728     request = Globs.request
2729     _ = request.getText
2730     
2731     months = Globs.months
2732     monthstyle_us = Globs.month_style_us
2733     cal_action = Globs.cal_action
2734     page_name = Globs.pagename
2735     wkdays = Globs.wkdays
2736     
2737     page_url = Globs.pageurl
2738     
2739     date_today = datetime.date( year, month, day )
2740     prevdate = date_today - datetime.timedelta(days=1)
2741     nextdate = date_today + datetime.timedelta(days=1)
2742     
2743     prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
2744     nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
2745     curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
2746     
2747     if monthstyle_us:
2748         stryearmonth = u'%s %d, %d' % (months[month-1], day, year)
2749         strnextmonth = u'%s %d, %d' % (months[nextdate.month-1], nextdate.day, nextdate.year)
2750         strprevmonth = u'%s %d, %d' % (months[prevdate.month-1], prevdate.day, prevdate.year)
2751     else:
2752         stryearmonth = u'%d / %02d / %02d' % (year, month, day)
2753         strnextmonth = u'%d / %02d / %02d' % (nextdate.year, nextdate.month, nextdate.day)
2754         strprevmonth = u'%d / %02d / %02d' % (prevdate.year, prevdate.month, prevdate.day)
2755     
2756     #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday()]))
2757     stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
2758     
2759     html = [
2760         u'<tr><td width="4%" style="border: none;">&nbsp;</td>',
2761         u'<td colspan="%d" style="border: none;">' % colspan,
2762         u'<table width="95%">',
2763         u'  <tr>',
2764         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
2765         u'      <td class="%s"><a href="%s" title="Go/Refresh this day">%s</a></td>' % (headclass, curlink, stryearmonth),
2766         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
2767         u'  </tr>',
2768         u'</table>',
2769         u'</td></tr>',
2770         ]
2771         
2772     return u'\r\n'.join(html)
2773     
2774 # show calendar head for weekly view (year & month & day)
2775 def calhead_yearmonthday2(year, month, day, headclass, colspan):
2776     
2777     request = Globs.request
2778     _ = request.getText
2779     
2780     months = Globs.months
2781     monthstyle_us = Globs.month_style_us
2782     cal_action = Globs.cal_action
2783     page_name = Globs.pagename
2784     wkdays = Globs.wkdays
2785     
2786     page_url = Globs.pageurl
2787     
2788     date_today = datetime.date( year, month, day )
2789     prevdate = date_today - datetime.timedelta(days=7)
2790     nextdate = date_today + datetime.timedelta(days=7)
2791     
2792     first_date_week = getFirstDateOfWeek(year, month, day)    
2793     prevdate_f = first_date_week - datetime.timedelta(days=7)
2794     nextdate_f = first_date_week + datetime.timedelta(days=7)
2795     
2796     last_date_week = first_date_week + datetime.timedelta(days=6)
2797     prevdate_l = last_date_week - datetime.timedelta(days=7)
2798     nextdate_l = last_date_week + datetime.timedelta(days=7)
2799     
2800     prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
2801     nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
2802     curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
2803     
2804     if monthstyle_us:
2805         stryearmonth = u'%s %d, %d ~ %s %d, %d' % (months[first_date_week.month-1], first_date_week.day, first_date_week.year, months[last_date_week.month-1], last_date_week.day, last_date_week.year)
2806         strnextmonth = u'%s %d, %d ~ %s %d, %d' % (months[nextdate_f.month-1], nextdate_f.day, nextdate_f.year, months[nextdate_l.month-1], nextdate_l.day, nextdate_l.year)
2807         strprevmonth = u'%s %d, %d ~ %s %d, %d' % (months[prevdate_f.month-1], prevdate_f.day, prevdate_f.year, months[prevdate_l.month-1], prevdate_l.day, prevdate_l.year)
2808     else:
2809         stryearmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (first_date_week.year, first_date_week.month, first_date_week.day, last_date_week.year, last_date_week.month, last_date_week.day)
2810         strnextmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (nextdate_f.year, nextdate_f.month, nextdate_f.day, nextdate_l.year, nextdate_l.month, nextdate_l.day)
2811         strprevmonth = u'%d / %02d / %02d ~ %d / %02d / %02d' % (prevdate_f.year, prevdate_f.month, prevdate_f.day, prevdate_l.year, prevdate_l.month, prevdate_l.day)
2812     
2813     #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
2814     
2815     html = [
2816         u'<tr><td width="2%" style="border: none;">&nbsp;</td>',
2817         u'<td colspan="%d" style="border: none;">' % colspan,
2818         u'<table width="95%">',
2819         u'  <tr>',
2820         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
2821         u'      <td class="%s"><a href="%s" title="Go/Refresh this week">%s</a></td>' % (headclass, curlink, stryearmonth),
2822         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
2823         u'  </tr>',
2824         u'</table>',
2825         u'</td></tr>',
2826         ]
2827         
2828     return u'\r\n'.join(html)
2829 
2830 
2831 # show calendar head for weekly view (the date)
2832 def calhead_weeklydate(year, month, day, colspan):
2833     
2834     request = Globs.request
2835     _ = request.getText
2836     
2837     months = Globs.months
2838     monthstyle_us = Globs.month_style_us
2839     cal_action = Globs.cal_action
2840     page_name = Globs.pagename
2841     wkdays = Globs.wkdays
2842     
2843     page_url = Globs.pageurl
2844     
2845     date_today = datetime.date( year, month, day )
2846     
2847     if monthstyle_us:
2848         stryearmonth = u'%s %d' % (months[month-1], day)
2849     else:
2850         stryearmonth = u'%02d / %02d' % (month, day)
2851     
2852     stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
2853     curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
2854     
2855     cyear, cmonth, cday = gettodaydate()
2856     if cyear == year and cmonth == month and cday == day:
2857         bgcolor = 'background-color: #FFFFAA;'
2858     else:
2859         bgcolor = ''
2860     
2861     if not Params.changeview:
2862         curlink = '#'
2863     
2864     html = [
2865         u'<td colspan="%d" style="border-width: 2px; text-align: center; font-size: 9pt; %s">' % (colspan, bgcolor),
2866         u'<a href="%s">%s</a>' % (curlink, stryearmonth),
2867         u'</td>',
2868         ]
2869         
2870     return u'\r\n'.join(html)
2871 
2872 # show days in simple
2873 def simple_eventbox(year, month, day, wkday, boxclass):
2874     wkend = Globs.wkend
2875     if wkday == wkend:
2876         html_text = u'<font color="#aa7744">%s</font>' % day
2877     else:
2878         html_text = u'%s' % day
2879     
2880     cyear, cmonth, cday = gettodaydate()
2881     
2882     page_url = Globs.pageurl
2883     linkkey = u'%d%02d%02d' % (year, month, day)
2884     
2885     curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
2886     
2887     if not Params.changeview:
2888         curlink = '#'
2889     
2890     curlink = u'<a href="%s" onMouseOver="tip(\'%s\')" onMouseOut="untip()" >%s</a>' % (curlink, linkkey, html_text)
2891     
2892     if boxclass == 'simple_nb':
2893         html = u'  <td class="%s">&nbsp;</td>\r\n' % boxclass
2894     else:
2895         if cyear == year and cmonth == month and cday == day:
2896             html = u'  <td class="%s_today">%s</td>\r\n' % (boxclass, curlink)
2897         else:
2898             html = u'  <td class="%s">%s</td>\r\n' % (boxclass, curlink)
2899        
2900     return html
2901 
2902 
2903 # show weekday
2904 def calhead_weekday(wday, headclass):
2905     if headclass == 'simple_weekday':
2906         html = u'       <td class="%s">%s</td>\r\n' % (headclass, wday[0])
2907     else:
2908         html = u'       <td class="%s">%s</td>\r\n' % (headclass, wday)
2909 
2910     return html
2911 
2912 
2913 # show days of current month
2914 def calhead_day(year, month, day, wkday):
2915     
2916     request = Globs.request
2917     page_name = Globs.pagename
2918     wkend = Globs.wkend
2919     
2920     if wkday == wkend:
2921         html_text = u'<font color="#FF3300">%s</font>' % day
2922     else:
2923         html_text = u'%s' % day
2924     
2925     page_url = Globs.pageurl
2926     html_text = u'<a href="%s?calaction=daily&caldate=%d%02d%02d">%s</a>' % (page_url, year, month, day, html_text)
2927     
2928     cyear, cmonth, cday = gettodaydate()
2929     
2930     if cyear == year and cmonth == month and cday == day:
2931         html = u'  <td class="head_day_today">&nbsp;%s</td>\r\n' % html_text
2932     else:
2933         html = u'  <td class="head_day">&nbsp;%s</td>\r\n' % html_text
2934        
2935     return html
2936 
2937 
2938 # show days of previous or next month
2939 def calhead_day_nbmonth(day):
2940     html = u'  <td class="head_day_nbmonth">&nbsp;%s</td>\r\n' % day
2941     return html
2942 
2943 
2944 # show blank calendar box
2945 def calshow_blankbox(classname):
2946     html = u'  <td class="%s">&nbsp;</td>' % classname
2947     return html
2948 
2949 
2950 def calshow_blankbox2(classname, colspan):
2951     html = u'  <td class="%s" colspan="%d">&nbsp;</td>' % (classname, colspan)
2952     return html
2953 
2954 
2955 # show eventbox
2956 def calshow_eventbox(event, colspan, status, cur_date):
2957     if status:
2958         status = u'_%s' % status
2959     
2960     title = event['title']
2961     eid = event['id']
2962     startdate = event['startdate']
2963     enddate = event['enddate']
2964     starttime = event['starttime']
2965     endtime = event['endtime']
2966     description = event['description']
2967     bgcolor = event['bgcolor']
2968     
2969     year, month, day = getdatefield(cur_date)
2970     
2971     if bgcolor:
2972         bgcolor = 'background-color: %s;' % bgcolor
2973     else:
2974         bgcolor = 'background-color: %s;' % Params.bgcolor
2975     
2976     if (startdate == enddate) and starttime:
2977         shour, smin = gettimefield(starttime)
2978         
2979         link = [
2980             u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
2981             u'<td nowrap class="cal_eventbox_time">%02d:%02d&nbsp;</td>\r\n' % (shour, smin),
2982             u'<td class="cal_eventbox_time_event">',
2983             u'%s' % showReferPageParsed(event, 'title', 1),
2984             u'</td>\r\n</tr></table>',
2985             ]
2986         link = u''.join(link)
2987     else:
2988         link = u'%s' % showReferPageParsed(event, 'title', 1)
2989     
2990     
2991     html = [
2992         u'  <td class="cal_eventbox" colspan="%d"><table class="cal_event">' % colspan,
2993         u'      <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
2994         u'      </table></td>',
2995         ]
2996         
2997     return u'\r\n'.join(html)
2998 
2999 
3000 # show eventbox
3001 def calshow_daily_eventbox2(event, colspan, status, cur_date):
3002     if status:
3003         status = u'_%s' % status
3004     
3005     title = event['title']
3006     eid = event['id']
3007     startdate = event['startdate']
3008     enddate = event['enddate']
3009     starttime = event['starttime']
3010     endtime = event['endtime']
3011     description = event['description']
3012     bgcolor = event['bgcolor']
3013     
3014     year, month, day = getdatefield(cur_date)
3015     
3016     if bgcolor:
3017         bgcolor = 'background-color: %s;' % bgcolor
3018     else:
3019         bgcolor = 'background-color: %s;' % Params.bgcolor
3020     
3021     if (startdate == enddate) and starttime:
3022         shour, smin = gettimefield(starttime)
3023         
3024         link = [
3025             u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3026             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),
3027             u'<td style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top;font-size: 8pt;">',
3028             u'%s' % showReferPageParsed(event, 'title', 1),
3029             u'</td>\r\n</tr></table>',
3030             ]
3031         link = u''.join(link)
3032     else:
3033         link = u'%s' % showReferPageParsed(event, 'title', 1)
3034     
3035     
3036     html = [
3037         u'  <td colspan="%d" style="width: 96%%; border-width: 0px; line-height: 11px;"><table class="cal_event">' % colspan,
3038         u'      <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3039         u'      </table></td>',
3040         ]
3041         
3042     return u'\r\n'.join(html)
3043 
3044 
3045 # show eventbox
3046 def calshow_daily_eventbox(event):
3047     
3048     title = event['title']
3049     eid = event['id']
3050     startdate = event['startdate']
3051     enddate = event['enddate']
3052     starttime = event['starttime']
3053     endtime = event['endtime']
3054     description = event['description']
3055     bgcolor = event['bgcolor']
3056     time_len = event['time_len']
3057     
3058     if bgcolor:
3059         bgcolor = 'background-color: %s;' % bgcolor
3060     else:
3061         bgcolor = 'background-color: %s;' % Params.bgcolor
3062     
3063     shour, smin = gettimefield(starttime)
3064     ehour, emin = gettimefield(endtime)
3065     
3066     html = [
3067         u'  <td colspan="%(colspan)d"',
3068         u'      style="%s border-width: 2px; border-color: #000000; vertical-align: top; font-size: 9pt; ' % bgcolor,
3069         u'      width: %(width)s;" ', 
3070         u'      rowspan="%(rowspan)d">' % { 'rowspan': time_len },
3071         u'      %02d:%02d ~ %02d:%02d<br>%s' % (shour, smin, ehour, emin, showReferPageParsed(event, 'title', 1)),
3072         u'  </td>',
3073         ]
3074         
3075     return u'\r\n'.join(html)
3076 
3077 
3078 # show eventbox
3079 def calshow_weekly_eventbox(event):
3080     
3081     title = event['title']
3082     eid = event['id']
3083     startdate = event['startdate']
3084     enddate = event['enddate']
3085     starttime = event['starttime']
3086     endtime = event['endtime']
3087     description = event['description']
3088     bgcolor = event['bgcolor']
3089     time_len = event['time_len']
3090     
3091     if bgcolor:
3092         bgcolor = 'background-color: %s;' % bgcolor
3093     else:
3094         bgcolor = 'background-color: %s;' % Params.bgcolor
3095     
3096     shour, smin = gettimefield(starttime)
3097     ehour, emin = gettimefield(endtime)
3098     
3099     html = [
3100         u'  <td colspan="%(colspan)d"',
3101         u'      style="%s;' % bgcolor,
3102         u'      width: %(width)s;" ', 
3103         u'      rowspan="%(rowspan)d"' % { 'rowspan': time_len },
3104         u'      class="cal_weekly_eventbox">',
3105         u'      %s' % showReferPageParsed(event, 'title', 1),
3106         u'  </td>',
3107         ]
3108         
3109     return u'\r\n'.join(html)
3110 
3111 # show blank eventbox
3112 def calshow_blankeventbox():
3113     
3114     html = [
3115         u'  <td colspan="%(colspan)d" style="width: %(width)s;" class="cal_blankeventbox">&nbsp;</td>',
3116         ]
3117         
3118     return u'\r\n'.join(html)
3119 
3120 
3121 # show eventbox
3122 def calshow_weekly_eventbox2(event, colspan, width, status, cur_date):
3123     if status:
3124         status = u'_%s' % status
3125     
3126     title = event['title']
3127     eid = event['id']
3128     startdate = event['startdate']
3129     enddate = event['enddate']
3130     starttime = event['starttime']
3131     endtime = event['endtime']
3132     description = event['description']
3133     bgcolor = event['bgcolor']
3134     
3135     year, month, day = getdatefield(cur_date)
3136     
3137     if bgcolor:
3138         bgcolor = 'background-color: %s;' % bgcolor
3139     else:
3140         bgcolor = 'background-color: %s;' % Params.bgcolor
3141     
3142     link = u'%s' % showReferPageParsed(event, 'title', 1)
3143     
3144     html = [
3145         u'  <td colspan="%d" style="width: %d%%;" class="cal_weekly_eventbox2"><table class="cal_event">' % (colspan, width),
3146         u'      <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3147         u'      </table></td>',
3148         ]
3149         
3150     return u'\r\n'.join(html)
3151 
3152 
3153 
3154 # show blank eventbox
3155 def calshow_blankeventbox2(colspan, width):
3156     html = [
3157         u'  <td colspan="%(colspan)d"' % { 'colspan': colspan },
3158         u'      style="width: %(width)s;" class="cal_blankeventbox">&nbsp;</td>' % { 'width': '%d%%%%' % width },
3159         ]
3160         
3161     return u'\r\n'.join(html)
3162 
3163 
3164 
3165 def calshow_daily_hourhead(hour):
3166     
3167     if hour >= Globs.dailystart and hour <= Globs.dailyend:
3168         bgcolor = "#ffffcc"
3169     else:
3170         bgcolor = "#ffeeee"
3171     
3172     html = [
3173         u'  <td class="cal_hourhead" style="background-color: %s; width: 4%%%%;">%02d</td>' % (bgcolor, hour),
3174         ]
3175         
3176     return u'\r\n'.join(html)
3177 
3178 def calshow_weekly_hourhead(hour):
3179     
3180     if hour >= Globs.dailystart and hour <= Globs.dailyend:
3181         bgcolor = "#ffffcc"
3182     else:
3183         bgcolor = "#ffeeee"
3184     
3185     html = [
3186         u'  <td class="cal_hourhead" style="width: 2%%%%; background-color: %s; ">%02d</td>' % (bgcolor, hour),
3187         ]
3188         
3189     return u'\r\n'.join(html)
3190 
3191 
3192 
3193 def insertcalevents(cal_events, datefrom, dateto, e_id, e_start_date, e_end_date):
3194     
3195     if not (int(e_start_date) > dateto or int(e_end_date) < datefrom):
3196         
3197         e_start_date = str(max(int(e_start_date), datefrom))
3198         e_end_date = str(min(int(e_end_date), dateto))
3199         
3200         day_delta = datetime.timedelta(days=1)
3201         e_start_year, e_start_month, e_start_day = getdatefield(e_start_date)
3202         cur_datetime = datetime.date(e_start_year, e_start_month, e_start_day)
3203         
3204         while 1:
3205             tmp_record_date = formatdateobject(cur_datetime)
3206             
3207             if not cal_events.has_key(tmp_record_date):
3208                 cal_events[tmp_record_date] = []
3209             cal_events[tmp_record_date].append(e_id)
3210             
3211             if tmp_record_date == e_end_date:
3212                 break
3213             
3214             cur_datetime = cur_datetime + day_delta   
3215 
3216 # date format should be like '20051004' for 2005, Oct., 04
3217 def diffday(date1, date2):
3218     
3219     try:
3220         year1, month1, day1 = getdatefield(date1)
3221         year2, month2, day2 = getdatefield(date2)
3222         tmp_diff = datetime.date(year2, month2, day2) - datetime.date(year1, month1, day1)
3223     except (TypeError, ValueError):
3224         debug('An event data is corrupted: invalid date format')
3225         return 0
3226 
3227     return tmp_diff.days
3228 
3229 
3230 # time format should be like '1700' for 05:00pm
3231 def difftime(time1, time2):
3232     
3233     try:
3234         hour1, min1 = gettimefield(time1)
3235         hour2, min2 = gettimefield(time2)
3236         
3237     except (TypeError, ValueError):
3238         debug('An event data is corrupted: invalid time format')
3239         return 0
3240 
3241     if min2 == 0 and hour2 != 0 and hour1 != hour2:
3242         hour2 -= 1
3243 
3244     tmp_diff = hour2 - hour1
3245     
3246     return tmp_diff
3247 
3248 
3249 def difftime_sec(time1, time2):
3250     
3251     try:
3252         hour1, min1 = gettimefield(time1)
3253         hour2, min2 = gettimefield(time2)
3254         tmp_diff = datetime.time(hour2, min2) - datetime.time(hour1, min1)
3255     except (TypeError, ValueError):
3256         debug('An event data is corrupted: invalid time format')
3257         return 0
3258 
3259     return tmp_diff.seconds
3260 
3261 def formatDate(year, month, day):
3262     # returns like: '20051004'
3263     return u'%4d%02d%02d' % (year, month, day)
3264 
3265 def formatTime(hour, min):
3266     # returns like: '1700'
3267     return u'%2d%02d' % (hour, min)
3268 
3269 
3270 def formatdateobject(obj_date):
3271 
3272     return formatDate(obj_date.year, obj_date.month, obj_date.day)
3273 
3274 def formattimeobject(obj_time):
3275 
3276     return formatTime(obj_time.hour, obj_time.minute)
3277 
3278 
3279 def debug(astring):
3280     Globs.debugmsg += u'<li>%s\n' % astring
3281 
3282 
3283 def yearmonthplusoffset(year, month, offset):
3284     month = month+offset
3285     # handle offset and under/overflows - quick and dirty, yes!
3286     while month < 1:
3287         month = month + 12
3288         year = year - 1
3289     while month > 12:
3290         month = month - 12
3291         year = year + 1
3292     return year, month
3293 
3294 
3295 def formatcfgdatetime(strdate, strtime=''):
3296     
3297     if not strdate:
3298         return ''
3299     
3300     request = Globs.request
3301     
3302     if request.user.date_fmt:
3303         date_fmt = request.user.date_fmt
3304     else:
3305         date_fmt = request.cfg.date_fmt
3306     
3307     if request.user.datetime_fmt:
3308         datetime_fmt = request.user.datetime_fmt
3309     else:
3310         datetime_fmt = request.cfg.datetime_fmt
3311     
3312     ## XXX HACK
3313     datetime_fmt = datetime_fmt.replace(':%S', '')
3314     
3315     date_fmt = str(date_fmt)
3316     datetime_fmt = str(datetime_fmt)
3317     
3318     year, month, day = getdatefield(str(strdate))
3319     if strtime:
3320         hour, min = gettimefield(str(strtime))
3321         objdatetime = datetime.datetime(year, month, day, hour, min)
3322         return objdatetime.strftime(datetime_fmt)
3323     else:
3324         objdate = getdatetimefromstring(strdate)
3325         return objdate.strftime(date_fmt)
3326 
3327 
3328 def getdatetimefromstring(strdate):
3329     year, month, day = getdatefield(str(strdate))
3330     return datetime.date( year, month, day )
3331 
3332 
3333 def searchPages(request, needle):
3334     # Search the pages and return the results
3335     query = search.QueryParser().parse_query(needle)
3336     results = search.searchPages(request, query)
3337     #results.sortByPagename()
3338     
3339     return results.hits
3340     
3341     html = []
3342     for page in results.hits:
3343         html.append(page.page_name)
3344     
3345     html = u',<br>'.join(html)
3346     return u'%s<p>%s' % (Params.category, html)
3347 
3348 
3349 def getFirstDateOfWeek(year, month, day):
3350 	orgday = datetime.date(year, month, day)
3351 	yearBase, week, weekday = orgday.isocalendar()
3352 	baseDate = datetime.date(yearBase, 2, 1)
3353 	yearBase, weekBase, dayBase = baseDate.isocalendar()
3354 	days = datetime.timedelta(1-dayBase+(week-weekBase)*7)
3355 	theday = baseDate + days
3356 	
3357 	theday -= datetime.timedelta(7 - calendar.firstweekday())
3358 	
3359 	if orgday - theday >= datetime.timedelta(7):
3360 	    theday += datetime.timedelta(7)
3361 	
3362 	return theday
3363     
3364 def gcd(a,b):
3365     """Return greatest common divisor using Euclid's Algorithm."""
3366     while b:      
3367         a, b = b, a % b
3368     
3369     return a
3370 
3371 def lcm(a,b):
3372     """
3373     Return lowest common multiple."""
3374     return (a*b)/gcd(a,b)
3375 
3376 def LCM(terms):
3377     "Return lcm of a list of numbers."   
3378     return reduce(lambda a,b: lcm(a,b), terms)

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.