Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > dd5ff701fdd2df6775e5cf25b2dd9e7c > files > 3

moin-1.1-3mdv2007.1.src.rpm

"""
    MoinMoin - MonthCalendar Macro

    You can use this macro to put a months calendar page on a Wiki page.

    The days are links to Wiki pages following this naming convention:
    BasePageName/year-month-day

    Copyright (c) 2002 by Thomas Waldmann <ThomasWaldmann@gmx.de>
    Licensed under GNU GPL - see COPYING for details.

----
    
    Revisions:
    * first revision without a number (=1.0):
        * was only online for a few hours and then replaced by 1.1
    * 1.1:
        * changed name to MonthCalendar to avoid conflict with "calendar" under case-insensitive OSes like Win32
        * days as subpages
        * basepage argument
        * change order of year/month argument
        * browsing links to prev/next month/year
	    * current limitation: you can only browse one calendar on the same
              page/url, if you try 
to browse another calendar on the same page, the first one jumps back to its original display
	* show basepage in calendar header if basepage<>currentpage
    * 1.2:
        * minor fixes in argument parsing
	* cosmetic fix for netscape, other cosmetic changes, changed css
        * i18n support (weekday short names)
    * 1.3:
        * fixes to run with MoinMoin 0.11, thanks to JuergenHermann
	* fix: withspace before "," allowed in argument list
        * BasePage in calendar header (if present) is a link now
	* more i18n
        * HTML cleanup, generating code avoids bracketing errors
        * colour cosmetics
    * 1.4:
        * new parameter for enabling fixed height of 6 "calendar weeks",
	  if you want to show a whole year's calendar, this just looks
	  better than having some months with 4, some with 5 and some with 6.
	* group calendaring functions:
	  * you can give mutliple BasePages UserName1*UserName2*UserName3
	  * first BasePage is considered "your" Basepage,
            used days are bright red
	  * 2nd and all other BasePages are considered "others" BasePages
	    and lead to an increasing green component the more "used" days
	    the others have. So white gets greener and red gets more yellowish.
          * in the head part of the calendar, you can click on each name
	    to get to the Page of the same name
	  * colouring of my and others BasePage is done in a way to show
	    the colouring used in the calendar:
	    * others use green colouring (increasingly green if multiply used)
	    * I use red colouring, which gets more and more yellowish as
	      the day is used by more and more others, too
    * 1.5:
        * fixed username colouring when using a BasePage
        * fixed navigation header of MonthCalendar not to get broken into
	  multiple lines
	* fixed SubPage handling (please do not use relative SubPages like
	  /SubPage yet. Use MyName/SubPage.)
    * 1.6:
        * syntactic cleanup
        * removed i18n compatibility for moin<1.1 or cvs<2003-06-10
        * integrated Scott Chapman's changes:
            * Made it configurable for Sunday or Monday as the first day of the week.
	      Search for "change here".
            * Made it so that today is not only set to a seperate css style, but also boldfaced.
              Some browsers don't show the other css style (Netscape).
            * Made it so weekend dates have different color.

TODO:
    * integrate patch for including day page contents directly into cal
     * still thinking over: does this make sense in a MonthCalendar?
     * it would be definitely nice in a week or day calendar (more space to
       burn)
    * integr. daycal -link-> monthcal

----

    Usage:
        [[MonthCalendar(BasePage,year,month,monthoffset,monthoffset2,height6)]]

        each parameter can be empty and then defaults to currentpage or currentdate or monthoffset=0

    Samples (paste that to one of your pages for a first try):

Calendar of current month for current page:
[[MonthCalendar]]

Calendar of last month:
[[MonthCalendar(,,,-1)]]

Calendar of next month:
[[MonthCalendar(,,,+1)]]

Calendar of Page SampleUser, this years december:
[[MonthCalendar(SampleUser,,12)]]

Calendar of current Page, this years december:
[[MonthCalendar(,,12)]]

Calendar of December, 2001:
[[MonthCalendar(,2001,12)]]

Calendar of the month two months after December, 2001
(maybe doesn't make much sense, but is possible)
[[MonthCalendar(,2001,12,+2)]]

Calendar of year 2002 (every month padded to height of 6):
||||||Year 2002||
||[[MonthCalendar(,2002,1,,,1)]]||[[MonthCalendar(,2002,2,,,1)]]||[[MonthCalendar(,2002,3,,,1)]]||
||[[MonthCalendar(,2002,4,,,1)]]||[[MonthCalendar(,2002,5,,,1)]]||[[MonthCalendar(,2002,6,,,1)]]||
||[[MonthCalendar(,2002,7,,,1)]]||[[MonthCalendar(,2002,8,,,1)]]||[[MonthCalendar(,2002,9,,,1)]]||
||[[MonthCalendar(,2002,10,,,1)]]||[[MonthCalendar(,2002,11,,,1)]]||[[MonthCalendar(,2002,12,,,1)]]||

Current calendar of me, also showing entries of A and B:
[[MonthCalendar(MyPage*TestUserA*TestUserB)]]

SubPage calendars:
[[MonthCalendar(MyName/CalPrivate)]]
[[MonthCalendar(MyName/CalBusiness)]]
[[MonthCalendar(MyName/CalBusiness*MyName/CalPrivate)]]

----

    You need to have some stylesheet entries like the following.
    Paste that to  default.css / moinmoin.css:
    
/* begin css for MonthCalendar macro */
/* days without and with pages linked to them */
a.cal-emptyday {
    color: #777777;
    text-align: center;
}
a.cal-usedday {
    font-weight: bold;
    color: #000000;
    text-align: center;
}
/* general stuff: workdays, weekend, today */
td.cal-workday {
    background-color: #DDDDFF;
    text-align: center;
}
td.cal-weekend {
    background-color: #FFDDDD;
    text-align: center;
}
td.cal-today {
    background-color: #CCFFCC;
    border-style: solid;
    border-width: 2pt;
    text-align: center;
}
/* invalid places on the monthly calendar sheet */
td.cal-invalidday {
    background-color: #CCCCCC;
}
/* links to prev/next month/year */
a.cal-link {
    color: #000000;
    text-decoration: none;
}
th.cal-header {
    background-color: #DDBBFF;
    text-align: center;
}
/* end css for MonthCalendar macro */

----

    If you want translated (german) messages, add something like this to
    i18n/de.py (if you have >=0.11, the weekday translation might be already
    there):
    
'Mon':'Mo','Tue':'Di','Wed':'Mi','Thu':'Do','Fri':'Fr','Sat':'Sa','Sun':'So',
    
'Invalid MonthCalendar calparms "%s"!':
'Ung\366ltige MonthCalendar calparms "%s"!',

'Invalid MonthCalendar arguments "%s"!':
'Ung\366ltige MonthCalendar Argumente "%s"!',

"""

# Imports
from MoinMoin import config, user, wikiutil
from MoinMoin.Page import Page
import sys, re, calendar, time, string

# The following line sets the calendar to have either Sunday or Monday as
# the first day of the week. Only SUNDAY or MONDAY (case sensitive) are
# valid here.  All other values will not make good calendars.
# If set to Sunday, the calendar is displayed at "March 2003" vs. "2003 / 3" also.
# XXX change here ----------------vvvvvv
calendar.setfirstweekday(calendar.MONDAY)

def cliprgb(r,g,b): # don't use 255!
    if r < 0:   r=0
    if r > 254: r=254
    if b < 0:   b=0
    if b > 254: b=254
    if g < 0:   g=0
    if g > 254: g=254
    return r, g, b

def yearmonthplusoffset(year, month, offset):
    month = month+offset
    # handle offset and under/overflows - quick and dirty, yes!
    while month < 1:
        month = month+12
        year = year-1
    while month > 12:
        month = month-12
        year = year+1
    return year, month

def parseargs(args, defpagename, defyear, defmonth, defoffset, defoffset2, defheight6):
    strpagename = args.group('basepage')
    if strpagename:
        parmpagename = strpagename
    else:
        parmpagename = defpagename
    # multiple pagenames separated by "*" - split into list of pagenames
    parmpagename = re.split(r'\*', parmpagename)

    stryear = args.group('year')
    if stryear:
        parmyear = int(stryear)
    else:
        parmyear = defyear

    strmonth = args.group('month')
    if strmonth:
        parmmonth = int(strmonth)
    else:
        parmmonth = defmonth
    
    stroffset = args.group('offset')
    if stroffset:
        parmoffset = int(stroffset)
    else:
        parmoffset = defoffset

    stroffset2 = args.group('offset2')
    if stroffset2:
        parmoffset2 = int(stroffset2)
    else:
        parmoffset2 = defoffset2

    strheight6 = args.group('height6')
    if strheight6:
        parmheight6 = int(strheight6)
    else:
        parmheight6 = defheight6

    return parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6
        
# FIXME:                          vvvvvv is there a better way for matching a pagename ?
_arg_basepage = r'\s*(?P<basepage>[^, ]+)?\s*'
_arg_year = r',\s*(?P<year>\d+)?\s*'
_arg_month = r',\s*(?P<month>\d+)?\s*'
_arg_offset = r',\s*(?P<offset>[+-]?\d+)?\s*'
_arg_offset2 = r',\s*(?P<offset2>[+-]?\d+)?\s*'
_arg_height6 = r',\s*(?P<height6>[+-]?\d+)?\s*'
_args_re_pattern = r'^(%s)?(%s)?(%s)?(%s)?(%s)?(%s)?$' % \
                   (_arg_basepage,_arg_year,_arg_month, \
		    _arg_offset,_arg_offset2,_arg_height6)


def execute(macro, text):
    _ = macro.request.getText

    # return immediately if getting links for the current page
    if macro.request.mode_getpagelinks:
        return ''

    args_re=re.compile(_args_re_pattern)
    
    currentyear, currentmonth, currentday, h, m, s, wd, yd, ds = time.localtime(time.time())
    thispage = macro.formatter.page.page_name
    # does the url have calendar params (= somebody has clicked on prev/next links in calendar) ?
    if macro.form.has_key('calparms'):
        text2 = macro.form['calparms'].value
        args2 = args_re.match(text2)
        if not args2:
            return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar calparms "%s"!')) % (text2,)
        else:
	    has_calparms = 1 # yes!
	    cparmpagename, cparmyear, cparmmonth, cparmoffset, cparmoffset2, cparmheight6 = \
                parseargs(args2, thispage, currentyear, currentmonth, 0, 0, 0)
    else:
        has_calparms = 0
	
    if text is None: # macro call without parameters
        parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6 = \
	    [thispage], currentyear, currentmonth, 0, 0, 0
    else:
        # parse and check arguments
        args = args_re.match(text)
        if not args:
            return ('<p><strong class="error">%s</strong></p>' % _('Invalid MonthCalendar arguments "%s"!')) % (text,)
        else:
	    parmpagename, parmyear, parmmonth, parmoffset, parmoffset2, parmheight6 = \
	        parseargs(args, thispage, currentyear, currentmonth, 0, 0, 0)

    # does url have calendar params and is THIS the right calendar to modify (we can have multiple
    # calendars on the same page)?
    if has_calparms and (cparmpagename,cparmyear,cparmmonth,cparmoffset) == (parmpagename,parmyear,parmmonth,parmoffset):
        year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset + cparmoffset2)
	parmoffset2 = cparmoffset2
    else:
        year,month = yearmonthplusoffset(parmyear, parmmonth, parmoffset)

    # get the calendar
    monthcal = calendar.monthcalendar(year, month)

    # european / US differences
    months = ('January','February','March','April','May','June','July','August','September','October','November','December')
    # Set things up for Monday or Sunday as the first day of the week
    if calendar.firstweekday() == calendar.MONDAY:
        wkend = (5, 6)
        wkdays = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
    if calendar.firstweekday() == calendar.SUNDAY:
        wkend = (0, 6)
        wkdays = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')

    colorstep = 85
    p = Page(thispage)
    querystr = "calparms=%s,%d,%d,%d,%%d" % (string.join(parmpagename,'*'), parmyear, parmmonth, parmoffset)
    prevlink  = p.url(querystr % (parmoffset2 - 1))
    nextlink  = p.url(querystr % (parmoffset2 + 1))
    prevylink = p.url(querystr % (parmoffset2 - 12))
    nextylink = p.url(querystr % (parmoffset2 + 12))
    prevmonth = macro.formatter.url(prevlink, '&lt;-', 'cal-link')
    nextmonth = macro.formatter.url(nextlink, '-&gt;', 'cal-link')
    prevyear  = macro.formatter.url(prevylink, '&lt;&lt;-', 'cal-link')
    nextyear  = macro.formatter.url(nextylink, '-&gt;&gt;', 'cal-link')
    
    if parmpagename <> [thispage]:
        pagelinks = ''
        r,g,b = (255, 0, 0)
	l = len(parmpagename[0])
        steps = len(parmpagename)
	maxsteps = (255 / colorstep)
	if steps > maxsteps:
	    steps = maxsteps
	chstep = int(l / steps)
	st = 0
	while st < l:
	    ch = parmpagename[0][st:st+chstep]
	    r, g, b = cliprgb(r, g, b)
	    pagelinks = pagelinks + '<a style="%s" href="%s">%s</a>' % \
                ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
                    (r,g,b), Page(parmpagename[0]).url(), ch)
	    r, g, b = (r, g+colorstep, b)
	    st = st + chstep
        r, g, b = (255-colorstep, 255, 255-colorstep)
        for page in parmpagename[1:]:
	    pagelinks = pagelinks + '*<a style="%s" href="%s">%s</a>' % \
	                    ('background-color:#%02x%02x%02x;color:#000000;text-decoration:none' % \
                                (r,g,b), Page(page).url(), page)
        showpagename = '   %s<BR>\n' % pagelinks
    else:
        showpagename = ''
    if calendar.firstweekday() == calendar.SUNDAY:
        resth1 = '  <th colspan="7" class="cal-header">\n' \
                 '%s' \
                 '   %s&nbsp;%s&nbsp;<b>&nbsp;%s&nbsp;%s</b>&nbsp;%s\n&nbsp;%s\n' \
                 '  </th>\n' % (showpagename, prevyear, prevmonth, months[month-1], str(year), nextmonth, nextyear)
    if calendar.firstweekday() == calendar.MONDAY:
        resth1 = '  <th colspan="7" class="cal-header">\n' \
                 '%s' \
	         '   %s&nbsp;%s&nbsp;<b>&nbsp;%s&nbsp;/&nbsp;%s</b>&nbsp;%s\n&nbsp;%s\n' \
                 '  </th>\n' % (showpagename, prevyear, prevmonth, str(year), month, nextmonth, nextyear)
    restr1 = ' <tr>\n%s </tr>\n' % resth1

    r7 = range(7)
    restd2 = []
    for wkday in r7:
        wday = _(wkdays[wkday])
        if wkday in wkend:
            cssday = "cal-weekend"
        else:
            cssday = "cal-workday"
        restd2.append('  <td class="%s" width="14%%">%s</td>\n' % (cssday, wday))
    restr2 = ' <tr>\n%s </tr>\n' % "".join(restd2)
 
    if parmheight6:
        while len(monthcal) < 6:
            monthcal = monthcal + [[0,0,0,0,0,0,0]]
	
    restrn = []
    for week in monthcal:
	restdn = []
        for wkday in r7:
            day = week[wkday]
            if not day:
                restdn.append('  <td class="cal-invalidday">&nbsp;</td>\n')
            else:
	        csslink = "cal-emptyday"
		r, g, b, u = (255, 255, 255, 0)
		page = parmpagename[0]
                link = "%s/%4d-%02d-%02d" % (page, year, month, day)
	        daypage = Page(link)
	        if daypage.exists():
    	            csslink = "cal-usedday"
		    r, g, b, u = (255, 0, 0, 1)
		else:
                    if wkday in wkend:
                        csslink = "cal-weekend"
                for otherpage in parmpagename[1:]:
                    otherlink = "%s/%4d-%02d-%02d" % (otherpage, year, month, day)
	            otherdaypage = Page(otherlink)
	            if otherdaypage.exists():
    	                csslink = "cal-usedday"
			if u == 0:
			    r, g, b = (r-colorstep, g, b-colorstep)
			else:
			    r, g, b = (r, g+colorstep, b)
		r, g, b = cliprgb(r, g, b)
		style = 'background-color:#%02x%02x%02x' % (r, g, b)
	        fmtlink = macro.formatter.url(daypage.url(), str(day), csslink)
	        if day == currentday and month == currentmonth and year == currentyear:
	            cssday = "cal-today"
                    fmtlink = "<b>%s</b>" % fmtlink # for browser with CSS probs
		else:
		    cssday = "cal-nottoday"
	        restdn.append('  <td style="%s" class="%s">%s</td>\n' % (style, cssday, fmtlink))
        restrn.append(' <tr>\n%s </tr>\n' % "".join(restdn))

    restable = '<table border="2" cellspacing="2" cellpadding="2">\n%s%s%s</table>\n'
    result = restable % (restr1, restr2, "".join(restrn))
    return macro.formatter.rawHTML(result)

# EOF