1 ###########################################################
2 ## EventsList.py
3 ## MoinMoin - EventsList macro
4 ##
5 ## Version 0.8, 6-Mar-2001
6 ##
7 ## About:
8 ## Inserts an HTML list of events in a page where
9 ## information about the events is extracted by parsing
10 ## another wiki page.
11 ##
12 ## Requirements:
13 ## Just MoinMoin (tested with Release 0.8 [Revision 1.108])
14 ##
15 ## Usage:
16 ##
17 ## [[EventsList(pagename,filter)]]
18 ##
19 ## pagename - name of a wiki page that contains info about
20 ## events
21 ## filter - 'all' or 'today' (optional: default is today)
22 ##
23 ## Examples:
24 ## [[EventsList(OurEvents)]]
25 ## [[EventsList(OurEvents,all)]]
26 ##
27 ## The format in which events need to be written
28 ## in a wiki page such that it can be grokked
29 ## is identified by the regular expressions in
30 ## the list below called defaultEventRecogRegexps.
31 ##
32 ## The following examples will work with the
33 ## current expressions:
34 ##
35 ## 11-Jan-2001 - release - our 2.0 version release
36 ## 11-Jan-2001 release our 2.0 version release
37 ## || 11-Jan-2001 || release || our 2.0 version release ||
38 ##
39 ## Each of the above examples describes an event for
40 ## date 11-Jan-2001 with event_name='release' and
41 ## event_description='our 2.0 version release'
42 ##
43 ## ToDo:
44 ## - Support many more event formats
45 ## - Put event date when all events list is generated
46 ## - Collect events from multiple wiki pages
47 ## - Generate nice-looking calendar
48 ## - Powerful filtering types
49 ## - events for week
50 ## - events for month
51 ## - events for year
52 ## - events within a specified range
53 ## - Differnt types of events?
54 ## - events with duration
55 ## - recurring events
56 ##
57 ## Copyright (c) 2001, Shalabh Chaturvedi
58 ##
59 ## Permission is hereby granted, free of charge, to any
60 ## person obtaining a copy of this software and associated
61 ## documentation files (the "Software"), to deal in the
62 ## Software without restriction, including without
63 ## limitation the rights to use, copy, modify, merge,
64 ## publish, distribute, sublicense, and/or sell copies of
65 ## the Software, and to permit persons to whom the Software
66 ## is furnished to do so, subject to the following
67 ## conditions:
68 ##
69 ## The above copyright notice and this permission notice
70 ## shall be included in all copies or substantial portions
71 ## of the Software.
72 ##
73 ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
74 ## KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
75 ## THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
76 ## PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
77 ## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
78 ## DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
79 ## CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
80 ## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
81 ## IN THE SOFTWARE.
82 ##
83 ###########################################################
84
85
86 import sys, string, re, cStringIO, time
87 from MoinMoin.Page import Page
88
89 defaultEventRecogRegexps = [r'(?P<day>[ 0123]{0,1}[0-9])-(?P<mon>[A-Za-z][a-z][a-z])-(?P<year>[0-9][0-9][0-9][0-9])\s*\|\|\s*(?P<name>\S+)\s*\|\|\s*(?P<description>.*?)\s*\|\|\s*',
90 r'(?P<day>[ 0123]{0,1}[0-9])-(?P<mon>[A-Za-z][a-z][a-z])-(?P<year>[0-9][0-9][0-9][0-9])[\s\W]*(?P<name>\S+)[\s\W]*(?P<description>.*)$']
91
92 monthnames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
93
94 class FileToEventsGenerator:
95 def __init__(self, file, eventRecogRegexps = defaultEventRecogRegexps):
96 self.file = file
97 self.events = {}
98 self.regexps = map(re.compile, eventRecogRegexps)
99 self.parsefile(file)
100
101 def parsefile(self,file):
102 lines = file.readlines()
103 for line in lines:
104 for r in self.regexps:
105 res = r.search(line)
106 event = {}
107 if res:
108 datemap = res.groupdict()
109 (year, month, day) = (0,0,0)
110 try:
111 event['name'] = res.group('name')
112 if datemap.has_key('description'):
113 event['description'] = datemap['description']
114 if datemap.has_key('mon'):
115 mm = monthnames.index(datemap['mon'])+1
116 (year, month, day) = (int(datemap['year']), mm, int(datemap['day']))
117 elif datemap.has_key('mm'):
118 (year, month, day) = (int(datemap['year']), int(datemap['mm']), int(datemap['day']))
119 except IndexError:
120 continue #dont create the event
121
122 date = event['date'] = (year, month, day)
123 event['datestring'] = "%s-%s-%s" % (day,monthnames[month-1],year)
124 if not self.events.has_key(date):
125 self.events[date] = []
126 self.events[date].append(event)
127 break
128
129 def getEvents(self, date):
130 "returns list of events for date where date is a tuple (year, month, day)"
131 if self.events.has_key(date):
132 return self.events[date]
133 else:
134 return []
135
136 def getTodaysEvents(self):
137 date = time.localtime(time.time())[:3]
138 return self.getEvents(date)
139
140 def getAllEvents(self):
141 l = []
142 for e in self.events.values():
143 l.extend(e)
144 return l
145
146
147 _args_re = r'\s*(?P<pagename>\w+)(,(?P<type>\w+)){0,1}'
148 _args_re = re.compile(_args_re)
149
150 def execute(macro, text):
151 ret = ''
152
153 res = _args_re.match(text).groupdict()
154
155 pagename = res['pagename']
156
157 if (not res.has_key('type')) or res['type'] is None:
158 res['type'] = 'today'
159
160 page = Page(pagename)
161
162 s = cStringIO.StringIO(page.get_raw_body())
163 events = FileToEventsGenerator(s)
164
165 eventslist = []
166 if res['type'] == 'today':
167 eventslist = events.getTodaysEvents()
168 elif res['type'] == 'all':
169 eventslist = events.getAllEvents()
170
171 ret = ret + macro.formatter.bullet_list(1)
172 for event in eventslist:
173 ret = ret + macro.formatter.listitem(1)
174 ret = ret + macro.formatter.strong(1) + macro.formatter.text(event['name']) + macro.formatter.strong(0)
175 ret = ret + macro.formatter.text(' ' + event['description'])
176 ret = ret + macro.formatter.listitem(0)
177 ret = ret + macro.formatter.bullet_list(0)
178
179 return ret