WikiCalendarMacro: WikiCalendar.py

File WikiCalendar.py, 6.8 kB (added by alexander.klimetschek@hpi.uni-potsdam.de, 3 years ago)

Another Calendar with more configuration and links to milestones

Line 
1 # Copyright (C) 2005 Matthew Good <trac@matt-good.net>
2 # Copyright (C) 2005 Jan Finell <finell@cenix-bioscience.com>
3 #
4 # "THE BEER-WARE LICENSE" (Revision 42):
5 # <trac@matt-good.net> wrote this file.  As long as you retain this notice you
6 # can do whatever you want with this stuff.  If we meet some day, and you think
7 # this stuff is worth it, you can buy me a beer in return.  Matthew Good
8 # (Beer-ware license written by Poul-Henning Kamp
9 #  http://people.freebsd.org/~phk/)
10 #
11 # Author: Matthew Good <trac@matt-good.net>
12 # Month/Year navigation by: Jan Finell <finell@cenix-bioscience.com>
13
14 import time
15 import calendar
16 from cStringIO import StringIO
17 from trac.wiki.api import WikiSystem
18 from trac.util import *
19
20 # format:
21 #   WikiCalendar([year,month,[showbuttons,[wiki_page_format]]])
22 #
23 #   displays a calendar, the days link to:
24 #     - milestones (day in bold) if there is one on that day
25 #     - a wiki page that has wiki_page_format (if exist)
26 #     - create that wiki page if it does not exist
27 #
28 # arguments:
29 #   year, month = display calendar for month in year ('*' for current year/month)
30 #   showbuttons = true/false, show prev/next buttons
31 #   wiki_page_format = strftime format for wiki pages to display as link
32 #                      (if there is not a milestone placed on that day)
33 #                      (if exist, otherwise link to create page)
34 #                      default is "%Y-%m-%d"
35 #
36 # examples:
37 #     WikiCalendar(2006,07)
38 #     WikiCalendar(2006,07,false)
39 #     WikiCalendar(*,*,true,Meeting-%Y-%m-%d)
40 #     WikiCalendar(2006,07,false,Meeting-%Y-%m-%d)
41
42 def execute(hdf, txt, env):
43     today = time.localtime()
44     http_param_year = hdf.getValue("args.year", "")
45     http_param_month = hdf.getValue("args.month", "")
46     if txt == "":
47         args = []
48     else:
49         args = txt.split(',', 3)
50    
51     # find out whether use http param, current or macro param year/month
52    
53     if http_param_year == "":
54         # not clicked on a prev or next button
55         if len(args) >= 1 and args[0] <> "*":
56             # year given in macro parameters
57             year = int(args[0])
58         else:
59             # use current year
60             year = today.tm_year
61     else:
62         # year in http params (clicked by user) overrides everything
63         year = int(http_param_year)
64    
65     if http_param_month == "":
66         # not clicked on a prev or next button
67         if len(args) >= 2 and args[1] <> "*":
68             # month given in macro parameters
69             month = int(args[1])
70         else:
71             # use current month
72             month = today.tm_mon
73     else:
74         # month in http params (clicked by user) overrides everything
75         month = int(http_param_month)
76    
77     showbuttons = 1
78     if len(args) >= 3:
79         showbuttons = bool(args[2]=="True" or args[2]=="true" or args[2]=="no" or args[2]=="0")
80        
81     wiki_page_format = "%Y-%m-%d"
82     if len(args) >= 4:
83         wiki_page_format = args[3]
84    
85     curr_day = None
86     if year == today.tm_year and month == today.tm_mon:
87         curr_day = today.tm_mday
88
89     # Can use this to change the day the week starts on, but this
90     # is a system-wide setting
91     #calendar.setfirstweekday(calendar.SUNDAY)
92     cal = calendar.monthcalendar(year, month)
93
94
95     date = [year, month] + [1] * 7
96
97     # url to the current page (used in the navigation links)
98     thispageURL = env.href.wiki(hdf.getValue('wiki.page_name', ''))
99     # for the prev/next navigation links
100     prevMonth = month-1
101     prevYear  = year
102     nextMonth = month+1
103     nextYear  = year
104     # check for year change (KISS version)
105     if prevMonth == 0:
106         prevMonth = 12
107         prevYear -= 1
108     if nextMonth == 13:
109         nextMonth = 1
110         nextYear += 1
111
112     # building the output
113     buff = StringIO()
114     buff.write('<table><caption>')
115
116     if showbuttons:
117         # prev month link
118         prevMonthURL = thispageURL+'?month=%d&year=%d' % (prevMonth, prevYear)
119         buff.write('<a href="%s">&lt; </a>' % prevMonthURL)
120        
121     # the caption
122     buff.write(time.strftime('%B %Y', tuple(date)))
123    
124     if showbuttons:
125         # next month link
126         nextMonthURL = thispageURL+'?month=%d&year=%d' % (nextMonth, nextYear)
127         buff.write('<a href="%s"> &gt;</a>' % nextMonthURL)
128        
129     buff.write('</caption>\n<thead><tr align="center">')
130    
131     for day in calendar.weekheader(2).split():
132         buff.write('<th scope="col"><b>%s</b></th>' % day)
133     buff.write('</tr></thead>\n<tbody>\n')
134
135     for row in cal:
136         buff.write('<tr align="right">')
137         for day in row:
138             if not day:
139                 buff.write('<td>&nbsp;</td>')
140             else:
141                 # first check for milestone on that day
142                 db = env.get_db_cnx()
143                 cursor = db.cursor()
144                 duedate = parse_date(str(day) + "." + str(month) + "." + str(year))
145                 cursor.execute("SELECT name,due FROM milestone WHERE due=%s", (duedate,))
146                 row = cursor.fetchone()
147                 if row:
148                     # found a milestone
149                     milestone_name = row[0]
150                     url = env.href.milestone(milestone_name)
151                     buff.write('<td%(style)s><b><a href="%(url)s" alt="%(alt)s">%(day)s</a></b></td>' % {
152                             'url': url,
153                             'alt': milestone_name,
154                             'day': day,
155                             'style': day == curr_day and ' style="border: 1px solid #b00;"' or '',
156                             })
157                 else:
158                     # secondly check for wikipage with name specified in 'wiki_page_format'
159                     date[2] = day
160                     wiki = time.strftime(wiki_page_format, tuple(date))
161                     url = env.href.wiki(wiki)
162                     if WikiSystem(env).has_page(wiki):
163                         buff.write('<td%(style)s><a href="%(url)s">%(day)s</a></td>' % {
164                             'url': url,
165                             'day': day,
166                             'style': day == curr_day and ' style="border: 1px solid #b00;"' or '',
167                             })
168                     # just display the date
169                     else:
170                         url += "?action=edit"
171                         buff.write('<td%(style)s><a href="%(url)s" class="missing">%(day)s</a></td>' % {
172                             'url': url,
173                             'day': day,
174                             'style': day == curr_day and ' style="border: 1px solid #b00;"' or '',
175                             })
176
177         buff.write('</tr>\n')
178
179     buff.write('</tbody>\n</table>')
180            
181     table = buff.getvalue()
182     buff.close()
183     return table