EventAggregator

actions/EventAggregatorSummary.py

44:5582d8b9d3ed
2009-04-05 Paul Boddie Added RSS notes.
     1 # -*- coding: iso-8859-1 -*-     2 """     3     MoinMoin - EventAggregatorSummary Action     4      5     @copyright: 2008, 2009 by Paul Boddie <paul@boddie.org.uk>     6     @copyright: 2000-2004 Juergen Hermann <jh@web.de>,     7                 2003-2008 MoinMoin:ThomasWaldmann,     8                 2004-2006 MoinMoin:AlexanderSchremmer,     9                 2007 MoinMoin:ReimarBauer.    10     @license: GNU GPL (v2 or later), see COPYING.txt for details.    11 """    12     13 from MoinMoin.action import ActionBase    14 from MoinMoin import config    15 from MoinMoin.Page import Page    16 import MoinMoin.util # for MoinMoin 1.5.x    17 from MoinMoin import wikiutil    18 import EventAggregatorSupport    19     20 Dependencies = ['pages']    21     22 # Action class and supporting functions.    23     24 class EventAggregatorSummary(ActionBase):    25     26     "A summary dialogue requesting various parameters."    27     28     def get_form_html(self, buttons_html):    29         _ = self._    30         request = self.request    31     32         category_list = []    33     34         for category_name, category_pagename in \    35             EventAggregatorSupport.getCategoryMapping(    36                 EventAggregatorSupport.getCategories(request),    37                 request):    38     39             category_list.append('<option value="%s">%s</option>' % (category_pagename, category_name))    40     41         month_list = []    42         month_list.append('<option value=""></option>')    43     44         for month in range(1, 13):    45             month_label = _(EventAggregatorSupport.getMonthLabel(month))    46             month_list.append('<option value="%02d">%s</option>' % (month, month_label))    47     48         year_label = []    49     50         d = {    51             "buttons_html" : buttons_html,    52             "category_label" : _("Categories"),    53             "category_list" : "\n".join(category_list),    54             "month_list" : "\n".join(month_list),    55             "start_label" : _("Start year and month"),    56             "start_year_default" : "",    57             "end_label" : _("End year and month"),    58             "end_year_default" : "",    59             }    60     61         return '''    62 <table>    63     <tr>    64         <td class="label"><label>%(category_label)s</label></td>    65         <td class="content">    66             <select multiple="multiple" name="category">    67                 %(category_list)s    68             </select>    69         </td>    70     </tr>    71     <tr>    72         <td class="label"><label>%(start_label)s</label></td>    73         <td>    74             <select name="start-month">    75                 %(month_list)s    76             </select>    77             <input name="start-year" type="text" value="%(start_year_default)s" size="4" />    78         </td>    79     </tr>    80     <tr>    81         <td class="label"><label>%(end_label)s</label></td>    82         <td>    83             <select name="end-month">    84                 %(month_list)s    85             </select>    86             <input name="end-year" type="text" value="%(end_year_default)s" size="4" />    87         </td>    88     </tr>    89     <tr>    90         <td></td>    91         <td class="buttons">    92             %(buttons_html)s    93         </td>    94     </tr>    95 </table>    96 ''' % d    97     98     def do_action(self):    99    100         "Write the iCalendar resource."   101    102         _ = self._   103         form = self.request.form   104    105         # If no category names exist in the request, an error message is   106         # returned.   107    108         category_names = form.get("category", [])   109    110         if not category_names:   111             return 0, _("No categories specified.")   112    113         write_resource(self.request)   114         return 1, None   115    116     def render_success(self, msg, msgtype=None):   117    118         """   119         Render neither 'msg' nor 'msgtype' since a resource has already been   120         produced.   121         NOTE: msgtype is optional because MoinMoin 1.5.x does not support it.   122         """   123    124         pass   125    126 def getQuotedText(text):   127    128     "Return the 'text' quoted for iCalendar purposes."   129    130     return text.replace(";", r"\;").replace(",", r"\,")   131    132 def write_resource(request):   133    134     """   135     For the given 'request', write an iCalendar summary of the event data found   136     in the categories specified via the "category" request parameter, using the   137     "start" and "end" parameters (if specified). Multiple "category" parameters   138     can be specified.   139     """   140    141     category_names = request.form.get("category", [])   142     format = request.form.get("format", ["iCalendar"])[0]   143    144     # Otherwise, produce an iCalendar resource.   145    146     calendar_start = EventAggregatorSupport.getFormMonth(request, None, "start")   147     calendar_end = EventAggregatorSupport.getFormMonth(request, None, "end")   148    149     # Look for separate start and end years and months.   150    151     form = request.form   152    153     if calendar_start is None:   154         calendar_start = EventAggregatorSupport.getFormMonthPair(request, "start-year", "start-month")   155    156     if calendar_end is None:   157         calendar_end = EventAggregatorSupport.getFormMonthPair(request, "end-year", "end-month")   158    159     events, shown_events, all_shown_events, earliest, latest = \   160         EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end)   161    162     latest_timestamp = EventAggregatorSupport.setEventTimestamps(request, all_shown_events)   163    164     # Output summary data...   165    166     if EventAggregatorSupport.isMoin15():   167         send_headers = request.http_headers   168     else:   169         send_headers = request.emit_http_headers   170    171     # Define headers.   172    173     if format == "iCalendar":   174         headers = ["Content-Type: text/calendar; charset=%s" % config.charset]   175     elif format == "RSS":   176         headers = ["Content-Type: application/rss+xml; charset=%s" % config.charset]   177    178     # Define the last modified time.   179    180     if latest_timestamp is not None:   181         headers.append("Last-Modified: %s" % EventAggregatorSupport.getHTTPTimeString(latest_timestamp))   182    183     send_headers(headers)   184    185     # iCalendar output...   186    187     if format == "iCalendar":   188         request.write("BEGIN:VCALENDAR\r\n")   189         request.write("PRODID:-//MoinMoin//EventAggregatorSummary\r\n")   190         request.write("VERSION:2.0\r\n")   191    192         for event_page, event_details in all_shown_events:   193    194             # Get the summary details.   195    196             event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)   197             link = EventAggregatorSupport.getPageURL(request, event_page)   198    199             # Output the event details.   200    201             request.write("BEGIN:VEVENT\r\n")   202             request.write("UID:%s\r\n" % link)   203             request.write("URL:%s\r\n" % link)   204             request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["created"][:6])   205             request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["last-modified"][:6])   206             request.write("SEQUENCE:%d\r\n" % event_details["sequence"])   207             request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"])   208             request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"]))   209             request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary))   210    211             # Optional details.   212    213             if event_details.has_key("topics") or event_details.has_key("categories"):   214                 request.write("CATEGORIES:%s\r\n" % ",".join(   215                     [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")]   216                     ))   217             if event_details.has_key("location"):   218                 request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"]))   219    220             request.write("END:VEVENT\r\n")   221    222         request.write("END:VCALENDAR\r\n")   223    224     elif format == "RSS":   225         request.write('<rss version="2.0">\r\n')   226         request.write('<channel>\r\n')   227         request.write('<title>Events</title>\r\n')   228         request.write('<link>%s</link>\r\n' % request.getBaseURL())   229         request.write('<description>Events published on %s</description>\r\n' % request.getBaseURL())   230         request.write('<lastBuildDate>%s</lastBuildDate>\r\n' % EventAggregatorSupport.getHTTPTimeString(latest_timestamp))   231    232         for event_page, event_details in all_shown_events:   233    234             # Get the summary details.   235    236             event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)   237             link = EventAggregatorSupport.getPageURL(request, event_page)   238    239             request.write('<item>\r\n')   240             request.write('<title>%s</title>\r\n' % wikiutil.escape(event_summary))   241             request.write('<link>%s</link>\r\n' % link)   242             request.write('<description>%s</description>\r\n' % wikiutil.escape(event_details["last-comment"]))   243    244             for topic in event_details.get("topics") or event_details.get("categories") or []:   245                 request.write('<category>%s</category>\r\n' % topic)   246    247             request.write('<pubDate>%s</pubDate>\r\n' % EventAggregatorSupport.getHTTPTimeString(event_details["created"]))   248             request.write('<guid>%s#%s</guid>\r\n' % (link, event_details["sequence"]))   249             request.write('</item>\r\n')   250    251         request.write('</channel>\r\n')   252         request.write('</rss>\r\n')   253    254     if EventAggregatorSupport.isMoin15():   255         raise MoinMoin.util.MoinMoinNoFooter   256    257 # Action function.   258    259 def execute(pagename, request):   260     EventAggregatorSummary(pagename, request).render()   261    262 # vim: tabstop=4 expandtab shiftwidth=4