1.1 --- a/macros/EventAggregator.py Sun Mar 22 22:46:53 2009 +0100
1.2 +++ b/macros/EventAggregator.py Mon Mar 23 01:52:13 2009 +0100
1.3 @@ -8,150 +8,23 @@
1.4 @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.5 """
1.6
1.7 -from MoinMoin.Page import Page
1.8 -from MoinMoin import wikiutil, search, version
1.9 +from MoinMoin import wikiutil
1.10 +import EventAggregatorSupport
1.11 import calendar
1.12 -import re
1.13
1.14 try:
1.15 set
1.16 except NameError:
1.17 from sets import Set as set
1.18
1.19 -__version__ = "0.1"
1.20 -
1.21 Dependencies = ['pages']
1.22
1.23 -# Regular expressions where MoinMoin does not provide the required support.
1.24 -
1.25 -category_regexp = None
1.26 -definition_list_regexp = re.compile(ur'^\s+(?P<term>.*?)::\s(?P<desc>.*?)$', re.UNICODE | re.MULTILINE)
1.27 -date_regexp = re.compile(ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})-(?P<day>[0-9]{2})', re.UNICODE)
1.28 -month_regexp = re.compile(ur'(?P<year>[0-9]{4})-(?P<month>[0-9]{2})', re.UNICODE)
1.29 -
1.30 # Date labels.
1.31
1.32 month_labels = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
1.33 weekday_labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
1.34
1.35 -# Utility functions.
1.36 -
1.37 -def isMoin15():
1.38 - return version.release.startswith("1.5.")
1.39 -
1.40 -def getCategoryPattern(request):
1.41 - global category_regexp
1.42 -
1.43 - try:
1.44 - return request.cfg.cache.page_category_regexact
1.45 - except AttributeError:
1.46 -
1.47 - # Use regular expression from MoinMoin 1.7.1 otherwise.
1.48 -
1.49 - if category_regexp is None:
1.50 - category_regexp = re.compile(u'^%s$' % ur'(?P<all>Category(?P<key>(?!Template)\S+))', re.UNICODE)
1.51 - return category_regexp
1.52 -
1.53 -# The main activity functions.
1.54 -
1.55 -def getPages(pagename, request):
1.56 -
1.57 - "Return the links minus category links for 'pagename' using the 'request'."
1.58 -
1.59 - query = search.QueryParser().parse_query('category:%s' % pagename)
1.60 - if isMoin15():
1.61 - results = search.searchPages(request, query)
1.62 - results.sortByPagename()
1.63 - else:
1.64 - results = search.searchPages(request, query, "page_name")
1.65 -
1.66 - cat_pattern = getCategoryPattern(request)
1.67 - pages = []
1.68 - for page in results.hits:
1.69 - if not cat_pattern.match(page.page_name):
1.70 - pages.append(page)
1.71 - return pages
1.72 -
1.73 -def getPrettyPageName(page):
1.74 -
1.75 - "Return a nicely formatted title/name for the given 'page'."
1.76 -
1.77 - return page.split_title(force=1).replace("_", " ").replace("/", u" » ")
1.78 -
1.79 -def getEventDetails(page):
1.80 -
1.81 - "Return a dictionary of event details from the given 'page'."
1.82 -
1.83 - event_details = {}
1.84 -
1.85 - if page.pi["format"] == "wiki":
1.86 - for match in definition_list_regexp.finditer(page.body):
1.87 - # Permit case-insensitive list terms.
1.88 - term = match.group("term").lower()
1.89 - desc = match.group("desc")
1.90 - if term in ("start", "end"):
1.91 - desc = getDate(desc)
1.92 - if desc is not None:
1.93 - event_details[term] = desc
1.94 -
1.95 - return event_details
1.96 -
1.97 -def getDate(s):
1.98 -
1.99 - "Parse the string 's', extracting and returning a date string."
1.100 -
1.101 - m = date_regexp.search(s)
1.102 - if m:
1.103 - return tuple(map(int, m.groups()))
1.104 - else:
1.105 - return None
1.106 -
1.107 -def getMonth(s):
1.108 -
1.109 - "Parse the string 's', extracting and returning a month string."
1.110 -
1.111 - m = month_regexp.search(s)
1.112 - if m:
1.113 - return tuple(map(int, m.groups()))
1.114 - else:
1.115 - return None
1.116 -
1.117 -def daterange(first, last):
1.118 - results = []
1.119 -
1.120 - months_only = len(first) == 2
1.121 - start_year = first[0]
1.122 - end_year = last[0]
1.123 -
1.124 - for year in range(start_year, end_year + 1):
1.125 - if year < end_year:
1.126 - end_month = 12
1.127 - else:
1.128 - end_month = last[1]
1.129 -
1.130 - if year > start_year:
1.131 - start_month = 1
1.132 - else:
1.133 - start_month = first[1]
1.134 -
1.135 - for month in range(start_month, end_month + 1):
1.136 - if months_only:
1.137 - results.append((year, month))
1.138 - else:
1.139 - if month < end_month:
1.140 - _wd, end_day = calendar.monthrange(year, month)
1.141 - else:
1.142 - end_day = last[2]
1.143 -
1.144 - if month > start_month:
1.145 - start_day = 1
1.146 - else:
1.147 - start_day = first[2]
1.148 -
1.149 - for day in range(start_day, end_day + 1):
1.150 - results.append((year, month, day))
1.151 -
1.152 - return results
1.153 +# HTML-related functions.
1.154
1.155 def getColour(s):
1.156 colour = [0, 0, 0]
1.157 @@ -169,6 +42,8 @@
1.158 else:
1.159 return (255, 255, 255)
1.160
1.161 +# Macro function.
1.162 +
1.163 def execute(macro, args):
1.164
1.165 """
1.166 @@ -211,9 +86,9 @@
1.167
1.168 for arg in parsed_args:
1.169 if arg.startswith("start="):
1.170 - calendar_start = getMonth(arg[6:])
1.171 + calendar_start = EventAggregatorSupport.getMonth(arg[6:])
1.172 elif arg.startswith("end="):
1.173 - calendar_end = getMonth(arg[4:])
1.174 + calendar_end = EventAggregatorSupport.getMonth(arg[4:])
1.175 elif arg.startswith("mode="):
1.176 mode = arg[5:]
1.177 elif arg.startswith("names="):
1.178 @@ -221,65 +96,8 @@
1.179 else:
1.180 category_names.append(arg)
1.181
1.182 - # Generate a list of events found on pages belonging to the specified
1.183 - # categories, as found in the macro arguments.
1.184 -
1.185 - events = []
1.186 - shown_events = {}
1.187 - all_shown_events = []
1.188 -
1.189 - earliest = None
1.190 - latest = None
1.191 -
1.192 - for category_name in category_names:
1.193 -
1.194 - # Get the pages and page names in the category.
1.195 -
1.196 - pages_in_category = getPages(category_name, request)
1.197 -
1.198 - # Visit each page in the category.
1.199 -
1.200 - for page_in_category in pages_in_category:
1.201 - pagename = page_in_category.page_name
1.202 -
1.203 - # Get a real page, not a result page.
1.204 -
1.205 - real_page_in_category = Page(request, pagename)
1.206 - event_details = getEventDetails(real_page_in_category)
1.207 -
1.208 - # Define the event as the page together with its details.
1.209 -
1.210 - event = (real_page_in_category, event_details)
1.211 - events.append(event)
1.212 -
1.213 - # Test for the suitability of the event.
1.214 -
1.215 - if event_details.has_key("start") and event_details.has_key("end"):
1.216 -
1.217 - start_month = event_details["start"][:2]
1.218 - end_month = event_details["end"][:2]
1.219 -
1.220 - # Compare the months of the dates to the requested calendar
1.221 - # window, if any.
1.222 -
1.223 - if (calendar_start is None or end_month >= calendar_start) and \
1.224 - (calendar_end is None or start_month <= calendar_end):
1.225 -
1.226 - if earliest is None or start_month < earliest:
1.227 - earliest = start_month
1.228 - if latest is None or end_month > latest:
1.229 - latest = end_month
1.230 -
1.231 - # Store the event in the month-specific dictionary.
1.232 -
1.233 - first = max(start_month, calendar_start or start_month)
1.234 - last = min(end_month, calendar_end or end_month)
1.235 -
1.236 - for event_month in daterange(first, last):
1.237 - if not shown_events.has_key(event_month):
1.238 - shown_events[event_month] = []
1.239 - shown_events[event_month].append(event)
1.240 - all_shown_events.append(event)
1.241 + events, shown_events, all_shown_events, earliest, latest = \
1.242 + EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end)
1.243
1.244 # Make a calendar.
1.245
1.246 @@ -295,7 +113,7 @@
1.247 first = calendar_start or earliest
1.248 last = calendar_end or latest
1.249
1.250 - for year, month in daterange(first, last):
1.251 + for year, month in EventAggregatorSupport.daterange(first, last):
1.252
1.253 # Either output a calendar view...
1.254
1.255 @@ -363,7 +181,7 @@
1.256
1.257 event_start = max(event_details["start"], week_start)
1.258 event_end = min(event_details["end"], week_end)
1.259 - event_coverage = set(daterange(event_start, event_end))
1.260 + event_coverage = set(EventAggregatorSupport.daterange(event_start, event_end))
1.261
1.262 # Update the overall coverage.
1.263
1.264 @@ -482,7 +300,7 @@
1.265
1.266 # Get a pretty version of the page name.
1.267
1.268 - pretty_pagename = getPrettyPageName(event_page)
1.269 + pretty_pagename = EventAggregatorSupport.getPrettyPageName(event_page)
1.270
1.271 # Generate a colour for the event.
1.272
1.273 @@ -552,7 +370,7 @@
1.274
1.275 # Get a pretty version of the page name.
1.276
1.277 - pretty_pagename = getPrettyPageName(event_page)
1.278 + pretty_pagename = EventAggregatorSupport.getPrettyPageName(event_page)
1.279
1.280 output.append(fmt.listitem(on=1, attr={"class" : "event-listing"}))
1.281
1.282 @@ -579,46 +397,9 @@
1.283
1.284 # Output top-level information.
1.285
1.286 - # Output iCalendar data...
1.287 -
1.288 - if mode == "ics":
1.289 -
1.290 - # Output the calendar details as preformatted text.
1.291 -
1.292 - output.append(fmt.preformatted(on=1))
1.293 - output.append(fmt.text("BEGIN:VCALENDAR"))
1.294 - output.append(fmt.linebreak())
1.295 - output.append(fmt.text("VERSION:1.0"))
1.296 - output.append(fmt.linebreak())
1.297 -
1.298 - for event_page, event_details in all_shown_events:
1.299 -
1.300 - # Get a pretty version of the page name.
1.301 -
1.302 - pretty_pagename = getPrettyPageName(event_page)
1.303 -
1.304 - # Output the event details.
1.305 -
1.306 - output.append(fmt.text("BEGIN:VEVENT"))
1.307 - output.append(fmt.linebreak())
1.308 - output.append(fmt.text("SUMMARY:%s" % pretty_pagename))
1.309 - output.append(fmt.linebreak())
1.310 - output.append(fmt.text("URL:%s" % request.getQualifiedURL(event_page.url(request))))
1.311 - output.append(fmt.linebreak())
1.312 - output.append(fmt.text("DTSTART:%04d%02d%02d" % event_details["start"]))
1.313 - output.append(fmt.linebreak())
1.314 - output.append(fmt.text("DTEND:%04d%02d%02d" % event_details["end"]))
1.315 - output.append(fmt.linebreak())
1.316 - output.append(fmt.text("END:VEVENT"))
1.317 - output.append(fmt.linebreak())
1.318 -
1.319 - output.append(fmt.text("END:VCALENDAR"))
1.320 - output.append(fmt.linebreak())
1.321 - output.append(fmt.preformatted(on=0))
1.322 -
1.323 # End of list view output.
1.324
1.325 - elif mode == "list":
1.326 + if mode == "list":
1.327 output.append(fmt.bullet_list(on=0))
1.328
1.329 return ''.join(output)