EventAggregator

actions/EventAggregatorSummary.py

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