# HG changeset patch # User Paul Boddie # Date 1238715001 -7200 # Node ID 69086565e2da89ed2e531c981aa9447f5b6cc5ec # Parent 2573d4464fae8ddc70e85857a0651fab7cf09dcb Moved event timestamp discovery into a new setEventTimestamps function which adds datetime and sequence information to the event details. Added Last-Modified header support, although Apache seems to want to override this. Added RSS 2.0 support. Made a minor edit to the action description. diff -r 2573d4464fae -r 69086565e2da EventAggregatorSupport.py --- a/EventAggregatorSupport.py Thu Apr 02 01:08:29 2009 +0200 +++ b/EventAggregatorSupport.py Fri Apr 03 01:30:01 2009 +0200 @@ -98,7 +98,18 @@ edit_info = page.last_edit(page.request) # MoinMoin 1.5.x and 1.6.x mtime = wikiutil.version2timestamp(long(edit_info['timestamp'])) # must be long for py 2.2.x - return tuple(time.gmtime(mtime)) + return time.gmtime(mtime) + +def getHTTPTimeString(tmtuple): + return "%s, %02d %s %04d %02d:%02d:%02d GMT" % ( + weekday_labels[tmtuple.tm_wday], + tmtuple.tm_mday, + month_labels[tmtuple.tm_mon -1], # zero-based labels + tmtuple.tm_year, + tmtuple.tm_hour, + tmtuple.tm_min, + tmtuple.tm_sec + ) # The main activity functions. @@ -434,6 +445,35 @@ return events, shown_events, all_shown_events, earliest, latest +def setEventTimestamps(request, events): + + """ + Using 'request', set timestamp details in the details dictionary of each of + the 'events': a list of the form (event_page, event_details). + + Retutn the latest timestamp found. + """ + + latest = None + + for event_page, event_details in events: + + # Get the initial revision of the page. + + revisions = event_page.getRevList() + event_page_initial = Page(request, event_page.page_name, rev=revisions[-1]) + + # Get the created and last modified times. + + event_details["created"] = getPageDate(event_page_initial) + event_details["last-modified"] = getPageDate(event_page) + event_details["sequence"] = len(revisions) - 1 + + if latest is None or latest < event_details["last-modified"]: + latest = event_details["last-modified"] + + return latest + def compareEvents(event1, event2): """ diff -r 2573d4464fae -r 69086565e2da README.txt --- a/README.txt Thu Apr 02 01:08:29 2009 +0200 +++ b/README.txt Fri Apr 03 01:30:01 2009 +0200 @@ -11,7 +11,8 @@ The EventAggregatorSummary action can be used to provide an iCalendar summary of event data based on pages belonging to specific categories, as described above. The category, start and end parameters are read directly from the -request as URL or form parameters. +request as URL or form parameters: these restrict the extent of each generated +summary. Installation ------------ diff -r 2573d4464fae -r 69086565e2da actions/EventAggregatorSummary.py --- a/actions/EventAggregatorSummary.py Thu Apr 02 01:08:29 2009 +0200 +++ b/actions/EventAggregatorSummary.py Fri Apr 03 01:30:01 2009 +0200 @@ -14,6 +14,7 @@ from MoinMoin import config from MoinMoin.Page import Page import MoinMoin.util # for MoinMoin 1.5.x +from MoinMoin import wikiutil import EventAggregatorSupport Dependencies = ['pages'] @@ -138,6 +139,7 @@ """ category_names = request.form.get("category", []) + format = request.form.get("format", ["iCalendar"])[0] # Otherwise, produce an iCalendar resource. @@ -157,60 +159,93 @@ events, shown_events, all_shown_events, earliest, latest = \ EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end) - # Output iCalendar data... + latest_timestamp = EventAggregatorSupport.setEventTimestamps(request, all_shown_events) + + # Output summary data... if EventAggregatorSupport.isMoin15(): send_headers = request.http_headers else: send_headers = request.emit_http_headers - send_headers(["Content-Type: text/calendar; charset=%s" % config.charset]) + # Define headers. + + if format == "iCalendar": + headers = ["Content-Type: text/calendar; charset=%s" % config.charset] + elif format == "RSS": + headers = ["Content-Type: application/rss+xml; charset=%s" % config.charset] + + # Define the last modified time. - request.write("BEGIN:VCALENDAR\r\n") - request.write("PRODID:-//MoinMoin//EventAggregatorSummary\r\n") - request.write("VERSION:2.0\r\n") + headers.append("Last-Modified: %s" % EventAggregatorSupport.getHTTPTimeString(latest_timestamp)) + send_headers(headers) + + # iCalendar output... - for event_page, event_details in all_shown_events: - - # Get the summary and timestamp details. + if format == "iCalendar": + request.write("BEGIN:VCALENDAR\r\n") + request.write("PRODID:-//MoinMoin//EventAggregatorSummary\r\n") + request.write("VERSION:2.0\r\n") - event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details) + for event_page, event_details in all_shown_events: + + # Get the summary details. - # Get the initial revision of the page. + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details) + + # Output the event details. - revisions = event_page.getRevList() - event_page_initial = Page(request, event_page.page_name, rev=revisions[-1]) + request.write("BEGIN:VEVENT\r\n") + request.write("UID:%s\r\n" % request.getQualifiedURL(event_page.url(request))) + request.write("URL:%s\r\n" % request.getQualifiedURL(event_page.url(request))) + request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["created"][:6]) + request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["last-modified"][:6]) + request.write("SEQUENCE:%d\r\n" % event_details["sequence"]) + request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"]) + request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"])) + request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary)) - # Get the created and last modified times. - - created = EventAggregatorSupport.getPageDate(event_page_initial) - last_modified = EventAggregatorSupport.getPageDate(event_page) - sequence = len(revisions) - 1 + # Optional details. - # Output the event details. + if event_details.has_key("topics") or event_details.has_key("categories"): + request.write("CATEGORIES:%s\r\n" % ",".join( + [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")] + )) + if event_details.has_key("location"): + request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"])) + + request.write("END:VEVENT\r\n") - request.write("BEGIN:VEVENT\r\n") - request.write("UID:%s\r\n" % request.getQualifiedURL(event_page.url(request))) - request.write("URL:%s\r\n" % request.getQualifiedURL(event_page.url(request))) - request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % created[:6]) - request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % last_modified[:6]) - request.write("SEQUENCE:%d\r\n" % sequence) - request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"]) - request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"])) - request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary)) + request.write("END:VCALENDAR\r\n") + + elif format == "RSS": + request.write('\r\n') + request.write('\r\n') + request.write('Events\r\n') + request.write('%s\r\n' % request.getBaseURL()) + request.write('Events published on %s\r\n' % request.getBaseURL()) + request.write('%s\r\n' % EventAggregatorSupport.getHTTPTimeString(latest_timestamp)) - # Optional details. + for event_page, event_details in all_shown_events: + + # Get the summary details. + + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details) + link = request.getQualifiedURL(event_page.url(request)) - if event_details.has_key("topics") or event_details.has_key("categories"): - request.write("CATEGORIES:%s\r\n" % ",".join( - [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")] - )) - if event_details.has_key("location"): - request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"])) + request.write('\r\n') + request.write('%s\r\n' % wikiutil.escape(event_summary)) + request.write('%s\r\n' % link) + + for topic in event_details.get("topics") or event_details.get("categories") or []: + request.write('%s\r\n' % topic) - request.write("END:VEVENT\r\n") + request.write('%s\r\n' % EventAggregatorSupport.getHTTPTimeString(event_details["created"])) + request.write('%s#%s\r\n' % (link, event_details["sequence"])) + request.write('\r\n') - request.write("END:VCALENDAR\r\n") + request.write('\r\n') + request.write('\r\n') if EventAggregatorSupport.isMoin15(): raise MoinMoin.util.MoinMoinNoFooter