1.1 --- a/EventAggregatorSupport.py Thu Apr 02 01:08:29 2009 +0200
1.2 +++ b/EventAggregatorSupport.py Fri Apr 03 01:30:01 2009 +0200
1.3 @@ -98,7 +98,18 @@
1.4 edit_info = page.last_edit(page.request) # MoinMoin 1.5.x and 1.6.x
1.5
1.6 mtime = wikiutil.version2timestamp(long(edit_info['timestamp'])) # must be long for py 2.2.x
1.7 - return tuple(time.gmtime(mtime))
1.8 + return time.gmtime(mtime)
1.9 +
1.10 +def getHTTPTimeString(tmtuple):
1.11 + return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
1.12 + weekday_labels[tmtuple.tm_wday],
1.13 + tmtuple.tm_mday,
1.14 + month_labels[tmtuple.tm_mon -1], # zero-based labels
1.15 + tmtuple.tm_year,
1.16 + tmtuple.tm_hour,
1.17 + tmtuple.tm_min,
1.18 + tmtuple.tm_sec
1.19 + )
1.20
1.21 # The main activity functions.
1.22
1.23 @@ -434,6 +445,35 @@
1.24
1.25 return events, shown_events, all_shown_events, earliest, latest
1.26
1.27 +def setEventTimestamps(request, events):
1.28 +
1.29 + """
1.30 + Using 'request', set timestamp details in the details dictionary of each of
1.31 + the 'events': a list of the form (event_page, event_details).
1.32 +
1.33 + Retutn the latest timestamp found.
1.34 + """
1.35 +
1.36 + latest = None
1.37 +
1.38 + for event_page, event_details in events:
1.39 +
1.40 + # Get the initial revision of the page.
1.41 +
1.42 + revisions = event_page.getRevList()
1.43 + event_page_initial = Page(request, event_page.page_name, rev=revisions[-1])
1.44 +
1.45 + # Get the created and last modified times.
1.46 +
1.47 + event_details["created"] = getPageDate(event_page_initial)
1.48 + event_details["last-modified"] = getPageDate(event_page)
1.49 + event_details["sequence"] = len(revisions) - 1
1.50 +
1.51 + if latest is None or latest < event_details["last-modified"]:
1.52 + latest = event_details["last-modified"]
1.53 +
1.54 + return latest
1.55 +
1.56 def compareEvents(event1, event2):
1.57
1.58 """
2.1 --- a/README.txt Thu Apr 02 01:08:29 2009 +0200
2.2 +++ b/README.txt Fri Apr 03 01:30:01 2009 +0200
2.3 @@ -11,7 +11,8 @@
2.4 The EventAggregatorSummary action can be used to provide an iCalendar summary
2.5 of event data based on pages belonging to specific categories, as described
2.6 above. The category, start and end parameters are read directly from the
2.7 -request as URL or form parameters.
2.8 +request as URL or form parameters: these restrict the extent of each generated
2.9 +summary.
2.10
2.11 Installation
2.12 ------------
3.1 --- a/actions/EventAggregatorSummary.py Thu Apr 02 01:08:29 2009 +0200
3.2 +++ b/actions/EventAggregatorSummary.py Fri Apr 03 01:30:01 2009 +0200
3.3 @@ -14,6 +14,7 @@
3.4 from MoinMoin import config
3.5 from MoinMoin.Page import Page
3.6 import MoinMoin.util # for MoinMoin 1.5.x
3.7 +from MoinMoin import wikiutil
3.8 import EventAggregatorSupport
3.9
3.10 Dependencies = ['pages']
3.11 @@ -138,6 +139,7 @@
3.12 """
3.13
3.14 category_names = request.form.get("category", [])
3.15 + format = request.form.get("format", ["iCalendar"])[0]
3.16
3.17 # Otherwise, produce an iCalendar resource.
3.18
3.19 @@ -157,60 +159,93 @@
3.20 events, shown_events, all_shown_events, earliest, latest = \
3.21 EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end)
3.22
3.23 - # Output iCalendar data...
3.24 + latest_timestamp = EventAggregatorSupport.setEventTimestamps(request, all_shown_events)
3.25 +
3.26 + # Output summary data...
3.27
3.28 if EventAggregatorSupport.isMoin15():
3.29 send_headers = request.http_headers
3.30 else:
3.31 send_headers = request.emit_http_headers
3.32
3.33 - send_headers(["Content-Type: text/calendar; charset=%s" % config.charset])
3.34 + # Define headers.
3.35 +
3.36 + if format == "iCalendar":
3.37 + headers = ["Content-Type: text/calendar; charset=%s" % config.charset]
3.38 + elif format == "RSS":
3.39 + headers = ["Content-Type: application/rss+xml; charset=%s" % config.charset]
3.40 +
3.41 + # Define the last modified time.
3.42
3.43 - request.write("BEGIN:VCALENDAR\r\n")
3.44 - request.write("PRODID:-//MoinMoin//EventAggregatorSummary\r\n")
3.45 - request.write("VERSION:2.0\r\n")
3.46 + headers.append("Last-Modified: %s" % EventAggregatorSupport.getHTTPTimeString(latest_timestamp))
3.47 + send_headers(headers)
3.48 +
3.49 + # iCalendar output...
3.50
3.51 - for event_page, event_details in all_shown_events:
3.52 -
3.53 - # Get the summary and timestamp details.
3.54 + if format == "iCalendar":
3.55 + request.write("BEGIN:VCALENDAR\r\n")
3.56 + request.write("PRODID:-//MoinMoin//EventAggregatorSummary\r\n")
3.57 + request.write("VERSION:2.0\r\n")
3.58
3.59 - event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)
3.60 + for event_page, event_details in all_shown_events:
3.61 +
3.62 + # Get the summary details.
3.63
3.64 - # Get the initial revision of the page.
3.65 + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)
3.66 +
3.67 + # Output the event details.
3.68
3.69 - revisions = event_page.getRevList()
3.70 - event_page_initial = Page(request, event_page.page_name, rev=revisions[-1])
3.71 + request.write("BEGIN:VEVENT\r\n")
3.72 + request.write("UID:%s\r\n" % request.getQualifiedURL(event_page.url(request)))
3.73 + request.write("URL:%s\r\n" % request.getQualifiedURL(event_page.url(request)))
3.74 + request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["created"][:6])
3.75 + request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["last-modified"][:6])
3.76 + request.write("SEQUENCE:%d\r\n" % event_details["sequence"])
3.77 + request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"])
3.78 + request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"]))
3.79 + request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary))
3.80
3.81 - # Get the created and last modified times.
3.82 -
3.83 - created = EventAggregatorSupport.getPageDate(event_page_initial)
3.84 - last_modified = EventAggregatorSupport.getPageDate(event_page)
3.85 - sequence = len(revisions) - 1
3.86 + # Optional details.
3.87
3.88 - # Output the event details.
3.89 + if event_details.has_key("topics") or event_details.has_key("categories"):
3.90 + request.write("CATEGORIES:%s\r\n" % ",".join(
3.91 + [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")]
3.92 + ))
3.93 + if event_details.has_key("location"):
3.94 + request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"]))
3.95 +
3.96 + request.write("END:VEVENT\r\n")
3.97
3.98 - request.write("BEGIN:VEVENT\r\n")
3.99 - request.write("UID:%s\r\n" % request.getQualifiedURL(event_page.url(request)))
3.100 - request.write("URL:%s\r\n" % request.getQualifiedURL(event_page.url(request)))
3.101 - request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % created[:6])
3.102 - request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % last_modified[:6])
3.103 - request.write("SEQUENCE:%d\r\n" % sequence)
3.104 - request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"])
3.105 - request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"]))
3.106 - request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary))
3.107 + request.write("END:VCALENDAR\r\n")
3.108 +
3.109 + elif format == "RSS":
3.110 + request.write('<rss version="2.0">\r\n')
3.111 + request.write('<channel>\r\n')
3.112 + request.write('<title>Events</title>\r\n')
3.113 + request.write('<link>%s</link>\r\n' % request.getBaseURL())
3.114 + request.write('<description>Events published on %s</description>\r\n' % request.getBaseURL())
3.115 + request.write('<lastBuildDate>%s</lastBuildDate>\r\n' % EventAggregatorSupport.getHTTPTimeString(latest_timestamp))
3.116
3.117 - # Optional details.
3.118 + for event_page, event_details in all_shown_events:
3.119 +
3.120 + # Get the summary details.
3.121 +
3.122 + event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)
3.123 + link = request.getQualifiedURL(event_page.url(request))
3.124
3.125 - if event_details.has_key("topics") or event_details.has_key("categories"):
3.126 - request.write("CATEGORIES:%s\r\n" % ",".join(
3.127 - [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")]
3.128 - ))
3.129 - if event_details.has_key("location"):
3.130 - request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"]))
3.131 + request.write('<item>\r\n')
3.132 + request.write('<title>%s</title>\r\n' % wikiutil.escape(event_summary))
3.133 + request.write('<link>%s</link>\r\n' % link)
3.134 +
3.135 + for topic in event_details.get("topics") or event_details.get("categories") or []:
3.136 + request.write('<category>%s</category>\r\n' % topic)
3.137
3.138 - request.write("END:VEVENT\r\n")
3.139 + request.write('<pubDate>%s</pubDate>\r\n' % EventAggregatorSupport.getHTTPTimeString(event_details["created"]))
3.140 + request.write('<guid>%s#%s</guid>\r\n' % (link, event_details["sequence"]))
3.141 + request.write('</item>\r\n')
3.142
3.143 - request.write("END:VCALENDAR\r\n")
3.144 + request.write('</channel>\r\n')
3.145 + request.write('</rss>\r\n')
3.146
3.147 if EventAggregatorSupport.isMoin15():
3.148 raise MoinMoin.util.MoinMoinNoFooter