Attachment 'EventCalendar-099a.py'

Download

   1 """
   2     EventCalendar.py  Version 0.99a  July 22, 2009
   3 
   4 	* Base 0.99 version
   5 	* Add ErikMartin's Defaults patch (defaults-099-01)
   6 	* Add AlanSnelson 2008-11-05 patch for Moin 1.8.0 caching methods
   7 	* Add tidyup patch for 1.6.1 (EventCalendar-099.py.patch) NeoCoin 
   8 	* Add Weeknumber patch from KlausMariaPfeiffer 2008-01-25
   9 	* Add label colour patch DavidOCallahan 2006-07-18 {see here for names: http://www.w3schools.com/html/html_colornames.asp}
  10 	* Add pagelinks-099-01.patch for OrphanedPages maintenance.
  11 	* Add showpagelist, to append list of contributing pages pagelist-099-01.patch (except: default now off not on)
  12 	* Add event sorting patch RuthIvimey 2007-05-17
  13 	* Fix url_prefix usage DaveGore 2008-04-04
  14     Not included:
  15 	ErikMartin's Label Priority patch - too big a patch for this wrapup release.
  16 	RuthIvimey's page label colour patch - not sure of side-effects
  17 	HyungyongKim's unicode patch: described as temporary
  18                                                                                                            
  19     EventCalendar.py  Version 0.99  May 22, 2006
  20 
  21     This macro gives a list of the events recorded at the sub-pages in the form of various views:
  22         monthly, weekly, daily, simple-month, list, and upcoming.
  23                                                                                                            
  24     @copyright: 2006 by Seungik Lee <seungiklee<at>gmail.com>  http://www.silee.net/
  25     @license: GPL
  26     
  27     For more information, please visit http://moinmoin.wikiwikiweb.de/MacroMarket/EventCalendar
  28     
  29     <Usage>
  30     
  31         * To list the events in a page, just insert [[EventCalendar]]
  32         * To insert an event, insert the event information in any pages of specified category (CategoryEventCalendar by default).
  33         
  34     <Parameters>
  35         
  36         * category: the category of the event data to be used in the calendar. default: 'CategoryEventCalendar'
  37         * menubar: shows menubar or not (1: show, 0: no menubar). default: 1
  38         * monthlywidth: calendar width in pixel or percent (monthly view). default: '600' (pixel)
  39         * simplewidth: calendar width in pixel or percent (simpleview). default: '150' (pixel)
  40         * firstview: initial calendar view: monthly, weekly, daily, list, simple, upcoming. default: 'monthly'
  41         * curdate: initial calendar date (in YYYYMM format). default: current month
  42         * upcomingrange: # of days for the range of upcoming event list. default: 7 (days)
  43         * changeview: enables to change the calendar view or not (1: enalbed, 0: disabled). default: 1
  44         * numcal: # of calendar. default: 1
  45         * showlastweekday: shows the event at the last weekday if the recurred weekday is not available. (1: enalbed, 0: disabled). default: 0
  46         * showerror: shows error messages below the calendar if event data format is invalid. (1: enalbed, 0: disabled). default: 1
  47         * showpagelist: shows a list of the pages used for event data below the calendar. (1: enalbed, 0: disabled). default: 0
  48         * showweeknumber: shows the week number of the year (1: enalbed, 0: disabled). default: 0
  49         
  50     
  51     <Event Data Format>
  52 
  53         * Event data fields:
  54 ...
  55 
  56  [default_description:: [page_default_description_text]]
  57  [default_bgcolor:: [page_default_background_color]]
  58  [label_def:: [label_name], [label_background_color]]
  59 
  60 == <title> ==
  61  start:: <startdate> [starttime]
  62  [end:: [enddate] [endtime]]
  63  [description:: [description_text]]
  64  [bgcolor:: [custom_background_color]]
  65  [recur:: <recur_freq> <recur_type> [until <recur_until>]]
  66  [label:: <label_name>]
  67  
  68 ...
  69 
  70 ----
  71 CategoryEventCalendar
  72 
  73             * default_bgcolor, default_description: default values of bgcolor and description in the page if unavailable. optional
  74             * label_def: label definition with name, bgcolor. optional
  75             
  76             * title: event title. required
  77                 * should be enclosed with heading marker ('='), Title cannot be omitted.
  78 
  79             * startdate: date of start. required
  80                 * should be in date format or date format
  81                 
  82             * starttime: time of start. optional
  83                 * should be in time format
  84                 
  85             * enddate: date of end. optional
  86                 * should be in date format or date format. If omitted, it will be assigned equal to <startdate>.
  87                 
  88             * endtime: time of end. optional
  89                 * should be in time format. Both of start|end Time can be omitted but not either of them.
  90                 
  91             * description: description of the event. optional
  92                 * any text with no markup. should be in a line.
  93                 
  94             * bgcolor: custom background color of the event in monthly view. optional
  95                 * e.g., #abcdef
  96             
  97             * recur: recurrence information of the event. optional
  98                 * recur_freq: how many intervals, digit or 'last' for weekday, required
  99                 * recur_type: [day|week|weekday|month|year], required
 100                     * day: every [recur_freq] days
 101                     * week: every [recur_freq] weeks
 102                     * weekday: on the same weekday of [recur_freq]-th week of the month. or 'last weekday'
 103                     * month: on the same day of [recur_freq]-th month
 104                     * year: on the same day of [recur_freq]-th year
 105                 * recur_until: recurred until when, date format, optional
 106                 
 107                 * e.g., 10 day, 2 week until 2006-06-31, 3 weekday, 6 month until 2007-12-31, 1 year
 108             
 109             * label: custom label for specific name, bgcolor. optional
 110             
 111             * The order of the fields after an event title does not matter.
 112             * Priority of bgcolor: bgcolor > default_bgcolor > label_bgcolor
 113 
 114 
 115         * Datetime format:
 116         
 117             * Date format:
 118                 * YYYY/MM/DD, YYYY-MM-DD, YYYY.MM.DD: 2006/05/12; 2006-05-12; 2006.05.12; 2006-5-12; 06/5/12
 119                 * B DD, YYYY: May 12, 2006; May 5th, 2006; January 1st, 2006; Jan 5, 06
 120                 * YYYYMMDD, YYMMDD: 20060512; 060512
 121                 
 122                 * Year: YY = 20YY. e.g., 06-2-2 = 2006-02-02, allowed 1900 ~ 2099 only.
 123 
 124             * Time format:
 125                 * H:M, HHMM: 12:00; 22:00; 2:00; 2 (= 2 o'clock); 2200; 12:0; 2:0
 126                 * I:M PP, IIMM PP: 12:00 PM; 3:00p; 2a (= 2 o'clock AM); 3:0pm; 0200 am; 10pm
 127 
 128             
 129 
 130     <Event Data Examples>
 131 
 132 == Default values ==
 133  default_bgcolor:: #c0c0c0
 134  default_description:: testing...
 135 
 136 == Labels ==
 137  label_def:: Holiday, #ff0000
 138  label_def:: Meeting, #00ff00
 139 
 140 === Test event ===
 141  start:: 2006-01-10 02:00p
 142  end:: 2006-01-12 17:00
 143  description:: test event
 144  bgcolor:: #cfcfcf
 145   
 146 === Jinah's Birthday ===
 147  start:: 1977-10-20
 148  recur:: 1 year
 149  label:: Holiday
 150  
 151 === Weekly meeting ===
 152  start:: Jan 17, 2006 7:00pm
 153  end:: 21:00
 154  recur:: 1 week until 061231
 155  label:: Meeting
 156 
 157 ----
 158 CategoryEventCalendar  
 159 
 160 
 161     <Notes>
 162     
 163         * It caches all the page list of the specified category and the event information.
 164         * If you added/removed a page into/from a category, you need to do 'Delete cache' in the macro page.
 165 
 166         * 'MonthCalendar.py' developed by Thomas Waldmann <ThomasWaldmann@gmx.de> has inspired this macro.
 167         * Much buggy.. : please report bugs and suggest your ideas.
 168         * If you missed to add css for EventCalender, monthly view may not be readable.
 169             * Insert the EventCalendar css classes into the screen.css of an appropriate theme.
 170 
 171         
 172 
 173 """
 174 
 175 from MoinMoin import wikiutil, config, search, caching
 176 from MoinMoin.Page import Page
 177 import re, calendar, time, datetime
 178 import codecs, os, urllib, sha
 179 
 180 try:
 181     import cPickle as pickle
 182 except ImportError:
 183     import pickle
 184 
 185 # Set pickle protocol, see http://docs.python.org/lib/node64.html
 186 PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL
 187 
 188 
 189 # The following line sets the calendar to have either Sunday or Monday as
 190 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
 191 # valid here.  All other values will not make good calendars.
 192 # XXX change here ----------------vvvvvv
 193 calendar.setfirstweekday(calendar.MONDAY)
 194 
 195 
 196 class Globs:
 197     month_style_us = 1  # 1: October 2005; 2: 2005 / 10
 198     defaultcategory = 'CategoryEventCalendar'
 199     upcomingrange = 7   # days
 200     dailystart = 9
 201     dailyend = 18
 202     pagename = ''
 203     baseurl = ''
 204     subname = ''
 205     wkend = ''
 206     months = ''
 207     wkdays = ''
 208     today = ''
 209     now = ''
 210     request = None
 211     formatter = None
 212     cal_action = ''
 213     debugmsg = ''
 214     errormsg = ''
 215     page_action = ''
 216     form_vals = {}
 217     events = None
 218     labels = None
 219 
 220 
 221 class Params:
 222     menubar = 0
 223     monthlywidth = ''
 224     weeklywidth = ''
 225     dailywidth = ''
 226     simplewidth = ''
 227     firstview = ''
 228     curdate = ''
 229     bgcolor = ''
 230     category = ''
 231     upcomingrange = 0
 232     changeview = 0
 233     numcal = 1
 234     showlastweekday = 0
 235     showerror = 1
 236     showpagelist = 0
 237     showweeknumber = 0
 238     debug = 0
 239     
 240 
 241 class EventcalError(Exception):
 242     def __init__(self, value):
 243         self.value = value
 244     
 245     def __str__(self):
 246         return repr(self.value) 
 247 
 248 
 249 def execute(macro, args):
 250     
 251     request = macro.request
 252     formatter = macro.formatter
 253     
 254     # INITIALIZATION ----------------------------------------
 255     setglobalvalues(macro)
 256     getparams(args)
 257     
 258     # allowed actions
 259     allowed_action = ['monthly', 'list', 'simple', 'upcoming', 'daily', 'weekly']
 260     default_action = Params.firstview
 261     
 262     # Internal variables
 263     cal_action = ''
 264     form_vals = {}
 265 
 266     # PROCESSING ARGUEMENTS ----------------------------------------
 267     if args:
 268         args=request.getText(args)
 269 
 270     for item in macro.form.items():
 271         if not form_vals.has_key(item[0]):
 272 	    try:
 273 		    form_vals[item[0]]=item[1][0]
 274 	    except AttributeError:
 275 	        pass
 276     
 277     # PROCESSING ACTIONS ----------------------------------------
 278     cal_action = form_vals.get('calaction', default_action)
 279     page_action = form_vals.get('action', 'show')
 280     
 281     if not cal_action in allowed_action:
 282         cal_action = default_action
 283     
 284     form_vals['calaction'] = cal_action
 285 
 286     Globs.form_vals = form_vals
 287 
 288     # CONTROL FUNCTIONS ----------------------------------------
 289     
 290     html = []
 291     html_result = ''
 292     
 293     Globs.cal_action = cal_action
 294     Globs.page_action = page_action
 295     
 296     
 297     # redirect to the appropriate view
 298     if cal_action == 'monthly':
 299         html_result = showcalendar()
 300         
 301     if cal_action == 'list':
 302         html_result = showeventlist()
 303 
 304     if cal_action == 'simple':
 305         html_result = showsimplecalendar()
 306     
 307     if cal_action == 'upcoming':
 308         html_result = showupcomingeventlist()
 309         
 310     if cal_action == 'daily':
 311         html_result = showdailycalendar()
 312         
 313     if cal_action == 'weekly':
 314         html_result = showweeklycalendar()
 315     
 316     
 317     # format output
 318     html.append( html_result )
 319     html.append( showmenubar() )
 320 
 321     html.append( showpagelist() )
 322     
 323     if Params.showerror and Globs.errormsg:
 324         html.append(u'<p><i><font size="2" color="#aa0000"><ol>%s</ol></font></i>' % Globs.errormsg)
 325 
 326     if Params.debug and Globs.debugmsg:
 327         html.append(u'<p><b>Debug messages:</b><font color="#000099"><ol>%s</ol></font>' % Globs.debugmsg)
 328 
 329     return formatter.rawHTML(u''.join(html))
 330 
 331 
 332 
 333 def getparams(args):
 334     # process arguments
 335     
 336     params = {}
 337     if args:
 338         # Arguments are comma delimited key=value pairs
 339         sargs = args.split(',')
 340     
 341         for item in sargs:
 342             sitem = item.split('=')
 343         
 344             if len(sitem) == 2:
 345                 key, value = sitem[0], sitem[1]
 346                 params[key.strip()] = value.strip()
 347 
 348     # category name: 
 349     # default: 'CategoryEventCalendar'
 350     Params.category = params.get('category', Globs.defaultcategory)
 351     
 352     # menu bar: shows menubar or not (1: show, 0: no menubar)
 353     # default: 1
 354     try:
 355         Params.menubar = int(params.get('menubar', 1))
 356     except (TypeError, ValueError):
 357         Params.menubar = 1
 358         
 359     # calendar width in pixel or percent (monthly)
 360     # default: 600px
 361     Params.monthlywidth = params.get('monthlywidth', '600')
 362     if Params.monthlywidth:
 363         Params.monthlywidth = ' width="%s" ' % Params.monthlywidth
 364         
 365     # calendar width in pixel or percent (weekly)
 366     # default: 600px
 367     Params.weeklywidth = params.get('weeklywidth', '600')
 368     if Params.weeklywidth:
 369         Params.weeklywidth = ' width="%s" ' % Params.weeklywidth
 370 
 371     # calendar width in pixel or percent (daily)
 372     # default: 600px
 373     Params.dailywidth = params.get('dailywidth', '600')
 374     if Params.monthlywidth:
 375         Params.dailywidth = ' width="%s" ' % Params.dailywidth
 376 
 377     # calendar width in pixel or percent (simply)
 378     # default: 150px
 379     Params.simplewidth = params.get('simplewidth', '150')
 380     if Params.simplewidth:
 381         # Params.simplewidth = Params.simplewidth.replace('%', '%%')
 382         Params.simplewidth = ' width="%s" ' % Params.simplewidth
 383     
 384     # calendar view: monthly, list, simple
 385     # default: 'monthly'
 386     Params.firstview = params.get('firstview', 'monthly')
 387 
 388     # calendar date: in YYYYMM format (in monthly, simple view)
 389     # default: current month
 390     Params.curdate = params.get('curdate', '')
 391     
 392     # upcoming range: # of days for upcoming event list
 393     # default: 7
 394     try:
 395         Params.upcomingrange = int(params.get('upcomingrange', Globs.upcomingrange))
 396     except (TypeError, ValueError):
 397         Params.upcomingrange = Globs.upcomingrange
 398         
 399     # number of calendar: # of calendar for monthly & simple view
 400     # default: 1
 401     try:
 402         Params.numcal = int(params.get('numcal', '1'))
 403     except (TypeError, ValueError):
 404         Params.numcal = 1
 405 
 406     # change view enabled?
 407     # default: 1
 408     try:
 409         Params.changeview = int(params.get('changeview', '1'))
 410     except (TypeError, ValueError):
 411         Params.changeview = 1
 412         
 413     # shows the event at the last weekday if the recurred weekday is not available.
 414     # default: 0
 415     try:
 416         Params.showlastweekday = int(params.get('showlastweekday', '0'))
 417     except (TypeError, ValueError):
 418         Params.showlastweekday = 0
 419         
 420     # show error message?
 421     # default: 1
 422     try:
 423         Params.showerror = int(params.get('showerror', '1'))
 424     except (TypeError, ValueError):
 425         Params.showerror = 1
 426         
 427     # show week number?
 428     # default: 0
 429     try:
 430         Params.showweeknumber = int(params.get('showweeknumber', '0'))
 431     except (TypeError, ValueError):
 432         Params.showweeknumber = 0
 433 
 434     # show definition table
 435     # default: 1
 436     try:
 437         Params.showpagelist = int(params.get('showpagelist', '0'))
 438     except (TypeError, ValueError):
 439         Params.showpagelist = 1
 440 
 441     # default bgcolor
 442     Params.bgcolor = '#ddffdd'
 443     
 444 
 445 def setglobalvalues(macro):
 446     
 447     request = macro.request
 448     formatter = macro.formatter
 449     
 450     # Useful variables
 451     Globs.baseurl = request.getBaseURL() + '/'
 452     Globs.pagename = formatter.page.page_name
 453     Globs.request = request
 454     Globs.formatter = formatter
 455     Globs.pageurl = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(formatter.page.page_name))
 456     
 457     # This fixes the subpages bug. subname is now used instead of pagename when creating certain urls
 458     Globs.subname = Globs.pagename.split('/')[-1]
 459 
 460     pagepath = formatter.page.getPagePath()
 461     Globs.pagepath = formatter.page.getPagePath()
 462     
 463     # european / US differences
 464     months = ('January','February','March','April','May','June','July','August','September','October','November','December')
 465     
 466     # Set things up for Monday or Sunday as the first day of the week
 467     if calendar.firstweekday() == calendar.MONDAY:
 468         wkend = 6
 469         wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
 470     elif calendar.firstweekday() == calendar.SUNDAY:
 471         wkend = 0
 472         wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
 473     
 474     Globs.months = months
 475     Globs.wkdays = wkdays
 476     Globs.wkend = wkend
 477 
 478     year, month, day, h, m, s, wd, yd, ds = request.user.getTime(time.time())
 479     Globs.today = datetime.date(year, month, day)
 480     Globs.now = datetime.time(h, m, s)
 481     
 482     Globs.debugmsg = ''
 483     Globs.errormsg = ''
 484 
 485 
 486 def showReferPageParsed(event, targettext='title', showdesc=0):
 487     request = Globs.request
 488     pagename = Globs.pagename
 489     
 490     refer = event['refer']
 491     targettext = event[targettext]
 492     startdate = event['startdate']
 493     enddate = event['enddate']
 494     description = event['description']
 495     starttime = event['starttime']
 496     endtime = event['endtime']
 497     hid = event['hid']
 498     
 499     refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
 500     
 501     if not Params.changeview:
 502         refer_url = ''
 503         hid = ''
 504     
 505     if showdesc:
 506         if (startdate == enddate) and (starttime and endtime):
 507             timedescription = '(%s:%s ~ %s:%s)' % (starttime[:2], starttime[2:], endtime[:2], endtime[2:])
 508             if description:
 509                 timedescription = '%s ' % timedescription
 510         else:
 511             timedescription = ''
 512         
 513         targetlink = '<a href="%s#%s" title="%s%s">%s</a>' % ( refer_url, hid, timedescription, wikiutil.escape(description), wikiutil.escape(targettext) )
 514             
 515     else:
 516         targetlink = '<a href="%s#%s">%s</a>' % ( refer_url, hid, wikiutil.escape(targettext))
 517     
 518     return targetlink
 519 
 520 
 521 def showReferPageParsedForLabel(thelabel, targettext='name', showdesc=1):
 522     request = Globs.request
 523     pagename = Globs.pagename
 524     
 525     labels = Globs.labels
 526     
 527     label_bgcolor = ''
 528     refer = ''
 529     
 530     if labels and labels.has_key(thelabel):
 531         targettext = labels[thelabel][targettext]
 532         refer = labels[thelabel]['refer']
 533         if showdesc:
 534             label_bgcolor = labels[thelabel]['bgcolor']
 535 
 536     if not refer:
 537         return '<i>%s</i>' % thelabel
 538     
 539     refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
 540     
 541     if showdesc:
 542         targetlink = '<a href="%s" title="%s">%s</a>' % ( refer_url, label_bgcolor, wikiutil.escape(targettext) )
 543     else:
 544         targetlink = '<a href="%s">%s</a>' % ( refer_url, wikiutil.escape(targettext))
 545     
 546     return targetlink
 547 
 548 
 549 def getheadingid(request, referpage, title):
 550 
 551     pntt = (referpage + title).encode(config.charset)
 552     hid = "head-" + sha.new(pntt).hexdigest()
 553     
 554     if not hasattr(request, '_eventcal_headings'):
 555         request._eventcal_headings = {}
 556     
 557     request._eventcal_headings.setdefault(pntt, 0)
 558     request._eventcal_headings[pntt] += 1
 559     if request._eventcal_headings[pntt] > 1:
 560         hid += '-%d'%(request._eventcal_headings[pntt],)
 561     
 562     return hid
 563 
 564 
 565 def getquerystring(req_fields):
 566     
 567     m_query = []
 568     tmp_form_vals = Globs.form_vals
 569     
 570     # format querystring
 571     # action should be poped out
 572     for field in req_fields:
 573         if tmp_form_vals.has_key(field):
 574             m_query.append(u'%s=%s' % (field, tmp_form_vals[field]) )
 575     
 576     if 'prevcalaction' in req_fields:
 577         if not tmp_form_vals.has_key('prevcalaction'):
 578             m_query.append(u'%s=%s' % ('prevcalaction', tmp_form_vals['calaction']) )
 579             
 580     m_query = u'&'.join(m_query)
 581     
 582     if m_query:
 583         m_query = '&%s' % m_query
 584     
 585     return m_query
 586 
 587 
 588 # bottom menu bar
 589 def showmenubar():
 590     
 591     request = Globs.request
 592     cal_action = Globs.cal_action
 593     page_name = Globs.pagename
 594     
 595     page_url = Globs.pageurl
 596     
 597     if not Params.menubar: return ''
 598 
 599     if cal_action == 'simple':
 600         menuwidth = Params.simplewidth
 601     elif cal_action == 'monthly':
 602         menuwidth = Params.monthlywidth
 603     else:
 604         menuwidth = ''
 605     
 606     left_menu_selected = []
 607     right_menu_selected = []
 608     
 609     # Go Today
 610     year, month, day = gettodaydate()
 611     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']))
 612     
 613     # List View
 614     mnu_listview = u'<a href="%s?calaction=list%s" title="List of all events">[List]</a>' % (page_url, getquerystring(['caldate', 'numcal']))
 615     
 616     # Monthly View
 617     mnu_monthview = u'<a href="%s?calaction=monthly%s" title="Monthly view">[Monthly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 618     
 619     # Simple Calendar View
 620     mnu_simpleview = u'<a href="%s?calaction=simple%s" title="Simple calendar view">[Simple]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 621     
 622     # Upcoming Event List
 623     mnu_upcomingview = u'<a href="%s?calaction=upcoming%s" title="Upcoming event list">[Upcoming]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 624     
 625     # Daily View
 626     mnu_dayview = u'<a href="%s?calaction=daily%s" title="Daily view">[Daily]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 627     
 628     # Weekly View
 629     mnu_weekview = u'<a href="%s?calaction=weekly%s" title="Weekly view">[Weekly]</a>' % (page_url, getquerystring(['caldate', 'numcal']) )
 630     
 631     html = [
 632         u'\r\n',
 633         u'<table class="eventcalendar_menubar" %s>',
 634         u'  <tr>',
 635         u'  <td class="eventcalendar_menubar" align="left">%s</td>',
 636         u'  <td class="eventcalendar_menubar" align="right">%s</td>',
 637         u'  </tr>',
 638         u'</table>',
 639         ]
 640         
 641     if cal_action == 'list':
 642         left_menu_selected.append(mnu_monthview)
 643         left_menu_selected.append(mnu_weekview)
 644         left_menu_selected.append(mnu_dayview)
 645         left_menu_selected.append(mnu_simpleview)
 646         right_menu_selected.append(mnu_upcomingview)
 647 
 648     elif cal_action == 'simple':
 649         left_menu_selected.append(mnu_monthview)
 650         left_menu_selected.append(mnu_weekview)
 651         left_menu_selected.append(mnu_dayview)
 652         right_menu_selected.append(mnu_listview)
 653         right_menu_selected.append(mnu_upcomingview)
 654         right_menu_selected.append(mnu_curmonthcal)
 655     
 656     elif cal_action == 'upcoming':
 657         left_menu_selected.append(mnu_monthview)
 658         left_menu_selected.append(mnu_weekview)
 659         left_menu_selected.append(mnu_dayview)
 660         left_menu_selected.append(mnu_simpleview)
 661         right_menu_selected.append(mnu_listview)
 662 
 663     elif cal_action == 'weekly':
 664         left_menu_selected.append(mnu_monthview)
 665         left_menu_selected.append(mnu_dayview)
 666         left_menu_selected.append(mnu_simpleview)
 667         right_menu_selected.append(mnu_upcomingview)
 668         right_menu_selected.append(mnu_listview)
 669         right_menu_selected.append(mnu_curmonthcal)
 670         
 671     elif cal_action == 'daily':
 672         left_menu_selected.append(mnu_monthview)
 673         left_menu_selected.append(mnu_weekview)
 674         left_menu_selected.append(mnu_simpleview)
 675         right_menu_selected.append(mnu_upcomingview)
 676         right_menu_selected.append(mnu_listview)
 677         right_menu_selected.append(mnu_curmonthcal)
 678 
 679     else:
 680         left_menu_selected.append(mnu_weekview)
 681         left_menu_selected.append(mnu_dayview)
 682         left_menu_selected.append(mnu_simpleview)
 683         right_menu_selected.append(mnu_upcomingview)
 684         right_menu_selected.append(mnu_listview)
 685         right_menu_selected.append(mnu_curmonthcal)
 686 
 687     left_menu_selected = u'\r\n'.join(left_menu_selected)
 688     right_menu_selected = u'\r\n'.join(right_menu_selected)
 689     
 690     html = u'\r\n'.join(html)
 691     html = html % (menuwidth, left_menu_selected, right_menu_selected)
 692 
 693     return html
 694         
 695 def show_page_list():
 696     html = ""
 697     request = Globs.request
 698     formatter = Globs.formatter
 699 
 700     if Params.showpagelist:
 701         source_pages = []
 702 
 703         events, cal_events, labels = loadEvents()
 704 
 705         for eid in events.keys():
 706             event = events[eid]
 707             refer = event['refer']
 708             refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
 709             targetlink = '<a href="%s">%s</a>' % ( refer_url, wikiutil.escape(refer))
 710             source_pages.append( targetlink )
 711 
 712         from sets import Set
 713         page_set = Set(source_pages)
 714 
 715         html = "\n"
 716         html += formatter.paragraph(1)
 717         html += "Constructed from events defined on these pages"
 718         html += formatter.paragraph(0)
 719         html += "\n"
 720         html += formatter.bullet_list(1)
 721         html += "\n"
 722         for p in page_set:
 723             html += formatter.listitem(1)
 724             html += p
 725             html += formatter.listitem(0)
 726             html += "\n"
 727         html += formatter.bullet_list(0)
 728         html += "\n"
 729 
 730     return html
 731 
 732 def getdatefield(str_date):
 733     str_year = ''
 734     str_month = ''
 735     str_day = ''
 736     
 737     if len(str_date) == 6:
 738         # year+month
 739         str_year = str_date[:4]
 740         str_month = str_date[4:]
 741         str_day = '1'
 742 
 743     elif len(str_date) == 8:
 744         # year+month+day
 745         str_year = str_date[:4]
 746         str_month = str_date[4:6]
 747         str_day = str_date[6:]
 748     
 749     elif len(str_date) == 10:
 750         # year+?+month+?+day
 751         str_year = str_date[:4]
 752         str_month = str_date[5:7]
 753         str_day = str_date[8:]
 754     
 755     else:
 756         raise ValueError
 757     
 758     # It raises exception if the input date is incorrect
 759     temp = datetime.date(int(str_year), int(str_month), int(str_day))
 760 
 761     return temp.year, temp.month, temp.day
 762 
 763 
 764 def gettimefield(str_time):
 765     str_hour = ''
 766     str_min = ''
 767     
 768     if len(str_time) == 4:
 769         # hour+minute
 770         str_hour = str_time[:2]
 771         str_min = str_time[2:]
 772     
 773     elif len(str_time) == 5:
 774         # hour+?+minute
 775         str_hour = str_time[:2]
 776         str_min = str_time[3:]
 777         
 778     else:
 779         raise ValueError
 780     
 781     # It raises exception if the input date is incorrect
 782     temp = datetime.time(int(str_hour), int(str_min))
 783 
 784     return temp.hour, temp.minute
 785 
 786 
 787 def gettodaydate():
 788     today = Globs.today
 789     return today.year, today.month, today.day    
 790 
 791 
 792 def cal_listhead():
 793 
 794     html = [
 795         u'  <tr>',
 796         u'      <td class="list_head">Title</td>',
 797         u'      <td class="list_head">Start Date</td>',
 798         u'      <td class="list_head">End Date</td>',
 799         u'      <td class="list_head">Recurrence</td>',
 800         u'      <td class="list_head">Label</td>',
 801         u'      <td class="list_head">Description</td>',
 802         u'      <td class="list_head">Reference</td>',
 803         u'  </tr>',
 804         ]
 805         
 806     return u'\r\n'.join(html)
 807 
 808 
 809 def showeventlist():
 810     
 811     debug('Show Calendar: List view')
 812     
 813     request = Globs.request
 814     formatter = Globs.formatter
 815     
 816     html_event_rows = []
 817     html_list_header = cal_listhead()
 818     
 819     # read all the events
 820     events, cal_events, labels = loadEvents()
 821     
 822     # sort events
 823     sorted_eventids = events.keys()
 824     sorted_eventids.sort(comp_list_events)
 825     
 826     for eid in sorted_eventids:
 827         if not events[eid]['clone']:
 828             html_event_rows.append( listshow_event(events[eid]) )
 829     
 830     html_event_rows = u'\r\n'.join(html_event_rows)
 831     
 832     html_list_table = [
 833         u'\r\n<div id="eventlist">',
 834         u'<table class="eventlist">',
 835         u'%s' % html_list_header,
 836         u'%s' % html_event_rows,
 837         u'</table>',
 838         u'</div>',
 839         ]
 840     html_list_table = u'\r\n'.join(html_list_table)
 841         
 842     return html_list_table
 843 
 844 
 845 def listshow_event(event):
 846     
 847     if event['recur_freq']:
 848         if event['recur_freq'] == -1:
 849             recur_desc = 'last %s' % event['recur_type']
 850         else:
 851             recur_desc = 'every %d %s' % (event['recur_freq'], event['recur_type'])
 852             
 853         if event['recur_until']:
 854              recur_desc = '%s until %s' % (recur_desc, formatcfgdatetime(event['recur_until']))
 855     else:
 856         recur_desc = ''
 857 
 858     html = [
 859         u'  <tr>',
 860         u'  <td class="list_entry">%s</td>' % converttext(event['title']),
 861         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['startdate'], event['starttime']),
 862         u'  <td class="list_entry">%s</td>' % formatcfgdatetime(event['enddate'], event['endtime']),
 863         u'  <td class="list_entry">%s</td>' % recur_desc,
 864         u'  <td class="list_entry">%s</td>' % showReferPageParsedForLabel(event['label']),
 865         u'  <td class="list_entry">%s</td>' % converttext(event['description']),
 866         u'  <td class="list_entry">%s</td>' % showReferPageParsed(event, 'refer'),
 867         u'  </tr>',
 868         ]
 869     
 870     return u'\r\n'.join(html)
 871 
 872 
 873 def showupcomingeventlist():
 874     
 875     debug('Show Calendar: Upcoming Event View')
 876     
 877     request = Globs.request
 878     formatter = Globs.formatter
 879     
 880     html_event_rows = []
 881     html_list_header = cal_listhead()
 882     
 883     year, month, day = gettodaydate()
 884     day_delta = datetime.timedelta(days=Params.upcomingrange)
 885     cur_date = datetime.date(year, month, day)
 886     next_range = cur_date + day_delta
 887     
 888     # set ranges of events
 889     datefrom = u'%04d%02d%02d' % (year, month, day)
 890     dateto = u'%04d%02d%02d' % (next_range.year, next_range.month, next_range.day)
 891     
 892     # read all the events (no cache)
 893     events, cal_events, labels = loadEvents(datefrom, dateto, 1)
 894     
 895     nowtime = formattimeobject(Globs.now)
 896     
 897     datefrom = formatcfgdatetime(cur_date, nowtime)
 898     #u'%04d-%02d-%02d %s:%s' % (year, month, day, nowtime[:2], nowtime[2:])
 899     dateto = formatcfgdatetime(formatdateobject(next_range))
 900     #u'%04d-%02d-%02d' % (next_range.year, next_range.month, next_range.day)
 901     
 902     # sort events
 903     sorted_eventids = events.keys()
 904     sorted_eventids.sort(comp_list_events)
 905     
 906     for eid in sorted_eventids:
 907         if events[eid]['enddate'] >= formatdateobject(Globs.today):
 908             if (not events[eid]['endtime']) or events[eid]['endtime'] >= formattimeobject(Globs.now):
 909                 html_event_rows.append( listshow_event(events[eid]) )
 910     
 911     html_event_rows = u'\r\n'.join(html_event_rows)
 912     
 913     html_list_table = [
 914         u'\r\n<div id="eventlist">',
 915         u'<table class="eventlist">',
 916         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),
 917         u'%s' % html_list_header,
 918         u'%s' % html_event_rows,
 919         u'</table>',
 920         u'</div>',
 921         ]
 922     html_list_table = u'\r\n'.join(html_list_table)
 923         
 924     return html_list_table
 925 
 926 
 927 
 928 
 929 def showcalendar():
 930     
 931     request = Globs.request
 932     formatter = Globs.formatter
 933     form_vals = Globs.form_vals
 934     
 935     html = []
 936     
 937     if form_vals.has_key('caldate'):
 938         try:
 939             year, month, str_temp = getdatefield(form_vals['caldate'])
 940         except (TypeError, ValueError):
 941             errormsgcode('invalid_caldate')
 942             year, month, dy = gettodaydate()
 943     
 944     elif Params.curdate:
 945         try:
 946             year, month, str_temp = getdatefield(Params.curdate)
 947         except (TypeError, ValueError):
 948             errormsgcode('invalid_curdate')
 949             year, month, dy = gettodaydate()
 950             
 951     else:
 952         year, month, dy = gettodaydate()
 953     
 954     # check number of calendar
 955     numcal = Params.numcal
 956     
 957     if form_vals.has_key('numcal'):
 958         try:
 959             numcal = int(form_vals['numcal'])
 960         except (TypeError, ValueError):
 961             errormsgcode('invalid_numcal')
 962 
 963     if numcal < 1:
 964         numcal = 1
 965     elif numcal > 12:
 966         numcal = 12
 967 
 968     for index in range(numcal):
 969     
 970         cyear, cmonth = yearmonthplusoffset(year, month, index)
 971     
 972         cal_html = showeventcalendar(cyear, cmonth)
 973         html.append(cal_html)
 974     
 975     return u''.join(html)
 976 
 977 
 978 def showdailycalendar():
 979     
 980     request = Globs.request
 981     formatter = Globs.formatter
 982     
 983     form_vals = Globs.form_vals
 984     
 985     if form_vals.has_key('caldate'):
 986         try:
 987             year, month, dy = getdatefield(form_vals['caldate'])
 988             
 989             if len(form_vals['caldate']) <= 6:
 990                 tyear, tmonth, tdy = gettodaydate()
 991                 if tyear == year and month == tmonth:
 992                     dy = tdy
 993                     
 994         except (TypeError, ValueError):
 995             errormsgcode('invalid_caldate')
 996             year, month, dy = gettodaydate()
 997             
 998     elif Params.curdate:
 999         try:
1000             year, month, dy = getdatefield(Params.curdate)
1001         except (TypeError, ValueError):
1002             errormsgcode('invalid_curdate')
1003             year, month, dy = gettodaydate()
1004         
1005     else:
1006         year, month, dy = gettodaydate()
1007     
1008     html = showdailyeventcalendar(year, month, dy)
1009     
1010     return u''.join(html)
1011 
1012 
1013 def showweeklycalendar():
1014     
1015     request = Globs.request
1016     formatter = Globs.formatter
1017     
1018     form_vals = Globs.form_vals
1019     
1020     if form_vals.has_key('caldate'):
1021         try:
1022             year, month, dy = getdatefield(form_vals['caldate'])
1023             
1024             if len(form_vals['caldate']) <= 6:
1025                 tyear, tmonth, tdy = gettodaydate()
1026                 if tyear == year and month == tmonth:
1027                     dy = tdy
1028 
1029         except (TypeError, ValueError):
1030             errormsgcode('invalid_caldate')
1031             year, month, dy = gettodaydate()
1032     
1033     elif Params.curdate:
1034         try:
1035             year, month, dy = getdatefield(Params.curdate)
1036         except (TypeError, ValueError):
1037             errormsgcode('invalid_curdate')
1038             year, month, dy = gettodaydate()
1039     else:
1040         year, month, dy = gettodaydate()
1041     
1042     html = showweeklyeventcalendar(year, month, dy)
1043     
1044     return u''.join(html)
1045 
1046     
1047 def showsimplecalendar():
1048     
1049     request = Globs.request
1050     formatter = Globs.formatter
1051     form_vals = Globs.form_vals
1052     
1053     html = []
1054     
1055     if form_vals.has_key('caldate'):
1056         try:
1057             year, month, str_temp = getdatefield(form_vals['caldate'])
1058         except (TypeError, ValueError):
1059             errormsgcode('invalid_caldate')
1060             year, month, dy = gettodaydate()
1061     elif Params.curdate:
1062         try:
1063             year, month, str_temp = getdatefield(Params.curdate)
1064         except (TypeError, ValueError):
1065             errormsgcode('invalid_curdate')
1066             year, month, dy = gettodaydate()
1067     else:
1068         year, month, dy = gettodaydate()
1069     
1070     # check number of calendar
1071     numcal = Params.numcal
1072     
1073     if form_vals.has_key('numcal'):
1074         try:
1075             numcal = int(form_vals['numcal'])
1076         except (TypeError, ValueError):
1077             errormsgcode('invalid_numcal')
1078             
1079 
1080     if numcal < 1:
1081         numcal = 1
1082     elif numcal > 12:
1083         numcal = 12
1084 
1085     for index in range(numcal):
1086     
1087         cyear, cmonth = yearmonthplusoffset(year, month, index)
1088     
1089         cal_html = showsimpleeventcalendar(cyear, cmonth)
1090         html.append(cal_html)
1091     
1092     return u''.join(html)
1093 
1094 
1095 
1096 # sort events in cal_events by length of days of the event
1097 def comp_cal_events(xid, yid):
1098     events = Globs.events
1099     
1100     if events[xid]['date_len'] > events[yid]['date_len']:
1101         return -1
1102     elif events[xid]['date_len'] == events[yid]['date_len']:
1103         if events[xid]['date_len'] == 1:
1104             if events[xid]['starttime'] == events[yid]['starttime']:
1105                 return cmp(events[yid]['time_len'], events[xid]['time_len'])
1106             else:
1107                 return cmp(events[xid]['starttime'], events[yid]['starttime'])
1108         else:
1109             return 0
1110     else:
1111         return 1
1112 
1113 
1114 # sort events in the list by start date of the event
1115 def comp_list_events(xid, yid):
1116     events = Globs.events
1117     
1118     if events[xid]['startdate'] == events[yid]['startdate']:
1119         return cmp(events[xid]['starttime'], events[yid]['starttime'])
1120     else:
1121         return cmp(events[xid]['startdate'], events[yid]['startdate'])
1122 
1123 
1124 # load events from wiki pages
1125 def loadEvents(datefrom='', dateto='', nocache=0):
1126     
1127     request = Globs.request
1128     
1129     debug('Loading event information.')
1130     
1131     events = {}
1132     labels = {}
1133     cal_events = {}
1134     raw_events = {}
1135     
1136     raw_events, labels = loadEventsFromWikiPages()
1137     
1138     # handling cal_events
1139     if datefrom or dateto:
1140         
1141         # cache configurations
1142         arena = Page(request, Globs.pagename)
1143         eventkey = 'events'
1144         filteredeventkey = 'events_%s-%s' % (datefrom, dateto)
1145         caleventkey = 'calevents_%s-%s' % (datefrom, dateto)
1146         
1147         cache_events = caching.CacheEntry(request, arena, eventkey, scope='item')
1148         cache_filteredevents = caching.CacheEntry(request, arena, filteredeventkey, scope='item')
1149         cache_calevents = caching.CacheEntry(request, arena, caleventkey, scope='item')
1150         
1151         dirty = 1
1152         
1153         debug('Checking cal_events cache')
1154         
1155         if not (cache_calevents.needsUpdate(cache_events._filename()) or cache_filteredevents.needsUpdate(cache_events._filename())):
1156         
1157             try:
1158                 events = pickle.loads(cache_filteredevents.content())
1159                 cal_events = pickle.loads(cache_calevents.content())
1160                 debug('Cached event (filtered) information is used: total %d events' % len(events))
1161                 dirty = 0
1162             except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1163                 debug('Picke error at fetching cached events (filtered)')
1164                 events = {}
1165                 cal_events = {}
1166 
1167 
1168         # if cache is dirty, update the cache
1169         if dirty:
1170         
1171             debug('Checking event cache: it\'s dirty or requested to refresh')
1172             debug('Building new cal_event information')
1173         
1174             try:
1175                 datefrom, dateto = int(datefrom), int(dateto)
1176             except (TypeError, ValueError):
1177                 datefrom, dateto = 0, 0
1178         
1179             clone_num = 0
1180             
1181             for e_id in raw_events.keys():
1182                 
1183                 cur_event = raw_events[e_id]
1184                 
1185                 # handling event recurrence
1186                 recur_freq = cur_event['recur_freq']
1187                 
1188                 if recur_freq or recur_freq == -1:
1189                     
1190                     if not (cur_event['recur_until'] and int(cur_event['recur_until']) < datefrom) or int(cur_event['startdate']) > dateto:
1191 
1192                         if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1193                             # generating cal_events for iteself
1194                             events[e_id] = cur_event.copy()
1195                             insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1196                         
1197                         delta_date_len = datetime.timedelta(days = int(cur_event['date_len']) - 1 )
1198                         
1199                         if cur_event['recur_type'] == 'day':
1200                         
1201                             day_delta = int(recur_freq)
1202                             startdate = getdatetimefromstring(cur_event['startdate'])
1203                             datefrom_date = getdatetimefromstring(datefrom)
1204                             
1205                             if int(datefrom) > int(cur_event['startdate']):
1206                                 diffs = datefrom_date - startdate
1207                                 q_delta = diffs.days / day_delta
1208                                 if diffs.days % day_delta > 0:
1209                                     q_delta += 1
1210                             else:
1211                                 q_delta = 1
1212                             
1213                             while 1:
1214                                 
1215                                 if q_delta == 0:
1216                                     q_delta += 1
1217                                     continue
1218                                 
1219                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1220                                 recurred_enddate = recurred_startdate + delta_date_len
1221                                 
1222                                 new_startdate = formatdateobject(recurred_startdate)
1223                                 new_enddate = formatdateobject(recurred_enddate)
1224                                 
1225                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1226                                     break
1227                                 
1228                                 clone_num += 1
1229                                 clone_id = 'c%d' % clone_num
1230                                 
1231                                 events[clone_id] = cur_event.copy()
1232                                 events[clone_id]['id'] = clone_id
1233                                 events[clone_id]['startdate'] = new_startdate
1234                                 events[clone_id]['enddate'] = new_enddate
1235                                 events[clone_id]['clone'] = 1
1236                                 
1237                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1238                                 
1239                                 q_delta += 1
1240                         
1241                         elif cur_event['recur_type'] == 'week':
1242                             
1243                             day_delta = int(recur_freq) * 7
1244                             
1245                             startdate = getdatetimefromstring(cur_event['startdate'])
1246                             datefrom_date = getdatetimefromstring(datefrom)
1247                             
1248                             if int(datefrom) > int(cur_event['startdate']):
1249                                 diffs = datefrom_date - startdate
1250                                 q_delta = diffs.days / day_delta
1251                                 if diffs.days % day_delta > 0:
1252                                     q_delta += 1
1253                             else:
1254                                 q_delta = 1
1255                             
1256                             while 1:
1257                                 
1258                                 if q_delta == 0:
1259                                     q_delta += 1
1260                                     continue
1261                                 
1262                                 recurred_startdate = startdate + datetime.timedelta(days = q_delta * day_delta )
1263                                 recurred_enddate = recurred_startdate + delta_date_len
1264                                 
1265                                 new_startdate = formatdateobject(recurred_startdate)
1266                                 new_enddate = formatdateobject(recurred_enddate)
1267                                 
1268                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1269                                     break
1270                                 
1271                                 clone_num += 1
1272                                 clone_id = 'c%d' % clone_num
1273                                 
1274                                 events[clone_id] = cur_event.copy()
1275                                 events[clone_id]['id'] = clone_id
1276                                 events[clone_id]['startdate'] = new_startdate
1277                                 events[clone_id]['enddate'] = new_enddate
1278                                 events[clone_id]['clone'] = 1
1279                                 
1280                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1281                                 
1282                                 q_delta += 1
1283                         
1284                         
1285                         elif cur_event['recur_type'] == 'weekday':
1286                             
1287                             syear, smonth, sday = getdatefield(cur_event['startdate'])
1288                             cyear, cmonth, cday = getdatefield(str(datefrom))
1289                             
1290                             recur_weekday = calendar.weekday(syear, smonth, sday)
1291 
1292                             while 1:
1293                                 
1294                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1295                                 firstmatch = (recur_weekday - firstweekday) % 7 + 1
1296                                 
1297                                 if recur_freq == -1:
1298                                     therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1299                                 else:
1300                                     #XXX should handle error
1301                                     try:
1302                                         therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[recur_freq-1]
1303                                     except IndexError:
1304                                         if Params.showlastweekday:
1305                                             # if no matched weekday, the last weekday will be displayed
1306                                             therecur_day = xrange(firstmatch, daysinmonth + 1, 7)[-1]
1307                                         else:
1308                                             # if no matched weekday, no event will be displayed
1309                                             cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1310                                             continue
1311                                     
1312                                 
1313                                 recurred_startdate = datetime.date(cyear, cmonth, therecur_day)
1314                                 recurred_enddate = recurred_startdate + delta_date_len
1315                                 
1316                                 new_startdate = formatdateobject(recurred_startdate)
1317                                 new_enddate = formatdateobject(recurred_enddate)
1318                                 
1319                                 if int(new_startdate) < int(datefrom) or new_startdate == cur_event['startdate']:
1320                                     cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1321                                     continue
1322                                 
1323                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1324                                     break
1325                                 
1326                                 clone_num += 1
1327                                 clone_id = 'c%d' % clone_num
1328                                 
1329                                 events[clone_id] = cur_event.copy()
1330                                 events[clone_id]['id'] = clone_id
1331                                 events[clone_id]['startdate'] = new_startdate
1332                                 events[clone_id]['enddate'] = new_enddate
1333                                 events[clone_id]['clone'] = 1
1334     
1335                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1336                                 
1337                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, 1)
1338                                 
1339                         
1340                         elif cur_event['recur_type'] == 'month':
1341                             
1342                             cyear, cmonth, therecurday = getdatefield(cur_event['startdate'])
1343                             
1344                             while 1:
1345                                 
1346                                 cyear, cmonth = yearmonthplusoffset(cyear, cmonth, recur_freq)
1347                                 firstweekday, daysinmonth = calendar.monthrange(cyear, cmonth)
1348                                 recur_day = therecurday 
1349                                 if daysinmonth < recur_day:
1350                                     recur_day = daysinmonth
1351                                 new_startdate = formatDate(cyear, cmonth, recur_day)
1352                                 
1353                                 if int(new_startdate) < int(datefrom):
1354                                     continue
1355                                 
1356                                 recurred_startdate = datetime.date(cyear, cmonth, recur_day)
1357                                 recurred_enddate = recurred_startdate + delta_date_len
1358                                 
1359                                 new_startdate = formatdateobject(recurred_startdate)
1360                                 new_enddate = formatdateobject(recurred_enddate)
1361                                 
1362                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1363                                     break
1364                                 
1365                                 clone_num += 1
1366                                 clone_id = 'c%d' % clone_num
1367                                 
1368                                 events[clone_id] = cur_event.copy()
1369                                 events[clone_id]['id'] = clone_id
1370                                 events[clone_id]['startdate'] = new_startdate
1371                                 events[clone_id]['enddate'] = new_enddate
1372                                 events[clone_id]['clone'] = 1
1373     
1374                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1375                         
1376                         elif cur_event['recur_type'] == 'year':
1377                             
1378                             ryear, rmonth, rday = getdatefield(cur_event['startdate'])
1379                             cyear, cmonth, cday = getdatefield(str(datefrom))
1380                             
1381                             while 1:
1382                                 
1383                                 ryear += recur_freq
1384                                 new_startdate = formatDate(ryear, rmonth, rday)
1385                                 
1386                                 if int(new_startdate) < int(datefrom):
1387                                     continue
1388                                     
1389                                 if int(new_startdate) > dateto or (cur_event['recur_until'] and int(cur_event['recur_until']) < int(new_startdate)):
1390                                     break
1391                                 
1392                                 recurred_startdate = datetime.date(ryear, rmonth, rday)
1393                                 recurred_enddate = recurred_startdate + delta_date_len
1394                                 
1395                                 new_startdate = formatdateobject(recurred_startdate)
1396                                 new_enddate = formatdateobject(recurred_enddate)
1397                                 
1398                                 clone_num += 1
1399                                 clone_id = 'c%d' % clone_num
1400                                 
1401                                 events[clone_id] = cur_event.copy()
1402                                 events[clone_id]['id'] = clone_id
1403                                 events[clone_id]['startdate'] = new_startdate
1404                                 events[clone_id]['enddate'] = new_enddate
1405                                 events[clone_id]['clone'] = 1
1406     
1407                                 insertcalevents(cal_events, datefrom, dateto, clone_id, new_startdate, new_enddate)
1408                 
1409                 else:
1410                     
1411                     if not (int(cur_event['enddate']) < datefrom or int(cur_event['startdate']) > dateto):
1412                         events[e_id] = cur_event.copy()
1413                         insertcalevents(cal_events, datefrom, dateto, e_id, cur_event['startdate'], cur_event['enddate'])
1414                         
1415             
1416             # sort cal_events
1417             # store event list into global variables in order to sort them
1418             Globs.events = events
1419             
1420             for eachdate in cal_events.keys():
1421                 cal_events[eachdate].sort(comp_cal_events)
1422             
1423             # cache update
1424             if not nocache:
1425                 cache_filteredevents.update(pickle.dumps(events, PICKLE_PROTOCOL))
1426                 cache_calevents.update(pickle.dumps(cal_events, PICKLE_PROTOCOL))
1427         
1428     else:
1429         events = raw_events
1430         
1431         # store event list into global variables in order to sort them
1432         Globs.events = events
1433     
1434     Globs.labels = labels
1435     
1436     debug(u'Total %d events are loaded finally.' % len(events))
1437     debug(u'Total %d labels are loaded finally.' % len(labels))
1438     
1439     return events, cal_events, labels
1440 
1441 
1442 
1443 def loadEventsFromWikiPages():
1444     
1445     events = {}
1446     labels = {}
1447     cached_event_loaded = 0
1448     dirty = 0
1449     
1450     eventrecord_list = []
1451     labelrecord_list = []
1452     eventpages = []
1453     stored_errmsg = ''
1454     
1455     request = Globs.request
1456     formatter = Globs.formatter
1457     category = Params.category
1458     
1459     # cache configurations
1460     arena = Page(request, Globs.pagename)
1461     
1462     eventkey = 'events'
1463     labelkey = 'labels'
1464     pagelistkey = 'eventpages'
1465     errmsglistkey = 'eventcalerrormsglist'
1466     
1467     cache_events = caching.CacheEntry(request, arena, eventkey, scope='item')
1468     cache_labels = caching.CacheEntry(request, arena, labelkey, scope='item')
1469     cache_pages = caching.CacheEntry(request, arena, pagelistkey, scope='item')
1470     cache_errmsglist = caching.CacheEntry(request, arena, errmsglistkey, scope='item')
1471     
1472     # page list cache
1473 
1474     debug('Checking page list cache')
1475     
1476     # check the time at which page list cache has been created
1477     
1478     cp_mtime = cache_pages.mtime()
1479     timedelta_days = 9999
1480     
1481     if cp_mtime:
1482         cp_date = datetime.datetime.fromtimestamp(cp_mtime)
1483         today = datetime.datetime.fromtimestamp(time.time())
1484         datediff = today - cp_date
1485         timedelta_days = datediff.days
1486         debug('Time from page list cache built = %s' % datediff)
1487 
1488     
1489     if Globs.page_action == 'refresh' or cache_pages.needsUpdate(arena._text_filename()) or timedelta_days >= 1:
1490         categorypages = searchPages(request, category)
1491         for page in categorypages:
1492             # this is to workaround the bug in the category search returning
1493             # pages that only referance the category but are not in it
1494             # i.e. in the paramiter list for this macro
1495             if not page.page_name == request.page.page_name:
1496                 formatter.pagelink(1, pagename=page.page_name)
1497             eventpages.append(page.page_name)
1498         cache_pages.update('\n'.join(eventpages).encode('utf-8'))
1499         debug('New page list is built: %d pages' % len(eventpages))
1500     else:
1501         eventpages = cache_pages.content().decode('utf-8').split('\n')
1502         debug('Cached page list is used: %d pages' % len(eventpages))
1503     
1504     if not Globs.page_action == 'refresh':
1505         # check the cache validity
1506         for page_name in eventpages:
1507             
1508             p = Page(request, page_name)
1509             e_ref = page_name
1510             
1511             if cache_events.needsUpdate(p._text_filename()) or cache_labels.needsUpdate(p._text_filename()) or cache_errmsglist.needsUpdate(p._text_filename()):
1512                 dirty = 1
1513                 break
1514     else:
1515         dirty = 1
1516 
1517     if dirty:
1518         # generating events
1519         
1520         dirty_local = 0
1521         debug_records = {}
1522         
1523         eventrecordkey = 'eventrecords'
1524         labelrecordkey = 'labelrecords'
1525         errmsgkey = 'eventcalerrormsg'
1526         
1527         # fetch event records from each page in the category
1528         for page_name in eventpages:
1529             
1530             p = Page(request, page_name)
1531             e_ref = page_name
1532             
1533             cache_errmsg = caching.CacheEntry(request, p, errmsgkey, scope='item')
1534             cache_eventrecords = caching.CacheEntry(request, p, eventrecordkey, scope='item')
1535             cache_labelrecords = caching.CacheEntry(request, p, labelrecordkey, scope='item')
1536             
1537             if cache_eventrecords.needsUpdate(p._text_filename()) or cache_labelrecords.needsUpdate(p._text_filename()) or Globs.page_action == 'refresh':
1538                 page_content = p.get_raw_body()
1539                 eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref)
1540                 
1541                 debug_records[e_ref] = '%d events are fetched from %s' % (len(eventrecords), e_ref)
1542                 
1543                 # XXXXX
1544                 #debug('events: %s' % eventrecords)
1545                 #debug('labels: %s' % labelrecords)
1546                 
1547                 cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1548                 cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL))
1549                 cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL))
1550                 
1551                 stored_errmsg += Globs.errormsg
1552                 Globs.errormsg = ''
1553                 
1554             else:
1555                 try:
1556                     eventrecords = pickle.loads(cache_eventrecords.content())
1557                     labelrecords = pickle.loads(cache_labelrecords.content())
1558                     Globs.errormsg = pickle.loads(cache_errmsg.content())
1559                     
1560                     debug_records[e_ref] = '%d cached eventrecords are used from %s' % (len(eventrecords), e_ref)
1561                     
1562                 except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1563                     dirty = 1
1564                     page_content = p.get_raw_body()
1565                     eventrecords, labelrecords = getEventRecordFromPage(page_content, e_ref)
1566                     debug_records[e_ref] = '%d eventrecords are fetched from %s due to pickle error' % (len(eventrecords), e_ref)
1567                     
1568                     cache_eventrecords.update(pickle.dumps(eventrecords, PICKLE_PROTOCOL))
1569                     cache_labelrecords.update(pickle.dumps(labelrecords, PICKLE_PROTOCOL))
1570                     cache_errmsg.update(pickle.dumps(Globs.errormsg, PICKLE_PROTOCOL))
1571     
1572             eventrecord_list.append(eventrecords)
1573             labelrecord_list.append(labelrecords)
1574             
1575             stored_errmsg += Globs.errormsg
1576             Globs.errormsg = ''
1577 
1578         debug('Checking event cache: it\'s dirty or requested to refresh')
1579 
1580     else:
1581         
1582         debug('Checking event cache: still valid')
1583         
1584         try:
1585             events = pickle.loads(cache_events.content())
1586             labels = pickle.loads(cache_labels.content())
1587             stored_errmsg = pickle.loads(cache_errmsglist.content())
1588             
1589             cached_event_loaded = 1
1590             
1591             debug('Cached event information is used: total %d events' % len(events))
1592             
1593         except (pickle.UnpicklingError, IOError, EOFError, ValueError):
1594             events = {}
1595             labels = {}
1596             stored_errmsg = ''
1597             
1598             debug('Picke error at fetching cached events')
1599     
1600     # if it needs refreshed, generate events dictionary
1601     if not cached_event_loaded:
1602 
1603         # XXX: just for debugging
1604         debug('Building new event information')
1605         for page_name in eventpages:
1606             debug(debug_records[page_name])
1607 
1608         for eventrecords in eventrecord_list:
1609             for evtrecord in eventrecords:
1610                 e_id = evtrecord['id']
1611                 events[e_id] = evtrecord
1612         
1613         for labelrecords in labelrecord_list:
1614             for label in labelrecords:
1615                 c_id = label['name']
1616                 if not labels.has_key(c_id):
1617                     labels[c_id] = label
1618                 else:
1619                     stored_errmsg += u'<li>%s\n' % geterrormsg('redefined_label', label['refer'], label['name'])
1620         
1621         # after generating updated events, update the cache
1622         cache_events.update(pickle.dumps(events, PICKLE_PROTOCOL))
1623         cache_labels.update(pickle.dumps(labels, PICKLE_PROTOCOL))
1624         cache_errmsglist.update(pickle.dumps(stored_errmsg, PICKLE_PROTOCOL))
1625         
1626         debug('Event information is newly built: total %d events' % len(events))
1627 
1628     Globs.errormsg = stored_errmsg
1629     
1630     # end of updating events block    
1631     
1632     return events, labels
1633     
1634 
1635 
1636 def getEventRecordFromPage(pagecontent, referpage):
1637     
1638     request = Globs.request
1639     
1640     eventrecords = []
1641     labelrecords = []
1642     page_bgcolor = ''
1643     page_description = ''
1644     
1645     e_num = 0
1646     
1647     # fetch the page default bgcolor
1648     regex_page_bgcolor = r"""
1649 (?P<req_field>^[ ]+default_bgcolor::[ ]+)
1650 (
1651     (?P<pagebgcolor>(\#[0-9a-fA-F]{6}|[a-zA-Z]+))
1652     \s*?
1653     $
1654 )?
1655 """
1656 
1657     pattern = re.compile(regex_page_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1658     match = pattern.search(pagecontent)
1659         
1660     if match:
1661         if match.group('pagebgcolor'):
1662             page_bgcolor = match.group('pagebgcolor')
1663         else:
1664             errormsg( geterrormsg('invalid_default_bgcolor', referpage) )
1665 
1666 
1667     # fetch the page default description
1668     regex_page_description = r"""
1669 (?P<req_field>^[ ]+default_description::[ ]+)
1670 (
1671     (?P<pagedescription>.*?)
1672     \s*?
1673     $
1674 )?
1675 """
1676    
1677     pattern = re.compile(regex_page_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1678     match = pattern.search(pagecontent)
1679         
1680     if match:
1681         if match.group('pagedescription'):
1682             page_description = match.group('pagedescription')
1683         else:
1684             errormsg( geterrormsg('empty_default_description', referpage) )
1685 
1686     # fetch the label definition
1687     regex_label_definition = r"""
1688 (?P<reqfield>^[ ]+label_def::[ ]+)
1689 (
1690 	(?P<name>[^,^:^\s]+?)
1691 	[,: ]+
1692 	(?P<bgcolor>(\#[0-9a-fA-F]{6}|[a-zA-Z]+))
1693 	\s*?
1694 	$
1695 )?
1696 """
1697 
1698     
1699     pattern = re.compile(regex_label_definition, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1700     match = pattern.findall(pagecontent)
1701         
1702     if match:
1703     
1704         for matchitem in match:
1705             
1706             labelitem = {}
1707             
1708             label_name = matchitem[2]
1709             label_bgcolor = matchitem[3]
1710         
1711             if label_name and label_bgcolor:
1712                 labelitem['name'] = label_name
1713                 labelitem['bgcolor'] = label_bgcolor
1714                 labelitem['refer'] = referpage
1715                 
1716                 labelrecords.append(labelitem)
1717             else:
1718                 errormsg( geterrormsg('empty_label_definition', referpage) )
1719                 continue
1720 
1721 
1722     # fetch event item
1723     regex_eventitem = r"""
1724 (?P<eventitem>
1725 	(?P<heading>^\s*(?P<hmarker>=+)\s(?P<eventtitle>.*?)\s(?P=hmarker) $)
1726 	(?P<eventdetail>
1727 		.*?
1728 		(?=
1729 			^\s*(?P<nexthmarker>=+)\s(?P<nexteventtitle>.*?)\s(?P=nexthmarker) $
1730 			| \Z
1731         )
1732 	)
1733 )
1734 """
1735     
1736     pattern = re.compile(regex_eventitem, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
1737     match = pattern.findall(pagecontent)
1738 
1739     if match:
1740         
1741         for matchitem in match:
1742             
1743             eventitem = {}
1744 
1745             eventtitle = matchitem[3]
1746             eventdetail = matchitem[4]
1747             
1748             e_headid = getheadingid(request, referpage, eventtitle)
1749             
1750             if not eventdetail:
1751                 continue
1752             
1753             #debug('Examininng "%s" event from %s ..' % (eventtitle, referpage))
1754             
1755             try:
1756                 e_start_date, e_start_time, e_end_date, e_end_time, e_bgcolor, e_label, e_description, e_recur_freq, e_recur_type, e_recur_until = geteventfield(eventdetail)
1757             except EventcalError, errmsgcode:
1758 
1759                 if not errmsgcode.value == 'pass':
1760                     errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) )
1761                 
1762                 continue
1763                 
1764             #except TypeError, ValueError:
1765             #    errormsg('undefined')
1766             #    continue
1767             
1768             # set default values
1769             if not e_bgcolor:
1770                 e_bgcolor = page_bgcolor
1771                 
1772             if not e_description:
1773                 e_description = page_description
1774             
1775             e_num += 1
1776             e_id = 'e_%s_%d' % (referpage, e_num)
1777             
1778             eventitem['id'] = e_id
1779             eventitem['title'] = eventtitle
1780             eventitem['startdate'] = e_start_date
1781             eventitem['starttime'] = e_start_time
1782             eventitem['enddate'] = e_end_date
1783             eventitem['endtime'] = e_end_time
1784             eventitem['title'] = eventtitle
1785             eventitem['refer'] = referpage
1786             eventitem['bgcolor'] = e_bgcolor
1787             eventitem['label'] = e_label
1788             eventitem['description'] = e_description
1789             eventitem['recur_freq'] = e_recur_freq
1790             eventitem['recur_type'] = e_recur_type
1791             eventitem['recur_until'] = e_recur_until
1792             
1793             try:
1794                 eventitem['date_len'] = diffday(e_start_date, e_end_date) + 1
1795                 eventitem['clone'] = 0
1796                 eventitem['hid'] = e_headid
1797                 
1798                 if eventitem['date_len'] == 1 and e_start_time and e_end_time:
1799                     eventitem['time_len'] = difftime(e_start_time, e_end_time) + 1
1800                 else:
1801                     eventitem['time_len'] = 0
1802                     
1803             except EventcalError, errmsgcode:
1804                 debug('Failed to add "%s" event from %s ..' % (eventtitle, referpage))
1805                 errormsg( geterrormsg(errmsgcode.value, referpage, eventtitle, e_headid) )
1806                 continue
1807             
1808             eventrecords.append(eventitem)
1809             
1810             #debug('Added "%s" event from %s ..' % (eventtitle, referpage))
1811 
1812     return eventrecords, labelrecords
1813     
1814 
1815 
1816 def geteventfield(detail):
1817     
1818 
1819     # START DATE REGEX ----------------------------
1820     regex_startdate = r"""
1821 (?P<reqfield>^[ ]+start::(?=[ ]+))
1822 (
1823     (?P<startdate>
1824         [ ]+
1825         (
1826             (?P<startdate1>
1827             	(?P<startyear1>19\d{2} | 20\d{2} | \d{2} )
1828             	[./-]
1829             	(?P<startmonth1>1[012] | 0[1-9] | [1-9])
1830             	[./-]
1831             	(?P<startday1>3[01] | 0[1-9] | [12]\d | [1-9])
1832             )
1833             |
1834             (?P<startdate2>
1835             	(?P<startmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1836             	[ ]+
1837             	(?P<startday2>3[01] | 0[1-9] | [12]\d | [1-9])
1838             	(?: st | nd | rd | th )?
1839             	[ ,]+
1840             	(?P<startyear2>19\d{2} | 20\d{2} | \d{2})
1841             )
1842             |
1843             (?P<startdate3>
1844             	(?P<startyear3>19\d{2} | 20\d{2} | \d{2} )
1845             	(?P<startmonth3>1[012] | 0[1-9])
1846             	(?P<startday3>3[01] | 0[1-9] | [12]\d)
1847             )
1848         )
1849     )
1850     (?P<starttime>
1851         [ ,]+
1852         (
1853             (?P<starttime1>
1854             	(?P<starthour1> 1[0-2] | [0]?[1-9] )
1855             	(
1856             		(?: [.:])
1857             		(?P<startminute1>[0-5]\d{0,1} | [6-9])
1858             	)?
1859             	[ ]*
1860             	(?P<am1> am | pm | p | a )
1861             )
1862             |
1863             (?P<starttime2>
1864             	(?P<starthour2> | [01]\d{0,1} | 2[0-3] | [1-9])
1865             	(
1866             		(?: [.:])
1867             		(?P<startminute2>[0-5]\d{0,1} | [6-9])
1868             	)?
1869             )
1870             |
1871             (?P<starttime3>
1872             	(?P<starthour3> [01]\d | 2[0-3])
1873             	(?P<startminute3> [0-5]\d)?
1874             )
1875             |
1876             (?P<starttime4>
1877             	(?P<starthour4> 0[1-9] | 1[0-2])
1878             	(?P<startminute4> [0-5]\d)?
1879             	[ ]*
1880             	(?P<am4> am | pm | p | a )
1881             )
1882         )
1883     )?
1884     \s*?
1885     $
1886 )?
1887 """
1888 
1889     
1890 
1891     # END DATE REGEX ----------------------------
1892     regex_enddate = r"""
1893 (?P<reqfield>^[ ]+end::(?=[ ]+))
1894 (
1895     (?P<enddate>
1896         [ ]+
1897         (
1898             (?P<enddate1>
1899             	(?P<endyear1>19\d{2} | 20\d{2} | \d{2} )
1900             	[./-]
1901             	(?P<endmonth1>1[012] | 0[1-9] | [1-9])
1902             	[./-]
1903             	(?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9])
1904             )
1905             |
1906             (?P<enddate2>
1907             	(?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
1908             	[ ]+
1909             	(?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9])
1910             	(?: st | nd | rd | th )?
1911             	[ ,]+
1912             	(?P<endyear2>19\d{2} | 20\d{2} | \d{2})
1913             )
1914             |
1915             (?P<enddate3>
1916             	(?P<endyear3>19\d{2} | 20\d{2} | \d{2} )
1917             	(?P<endmonth3>1[012] | 0[1-9])
1918             	(?P<endday3>3[01] | 0[1-9] | [12]\d)
1919             )
1920         )
1921     )?
1922     (?P<endtime>
1923         [ ,]+
1924         (
1925             (?P<endtime1>
1926             	(?P<endhour1> 1[0-2] | [0]?[1-9] )
1927             	(
1928             		(?: [.:])
1929             		(?P<endminute1>[0-5]\d{0,1} | [6-9])
1930             	)?
1931             	[ ]*
1932             	(?P<am1> am | pm | p | a )
1933             )
1934             |
1935             (?P<endtime2>
1936             	(?P<endhour2> | [01]\d{0,1} | 2[0-3] | [1-9])
1937             	(
1938             		(?: [.:])
1939             		(?P<endminute2>[0-5]\d{0,1} | [6-9])
1940             	)?
1941             )
1942             |
1943             (?P<endtime3>
1944             	(?P<endhour3> [01]\d | 2[0-3])
1945             	(?P<endminute3> [0-5]\d)?
1946             )
1947             |
1948             (?P<endtime4>
1949             	(?P<endhour4> 0[1-9] | 1[0-2])
1950             	(?P<endminute4> [0-5]\d)?
1951             	[ ]*
1952             	(?P<am4> am | pm | p | a )
1953             )
1954         )
1955     )?
1956     \s*?
1957     $
1958 )?
1959 """
1960 
1961     regex_bgcolor = r"""
1962 (?P<reqfield>^[ ]+bgcolor::[ ]+)
1963 (
1964     (?P<bgcolor>(\#[0-9a-fA-F]{6}|[a-zA-Z]+))?
1965     \s*?
1966     $
1967 )?
1968 """
1969 
1970     regex_description = r"""
1971 (?P<reqfield>^[ ]+description::[ ]+)
1972 (
1973     (?P<description>.*?)
1974     \s*?
1975     $
1976 )?
1977 """
1978 
1979     
1980     regex_recur = r"""
1981 (?P<reqfield>^[ ]+recur::[ ]+)
1982 (
1983     (?P<recur_freq>\d+|last)
1984     \s+
1985     (?P<recur_type>weekday|day|week|month|year)
1986     (
1987     	\s+
1988     	(?P<recur_until_req>until)
1989     	\s+
1990     	(?P<recur_until>
1991             (?P<enddate>
1992                 (?P<enddate1>
1993                 	(?P<endyear1>19\d{2} | 20\d{2} | \d{2} )
1994                 	[./-]
1995                 	(?P<endmonth1>1[012] | 0[1-9] | [1-9])
1996                 	[./-]
1997                 	(?P<endday1>3[01] | 0[1-9] | [12]\d | [1-9])
1998                 )
1999                 |
2000                 (?P<enddate2>
2001                 	(?P<endmonth2>january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|october|oct|november|nov|december|dec)
2002                 	\s+
2003                 	(?P<endday2>3[01] | 0[1-9] | [12]\d | [1-9])
2004                 	(?: st | nd | rd | th )?
2005                 	[\s,]+
2006                 	(?P<endyear2>19\d{2} | 20\d{2} | \d{2})
2007                 )
2008                 |
2009                 (?P<enddate3>
2010                 	(?P<endyear3>19\d{2} | 20\d{2} | \d{2} )
2011                 	(?P<endmonth3>1[012] | 0[1-9])
2012                 	(?P<endday3>3[01] | 0[1-9] | [12]\d)
2013                 )
2014             )?
2015         )?
2016     )?
2017     \s*?
2018     $
2019 )?
2020 """
2021 
2022     regex_label = r"""
2023 (?P<reqfield>^[ ]+label::[ ]+)
2024 (
2025 	(?P<name>[^,^:^\s]+?)
2026 	\s*?
2027 	$
2028 )?
2029 """
2030 
2031 
2032     # need help on regular expressions for more efficient/flexible form
2033     
2034     # compile regular expression objects
2035     
2036     pattern_startdate = re.compile(regex_startdate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
2037     pattern_enddate = re.compile(regex_enddate, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
2038     pattern_bgcolor = re.compile(regex_bgcolor, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
2039     pattern_label = re.compile(regex_label, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
2040     pattern_description = re.compile(regex_description, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
2041     pattern_recur = re.compile(regex_recur, re.UNICODE + re.MULTILINE + re.IGNORECASE + re.DOTALL + re.VERBOSE)
2042     
2043     ##################### retrieve startdate
2044     match = pattern_startdate.search(detail)
2045     
2046     if match:
2047     
2048         if match.group('startdate'):
2049             passed = 1
2050             # yyyy/mm/dd: 2006/05/10; 06/05/10, 
2051             if match.group('startdate1'):
2052                 if len(match.group('startyear1')) == 2:
2053                     startyear = '20%s' % match.group('startyear1')
2054                 else:
2055                     startyear = match.group('startyear1')
2056                 
2057                 startmonth = match.group('startmonth1')
2058                 startday = match.group('startday1')
2059                 
2060             # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2061             elif match.group('startdate2'):
2062                 if len(match.group('startyear2')) == 2:
2063                     startyear = '20%s' % match.group('startyear2')
2064                 else:
2065                     startyear = match.group('startyear2')
2066                 
2067                 startmonth = getNumericalMonth(match.group('startmonth2'))
2068                 if not startmonth:
2069                     raise EventcalError('invalid_startdate')
2070                     
2071                 startday = match.group('startday2')
2072             
2073             # yyyymmdd: 20060510, 060510
2074             elif match.group('startdate3'):
2075                 if len(match.group('startyear3')) == 2:
2076                     startyear = '20%s' % match.group('startyear3')
2077                 else:
2078                     startyear = match.group('startyear3')
2079                 
2080                 startmonth = match.group('startmonth3')
2081                 startday = match.group('startday3')
2082             
2083             else:
2084                 if len(match.group('startdate').strip()) > 0:
2085                     raise EventcalError('invalid_startdate')
2086                 else:
2087                     passed = 0
2088             
2089             if passed:
2090                 startdate = '%d/%02d/%02d' % (int(startyear), int(startmonth), int(startday))
2091             else:
2092                 startdate = ''
2093                 
2094         else:
2095             startdate = ''
2096             
2097         if match.group('starttime'):
2098             passed = 1
2099             # 12h with ':': 12:00; 9:00pm
2100             if match.group('starttime1'):
2101                 starthour = int(match.group('starthour1'))
2102                 if match.group('startminute1'):
2103                     startmin = int(match.group('startminute1'))
2104                 else:
2105                     startmin = 0
2106                 
2107                 if starthour < 12 and match.group('am1').lower().startswith('p'):
2108                     starthour += 12
2109                 
2110             # 24h with ':': 12:00; 23:00
2111             elif match.group('starttime2'):
2112                 starthour = int(match.group('starthour2'))
2113                 if match.group('startminute2'):
2114                     startmin = int(match.group('startminute2'))
2115                 else:
2116                     startmin = 0
2117                 
2118             # 24h without ':': 1200; 2300
2119             elif match.group('starttime3'):
2120                 starthour = int(match.group('starthour3'))
2121                 if match.group('startminute3'):
2122                     startmin = int(match.group('startminute3'))
2123                 else:
2124                     startmin = 0
2125 
2126             # 12h without ':': 1200; 0900pm
2127             elif match.group('starttime4'):
2128                 
2129                 starthour = int(match.group('starthour4'))
2130                 if match.group('startminute4'):
2131                     startmin = int(match.group('startminute4'))
2132                 else:
2133                     startmin = 0
2134                 
2135                 if starthour < 12 and match.group('am4').lower().startswith('p'):
2136                     starthour += 12
2137 
2138             else:
2139                 if len(match.group('starttime').strip()) > 0:
2140                     raise EventcalError('invalid_starttime')
2141                 else:
2142                     passed = 0
2143             
2144             if passed:
2145                 starttime = '%02d:%02d' % (int(starthour), int(startmin))
2146             else:
2147                 starttime = ''
2148         
2149         else:
2150             starttime = ''
2151             
2152         if not startdate:
2153             raise EventcalError('invalid_start')
2154 
2155     else:
2156         raise EventcalError('pass')
2157     
2158     ##################### retrieve enddate
2159     match = pattern_enddate.search(detail)
2160     
2161     if match:
2162     
2163         if match.group('enddate'):
2164             passed = 1
2165             # yyyy/mm/dd: 2006/05/10; 06/05/10, 
2166             if match.group('enddate1'):
2167                 if len(match.group('endyear1')) == 2:
2168                     endyear = '20%s' % match.group('endyear1')
2169                 else:
2170                     endyear = match.group('endyear1')
2171                 
2172                 endmonth = match.group('endmonth1')
2173                 endday = match.group('endday1')
2174                 
2175             # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2176             elif match.group('enddate2'):
2177                 if len(match.group('endyear2')) == 2:
2178                     endyear = '20%s' % match.group('endyear2')
2179                 else:
2180                     endyear = match.group('endyear2')
2181                 
2182                 endmonth = getNumericalMonth(match.group('endmonth2'))
2183                 if not endmonth:
2184                     raise EventcalError('invalid_enddate')
2185                 
2186                 endday = match.group('endday2')
2187             
2188             # yyyymmdd: 20060510, 060510
2189             elif match.group('enddate3'):
2190                 if len(match.group('endyear3')) == 2:
2191                     endyear = '20%s' % match.group('endyear3')
2192                 else:
2193                     endyear = match.group('endyear3')
2194                 
2195                 endmonth = match.group('endmonth3')
2196                 endday = match.group('endday3')
2197             
2198             else:
2199                 if len(match.group('enddate').strip()) > 0:
2200                     raise EventcalError('invalid_enddate')
2201                 else:
2202                     passed = 0
2203             
2204             if passed:
2205                 enddate = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2206             else:
2207                 enddate = ''
2208                 
2209         else:
2210             enddate = ''
2211         
2212         if match.group('endtime'):
2213             passed = 1
2214             # 12h with ':': 12:00; 9:00pm
2215             if match.group('endtime1'):
2216                 endhour = int(match.group('endhour1'))
2217                 if match.group('endminute1'):
2218                     endmin = int(match.group('endminute1'))
2219                 else:
2220                     endmin = 0
2221                 
2222                 if endhour < 12 and match.group('am1').lower() == 'pm':
2223                     endhour += 12
2224                 
2225             # 24h with ':': 12:00; 23:00
2226             elif match.group('endtime2'):
2227                 endhour = int(match.group('endhour2'))
2228                 if match.group('endminute2'):
2229                     endmin = int(match.group('endminute2'))
2230                 else:
2231                     endmin = 0
2232                 
2233             # 24h without ':': 1200; 2300
2234             elif match.group('endtime3'):
2235                 endhour = int(match.group('endhour3'))
2236                 if match.group('endminute3'):
2237                     endmin = int(match.group('endminute3'))
2238                 else:
2239                     endmin = 0
2240 
2241             # 12h without ':': 1200; 0900pm
2242             elif match.group('endtime4'):
2243                 
2244                 endhour = int(match.group('endhour4'))
2245                 if match.group('endminute4'):
2246                     endmin = int(match.group('endminute4'))
2247                 else:
2248                     endmin = 0
2249                 
2250                 if endhour < 12 and match.group('am4').lower() == 'pm':
2251                     endhour += 12
2252             
2253             else:
2254                 if len(match.group('endtime').strip()) > 0:
2255                     raise EventcalError('invalid_endtime')
2256                 else:
2257                     passed = 0
2258                 
2259             if passed:
2260                 endtime = '%02d:%02d' % (int(endhour), int(endmin))
2261             else:
2262                 endtime = ''
2263                 
2264         else:
2265             endtime = ''
2266 
2267         if not (enddate or endtime):
2268             raise EventcalError('invalid_end')
2269 
2270     else:
2271         enddate = ''
2272         endtime = '' 
2273 
2274 
2275     ##################### retrieve bgcolor
2276     match = pattern_bgcolor.search(detail)
2277     
2278     if match:
2279         if match.group('bgcolor'):
2280             bgcolor = match.group('bgcolor')
2281         else:
2282             errormsgcode('invalid_bgcolor')
2283             bgcolor = ''
2284             
2285     else:
2286         bgcolor = ''
2287 
2288     ##################### retrieve label
2289     match = pattern_label.search(detail)
2290     
2291     if match:
2292         if match.group('name'):
2293             label = match.group('name')
2294         else:
2295             errormsgcode('invalid_label')
2296             label = ''
2297             
2298     else:
2299         label = ''
2300 
2301     ##################### retrieve description
2302     match = pattern_description.search(detail)
2303     
2304     if match:
2305         if match.group('description'):
2306             description = match.group('description')
2307         else:
2308             errormsgcode('empty_description')
2309             description = ''
2310     else:
2311         description = ''
2312         
2313     ##################### retrieve recurrence
2314     match = pattern_recur.search(detail)
2315     
2316     if match:
2317     
2318         if match.group('recur_freq') and match.group('recur_type'):
2319     
2320             if match.group('recur_freq') == 'last':
2321                 if match.group('recur_type') == 'weekday':
2322                     recur_freq = -1
2323                     recur_type = match.group('recur_type')
2324                     recur_until = match.group('recur_until')
2325                 else:
2326                     recur_freq = 0
2327                     recur_type = ''
2328                     recur_until = ''
2329                     
2330             else:
2331                 recur_freq = int(match.group('recur_freq'))
2332                 recur_type = match.group('recur_type')
2333                 
2334                 if match.group('recur_until_req'):
2335                     if match.group('recur_until'):
2336                         # yyyy/mm/dd: 2006/05/10; 06/05/10, 
2337                         if match.group('enddate1'):
2338                             if len(match.group('endyear1')) == 2:
2339                                 endyear = '20%s' % match.group('endyear1')
2340                             else:
2341                                 endyear = match.group('endyear1')
2342                             
2343                             endmonth = match.group('endmonth1')
2344                             endday = match.group('endday1')
2345                             
2346                         # M dd, yyyy: May 10, 2006; Jan 10th, 2006; Jan 10, 06
2347                         elif match.group('enddate2'):
2348                             if len(match.group('endyear2')) == 2:
2349                                 endyear = '20%s' % match.group('endyear2')
2350                             else:
2351                                 endyear = match.group('endyear2')
2352                             
2353                             endmonth = getNumericalMonth(match.group('endmonth2'))
2354                             if not endmonth:
2355                                 raise EventcalError('invalid_recur_until')
2356                             
2357                             endday = match.group('endday2')
2358                         
2359                         # yyyymmdd: 20060510, 060510
2360                         elif match.group('enddate3'):
2361                             if len(match.group('endyear3')) == 2:
2362                                 endyear = '20%s' % match.group('endyear3')
2363                             else:
2364                                 endyear = match.group('endyear3')
2365                             
2366                             endmonth = match.group('endmonth3')
2367                             endday = match.group('endday3')
2368                             
2369                         else:
2370                             raise EventcalError('invalid_recur_until')
2371                             
2372                         recur_until = '%d/%02d/%02d' % (int(endyear), int(endmonth), int(endday))
2373 
2374                     else:
2375                         raise EventcalError('invalid_recur_until')
2376                         
2377                 else:
2378                     recur_until = ''
2379             
2380         else:
2381             raise EventcalError('invalid_recur')
2382                     
2383     else:
2384         recur_freq = 0
2385         recur_type = ''
2386         recur_until = ''
2387         
2388     # check validity of each fields
2389     
2390     if (starttime or endtime):
2391         if not endtime:
2392             endtime = starttime
2393         elif not starttime:
2394             raise EventcalError('need_starttime')
2395             
2396 
2397     # if no time, it's 1-day event
2398     if not enddate:
2399         enddate = startdate
2400     
2401     try:
2402         syear, smonth, sday = getdatefield(startdate)
2403     except (TypeError, ValueError):
2404         raise EventcalError('invalid_startdate')
2405 
2406     try:
2407         eyear, emonth, eday = getdatefield(enddate)
2408     except (TypeError, ValueError):
2409         raise EventcalError('invalid_enddate')
2410     
2411     if datetime.date(syear, smonth, sday) > datetime.date(eyear, emonth, eday):
2412         raise EventcalError('enddate_precede')
2413     
2414     # format date
2415     startdate = formatDate(syear, smonth, sday)
2416     enddate = formatDate(eyear, emonth, eday)
2417     
2418     if (starttime and endtime):
2419         try:
2420             shour, smin = gettimefield(starttime)
2421         except (TypeError, ValueError):
2422             raise EventcalError('invalid_starttime')
2423         
2424         try:
2425             ehour, emin = gettimefield(endtime)
2426         except (TypeError, ValueError):
2427             raise EventcalError('invalid_endtime')
2428         
2429         if startdate == enddate:
2430             if datetime.time(shour, smin) > datetime.time(ehour, emin):
2431                 raise EventcalError('endtime_precede')
2432                 
2433         # format time
2434         starttime = u'%02d%02d' %(shour, smin)
2435         endtime = u'%02d%02d' %(ehour, emin)
2436     
2437     # check recurrent data
2438     event_len = diffday(startdate, enddate)
2439     if recur_freq:
2440         
2441         if recur_type == 'day':
2442             if event_len > int(recur_freq):
2443                 raise EventcalError('len_recur_int')
2444         
2445         elif recur_type == 'week':
2446             if event_len > int(recur_freq) * 7:
2447                 raise EventcalError('len_recur_int')
2448         
2449         elif recur_type == 'weekday':
2450             if event_len > 25:
2451                 raise EventcalError('len_recur_int')
2452         
2453         elif recur_type == 'month':
2454             if event_len > int(recur_freq) * 25:
2455                 raise EventcalError('len_recur_int')
2456         
2457         elif recur_type == 'year':
2458             if event_len > int(recur_freq) * 365:
2459                 raise EventcalError('len_recur_int')
2460         
2461         if recur_until:
2462             try:
2463                 ryear, rmonth, rday = getdatefield(recur_until)
2464             except (TypeError, ValueError):
2465                 raise EventcalError('invalid_recur_until')
2466             
2467             recur_until = formatDate(ryear, rmonth, rday)
2468             
2469             if int(recur_until) < int(enddate):
2470                 raise EventcalError('recur_until_precede')
2471     
2472     return startdate, starttime, enddate, endtime, bgcolor, label, description, recur_freq, recur_type, recur_until
2473 
2474 
2475 
2476 def converttext(targettext):
2477     # Converts some special characters of html to plain-text style
2478     # What else to handle?
2479 
2480     targettext = targettext.replace(u'&', '&amp')
2481     targettext = targettext.replace(u'>', '&gt;')
2482     targettext = targettext.replace(u'<', '&lt;')
2483     targettext = targettext.replace(u'\n', '<br>')
2484     targettext = targettext.replace(u'"', '&quot;')
2485     targettext = targettext.replace(u'\t', '&nbsp;&nbsp;&nbsp;&nbsp')
2486     targettext = targettext.replace(u'  ', '&nbsp;&nbsp;')
2487         
2488     return targettext
2489 
2490 
2491 # monthly view
2492 def showeventcalendar(year, month):
2493     
2494     debug('Show Calendar: Monthly View')
2495     
2496     request = Globs.request
2497     formatter = Globs.formatter
2498     _ = request.getText
2499     
2500     wkend = Globs.wkend
2501     months= Globs.months
2502     wkdays = Globs.wkdays
2503     
2504     # get the calendar
2505     monthcal = calendar.monthcalendar(year, month)
2506 
2507     # shows current year & month
2508     html_header_curyearmonth = calhead_yearmonth(year, month, 'head_yearmonth')
2509     
2510     r7 = range(7)
2511     
2512     # shows header of week days
2513     html_header_weekdays = []
2514     
2515     for wkday in r7:
2516         wday = _(wkdays[wkday])
2517         html_header_weekdays.append( calhead_weekday(wday, 'head_weekday') )
2518     html_header_weekdays = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
2519  
2520     # pending events for next row
2521     next_pending = []
2522     
2523     # gets previous, next month
2524     day_delta = datetime.timedelta(days=-1)
2525     cur_month = datetime.date(year, month, 1)
2526     prev_month = cur_month + day_delta
2527     
2528     day_delta = datetime.timedelta(days=15)
2529     cur_month_end = datetime.date(year, month, 25)
2530     next_month = cur_month_end + day_delta
2531     
2532     prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
2533     next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
2534     
2535     # shows days
2536     html_week_rows = []
2537     
2538     # set ranges of events
2539     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2540     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2541     
2542     # read all the events
2543     events, cal_events, labels = loadEvents(datefrom, dateto)
2544     
2545     #debug(u'  events: %s' % events)
2546     #debug(u'  cal_events: %s' % cal_events)
2547     
2548     for week in monthcal:
2549         
2550         # day head rows
2551         html_headday_cols = []
2552         html_events_rows = []
2553         
2554         for wkday in r7:
2555              
2556             day = week[wkday]
2557             
2558             if not day:
2559                 if week == monthcal[0]:
2560                     nb_day = prev_monthcal[-1][wkday]
2561                 else:
2562                     nb_day = next_monthcal[0][wkday]
2563                     
2564                 html_headday_cols.append( calhead_day_nbmonth(nb_day) )
2565             else:
2566                 html_headday_cols.append( calhead_day(year, month, day, wkday) )
2567         
2568         html_headday_row = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
2569         html_week_rows.append(html_headday_row)
2570         
2571         # dummy rows
2572         html_headdummy_cols = []
2573         
2574         for wkday in r7:
2575             day = week[wkday]
2576             if not day:
2577                 html_headdummy_cols.append( calshow_blankbox('head_dummy_nbmonth') )
2578             else:
2579                 html_headdummy_cols.append( calshow_blankbox('head_dummy') )
2580         
2581         html_headdummy_cols = u'\r\n'.join(html_headdummy_cols)
2582         html_week_rows.append(' <tr>\r\n%s </tr>\r\n' % html_headdummy_cols)
2583         
2584         # pending events for next row
2585         pending = next_pending
2586         next_pending = []
2587         
2588         # show events
2589         while 1: 
2590             event_left = 7
2591             colspan = -1
2592             html_events_cols = []
2593 
2594             for wkday in r7:
2595              
2596                 day = week[wkday]
2597                 
2598                 if not day:
2599                     if week == monthcal[0]:
2600                         cur_date = formatDate(prev_month.year, prev_month.month, prev_monthcal[-1][wkday])
2601                     else:
2602                         cur_date = formatDate(next_month.year, next_month.month, next_monthcal[0][wkday])
2603                 else:
2604                     cur_date = formatDate(year, month, day)
2605 
2606                 # if an event is already displayed with colspan
2607                 if colspan > 0:
2608                     colspan -= 1
2609                     if cal_events.has_key(cur_date) and lastevent in cal_events[cur_date]:
2610                         cal_events[cur_date].remove(lastevent)
2611                     
2612                     continue
2613                     
2614                 # if there is any event for this date
2615                 if cal_events.has_key(cur_date):
2616                     if len(cal_events[cur_date]) > 0:
2617                         
2618                         # if there is any pending event in the previous week
2619                         if wkday == 0 and len(pending) > 0:
2620                             todo_event_id = pending.pop(0)
2621                             if todo_event_id in cal_events[cur_date]:
2622                                 cur_event = events[todo_event_id]
2623                                 temp_len = diffday(cur_date, cur_event['enddate']) + 1
2624                                 
2625                                 # calculate colspan value
2626                                 if (7-wkday) < temp_len:
2627                                     colspan = 7 - wkday
2628                                     next_pending.append(cur_event['id'])
2629                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
2630 
2631                                 else:
2632                                     colspan = temp_len
2633                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
2634                                 
2635                                 
2636                                 cal_events[cur_date].remove(todo_event_id)
2637 
2638                                 colspan -= 1
2639                                 lastevent = todo_event_id
2640                             else:
2641                                 debug('Warning: no such event in cal_events')
2642                             
2643                             continue
2644                         
2645                         # if there is no pending event in the previous week, start a new event
2646                         event_found = 0
2647                         for e_id in cal_events[cur_date]:
2648                             
2649                             # if the start date of the event is current date    
2650                             if events[e_id]['startdate'] == cur_date:
2651                                 
2652                                 cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2653                                 
2654                                 # calculate colspan value
2655                                 if (7-wkday) < cur_event['date_len']:
2656                                     colspan = 7 - wkday
2657                                     next_pending.append(cur_event['id'])
2658                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, 'pending', cur_date) )
2659 
2660                                 else:
2661                                     colspan = cur_event['date_len']
2662                                     html_events_cols.append( calshow_eventbox(cur_event, colspan, '', cur_date) )
2663                                 
2664                                 colspan -= 1
2665                                 lastevent = cur_event['id']
2666                                 event_found = 1
2667                                 break
2668                             
2669                             # if the start date of the event is NOT current date
2670                             else:
2671                                 
2672                                 # pending event from previous month
2673                                 if wkday == 0 and week == monthcal[0]:
2674                                     
2675                                     cur_event = events[cal_events[cur_date].pop(0)]
2676                                     temp_len = diffday(cur_date, cur_event['enddate']) + 1
2677                                     
2678                                     # calculate colspan value
2679                                     if (7-wkday) < temp_len:
2680                                         colspan = 7 - wkday
2681                                         next_pending.append(cur_event['id'])
2682                                         html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append_pending', cur_date) )
2683                                     else:
2684                                         colspan = temp_len
2685                                         html_events_cols.append( calshow_eventbox(cur_event, colspan, 'append', cur_date) )
2686                                     
2687                                     colspan -= 1
2688                                     lastevent = cur_event['id']
2689                                     event_found = 1
2690                                     break
2691                                 
2692                         # if there is no event to start
2693                         if not event_found:
2694                             if not day:
2695                                 html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2696                             else:
2697                                 html_events_cols.append( calshow_blankbox('cal_noevent') )
2698                             event_left -= 1
2699                                 
2700                     else:
2701                         if not day:
2702                             html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2703                         else:
2704                             html_events_cols.append( calshow_blankbox('cal_noevent') )
2705                         
2706                         event_left -= 1        
2707                 
2708                 # if there is NO event for this date
2709                 else:
2710                     if not day:
2711                         html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2712                     else:
2713                         html_events_cols.append( calshow_blankbox('cal_noevent') )
2714                         
2715                     event_left -= 1
2716             
2717             # if no event for this entry
2718             if not event_left:
2719                 # ignore the previous entry
2720                 break
2721             else:
2722                 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2723             
2724         # show dummy blank slots for week height
2725         left_blank_rows = 2 - len(html_events_rows)
2726         
2727         # remove the followings
2728         if left_blank_rows > 0 and 0:
2729             for i in range(left_blank_rows):
2730                 html_events_cols = []
2731                 for wkday in r7:
2732                     day = week[wkday]
2733                     if not day:
2734                         html_events_cols.append( calshow_blankbox('cal_nbmonth') )
2735                     else:
2736                         html_events_cols.append( calshow_blankbox('cal_noevent') )
2737                 
2738                 html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2739         
2740         
2741         # close the week slots
2742         html_events_cols = []
2743         for wkday in r7:
2744             day = week[wkday]
2745             if not day:
2746                 html_events_cols.append( calshow_blankbox('cal_last_nbmonth') )
2747             else:
2748                 html_events_cols.append( calshow_blankbox('cal_last_noevent') )
2749     
2750         html_events_rows.append(' <tr>\r\n%s </tr>\r\n' % u'\r\n'.join(html_events_cols))
2751         
2752         html_events_rows = u'\r\n'.join(html_events_rows)
2753         html_week_rows.append(html_events_rows)
2754             
2755     html_calendar_rows = u'\r\n'.join(html_week_rows)
2756     
2757     html_cal_table = [
2758         u'\r\n<div id="eventcalendar">',
2759         u'<table class="eventcalendar" %s>' % Params.monthlywidth,
2760         u'%s' % html_header_curyearmonth,
2761         u'%s' % html_header_weekdays,
2762         u'%s' % html_calendar_rows,
2763         u'</table>',
2764         u'</div>',
2765         ]
2766     html_cal_table = u'\r\n'.join(html_cal_table)
2767         
2768     return html_cal_table
2769 
2770 
2771 
2772 # daily view
2773 def showdailyeventcalendar(year, month, day):
2774     
2775     debug('Show Calendar: Daily View')
2776     
2777     request = Globs.request
2778     formatter = Globs.formatter
2779     _ = request.getText
2780     
2781     wkend = Globs.wkend
2782     months= Globs.months
2783     wkdays = Globs.wkdays
2784     
2785     cur_date = formatDate(year, month, day)
2786     
2787     # gets previous, next month
2788     day_delta = datetime.timedelta(days=-1)
2789     cur_month = datetime.date(year, month, 1)
2790     prev_month = cur_month + day_delta
2791     
2792     day_delta = datetime.timedelta(days=15)
2793     cur_month_end = datetime.date(year, month, 25)
2794     next_month = cur_month_end + day_delta
2795     
2796     # set ranges of events
2797     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
2798     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
2799     
2800     # read all the events
2801     events, cal_events, labels = loadEvents(datefrom, dateto)
2802     
2803     #debug(u'  events: %s' % events)
2804     #debug(u'  cal_events: %s' % cal_events)
2805     
2806     # calculates hour_events
2807     hour_events = {}
2808     
2809     if cal_events.has_key(cur_date):
2810         for e_id in cal_events[cur_date]:
2811             cur_event = events[e_id]
2812             
2813             if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
2814                 start_hour, start_min = gettimefield(cur_event['starttime'])
2815                 
2816                 if not hour_events.has_key(start_hour):
2817                     hour_events[start_hour] = []
2818                 
2819                 hour_events[start_hour].append(e_id)
2820 
2821     #debug(u'hour_events: %s' % hour_events)
2822 
2823     # in-day events
2824     html_calendar_rows = []
2825     html_hour_cols = {}
2826     
2827     slot_pending = {}
2828     max_num_slots = 0
2829     hour_max_slots = {}
2830     block_slots = []
2831     
2832     start_hour_index = 0
2833     
2834     r24 = range(24)
2835     
2836     for hour_index in r24:
2837         
2838         html_hour_cols[hour_index] = []
2839         hour_max_slots[hour_index] = 1
2840         html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
2841         
2842         if len(slot_pending) > 0 or hour_events.has_key(hour_index):
2843             
2844             #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2845             if len(slot_pending) == 0:
2846                 if max_num_slots < 1:
2847                     max_num_slots = 1
2848                 
2849                 for hour_lines in range(start_hour_index, hour_index):
2850                     hour_max_slots[hour_lines] = max_num_slots
2851                 
2852                 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2853                 
2854                 block_slots.append(max_num_slots)
2855                 
2856                 max_num_slots = 0
2857                 start_hour_index = hour_index
2858             
2859             for slot_index in range(max_num_slots):
2860                 if slot_pending.has_key(slot_index) and slot_pending[slot_index] > 0:
2861                     if slot_pending[slot_index] == 1:
2862                         del slot_pending[slot_index]
2863                     else:
2864                         slot_pending[slot_index] -= 1
2865                     html_hour_cols[hour_index].append ( '' )
2866                     
2867                 else:
2868                     if hour_events.has_key(hour_index) and len(hour_events[hour_index]) > 0:
2869                         e_id = hour_events[hour_index][0]
2870                         cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2871                         html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2872                         slot_pending[slot_index] = cur_event['time_len'] - 1
2873                     else:
2874                         if not ((len(slot_pending) > 0 and slot_index > max(slot_pending.keys())) or len(slot_pending) == 0):
2875                             html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2876 
2877             if hour_events.has_key(hour_index):
2878                 for tmp_cnt in range(len(hour_events[hour_index])):
2879                     e_id = hour_events[hour_index][0]
2880                     cur_event = events[hour_events[hour_index].pop(hour_events[hour_index].index(e_id))]
2881                     html_hour_cols[hour_index].append ( calshow_daily_eventbox(cur_event) )
2882                     slot_pending[max_num_slots] = cur_event['time_len'] - 1
2883                     if slot_pending[max_num_slots] == 0:
2884                         del slot_pending[max_num_slots]
2885                     max_num_slots += 1
2886 
2887         else:
2888             html_hour_cols[hour_index].append ( calshow_blankeventbox() )
2889             #hour_max_slots[hour_index] = 1
2890             
2891             if max_num_slots < 1:
2892                 max_num_slots = 1
2893             
2894             for hour_lines in range(start_hour_index, hour_index):
2895                 hour_max_slots[hour_lines] = max_num_slots
2896             
2897             #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, hour_index-1, max_num_slots))
2898             
2899             block_slots.append(max_num_slots)
2900             
2901             max_num_slots = 0
2902             start_hour_index = hour_index
2903             
2904         
2905         #debug('end: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending))
2906         
2907     if max_num_slots < 1:
2908         max_num_slots = 1
2909     
2910     for hour_lines in range(start_hour_index, 24):
2911         hour_max_slots[hour_lines] = max_num_slots
2912     
2913     #debug('block ended: %d ~ %d, max=%d' % (start_hour_index, 23, max_num_slots))
2914     
2915     block_slots.append(max_num_slots)
2916     
2917     #debug('hour_max_slots: %s' % hour_max_slots)
2918     
2919     
2920     # calculates global colspan
2921     if len(block_slots):
2922         global_colspan = LCM(block_slots)
2923     else:
2924         global_colspan = 1
2925 
2926     for hour_index in r24:
2927         
2928         colspan = global_colspan / hour_max_slots[hour_index]
2929         width = 96 / hour_max_slots[hour_index]
2930         
2931         left_slots = hour_max_slots[hour_index] - (len(html_hour_cols[hour_index]) - 1)
2932         
2933         if left_slots > 0:
2934             #debug('appending left %d slots: %d' % (left_slots, hour_index))
2935             html_hour_cols[hour_index].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
2936         
2937         html_cols = u'\r\n'.join(html_hour_cols[hour_index]) % {'colspan': colspan, 'width': u'%d%%' % width}
2938         html_cols = u'<tr>%s</tr>\r\n' % html_cols
2939         
2940         html_calendar_rows.append (html_cols)
2941 
2942     html_calendar_rows = u'\r\n'.join(html_calendar_rows)
2943     
2944     # shows current year & month
2945     html_header_curyearmonthday = calhead_yearmonthday(year, month, day, 'head_yearmonth', global_colspan)
2946     
2947     # one-day long events
2948     html_oneday_rows = []
2949     
2950     #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2951     
2952     if cal_events.has_key(cur_date):
2953         if len(cal_events[cur_date]) > 0:
2954             for e_id in cal_events[cur_date]:
2955                 #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
2956                 #debug('test events[%s] = %s' % (e_id, events[e_id]))
2957                 if events[e_id]['time_len'] <= 0 or events[e_id]['date_len'] > 1:
2958                     #cur_event = events[cal_events[cur_date].pop(cal_events[cur_date].index(e_id))]
2959                     cur_event = events[e_id]
2960                     
2961                     if cur_event['startdate'] == cur_date:
2962                         if cur_event['enddate'] == cur_date:
2963                             str_status = ''
2964                         else:
2965                             str_status = 'pending'
2966                     else:
2967                         if cur_event['enddate'] == cur_date:
2968                             str_status = 'append'
2969                         else:
2970                             str_status = 'append_pending'
2971                     
2972                     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)
2973                     html_oneday_rows.append( tmp_html )
2974                     
2975                 #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2976     else:
2977         tmp_html = u'<tr><td width="4%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % calshow_blankbox2('cal_daily_noevent', global_colspan)
2978         html_oneday_rows.append( tmp_html )
2979     
2980     #debug('after cal_events[cur_date] = %s' % cal_events[cur_date])
2981     #debug('html_oneday_rows = %s' % html_oneday_rows)
2982     
2983     html_oneday_rows = u'\r\n'.join(html_oneday_rows)
2984     
2985    
2986     html_cal_table = [
2987         u'\r\n<div id="eventcalendar">',
2988         u'<table class="eventcalendar" %s>' % Params.dailywidth,
2989         u'<table border="0">',
2990         u'%s' % html_header_curyearmonthday,
2991         u'%s' % html_oneday_rows,
2992         u'%s' % html_calendar_rows,
2993         u'</table>',
2994         u'</td></tr>',
2995         u'</div>',
2996         ]
2997     html_cal_table = u'\r\n'.join(html_cal_table)
2998         
2999     return html_cal_table
3000 
3001 
3002 
3003 # weekly view
3004 def showweeklyeventcalendar(year, month, day):
3005     
3006     debug('Show Calendar: Weekly View')
3007     
3008     request = Globs.request
3009     formatter = Globs.formatter
3010     _ = request.getText
3011     
3012     wkend = Globs.wkend
3013     months= Globs.months
3014     wkdays = Globs.wkdays
3015     
3016     cur_date = formatDate(year, month, day)
3017     
3018     # gets previous, next month
3019     day_delta = datetime.timedelta(days=-1)
3020     cur_month = datetime.date(year, month, 1)
3021     prev_month = cur_month + day_delta
3022     
3023     day_delta = datetime.timedelta(days=15)
3024     cur_month_end = datetime.date(year, month, 25)
3025     next_month = cur_month_end + day_delta
3026     
3027     # set ranges of events
3028     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
3029     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
3030     
3031     # read all the events
3032     events, cal_events, labels = loadEvents(datefrom, dateto)
3033     
3034     #debug(u'  events: %s' % events)
3035     #debug(u'  cal_events: %s' % cal_events)
3036     
3037     # calculates hour_events
3038     hour_events = {}
3039     
3040     first_date_week = getFirstDateOfWeek(year, month, day)
3041     
3042     
3043     for dayindex in range(7):
3044         hour_events[dayindex] = {}
3045         
3046         cur_date = first_date_week + datetime.timedelta(dayindex)
3047         cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
3048         
3049         if cal_events.has_key(cur_date):
3050             for e_id in cal_events[cur_date]:
3051                 cur_event = events[e_id]
3052                 
3053                 if cur_event['date_len'] == 1 and cur_event['time_len'] > 0:
3054                     start_hour, start_min = gettimefield(cur_event['starttime'])
3055                     
3056                     if not hour_events[dayindex].has_key(start_hour):
3057                         hour_events[dayindex][start_hour] = []
3058                     
3059                     hour_events[dayindex][start_hour].append(e_id)
3060 
3061     #debug(u'hour_events: %s' % hour_events)
3062 
3063     # in-day events
3064     html_calendar_rows = []
3065     html_hour_cols = {}
3066     
3067     slot_pending = {}
3068     max_num_slots = {}
3069     hour_max_slots = {}
3070     block_slots = {}
3071     
3072     start_hour_index = {}
3073     
3074     r24 = range(24)
3075     
3076     for hour_index in r24:
3077         
3078         html_hour_cols[hour_index] = {}
3079         hour_max_slots[hour_index] = {}
3080             
3081         #html_hour_cols[hour_index].append ( calshow_daily_hourhead(hour_index) )
3082         
3083         for dayindex in range(7):
3084             
3085             if not max_num_slots.has_key(dayindex):
3086                 max_num_slots[dayindex] = 0
3087                
3088             if not slot_pending.has_key(dayindex):
3089                 slot_pending[dayindex] = {}
3090             
3091             if not start_hour_index.has_key(dayindex):
3092                 start_hour_index[dayindex] = 0
3093                 
3094             if not block_slots.has_key(dayindex):
3095                 block_slots[dayindex] = []
3096             
3097             html_hour_cols[hour_index][dayindex] = []
3098             hour_max_slots[hour_index][dayindex] = 1
3099         
3100             if len(slot_pending[dayindex]) > 0 or hour_events[dayindex].has_key(hour_index):
3101                 
3102                 #debug('start: hour_index = %d, slot_pending = %s' % (hour_index, slot_pending[dayindex]))
3103                 if len(slot_pending[dayindex]) == 0:
3104                     if max_num_slots[dayindex] < 1:
3105                         max_num_slots[dayindex] = 1
3106                     
3107                     for hour_lines in range(start_hour_index[dayindex], hour_index):
3108                         hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3109                     
3110                     #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
3111                     
3112                     block_slots[dayindex].append(max_num_slots[dayindex])
3113                     
3114                     max_num_slots[dayindex] = 0
3115                     start_hour_index[dayindex] = hour_index
3116                 
3117                 for slot_index in range(max_num_slots[dayindex]):
3118                     if slot_pending[dayindex].has_key(slot_index) and slot_pending[dayindex][slot_index] > 0:
3119                         if slot_pending[dayindex][slot_index] == 1:
3120                             del slot_pending[dayindex][slot_index]
3121                         else:
3122                             slot_pending[dayindex][slot_index] -= 1
3123                         html_hour_cols[hour_index][dayindex].append ( '' )
3124                         
3125                     else:
3126                         if hour_events[dayindex].has_key(hour_index) and len(hour_events[dayindex][hour_index]) > 0:
3127                             e_id = hour_events[dayindex][hour_index][0]
3128                             cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
3129                             html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
3130                             slot_pending[dayindex][slot_index] = cur_event['time_len'] - 1
3131                         else:
3132                             if not ((len(slot_pending[dayindex]) > 0 and slot_index > max(slot_pending[dayindex].keys())) or len(slot_pending[dayindex]) == 0):
3133                                 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
3134     
3135                 if hour_events[dayindex].has_key(hour_index):
3136                     for tmp_cnt in range(len(hour_events[dayindex][hour_index])):
3137                         e_id = hour_events[dayindex][hour_index][0]
3138                         cur_event = events[hour_events[dayindex][hour_index].pop(hour_events[dayindex][hour_index].index(e_id))]
3139                         html_hour_cols[hour_index][dayindex].append ( calshow_weekly_eventbox(cur_event) )
3140                         slot_pending[dayindex][max_num_slots[dayindex]] = cur_event['time_len'] - 1
3141                         if slot_pending[dayindex][max_num_slots[dayindex]] == 0:
3142                             del slot_pending[dayindex][max_num_slots[dayindex]]
3143                         max_num_slots[dayindex] += 1
3144     
3145             else:
3146                 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox() )
3147                 #hour_max_slots[hour_index][dayindex] = 1
3148                 
3149                 if max_num_slots[dayindex] < 1:
3150                     max_num_slots[dayindex] = 1
3151                 
3152                 for hour_lines in range(start_hour_index[dayindex], hour_index):
3153                     hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3154                 
3155                 #debug('block ended: %d ~ %d, max=%d' % (start_hour_index[dayindex], hour_index-1, max_num_slots[dayindex]))
3156                 
3157                 block_slots[dayindex].append(max_num_slots[dayindex])
3158                 
3159                 max_num_slots[dayindex] = 0
3160                 start_hour_index[dayindex] = hour_index
3161             
3162     global_colspan = {}
3163     header_colspan = 0
3164 
3165     for dayindex in range(7):
3166         if max_num_slots[dayindex] < 1:
3167             max_num_slots[dayindex] = 1
3168         
3169         for hour_lines in range(start_hour_index[dayindex], 24):
3170             hour_max_slots[hour_lines][dayindex] = max_num_slots[dayindex]
3171         
3172         block_slots[dayindex].append(max_num_slots[dayindex])
3173         
3174         # calculates global colspan
3175         if len(block_slots[dayindex]):
3176             global_colspan[dayindex] = LCM(block_slots[dayindex])
3177         else:
3178             global_colspan[dayindex] = 1
3179         
3180         header_colspan += global_colspan[dayindex]
3181 
3182 
3183     for hour_index in r24:
3184         
3185         html_cols_days = []
3186         
3187         for dayindex in range(7):
3188         
3189             colspan = global_colspan[dayindex] / hour_max_slots[hour_index][dayindex]
3190             width = (100 - 2) / 7 / hour_max_slots[hour_index][dayindex]
3191             
3192             left_slots = hour_max_slots[hour_index][dayindex] - len(html_hour_cols[hour_index][dayindex])
3193             
3194             if left_slots > 0:
3195                 #debug('appending left %d slots: %d' % (left_slots, hour_index))
3196                 html_hour_cols[hour_index][dayindex].append ( calshow_blankeventbox2( left_slots * colspan, left_slots * width ) )
3197             
3198             html_cols = u'\r\n'.join(html_hour_cols[hour_index][dayindex]) % {'colspan': colspan, 'width': u'%d%%' % width}
3199             html_cols_days.append(html_cols)
3200             
3201         html_cols_collected = u'\r\n'.join(html_cols_days)
3202         html_cols = u'<tr>%s\r\n%s</tr>\r\n' % (calshow_weekly_hourhead(hour_index), html_cols_collected)
3203         
3204         html_calendar_rows.append (html_cols)
3205 
3206     html_calendar_rows = u'\r\n'.join(html_calendar_rows)
3207     
3208     # shows current year & month
3209     html_header_curyearmonthday = calhead_yearmonthday2(year, month, day, 'head_yearmonth', header_colspan)
3210     
3211     # one-day long events
3212     html_oneday_rows = {}
3213     
3214     #debug('before cal_events[cur_date] = %s' % cal_events[cur_date])
3215     
3216     #first_date_week = getFirstDateOfWeek(year, month, day)
3217     
3218     html_oneday_rows = []
3219     
3220     while 1:
3221         html_oneday_cols = []
3222         cnt_blank_cols = 0
3223         pending = -1
3224         
3225         for dayindex in range(7):
3226             
3227             if pending > 0:
3228                 pending -= 1
3229                 html_oneday_cols.append('')
3230                 continue
3231             else:
3232                 pending = -1
3233             
3234             cur_date = first_date_week + datetime.timedelta(dayindex)
3235             cur_date = formatDate(cur_date.year, cur_date.month, cur_date.day)
3236             
3237             if cal_events.has_key(cur_date) and len(cal_events[cur_date]) > 0:
3238                 
3239                 tmpcount = len(cal_events[cur_date])
3240                 for tmp_index in range(tmpcount):
3241                     cur_event = events[cal_events[cur_date].pop(0)]
3242                     
3243                     #debug('event poped out at %s: %s' % (cur_date, cur_event))
3244                     
3245                     if (cur_event['startdate'] <= cur_date and dayindex == 0) or cur_event['startdate'] == cur_date:
3246                         if cur_event['time_len'] <= 0 or cur_event['date_len'] > 1:
3247                         
3248                             temp_len = diffday(cur_date, cur_event['enddate']) + 1
3249                             
3250                             if cur_event['startdate'] == cur_date:
3251                                 if temp_len <= 7 - dayindex:
3252                                     str_status = ''
3253                                 else:
3254                                     str_status = 'pending'
3255                             else:
3256                                 if temp_len <= 7 - dayindex:
3257                                     str_status = 'append'
3258                                 else:
3259                                     str_status = 'append_pending'
3260                             
3261                             if temp_len > 7 - dayindex:
3262                                 temp_len = 7 - dayindex
3263                             
3264                             pending = temp_len - 1
3265                             
3266                             tmp_global_colspan = 0
3267                             for tmp_index in range(dayindex, dayindex+temp_len):
3268                                 tmp_global_colspan += global_colspan[tmp_index]
3269                             
3270                             #debug('event appended at %s with pending=%d: %s' % (cur_date, pending, cur_event))
3271                             
3272                             html_oneday_cols.append( calshow_weekly_eventbox2(cur_event, tmp_global_colspan, 14 * temp_len, str_status, cur_date) )
3273                             break
3274                             
3275                 if pending < 0:
3276                     html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
3277                     cnt_blank_cols += 1
3278 
3279             else:
3280                 html_oneday_cols.append( calshow_blankbox2('cal_weekly_noevent', global_colspan[dayindex]) )
3281                 cnt_blank_cols += 1
3282                 
3283         if cnt_blank_cols >= 7:
3284             if len(html_oneday_rows) == 0:
3285                 html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
3286                 html_oneday_rows.append (html_oneday_cols)
3287             break
3288         else:
3289             html_oneday_cols = u'<tr><td width="2%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % u'\r\n'.join(html_oneday_cols)
3290             html_oneday_rows.append (html_oneday_cols)
3291         
3292     html_date_rows = []
3293     
3294     for dayindex in range(7):
3295         cur_date = first_date_week + datetime.timedelta(dayindex)
3296         html_date_rows.append(calhead_weeklydate(cur_date.year, cur_date.month, cur_date.day, global_colspan[dayindex]))
3297 
3298     html_date_rows = u'<tr><td width="2%%" style="border-width: 0px; ">&nbsp;</td>%s</tr>' % u'\r\n'.join(html_date_rows)
3299 
3300     html_oneday_rows = u'\r\n'.join(html_oneday_rows)
3301    
3302     html_cal_table = [
3303         u'\r\n<div id="eventcalendar">',
3304         u'<table class="eventcalendar" %s>' % Params.weeklywidth,
3305         u'<table border="0">',
3306         u'%s' % html_header_curyearmonthday,
3307         u'%s' % html_date_rows,
3308         u'%s' % html_oneday_rows,
3309         u'%s' % html_calendar_rows,
3310         u'</table>',
3311         u'</td></tr>',
3312         u'</div>',
3313         ]
3314     html_cal_table = u'\r\n'.join(html_cal_table)
3315         
3316     return html_cal_table
3317 
3318 
3319 
3320 # simple view
3321 def showsimpleeventcalendar(year, month):
3322     
3323     debug('Show Calendar: Simple View')
3324     
3325     request = Globs.request
3326     formatter = Globs.formatter
3327     _ = request.getText
3328     monthstyle_us = Globs.month_style_us
3329     
3330     wkend = Globs.wkend
3331     months= Globs.months
3332     wkdays = Globs.wkdays
3333     
3334     # get the calendar
3335     monthcal = calendar.monthcalendar(year, month)
3336 
3337     # shows current year & month
3338     html_header_curyearmonth = calhead_yearmonth(year, month, 'simple_yearmonth')
3339     
3340     r7 = range(7)
3341     
3342     # shows header of week days
3343     html_header_weekdays = []
3344     
3345     for wkday in r7:
3346         wday = wkdays[wkday]
3347         html_header_weekdays.append( calhead_weekday(wday, 'simple_weekday') )
3348     html_header_weekdays = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_header_weekdays)
3349  
3350     # gets previous, next month
3351     day_delta = datetime.timedelta(days=-1)
3352     cur_month = datetime.date(year, month, 1)
3353     prev_month = cur_month + day_delta
3354     
3355     day_delta = datetime.timedelta(days=15)
3356     cur_month_end = datetime.date(year, month, 25)
3357     next_month = cur_month_end + day_delta
3358     
3359     prev_monthcal = calendar.monthcalendar(prev_month.year, prev_month.month)
3360     next_monthcal = calendar.monthcalendar(next_month.year, next_month.month)
3361     
3362     # shows days
3363     html_week_rows = []
3364 
3365     # set ranges of events
3366     datefrom = u'%04d%02d21' % (prev_month.year, prev_month.month)
3367     dateto = u'%04d%02d06' % (next_month.year, next_month.month)
3368     
3369     # read all the events
3370     events, cal_events, labels = loadEvents(datefrom, dateto)
3371     
3372     maketip_js = []
3373     
3374     for week in monthcal:
3375         
3376         # day head rows
3377         html_headday_cols = []
3378         html_events_rows = []
3379         
3380         for wkday in r7:
3381              
3382             day = week[wkday]
3383             
3384             if not day:
3385                 if week == monthcal[0]:
3386                     nb_day = prev_monthcal[-1][wkday]
3387                 else:
3388                     nb_day = next_monthcal[0][wkday]
3389                     
3390                 html_headday_cols.append( simple_eventbox(year, month, day, nb_day, 'simple_nb') )
3391             else:
3392                 cur_date = formatDate(year, month, day)
3393                 
3394                 if cal_events.has_key(cur_date):
3395                     html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_event') )
3396                     
3397                     if monthstyle_us:
3398                         tiptitle = u'%s %d, %d' % (months[month-1], day, year)
3399                     else:
3400                         tiptitle = u'%d / %02d / %02d' % (year, month, day)
3401 
3402                     date_today = datetime.date( year, month, day )                    
3403                     tiptitle = u'%s (%s)' % (tiptitle, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3404                     
3405                     tiptext = []
3406                     
3407                     for e_id in cal_events[cur_date]:
3408                         cur_event = events[e_id]
3409                         if cur_event['starttime']:
3410                             time_string = u'(%s:%s)' % (cur_event['starttime'][:2], cur_event['starttime'][2:])
3411                         else:
3412                             time_string = ''
3413 
3414                         title = wikiutil.escape(cur_event['title']).replace("'","\\'")
3415                         description = wikiutil.escape(cur_event['description']).replace("'","\\'")
3416                         
3417                         tiptext.append( u'<b>%s</b>%s %s' % (title, time_string, description) )
3418                     
3419                     tiptext = u'<br>'.join(tiptext)
3420                     
3421                     maketip_js.append("maketip('%s','%s','%s');" % (cur_date, tiptitle, tiptext))
3422                 else:
3423                     html_headday_cols.append( simple_eventbox(year, month, day, wkday, 'simple_noevent') )
3424         
3425         html_headday_row = '    <tr>\r\n%s\r\n</tr>\r\n' % u'\r\n'.join(html_headday_cols)
3426         html_week_rows.append(html_headday_row)
3427             
3428     html_calendar_rows = u'\r\n'.join(html_week_rows)
3429     
3430     html_tooltip_result = """\
3431 <script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script>
3432 <div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div>
3433 <script language="JavaScript" type="text/javascript">
3434 <!--
3435 %s
3436 // -->
3437 </script>
3438 
3439 """ % (request.cfg.url_prefix_static, "\n".join(maketip_js))
3440     
3441     
3442     html_cal_table = [
3443         u'\r\n<div id="eventcalendar">',
3444         u'%s' % html_tooltip_result,
3445         u'<table class="simplecalendar" %s>' % Params.simplewidth,
3446         u'%s' % html_header_curyearmonth,
3447         u'%s' % html_header_weekdays,
3448         u'%s' % html_calendar_rows,
3449         u'</table>',
3450         u'</div>',
3451         ]
3452     html_cal_table = u'\r\n'.join(html_cal_table)
3453         
3454     return html_cal_table
3455 
3456 
3457 # show calendar head (year & month)
3458 def calhead_yearmonth(year, month, headclass):
3459     
3460     request = Globs.request
3461     
3462     months = Globs.months
3463     monthstyle_us = Globs.month_style_us
3464     cal_action = Globs.cal_action
3465     page_name = Globs.pagename
3466     
3467     page_url = Globs.pageurl
3468     
3469     nextyear, nextmonth = yearmonthplusoffset(year, month, 1)
3470     prevyear, prevmonth = yearmonthplusoffset(year, month, -1)
3471     
3472     prevlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, prevyear, prevmonth, getquerystring(['numcal']) )
3473     nextlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, nextyear, nextmonth, getquerystring(['numcal']))
3474     curlink = u'%s?calaction=%s&caldate=%d%02d%s' % (page_url, cal_action, year, month, getquerystring(['numcal']))
3475     
3476     if monthstyle_us:
3477         stryearmonth = u'%s %d' % (months[month-1], year)
3478         strnextmonth = u'%s %d' % (months[nextmonth-1], nextyear)
3479         strprevmonth = u'%s %d' % (months[prevmonth-1], prevyear)
3480     else:
3481         stryearmonth = u'%d / %02d' % (year, month)
3482         strnextmonth = u'%d / %02d' % (nextyear, nextmonth)
3483         strprevmonth = u'%d / %02d' % (prevyear, prevmonth)
3484     
3485     html = [
3486         u'  <tr>',
3487         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
3488         u'      <td colspan="5" class="%s"><a href="%s" title="Go/Refresh this month">%s</a></td>' % (headclass, curlink, stryearmonth),
3489         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
3490         u'  </tr>',
3491         ]
3492         
3493     return u'\r\n'.join(html)
3494 
3495 
3496 # show calendar head (year & month & day)
3497 def calhead_yearmonthday(year, month, day, headclass, colspan):
3498     
3499     request = Globs.request
3500     _ = request.getText
3501     
3502     months = Globs.months
3503     monthstyle_us = Globs.month_style_us
3504     cal_action = Globs.cal_action
3505     page_name = Globs.pagename
3506     wkdays = Globs.wkdays
3507     
3508     page_url = Globs.pageurl
3509     
3510     date_today = datetime.date( year, month, day )
3511     prevdate = date_today - datetime.timedelta(days=1)
3512     nextdate = date_today + datetime.timedelta(days=1)
3513     
3514     prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
3515     nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
3516     curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
3517     
3518     if monthstyle_us:
3519         stryearmonth = u'%s %d, %d' % (months[month-1], day, year)
3520         strnextmonth = u'%s %d, %d' % (months[nextdate.month-1], nextdate.day, nextdate.year)
3521         strprevmonth = u'%s %d, %d' % (months[prevdate.month-1], prevdate.day, prevdate.year)
3522     else:
3523         stryearmonth = u'%d / %02d / %02d' % (year, month, day)
3524         strnextmonth = u'%d / %02d / %02d' % (nextdate.year, nextdate.month, nextdate.day)
3525         strprevmonth = u'%d / %02d / %02d' % (prevdate.year, prevdate.month, prevdate.day)
3526     
3527     #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday()]))
3528     stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3529     
3530     html = [
3531         u'<tr><td width="4%" style="border: none;">&nbsp;</td>',
3532         u'<td colspan="%d" style="border: none;">' % colspan,
3533         u'<table width="95%">',
3534         u'  <tr>',
3535         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
3536         u'      <td class="%s"><a href="%s" title="Go/Refresh this day">%s</a></td>' % (headclass, curlink, stryearmonth),
3537         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
3538         u'  </tr>',
3539         u'</table>',
3540         u'</td></tr>',
3541         ]
3542         
3543     return u'\r\n'.join(html)
3544     
3545 # show calendar head for weekly view (year & month & day)
3546 def calhead_yearmonthday2(year, month, day, headclass, colspan):
3547     
3548     request = Globs.request
3549     _ = request.getText
3550     
3551     months = Globs.months
3552     monthstyle_us = Globs.month_style_us
3553     cal_action = Globs.cal_action
3554     page_name = Globs.pagename
3555     wkdays = Globs.wkdays
3556     
3557     page_url = Globs.pageurl
3558     
3559     date_today = datetime.date( year, month, day )
3560     prevdate = date_today - datetime.timedelta(days=7)
3561     nextdate = date_today + datetime.timedelta(days=7)
3562     
3563     first_date_week = getFirstDateOfWeek(year, month, day)    
3564     prevdate_f = first_date_week - datetime.timedelta(days=7)
3565     nextdate_f = first_date_week + datetime.timedelta(days=7)
3566     
3567     last_date_week = first_date_week + datetime.timedelta(days=6)
3568     prevdate_l = last_date_week - datetime.timedelta(days=7)
3569     nextdate_l = last_date_week + datetime.timedelta(days=7)
3570     
3571     prevlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, prevdate.year, prevdate.month, prevdate.day, getquerystring(['numcal']) )
3572     nextlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, nextdate.year, nextdate.month, nextdate.day, getquerystring(['numcal']))
3573     curlink = u'%s?calaction=%s&caldate=%d%02d%02d%s' % (page_url, cal_action, year, month, day, getquerystring(['numcal']))
3574     
3575     if monthstyle_us:
3576         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)
3577         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)
3578         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)
3579     else:
3580         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)
3581         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)
3582         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)
3583     
3584     #stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3585     
3586     html = [
3587         u'<tr><td width="2%" style="border: none;">&nbsp;</td>',
3588         u'<td colspan="%d" style="border: none;">' % colspan,
3589         u'<table width="95%">',
3590         u'  <tr>',
3591         u'      <td class="%s"><a href="%s" title="%s">&lt;</a></td>' % (headclass, prevlink, strprevmonth),
3592         u'      <td class="%s"><a href="%s" title="Go/Refresh this week">%s</a></td>' % (headclass, curlink, stryearmonth),
3593         u'      <td class="%s"><a href="%s" title="%s">&gt;</a></td>' % (headclass, nextlink, strnextmonth),
3594         u'  </tr>',
3595         u'</table>',
3596         u'</td></tr>',
3597         ]
3598         
3599     return u'\r\n'.join(html)
3600 
3601 
3602 # show calendar head for weekly view (the date)
3603 def calhead_weeklydate(year, month, day, colspan):
3604     
3605     request = Globs.request
3606     _ = request.getText
3607     
3608     months = Globs.months
3609     monthstyle_us = Globs.month_style_us
3610     cal_action = Globs.cal_action
3611     page_name = Globs.pagename
3612     wkdays = Globs.wkdays
3613     
3614     page_url = Globs.pageurl
3615     
3616     date_today = datetime.date( year, month, day )
3617     
3618     if monthstyle_us:
3619         stryearmonth = u'%s %d' % (months[month-1], day)
3620     else:
3621         stryearmonth = u'%02d / %02d' % (month, day)
3622     
3623     stryearmonth = u'%s (%s)' % (stryearmonth, _(wkdays[date_today.weekday() - calendar.firstweekday()]))
3624     curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
3625     
3626     cyear, cmonth, cday = gettodaydate()
3627     if cyear == year and cmonth == month and cday == day:
3628         bgcolor = 'background-color: #FFFFAA;'
3629     else:
3630         bgcolor = ''
3631     
3632     if not Params.changeview:
3633         curlink = '#'
3634     
3635     html = [
3636         u'<td colspan="%d" style="border-width: 2px; text-align: center; font-size: 9pt; %s">' % (colspan, bgcolor),
3637         u'<a href="%s">%s</a>' % (curlink, stryearmonth),
3638         u'</td>',
3639         ]
3640         
3641     return u'\r\n'.join(html)
3642 
3643 # show days in simple
3644 def simple_eventbox(year, month, day, wkday, boxclass):
3645     wkend = Globs.wkend
3646     if wkday == wkend:
3647         html_text = u'<font color="#aa7744">%s</font>' % day
3648     else:
3649         html_text = u'%s' % day
3650     
3651     cyear, cmonth, cday = gettodaydate()
3652     
3653     page_url = Globs.pageurl
3654     linkkey = u'%d%02d%02d' % (year, month, day)
3655     
3656     curlink = u'%s?calaction=daily&caldate=%d%02d%02d' % (page_url, year, month, day)
3657     
3658     if not Params.changeview:
3659         curlink = '#'
3660     
3661     curlink = u'<a href="%s" onMouseOver="tip(\'%s\')" onMouseOut="untip()" >%s</a>' % (curlink, linkkey, html_text)
3662     
3663     if boxclass == 'simple_nb':
3664         html = u'  <td class="%s">&nbsp;</td>\r\n' % boxclass
3665     else:
3666         if cyear == year and cmonth == month and cday == day:
3667             html = u'  <td class="%s_today">%s</td>\r\n' % (boxclass, curlink)
3668         else:
3669             html = u'  <td class="%s">%s</td>\r\n' % (boxclass, curlink)
3670        
3671     return html
3672 
3673 
3674 # show weekday
3675 def calhead_weekday(wday, headclass):
3676     if headclass == 'simple_weekday':
3677         html = u'       <td class="%s">%s</td>\r\n' % (headclass, wday[0])
3678     else:
3679         html = u'       <td class="%s">%s</td>\r\n' % (headclass, wday)
3680 
3681     return html
3682 
3683 
3684 # show days of current month
3685 def calhead_day(year, month, day, wkday):
3686     
3687     request = Globs.request
3688     page_name = Globs.pagename
3689     wkend = Globs.wkend
3690     
3691     if wkday == wkend:
3692         html_text = u'<font color="#FF3300">%s</font>' % day
3693     else:
3694         html_text = u'%s' % day
3695     
3696     page_url = Globs.pageurl
3697     html_text = u'<a href="%s?calaction=daily&caldate=%d%02d%02d">%s</a>' % (page_url, year, month, day, html_text)
3698     
3699     cyear, cmonth, cday = gettodaydate()
3700     
3701     if (not wkday) and Params.showweeknumber:
3702         html_text = u'%s <font size="1" color="#aaaaaa"><i>(%d)</i></font>' % (html_text, (int(datetime.date(year, month, day).isocalendar()[1])))
3703       
3704     if cyear == year and cmonth == month and cday == day:
3705         html = u'  <td class="head_day_today">&nbsp;%s</td>\r\n' % html_text
3706     else:
3707         html = u'  <td class="head_day">&nbsp;%s</td>\r\n' % html_text
3708        
3709     return html
3710 
3711 
3712 # show days of previous or next month
3713 def calhead_day_nbmonth(day):
3714     
3715     html = u'  <td class="head_day_nbmonth">&nbsp;%s</td>\r\n' % day
3716     return html
3717 
3718 
3719 # show blank calendar box
3720 def calshow_blankbox(classname):
3721     html = u'  <td class="%s">&nbsp;</td>' % classname
3722     return html
3723 
3724 
3725 def calshow_blankbox2(classname, colspan):
3726     html = u'  <td class="%s" colspan="%d">&nbsp;</td>' % (classname, colspan)
3727     return html
3728 
3729 
3730 # show eventbox
3731 def calshow_eventbox(event, colspan, status, cur_date):
3732     
3733     if status:
3734         status = u'_%s' % status
3735     
3736     title = event['title']
3737     eid = event['id']
3738     startdate = event['startdate']
3739     enddate = event['enddate']
3740     starttime = event['starttime']
3741     endtime = event['endtime']
3742     description = event['description']
3743     bgcolor = event['bgcolor']
3744     
3745     if not bgcolor:
3746         if Globs.labels:
3747             labels = Globs.labels
3748             # for backward compatibility
3749             if event.has_key('label'):
3750                 if labels.has_key(event['label']):
3751                     bgcolor = labels[event['label']]['bgcolor']
3752     
3753     year, month, day = getdatefield(cur_date)
3754     
3755     if bgcolor:
3756         bgcolor = 'background-color: %s;' % bgcolor
3757     else:
3758         bgcolor = 'background-color: %s;' % Params.bgcolor
3759     
3760     if (startdate == enddate) and starttime:
3761         shour, smin = gettimefield(starttime)
3762         
3763         link = [
3764             u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3765             u'<td nowrap class="cal_eventbox_time">%02d:%02d&nbsp;</td>\r\n' % (shour, smin),
3766             u'<td class="cal_eventbox_time_event">',
3767             u'%s' % showReferPageParsed(event, 'title', 1),
3768             u'</td>\r\n</tr></table>',
3769             ]
3770         link = u''.join(link)
3771     else:
3772         link = u'%s' % showReferPageParsed(event, 'title', 1)
3773     
3774     
3775     html = [
3776         u'  <td class="cal_eventbox" colspan="%d"><table class="cal_event">' % colspan,
3777         u'      <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3778         u'      </table></td>',
3779         ]
3780         
3781     return u'\r\n'.join(html)
3782 
3783 
3784 # show eventbox
3785 def calshow_daily_eventbox2(event, colspan, status, cur_date):
3786     if status:
3787         status = u'_%s' % status
3788     
3789     title = event['title']
3790     eid = event['id']
3791     startdate = event['startdate']
3792     enddate = event['enddate']
3793     starttime = event['starttime']
3794     endtime = event['endtime']
3795     description = event['description']
3796     bgcolor = event['bgcolor']
3797     
3798     if not bgcolor:
3799         labels = Globs.labels
3800         # for backward compatibility
3801         if event.has_key('label'):
3802             if labels.has_key(event['label']):
3803                 bgcolor = labels[event['label']]['bgcolor']
3804     
3805     year, month, day = getdatefield(cur_date)
3806     
3807     if bgcolor:
3808         bgcolor = 'background-color: %s;' % bgcolor
3809     else:
3810         bgcolor = 'background-color: %s;' % Params.bgcolor
3811     
3812     if (startdate == enddate) and starttime:
3813         shour, smin = gettimefield(starttime)
3814         
3815         link = [
3816             u'<table width="100%" style="border-width: 0px; padding: 0px; margin: 0px;"><tr>\r\n',
3817             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),
3818             u'<td style="border-width: 0px; padding: 0px; margin: 0px; text-align: left; vertical-align: top;font-size: 8pt;">',
3819             u'%s' % showReferPageParsed(event, 'title', 1),
3820             u'</td>\r\n</tr></table>',
3821             ]
3822         link = u''.join(link)
3823     else:
3824         link = u'%s' % showReferPageParsed(event, 'title', 1)
3825     
3826     
3827     html = [
3828         u'  <td colspan="%d" style="width: 96%%; border-width: 0px; line-height: 11px;"><table class="cal_event">' % colspan,
3829         u'      <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3830         u'      </table></td>',
3831         ]
3832         
3833     return u'\r\n'.join(html)
3834 
3835 
3836 # show eventbox
3837 def calshow_daily_eventbox(event):
3838     
3839     title = event['title']
3840     eid = event['id']
3841     startdate = event['startdate']
3842     enddate = event['enddate']
3843     starttime = event['starttime']
3844     endtime = event['endtime']
3845     description = event['description']
3846     bgcolor = event['bgcolor']
3847     time_len = event['time_len']
3848     
3849     if not bgcolor:
3850         labels = Globs.labels
3851         # for backward compatibility
3852         if event.has_key('label'):
3853             if labels.has_key(event['label']):
3854                 bgcolor = labels[event['label']]['bgcolor']
3855     
3856     if bgcolor:
3857         bgcolor = 'background-color: %s;' % bgcolor
3858     else:
3859         bgcolor = 'background-color: %s;' % Params.bgcolor
3860     
3861     shour, smin = gettimefield(starttime)
3862     ehour, emin = gettimefield(endtime)
3863     
3864     html = [
3865         u'  <td colspan="%(colspan)d"',
3866         u'      style="%s border-width: 2px; border-color: #000000; vertical-align: top; font-size: 9pt; ' % bgcolor,
3867         u'      width: %(width)s;" ', 
3868         u'      rowspan="%(rowspan)d">' % { 'rowspan': time_len },
3869         u'      %02d:%02d ~ %02d:%02d<br>%s' % (shour, smin, ehour, emin, showReferPageParsed(event, 'title', 1)),
3870         u'  </td>',
3871         ]
3872         
3873     return u'\r\n'.join(html)
3874 
3875 
3876 # show eventbox
3877 def calshow_weekly_eventbox(event):
3878     
3879     title = event['title']
3880     eid = event['id']
3881     startdate = event['startdate']
3882     enddate = event['enddate']
3883     starttime = event['starttime']
3884     endtime = event['endtime']
3885     description = event['description']
3886     bgcolor = event['bgcolor']
3887     time_len = event['time_len']
3888     
3889     if not bgcolor:
3890         labels = Globs.labels
3891         # for backward compatibility
3892         if event.has_key('label'):
3893             if labels.has_key(event['label']):
3894                 bgcolor = labels[event['label']]['bgcolor']
3895     
3896     if bgcolor:
3897         bgcolor = 'background-color: %s;' % bgcolor
3898     else:
3899         bgcolor = 'background-color: %s;' % Params.bgcolor
3900     
3901     shour, smin = gettimefield(starttime)
3902     ehour, emin = gettimefield(endtime)
3903     
3904     html = [
3905         u'  <td colspan="%(colspan)d"',
3906         u'      style="%s;' % bgcolor,
3907         u'      width: %(width)s;" ', 
3908         u'      rowspan="%(rowspan)d"' % { 'rowspan': time_len },
3909         u'      class="cal_weekly_eventbox">',
3910         u'      %s' % showReferPageParsed(event, 'title', 1),
3911         u'  </td>',
3912         ]
3913         
3914     return u'\r\n'.join(html)
3915 
3916 # show blank eventbox
3917 def calshow_blankeventbox():
3918     
3919     html = [
3920         u'  <td colspan="%(colspan)d" style="width: %(width)s;" class="cal_blankeventbox">&nbsp;</td>',
3921         ]
3922         
3923     return u'\r\n'.join(html)
3924 
3925 
3926 # show eventbox
3927 def calshow_weekly_eventbox2(event, colspan, width, status, cur_date):
3928     if status:
3929         status = u'_%s' % status
3930     
3931     title = event['title']
3932     eid = event['id']
3933     startdate = event['startdate']
3934     enddate = event['enddate']
3935     starttime = event['starttime']
3936     endtime = event['endtime']
3937     description = event['description']
3938     bgcolor = event['bgcolor']
3939     
3940     year, month, day = getdatefield(cur_date)
3941     
3942     if not bgcolor:
3943         labels = Globs.labels
3944         # for backward compatibility
3945         if event.has_key('label'):
3946             if labels.has_key(event['label']):
3947                 bgcolor = labels[event['label']]['bgcolor']
3948     
3949     if bgcolor:
3950         bgcolor = 'background-color: %s;' % bgcolor
3951     else:
3952         bgcolor = 'background-color: %s;' % Params.bgcolor
3953     
3954     link = u'%s' % showReferPageParsed(event, 'title', 1)
3955     
3956     html = [
3957         u'  <td colspan="%d" style="width: %d%%;" class="cal_weekly_eventbox2"><table class="cal_event">' % (colspan, width),
3958         u'      <tr><td class="cal_event%s" style="%s">%s</td></tr>' % (status, bgcolor, link),
3959         u'      </table></td>',
3960         ]
3961         
3962     return u'\r\n'.join(html)
3963 
3964 
3965 
3966 # show blank eventbox
3967 def calshow_blankeventbox2(colspan, width):
3968     html = [
3969         u'  <td colspan="%(colspan)d"' % { 'colspan': colspan },
3970         u'      style="width: %(width)s;" class="cal_blankeventbox">&nbsp;</td>' % { 'width': '%d%%%%' % width },
3971         ]
3972         
3973     return u'\r\n'.join(html)
3974 
3975 
3976 
3977 def calshow_daily_hourhead(hour):
3978     
3979     if hour >= Globs.dailystart and hour <= Globs.dailyend:
3980         bgcolor = "#ffffcc"
3981     else:
3982         bgcolor = "#ffeeee"
3983     
3984     html = [
3985         u'  <td class="cal_hourhead" style="background-color: %s; width: 4%%%%;">%02d</td>' % (bgcolor, hour),
3986         ]
3987         
3988     return u'\r\n'.join(html)
3989 
3990 def calshow_weekly_hourhead(hour):
3991     
3992     if hour >= Globs.dailystart and hour <= Globs.dailyend:
3993         bgcolor = "#ffffcc"
3994     else:
3995         bgcolor = "#ffeeee"
3996     
3997     html = [
3998         u'  <td class="cal_hourhead" style="width: 2%%%%; background-color: %s; ">%02d</td>' % (bgcolor, hour),
3999         ]
4000         
4001     return u'\r\n'.join(html)
4002 
4003 
4004 
4005 def insertcalevents(cal_events, datefrom, dateto, e_id, e_start_date, e_end_date):
4006     
4007     if not (int(e_start_date) > dateto or int(e_end_date) < datefrom):
4008         
4009         e_start_date = str(max(int(e_start_date), datefrom))
4010         e_end_date = str(min(int(e_end_date), dateto))
4011         
4012         day_delta = datetime.timedelta(days=1)
4013         e_start_year, e_start_month, e_start_day = getdatefield(e_start_date)
4014         cur_datetime = datetime.date(e_start_year, e_start_month, e_start_day)
4015         
4016         while 1:
4017             tmp_record_date = formatdateobject(cur_datetime)
4018             
4019             if not cal_events.has_key(tmp_record_date):
4020                 cal_events[tmp_record_date] = []
4021             cal_events[tmp_record_date].append(e_id)
4022             
4023             if tmp_record_date == e_end_date:
4024                 break
4025             
4026             cur_datetime = cur_datetime + day_delta   
4027 
4028 # date format should be like '20051004' for 2005, Oct., 04
4029 def diffday(date1, date2):
4030     
4031     try:
4032         year1, month1, day1 = getdatefield(date1)
4033         year2, month2, day2 = getdatefield(date2)
4034         tmp_diff = datetime.date(year2, month2, day2) - datetime.date(year1, month1, day1)
4035     except (TypeError, ValueError):
4036         raise EventcalError('invalid_date')
4037 
4038     return tmp_diff.days
4039 
4040 
4041 # time format should be like '1700' for 05:00pm
4042 def difftime(time1, time2):
4043     
4044     try:
4045         hour1, min1 = gettimefield(time1)
4046         hour2, min2 = gettimefield(time2)
4047         
4048     except (TypeError, ValueError):
4049         raise EventcalError('invalid_time')
4050 
4051     if min2 == 0 and hour2 != 0 and hour1 != hour2:
4052         hour2 -= 1
4053 
4054     tmp_diff = hour2 - hour1
4055     
4056     return tmp_diff
4057 
4058 
4059 
4060 def formatDate(year, month, day):
4061     # returns like: '20051004'
4062     return u'%4d%02d%02d' % (year, month, day)
4063 
4064 def formatTime(hour, min):
4065     # returns like: '1700'
4066     return u'%2d%02d' % (hour, min)
4067 
4068 
4069 def formatdateobject(obj_date):
4070 
4071     return formatDate(obj_date.year, obj_date.month, obj_date.day)
4072 
4073 def formattimeobject(obj_time):
4074 
4075     return formatTime(obj_time.hour, obj_time.minute)
4076 
4077 
4078 def debug(astring):
4079     Globs.debugmsg += u'<li>%s\n' % astring
4080 
4081 
4082 def geterrormsg(errmsgcode, refer='', title='', hid=''):
4083     
4084     if errmsgcode == 'invalid_caldate':
4085         msg = 'Warning: Invalid value for "caldate" parameter. Shows today.'
4086     
4087     elif errmsgcode == 'invalid_curdate':
4088         msg = 'Warning: Invalid value for "curdate" parameter. Shows today.'
4089 
4090     elif errmsgcode == 'invalid_numcal':
4091         msg = 'Warning: Invalid value of "numcal" parameter. Shows one.'
4092         
4093     elif errmsgcode == 'invalid_startdate':
4094         msg = 'Error: Invalid startdate format. Not handled.'
4095         
4096     elif errmsgcode == 'invalid_enddate':
4097         msg = 'Error: Invalid enddate format. Not handled.'
4098         
4099     elif errmsgcode == 'invalid_start':
4100         msg = 'Error: Invalid start date or time format. Not handled.'
4101         
4102     elif errmsgcode == 'invalid_end':
4103         msg = 'Error: Invalid end date or time format. Not handled.'
4104         
4105     elif errmsgcode == 'invalid_date':
4106         msg = 'Error: Invalid date format. Not handled.'
4107         
4108     elif errmsgcode == 'enddate_precede':
4109         msg = 'Error: Startdate should be earlier than Enddate. Not handled.'
4110 
4111     elif errmsgcode == 'invalid_starttime':
4112         msg = 'Error: Invalid starttime format. Not handled.'
4113         
4114     elif errmsgcode == 'invalid_endtime':
4115         msg = 'Error: Invalid endtime format. Not handled.'
4116         
4117     elif errmsgcode == 'invalid_time':
4118         msg = 'Error: Invalid time format. Not handled.'
4119         
4120     elif errmsgcode == 'endtime_precede':
4121         msg = 'Error: Starttime should be earlier than Endtime. Not handled.'
4122 
4123     elif errmsgcode == 'len_recur_int':
4124         msg = 'Error: Event length should be smaller than recurrence interval. Not handled.'
4125 
4126     elif errmsgcode == 'invalid_bgcolor':
4127         msg = 'Warning: Invalid bgcolor format. Ignored.'
4128     
4129     elif errmsgcode == 'invalid_label':
4130         msg = 'Warning: Invalid label format. Ignored.'
4131     
4132     elif errmsgcode == 'invalid_recur':
4133         msg = 'Error: Invalid recurrence format. Not handled.'
4134         
4135     elif errmsgcode == 'invalid_recur_until':
4136         msg = 'Error: Invalid end date (until) format of the recurrence. Not handled.'
4137     
4138     elif errmsgcode == 'empty_description':
4139         msg = 'Warning: Empty description. Ignored.'
4140     
4141     elif errmsgcode == 'invalid_default_bgcolor':
4142         msg = 'Warning: Invalid default_bgcolor format. Ignored.'
4143         
4144     elif errmsgcode == 'empty_default_description':
4145         msg = 'Warning: Empty default_description. Ignored.'
4146     
4147     elif errmsgcode == 'redefined_label':
4148         msg = 'Warning: Redefined label. Ignored.'
4149     
4150     elif errmsgcode == 'empty_label_definition':
4151         msg = 'Warning: Invalid label definition. Ignored.'
4152 
4153     elif errmsgcode == 'need_starttime':
4154         msg = 'Error: Starttime should be specified. Not handled.'
4155     
4156     elif errmsgcode == 'recur_until_precede':
4157         msg = 'Error: Enddate should be earlier than the end date (until) of recurrence. Not handled.'
4158     
4159     else:
4160         msg = 'undefined: %s' % errmsgcode
4161     
4162     if refer:
4163         msg = '%s (%s)' % (msg, getReferLink(refer, title, hid))
4164     
4165     return msg
4166 
4167 
4168 def errormsgcode(errmsgcode):
4169 
4170     errormsg(geterrormsg(errmsgcode))
4171 
4172 
4173 def errormsg(astring):
4174     Globs.errormsg += u'<li>%s\n' % astring
4175 
4176 
4177 def yearmonthplusoffset(year, month, offset):
4178     month = month+offset
4179     # handle offset and under/overflows - quick and dirty, yes!
4180     while month < 1:
4181         month = month + 12
4182         year = year - 1
4183     while month > 12:
4184         month = month - 12
4185         year = year + 1
4186     return year, month
4187 
4188 
4189 def formatcfgdatetime(strdate, strtime=''):
4190     
4191     if not strdate:
4192         return ''
4193     
4194     request = Globs.request
4195     
4196     if request.user.date_fmt:
4197         date_fmt = request.user.date_fmt
4198     else:
4199         date_fmt = request.cfg.date_fmt
4200     
4201     if request.user.datetime_fmt:
4202         datetime_fmt = request.user.datetime_fmt
4203     else:
4204         datetime_fmt = request.cfg.datetime_fmt
4205     
4206     ## XXX HACK
4207     datetime_fmt = datetime_fmt.replace(':%S', '')
4208     
4209     date_fmt = str(date_fmt)
4210     datetime_fmt = str(datetime_fmt)
4211     
4212     year, month, day = getdatefield(str(strdate))
4213     if strtime:
4214         hour, min = gettimefield(str(strtime))
4215         objdatetime = datetime.datetime(year, month, day, hour, min)
4216         return objdatetime.strftime(datetime_fmt)
4217     else:
4218         objdate = getdatetimefromstring(strdate)
4219         return objdate.strftime(date_fmt)
4220 
4221 
4222 def getdatetimefromstring(strdate):
4223     year, month, day = getdatefield(str(strdate))
4224     return datetime.date( year, month, day )
4225 
4226 
4227 def searchPages(request, needle):
4228     # Search the pages and return the results
4229     query = search.QueryParser().parse_query(needle)
4230     results = search.searchPages(request, query)
4231     #results.sortByPagename()
4232     
4233     return results.hits
4234     
4235     html = []
4236     for page in results.hits:
4237         html.append(page.page_name)
4238     
4239     html = u',<br>'.join(html)
4240     return u'%s<p>%s' % (Params.category, html)
4241 
4242 
4243 def getFirstDateOfWeek(year, month, day):
4244 	orgday = datetime.date(year, month, day)
4245 	yearBase, week, weekday = orgday.isocalendar()
4246 	baseDate = datetime.date(yearBase, 2, 1)
4247 	yearBase, weekBase, dayBase = baseDate.isocalendar()
4248 	days = datetime.timedelta(1-dayBase+(week-weekBase)*7)
4249 	theday = baseDate + days
4250 	
4251 	theday -= datetime.timedelta(7 - calendar.firstweekday())
4252 	
4253 	if orgday - theday >= datetime.timedelta(7):
4254 	    theday += datetime.timedelta(7)
4255 	
4256 	return theday
4257     
4258 def gcd(a,b):
4259     """Return greatest common divisor using Euclid's Algorithm."""
4260     while b:      
4261         a, b = b, a % b
4262     
4263     return a
4264 
4265 def lcm(a,b):
4266     """
4267     Return lowest common multiple."""
4268     return (a*b)/gcd(a,b)
4269 
4270 def LCM(terms):
4271     "Return lcm of a list of numbers."   
4272     return reduce(lambda a,b: lcm(a,b), terms)
4273 
4274 
4275 def getNumericalMonth(strMonth):
4276     months = Globs.months
4277     
4278     strMonth = strMonth.lower()
4279     
4280     index = 0
4281     for monthitem in months:
4282         index += 1
4283         if monthitem.lower().startswith(strMonth):
4284             return index
4285 
4286     return 0
4287     
4288 
4289 def getReferLink(refer, title='', hid=''):
4290     request = Globs.request
4291     
4292     refer_url = '%s/%s' % (request.getScriptname(), wikiutil.quoteWikinameURL(refer))
4293     
4294     if hid:
4295         refer_url += '#%s' % hid
4296 
4297     if title:
4298         refer = '%s: "%s"' % (refer, title)
4299     
4300     return '<a href="%s">%s</a>' % (refer_url, refer)
4301     

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.