Attachment 'MonthCalendarHack-1.0.py'

Download

   1 """
   2     MoinMoin - MonthCalendarHack Macro
   3     
   4     This macro is a hack of the MonthCalendar one delivered with MoinMoin, to enable subpages titles in form
   5     
   6     = title =
   7     
   8     or 
   9     
  10     '''title'''
  11 
  12     You can use this macro to put a month's calendar page on a Wiki page.
  13 
  14     The days are links to Wiki pages following this naming convention:
  15     BasePageName/year-month-day
  16 
  17     @copyright: 2002-2005 by Thomas Waldmann <ThomasWaldmann@gmx.de>
  18     @copyright: 2007- by Eric Veiras Galisson 
  19     @license: GNU GPL - see http://www.gnu.org/licenses/old-licenses/gpl-1.0.txt for details.
  20 
  21     Revisions:
  22     * first revision without a number (=1.0):
  23         * work with MoinMoin 1.5
  24 
  25     Usage:
  26         [[MonthCalendarHack(BasePage,year,month,monthoffset,monthoffset2,height6)]]
  27 
  28         each parameter can be empty and then defaults to currentpage or currentdate or monthoffset=0
  29 
  30     Samples (paste that to one of your pages for a first try):
  31 
  32 Calendar of current month for current page:
  33 [[MonthCalendar]]
  34 
  35 Calendar of last month:
  36 [[MonthCalendarHack(,,,-1)]]
  37 
  38 Calendar of next month:
  39 [[MonthCalendarHack(,,,+1)]]
  40 
  41 Calendar of Page SampleUser, this years december:
  42 [[MonthCalendarHack(SampleUser,,12)]]
  43 
  44 Calendar of current Page, this years december:
  45 [[MonthCalendarHack(,,12)]]
  46 
  47 Calendar of December, 2001:
  48 [[MonthCalendarHack(,2001,12)]]
  49 
  50 Calendar of the month two months after December, 2001
  51 (maybe doesn't make much sense, but is possible)
  52 [[MonthCalendarHack(,2001,12,+2)]]
  53 
  54 Calendar of year 2002 (every month padded to height of 6):
  55 ||||||Year 2002||
  56 ||[[MonthCalendarHack(,2002,1,,,1)]]||[[MonthCalendarHack(,2002,2,,,1)]]||[[MonthCalendarHack(,2002,3,,,1)]]||
  57 ||[[MonthCalendarHack(,2002,4,,,1)]]||[[MonthCalendarHack(,2002,5,,,1)]]||[[MonthCalendarHack(,2002,6,,,1)]]||
  58 ||[[MonthCalendarHack(,2002,7,,,1)]]||[[MonthCalendarHack(,2002,8,,,1)]]||[[MonthCalendarHack(,2002,9,,,1)]]||
  59 ||[[MonthCalendarHack(,2002,10,,,1)]]||[[MonthCalendarHack(,2002,11,,,1)]]||[[MonthCalendarHack(,2002,12,,,1)]]||
  60 
  61 Current calendar of me, also showing entries of A and B:
  62 [[MonthCalendarHack(MyPage*TestUserA*TestUserB)]]
  63 
  64 SubPage calendars:
  65 [[MonthCalendarHack(MyName/CalPrivate)]]
  66 [[MonthCalendarHack(MyName/CalBusiness)]]
  67 [[MonthCalendarHack(MyName/CalBusiness*MyName/CalPrivate)]]
  68 
  69 
  70 Anniversary Calendars: (no year data)
  71 [[MonthCalendarHack(Yearly,,,+1,,6,1)]]
  72 
  73 This creates calendars of the format Yearly/MM-DD 
  74 By leaving out the year, you can set birthdays, and anniversaries in this 
  75 calendar and not have to re-enter each year.
  76 
  77 This creates a calendar which uses MonthCalendarTemplate for directly editing
  78 nonexisting day pages:
  79 [[MonthCalendarHack(,,,,,,MonthCalendarTemplate)]]
  80 """
  81 
  82 Dependencies = ['namespace','time']
  83 
  84 from MoinMoin import wikiutil
  85 from MoinMoin.Page import Page
  86 import re, calendar, time
  87 
  88 # The following line sets the calendar to have either Sunday or Monday as
  89 # the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
  90 # valid here.  All other values will not make good calendars.
  91 # If set to Sunday, the calendar is displayed at "March 2003" vs. "2003 / 3" also.
  92 # XXX change here ----------------vvvvvv
  93 calendar.setfirstweekday(calendar.MONDAY)
  94 
  95 def cliprgb(r,g,b): # don't use 255!
  96     if r < 0:   r=0
  97     if r > 254: r=254
  98     if b < 0:   b=0
  99     if b > 254: b=254
 100     if g < 0:   g=0
 101     if g > 254: g=254
 102     return r, g, b
 103 
 104 def yearmonthplusoffset(year, month, offset):
 105     month = month+offset
 106     # handle offset and under/overflows - quick and dirty, yes!
 107     while month < 1:
 108         month = month + 12
 109         year = year - 1
 110     while month > 12:
 111         month = month - 12
 112         year = year + 1
 113     return year, month
 114 
 115 def parseargs(args, defpagename, defyear, defmonth, defoffset, defoffset2, defheight6, defanniversary, deftemplate):
 116     strpagename = args.group('basepage')
 117     if strpagename:
 118         parmpagename = wikiutil.unquoteWikiname(strpagename)
 119     else:
 120         parmpagename = defpagename
 121     # multiple pagenames separated by "*" - split into list of pagenames
 122     parmpagename = re.split(r'\*', parmpagename)
 123 
 124     stryear = args.group('year')
 125     if stryear:
 126         parmyear = int(stryear)
 127     else:
 128         parmyear = defyear
 129 
 130     strmonth = args.group('month')
 131     if strmonth:
 132         parmmonth = int(strmonth)
 133     else:
 134         parmmonth = defmonth
 135     
 136     stroffset = args.group('offset')
 137     if stroffset:
 138         parmoffset = int(stroffset)
 139     else:
 140         parmoffset = defoffset
 141 
 142     stroffset2 = args.group('offset2')
 143     if stroffset2:
 144         parmoffset2 = int(stroffset2)
 145     else:
 146         parmoffset2 = defoffset2
 147 
 148     strheight6 = args.group('height6')
 149     if strheight6:
 150         parmheight6 = int(strheight6)
 151     else:
 152         parmheight6 = defheight6
 153 
 154     stranniversary = args.group('anniversary')
 155     if stranniversary:
 156             parmanniversary = int(stranniversary)
 157     else:
 158         parmanniversary = defanniversary
 159 
 160     strtemplate = args.group('template')
 161     if strtemplate:
 162         parmtemplate = wikiutil.unquoteWikiname(strtemplate)
 163     else:
 164         parmtemplate = deftemplate
 165     return parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, parmanniversary, parmtemplate
 166         
 167 # FIXME:                          vvvvvv is there a better way for matching a pagename ?
 168 _arg_basepage = r'\s*(?P<basepage>[^, ]+)?\s*'
 169 _arg_year = r',\s*(?P<year>\d+)?\s*'
 170 _arg_month = r',\s*(?P<month>\d+)?\s*'
 171 _arg_offset = r',\s*(?P<offset>[+-]?\d+)?\s*'
 172 _arg_offset2 = r',\s*(?P<offset2>[+-]?\d+)?\s*'
 173 _arg_height6 = r',\s*(?P<height6>[+-]?\d+)?\s*'
 174 _arg_anniversary =  r',\s*(?P<anniversary>[+-]?\d+)?\s*'
 175 _arg_template = r',\s*(?P<template>[^, ]+)?\s*' # XXX see basepage comment
 176 _args_re_pattern = r'^(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?$' % \
 177                      (_arg_basepage,_arg_year,_arg_month, \
 178                       _arg_offset,_arg_offset2,_arg_height6,_arg_anniversary,_arg_template)
 179 
 180 
 181 def execute(macro, text):
 182     request = macro.request
 183     formatter = macro.formatter
 184     _ = request.getText
 185 
 186     # return immediately if getting links for the current page
 187     if request.mode_getpagelinks:
 188         return ''
 189 
 190     args_re = re.compile(_args_re_pattern)
 191     
 192     currentyear, currentmonth, currentday, h, m, s, wd, yd, ds = request.user.getTime(time.time())
 193     thispage = formatter.page.page_name
 194     # does the url have calendar params (= somebody has clicked on prev/next links in calendar) ?
 195     if macro.form.has_key('calparms'):
 196         text2 = macro.form['calparms'][0]
 197         args2 = args_re.match(text2)
 198         if not args2:
 199             return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar calparms "%s"!')) % (text2,)
 200         else:
 201             has_calparms = 1 # yes!
 202             cparmpagename, cparmyear, cparmmonth, cparmoffset, cparmoffset2, cparmheight6, cparmanniversary, cparmtemplate = \
 203                 parseargs(args2, thispage, currentyear, currentmonth, 0, 0, 0, 0, '')
 204     else:
 205         has_calparms = 0
 206 
 207     if text is None: # macro call without parameters
 208         parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, anniversary, parmtemplate = \
 209             [thispage], currentyear, currentmonth, 0, 0, 0, 0, ''
 210     else:
 211         # parse and check arguments
 212         args = args_re.match(text)
 213         if not args:
 214             return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar arguments "%s"!')) % (text,)
 215         else:
 216             parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6, anniversary, parmtemplate = \
 217                 parseargs(args, thispage, currentyear, currentmonth, 0, 0, 0, 0, '')
 218 
 219     # does url have calendar params and is THIS the right calendar to modify (we can have multiple
 220     # calendars on the same page)?
 221     #if has_calparms and (cparmpagename,cparmyear,cparmmonth,cparmoffset) == (parmpagename,parmyear,parmmonth,parmoffset):
 222     
 223     # move all calendars when using the navigation:
 224     if has_calparms and cparmpagename == parmpagename:
 225         year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset + cparmoffset2)
 226         parmoffset2 = cparmoffset2
 227         parmtemplate = cparmtemplate
 228     else:
 229         year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset)
 230 
 231     # get the calendar
 232     monthcal = calendar.monthcalendar(year, month)
 233 
 234     # european / US differences
 235     months = ('January','February','March','April','May','June','July','August','September','October','November','December')
 236     # Set things up for Monday or Sunday as the first day of the week
 237     if calendar.firstweekday() == calendar.MONDAY:
 238         wkend = (5, 6)
 239         wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
 240     if calendar.firstweekday() == calendar.SUNDAY:
 241         wkend = (0, 6)
 242         wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
 243 
 244     colorstep = 85
 245     p = Page(request, thispage)
 246     qpagenames = '*'.join(map(wikiutil.quoteWikinameURL, parmpagename))
 247     qtemplate = wikiutil.quoteWikinameURL(parmtemplate)
 248     querystr = "calparms=%%s,%d,%d,%d,%%d,%%s" % (parmyear, parmmonth, parmoffset)
 249     prevlink  = p.url(request, querystr % (qpagenames, parmoffset2 - 1, qtemplate), 0)
 250     nextlink  = p.url(request, querystr % (qpagenames, parmoffset2 + 1, qtemplate), 0)
 251     prevylink = p.url(request, querystr % (qpagenames, parmoffset2 - 12, qtemplate), 0)
 252     nextylink = p.url(request, querystr % (qpagenames, parmoffset2 + 12, qtemplate), 0)
 253     prevmonth = formatter.url(1, prevlink, 'cal-link') + '&lt;' + formatter.url(0)
 254     nextmonth = formatter.url(1, nextlink, 'cal-link') + '&gt;' + formatter.url(0)
 255     prevyear  = formatter.url(1, prevylink, 'cal-link') + '&lt;&lt;' + formatter.url(0)
 256     nextyear  = formatter.url(1, nextylink, 'cal-link') + '&gt;&gt;' + formatter.url(0)
 257     
 258     if parmpagename != [thispage]:
 259         pagelinks = ''
 260         r, g, b = (255, 0, 0)
 261         l = len(parmpagename[0])
 262         steps = len(parmpagename)
 263         maxsteps = (255 / colorstep)
 264         if steps > maxsteps:
 265             steps = maxsteps
 266         chstep = int(l / steps)
 267         st = 0
 268         while st < l:
 269             ch = parmpagename[0][st:st+chstep]
 270             r, g, b = cliprgb(r, g, b)
 271             pagelinks = pagelinks + '<a style="%s" href="%s">%s</a>' % \
 272                 ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
 273                     (r,g,b), Page(request, parmpagename[0]).url(request), ch)
 274             r, g, b = (r, g+colorstep, b)
 275             st = st + chstep
 276         r, g, b = (255-colorstep, 255, 255-colorstep)
 277         for page in parmpagename[1:]:
 278             pagelinks = pagelinks + '*<a style="%s" href="%s">%s</a>' % \
 279                             ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
 280                                 (r,g,b), Page(request, page).url(request), page)
 281         showpagename = '   %s<BR>\n' % pagelinks
 282     else:
 283         showpagename = ''
 284     if calendar.firstweekday() == calendar.SUNDAY:
 285         resth1 = '  <th colspan="7" class="cal-header">\n' \
 286                  '%s' \
 287                  '   %s&nbsp;%s&nbsp;<b>&nbsp;%s&nbsp;%s</b>&nbsp;%s\n&nbsp;%s\n' \
 288                  '  </th>\n' % (showpagename, prevyear, prevmonth, months[month-1], str(year), nextmonth, nextyear)
 289     if calendar.firstweekday() == calendar.MONDAY:
 290         resth1 = '  <th colspan="7" class="cal-header">\n' \
 291                  '%s' \
 292                  '   %s&nbsp;%s&nbsp;<b>&nbsp;%s&nbsp;/&nbsp;%s</b>&nbsp;%s\n&nbsp;%s\n' \
 293                  '  </th>\n' % (showpagename, prevyear, prevmonth, str(year), month, nextmonth, nextyear)
 294     restr1 = ' <tr>\n%s </tr>\n' % resth1
 295 
 296     r7 = range(7)
 297     restd2 = []
 298     for wkday in r7:
 299         wday = _(wkdays[wkday])
 300         if wkday in wkend:
 301             cssday = "cal-weekend"
 302         else:
 303             cssday = "cal-workday"
 304         restd2.append('  <td class="%s" width="14%%">%s</td>\n' % (cssday, wday))
 305     restr2 = ' <tr>\n%s </tr>\n' % "".join(restd2)
 306  
 307     if parmheight6:
 308         while len(monthcal) < 6:
 309             monthcal = monthcal + [[0,0,0,0,0,0,0]]
 310 
 311     maketip_js = []
 312     restrn = []
 313     for week in monthcal:
 314         restdn = []
 315         for wkday in r7:
 316             day = week[wkday]
 317             if not day:
 318                 restdn.append('  <td class="cal-invalidday">&nbsp;</td>\n')
 319             else:
 320                 page = parmpagename[0]
 321                 if anniversary:
 322                     link = "%s/%02d-%02d" % (page, month, day)
 323                 else:
 324                     link = "%s/%4d-%02d-%02d" % (page, year, month, day)
 325                 daypage = Page(request, link)
 326                 if daypage.exists() and request.user.may.read(link):
 327                     csslink = "cal-usedday"
 328                     query = {}
 329                     r, g, b, u = (255, 0, 0, 1)
 330                     daycontent = daypage.get_raw_body()
 331                     header1_re = re.compile(r"^\s*('''\s*(.*)\s*'''|=\s+(.*)\s+=)\s*$", re.MULTILINE) # re.UNICODE
 332                     titletext = []
 333                     for match in header1_re.finditer(daycontent):
 334                         if match:
 335                             if match.group(2) == None:
 336                 		        title = match.group(3)
 337                             else:
 338                                 title = match.group(2)
 339                             title = wikiutil.escape(title).replace("'","\\'")
 340                             titletext.append(title)
 341                     tipname = link
 342                     tiptitle = link
 343                     tiptext = '<br>'.join(titletext)
 344                     maketip_js.append("maketip('%s','%s','%s');" % (tipname, tiptitle, tiptext))
 345                     onmouse = {'onMouseOver': "tip('%s')" % tipname,
 346                                'onMouseOut':  "untip()"}
 347                 else:
 348                     csslink = "cal-emptyday"
 349                     if parmtemplate:
 350                         query = {'action': 'edit', 'template': parmtemplate}
 351                     else:
 352                         query = {}
 353                     r, g, b, u = (255, 255, 255, 0)
 354                     if wkday in wkend:
 355                         csslink = "cal-weekend"
 356                     onmouse = {}
 357                 for otherpage in parmpagename[1:]:
 358                     otherlink = "%s/%4d-%02d-%02d" % (otherpage, year, month, day)
 359                     otherdaypage = Page(request, otherlink)
 360                     if otherdaypage.exists():
 361                         csslink = "cal-usedday"
 362                         if u == 0:
 363                             r, g, b = (r-colorstep, g, b-colorstep)
 364                         else:
 365                             r, g, b = (r, g+colorstep, b)
 366                 r, g, b = cliprgb(r, g, b)
 367                 style = 'background-color:#%02x%02x%02x' % (r, g, b)
 368                 fmtlink = formatter.url(1, daypage.url(request, query), csslink, **onmouse) + str(day) + formatter.url(0)
 369                 if day == currentday and month == currentmonth and year == currentyear:
 370                     cssday = "cal-today"
 371                     fmtlink = "<b>%s</b>" % fmtlink # for browser with CSS probs
 372                 else:
 373                     cssday = "cal-nottoday"
 374                 restdn.append('  <td style="%s" class="%s">%s</td>\n' % (style, cssday, fmtlink))
 375         restrn.append(' <tr>\n%s </tr>\n' % "".join(restdn))
 376 
 377     restable = '<table border="2" cellspacing="2" cellpadding="2">\n%s%s%s</table>\n'
 378     restable = restable % (restr1, restr2, "".join(restrn))
 379 
 380     result = """\
 381 <script language="JavaScript" type="text/javascript" src="%s/common/js/infobox.js"></script>
 382 <div id="infodiv" style="position:absolute; visibility:hidden; z-index:20; top:-999em; left:0px;"></div>
 383 <script language="JavaScript" type="text/javascript">
 384 <!--
 385 %s
 386 // -->
 387 </script>
 388 %s
 389 """ % (request.cfg.url_prefix, "\n".join(maketip_js), restable)
 390     return formatter.rawHTML(result)
 391 
 392 # EOF

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] (2008-04-07 12:31:18, 15.6 KB) [[attachment:MonthCalendarHack-1.0.py]]
  • [get | view] (2008-04-07 12:31:49, 15.9 KB) [[attachment:MonthCalendarHack-1.1.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.