1.1 --- a/EventAggregatorSupport.py Thu Jan 28 23:57:15 2010 +0100
1.2 +++ b/EventAggregatorSupport.py Fri Jan 29 01:05:53 2010 +0100
1.3 @@ -16,6 +16,11 @@
1.4 import time
1.5 import re
1.6
1.7 +try:
1.8 + set
1.9 +except NameError:
1.10 + from sets import Set as set
1.11 +
1.12 __version__ = "0.5"
1.13
1.14 # Date labels.
1.15 @@ -190,23 +195,10 @@
1.16
1.17 def __init__(self, page):
1.18 self.page = page
1.19 - self.details = None
1.20 + self.events = None
1.21 self.body = None
1.22 self.categories = None
1.23
1.24 - def __cmp__(self, other):
1.25 -
1.26 - """
1.27 - Compare this object with 'other' using the event start and end details.
1.28 - """
1.29 -
1.30 - event_details1 = self.getEventDetails()
1.31 - event_details2 = other.getEventDetails()
1.32 - return cmp(
1.33 - (event_details1["start"], event_details1["end"]),
1.34 - (event_details2["start"], event_details2["end"])
1.35 - )
1.36 -
1.37 def copyPage(self, page):
1.38
1.39 "Copy the body of the given 'page'."
1.40 @@ -265,12 +257,13 @@
1.41 self.body = self.page.get_raw_body()
1.42 return self.body
1.43
1.44 - def getEventDetails(self):
1.45 + def getEvents(self):
1.46 +
1.47 + "Return a list of events from this page."
1.48
1.49 - "Return a dictionary of event details from this page."
1.50 -
1.51 - if self.details is None:
1.52 - self.details = {}
1.53 + if self.events is None:
1.54 + details = {}
1.55 + self.events = [Event(self, details)]
1.56
1.57 if self.getFormat() == "wiki":
1.58 for match in definition_list_regexp.finditer(self.getBody()):
1.59 @@ -303,9 +296,23 @@
1.60 desc = getSimpleWikiText(desc)
1.61
1.62 if desc is not None:
1.63 - self.details[term] = desc
1.64 +
1.65 + # Handle apparent duplicates by creating a new set of
1.66 + # details.
1.67 +
1.68 + if details.has_key(term):
1.69 + details = {}
1.70 + self.events.append(Event(self, details))
1.71
1.72 - return self.details
1.73 + details[term] = desc
1.74 +
1.75 + return self.events
1.76 +
1.77 + def setEvents(self, events):
1.78 +
1.79 + "Set the given 'events' on this page."
1.80 +
1.81 + self.events = events
1.82
1.83 def getCategoryMembership(self):
1.84
1.85 @@ -318,40 +325,6 @@
1.86
1.87 return self.categories
1.88
1.89 - def getEventSummary(self, event_parent=None):
1.90 -
1.91 - """
1.92 - Return either the given title or summary of the event described by this
1.93 - page, according to the page's event details, or using the pretty version
1.94 - of the page name.
1.95 -
1.96 - If the optional 'event_parent' is specified, any page beneath the given
1.97 - 'event_parent' page in the page hierarchy will omit this parent information
1.98 - if its name is used as the summary.
1.99 - """
1.100 -
1.101 - event_details = self.getEventDetails()
1.102 -
1.103 - if event_details.has_key("title"):
1.104 - return event_details["title"]
1.105 - elif event_details.has_key("summary"):
1.106 - return event_details["summary"]
1.107 - else:
1.108 - # If appropriate, remove the parent details and "/" character.
1.109 -
1.110 - title = self.getPageName()
1.111 -
1.112 - if event_parent is not None and title.startswith(event_parent):
1.113 - title = title[len(event_parent.rstrip("/")) + 1:]
1.114 -
1.115 - return getPrettyTitle(title)
1.116 -
1.117 - def setEventDetails(self, event_details):
1.118 -
1.119 - "Set the 'event_details' for this page."
1.120 -
1.121 - self.details = event_details
1.122 -
1.123 def setCategoryMembership(self, category_names):
1.124
1.125 """
1.126 @@ -368,14 +341,18 @@
1.127 new_body_parts = []
1.128 end_of_last_match = 0
1.129 body = self.getBody()
1.130 - event_details = self.getEventDetails()
1.131 +
1.132 + events = iter(self.getEvents())
1.133 +
1.134 + event = events.next()
1.135 + event_details = event.getDetails()
1.136 + replaced_terms = set()
1.137
1.138 for match in definition_list_regexp.finditer(body):
1.139
1.140 # Add preceding text to the new body.
1.141
1.142 new_body_parts.append(body[end_of_last_match:match.start()])
1.143 - end_of_last_match = match.end()
1.144
1.145 # Get the matching regions, adding the term to the new body.
1.146
1.147 @@ -386,6 +363,21 @@
1.148 term = match.group("term").lower()
1.149 desc = match.group("desc")
1.150
1.151 + # Check that the term has not already been substituted. If so,
1.152 + # get the next event.
1.153 +
1.154 + if term in replaced_terms:
1.155 + try:
1.156 + event = events.next()
1.157 +
1.158 + # No more events.
1.159 +
1.160 + except StopIteration:
1.161 + break
1.162 +
1.163 + event_details = event.getDetails()
1.164 + replaced_terms = set()
1.165 +
1.166 # Special value type handling.
1.167
1.168 if event_details.has_key(term):
1.169 @@ -410,10 +402,17 @@
1.170 elif term in ("description",):
1.171 desc = event_details[term]
1.172
1.173 + replaced_terms.add(term)
1.174 +
1.175 new_body_parts.append(desc)
1.176
1.177 - else:
1.178 - new_body_parts.append(body[end_of_last_match:])
1.179 + # Remember where in the page has been processed.
1.180 +
1.181 + end_of_last_match = match.end()
1.182 +
1.183 + # Write the rest of the page.
1.184 +
1.185 + new_body_parts.append(body[end_of_last_match:])
1.186
1.187 self.body = "".join(new_body_parts)
1.188
1.189 @@ -445,6 +444,79 @@
1.190
1.191 return linkToPage(request, self.page, text, query_string)
1.192
1.193 +class Event:
1.194 +
1.195 + "A description of an event."
1.196 +
1.197 + def __init__(self, page, details):
1.198 + self.page = page
1.199 + self.details = details
1.200 +
1.201 + def __cmp__(self, other):
1.202 +
1.203 + """
1.204 + Compare this object with 'other' using the event start and end details.
1.205 + """
1.206 +
1.207 + details1 = self.details
1.208 + details2 = other.details
1.209 + return cmp(
1.210 + (details1["start"], details1["end"]),
1.211 + (details2["start"], details2["end"])
1.212 + )
1.213 +
1.214 + def getPage(self):
1.215 +
1.216 + "Return the page describing this event."
1.217 +
1.218 + return self.page
1.219 +
1.220 + def setPage(self, page):
1.221 +
1.222 + "Set the 'page' describing this event."
1.223 +
1.224 + self.page = page
1.225 +
1.226 + def getSummary(self, event_parent=None):
1.227 +
1.228 + """
1.229 + Return either the given title or summary of the event according to the
1.230 + event details, or a summary made from using the pretty version of the
1.231 + page name.
1.232 +
1.233 + If the optional 'event_parent' is specified, any page beneath the given
1.234 + 'event_parent' page in the page hierarchy will omit this parent information
1.235 + if its name is used as the summary.
1.236 + """
1.237 +
1.238 + event_details = self.details
1.239 +
1.240 + if event_details.has_key("title"):
1.241 + return event_details["title"]
1.242 + elif event_details.has_key("summary"):
1.243 + return event_details["summary"]
1.244 + else:
1.245 + # If appropriate, remove the parent details and "/" character.
1.246 +
1.247 + title = self.page.getPageName()
1.248 +
1.249 + if event_parent is not None and title.startswith(event_parent):
1.250 + title = title[len(event_parent.rstrip("/")) + 1:]
1.251 +
1.252 + return getPrettyTitle(title)
1.253 +
1.254 + def getDetails(self):
1.255 +
1.256 + "Return the details for this event."
1.257 +
1.258 + return self.details
1.259 +
1.260 + def setDetails(self, event_details):
1.261 +
1.262 + "Set the 'event_details' for this event."
1.263 +
1.264 + self.details = event_details
1.265 +
1.266 def getEvents(request, category_names, calendar_start=None, calendar_end=None):
1.267
1.268 """
1.269 @@ -493,41 +565,45 @@
1.270 # Get a real page, not a result page.
1.271
1.272 event_page = EventPage(Page(request, pagename))
1.273 - event_details = event_page.getEventDetails()
1.274
1.275 - # Remember the event page.
1.276 + # Get all events described in the page.
1.277
1.278 - events.append(event_page)
1.279 + for event in event_page.getEvents():
1.280 + event_details = event.getDetails()
1.281
1.282 - # Test for the suitability of the event.
1.283 + # Remember the event.
1.284 +
1.285 + events.append(event)
1.286
1.287 - if event_details.has_key("start") and event_details.has_key("end"):
1.288 + # Test for the suitability of the event.
1.289 +
1.290 + if event_details.has_key("start") and event_details.has_key("end"):
1.291
1.292 - start_month = event_details["start"].as_month()
1.293 - end_month = event_details["end"].as_month()
1.294 + start_month = event_details["start"].as_month()
1.295 + end_month = event_details["end"].as_month()
1.296
1.297 - # Compare the months of the dates to the requested calendar
1.298 - # window, if any.
1.299 + # Compare the months of the dates to the requested calendar
1.300 + # window, if any.
1.301
1.302 - if (calendar_start is None or end_month >= calendar_start) and \
1.303 - (calendar_end is None or start_month <= calendar_end):
1.304 + if (calendar_start is None or end_month >= calendar_start) and \
1.305 + (calendar_end is None or start_month <= calendar_end):
1.306
1.307 - all_shown_events.append(event_page)
1.308 + all_shown_events.append(event)
1.309
1.310 - if earliest is None or start_month < earliest:
1.311 - earliest = start_month
1.312 - if latest is None or end_month > latest:
1.313 - latest = end_month
1.314 + if earliest is None or start_month < earliest:
1.315 + earliest = start_month
1.316 + if latest is None or end_month > latest:
1.317 + latest = end_month
1.318
1.319 - # Store the event in the month-specific dictionary.
1.320 + # Store the event in the month-specific dictionary.
1.321
1.322 - first = max(start_month, calendar_start or start_month)
1.323 - last = min(end_month, calendar_end or end_month)
1.324 + first = max(start_month, calendar_start or start_month)
1.325 + last = min(end_month, calendar_end or end_month)
1.326
1.327 - for event_month in first.months_until(last):
1.328 - if not shown_events.has_key(event_month):
1.329 - shown_events[event_month] = []
1.330 - shown_events[event_month].append(event_page)
1.331 + for event_month in first.months_until(last):
1.332 + if not shown_events.has_key(event_month):
1.333 + shown_events[event_month] = []
1.334 + shown_events[event_month].append(event)
1.335
1.336 return events, shown_events, all_shown_events, earliest, latest
1.337
1.338 @@ -542,8 +618,9 @@
1.339
1.340 latest = None
1.341
1.342 - for event_page in events:
1.343 - event_details = event_page.getEventDetails()
1.344 + for event in events:
1.345 + event_details = event.getDetails()
1.346 + event_page = event.getPage()
1.347
1.348 # Get the initial revision of the page.
1.349
1.350 @@ -620,8 +697,8 @@
1.351
1.352 # Get event details.
1.353
1.354 - for event_page in events:
1.355 - event_details = event_page.getEventDetails()
1.356 + for event in events:
1.357 + event_details = event.getDetails()
1.358
1.359 # Test for the event in the period.
1.360
1.361 @@ -645,7 +722,7 @@
1.362 # element, add it alongside existing events.
1.363
1.364 if not coverage.intersection(event_coverage):
1.365 - covered_events.append(event_page)
1.366 + covered_events.append(event)
1.367 all_events[i] = coverage.union(event_coverage), covered_events
1.368 break
1.369
1.370 @@ -653,7 +730,7 @@
1.371 # marked alongside existing events.
1.372
1.373 else:
1.374 - all_events.append((event_coverage, [event_page]))
1.375 + all_events.append((event_coverage, [event]))
1.376
1.377 return full_coverage, all_events
1.378