EventAggregator

actions/EventAggregatorSummary.py

55:1840106b3f87
2009-10-31 Paul Boddie Added parent page and template default support. Made new events assume the categories of the calendar in which they were created, at least by default. Fixed the styles for pop-up elements, avoiding re-wrapping and hiding the original link text. Updated the help pages.
     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         descriptions_list = [    49             '<option value="%s">%s</option>' % ("page", _("page")),    50             '<option value="%s">%s</option>' % ("comment", _("comment"))    51             ]    52     53         format_list = [    54             '<option value="%s">%s</option>' % ("iCalendar", _("iCalendar")),    55             '<option value="%s">%s</option>' % ("RSS", _("RSS 2.0"))    56             ]    57     58         d = {    59             "buttons_html" : buttons_html,    60             "category_label" : _("Categories"),    61             "category_list" : "\n".join(category_list),    62             "month_list" : "\n".join(month_list),    63             "start_label" : _("Start year and month"),    64             "start_year_default" : "",    65             "end_label" : _("End year and month"),    66             "end_year_default" : "",    67             "descriptions_label" : _("Use descriptions from..."),    68             "descriptions_list" : "\n".join(descriptions_list),    69             "format_label" : _("Summary format"),    70             "format_list" : "\n".join(format_list),    71             }    72     73         return '''    74 <table>    75     <tr>    76         <td class="label"><label>%(category_label)s</label></td>    77         <td class="content">    78             <select multiple="multiple" name="category">    79                 %(category_list)s    80             </select>    81         </td>    82     </tr>    83     <tr>    84         <td class="label"><label>%(start_label)s</label></td>    85         <td>    86             <select name="start-month">    87                 %(month_list)s    88             </select>    89             <input name="start-year" type="text" value="%(start_year_default)s" size="4" />    90         </td>    91     </tr>    92     <tr>    93         <td class="label"><label>%(end_label)s</label></td>    94         <td>    95             <select name="end-month">    96                 %(month_list)s    97             </select>    98             <input name="end-year" type="text" value="%(end_year_default)s" size="4" />    99         </td>   100     </tr>   101     <tr>   102         <td class="label"><label>%(descriptions_label)s</label></td>   103         <td class="content">   104             <select name="descriptions">   105                 %(descriptions_list)s   106             </select>   107         </td>   108     </tr>   109     <tr>   110         <td class="label"><label>%(format_label)s</label></td>   111         <td class="content">   112             <select name="format">   113                 %(format_list)s   114             </select>   115         </td>   116     </tr>   117     <tr>   118         <td></td>   119         <td class="buttons">   120             %(buttons_html)s   121         </td>   122     </tr>   123 </table>   124 ''' % d   125    126     def do_action(self):   127    128         "Write the iCalendar resource."   129    130         _ = self._   131         form = self.request.form   132    133         # If no category names exist in the request, an error message is   134         # returned.   135    136         category_names = form.get("category", [])   137    138         if not category_names:   139             return 0, _("No categories specified.")   140    141         write_resource(self.request)   142         return 1, None   143    144     def render_success(self, msg, msgtype=None):   145    146         """   147         Render neither 'msg' nor 'msgtype' since a resource has already been   148         produced.   149         NOTE: msgtype is optional because MoinMoin 1.5.x does not support it.   150         """   151    152         pass   153    154 def getQuotedText(text):   155    156     "Return the 'text' quoted for iCalendar purposes."   157    158     return text.replace(";", r"\;").replace(",", r"\,")   159    160 def write_resource(request):   161    162     """   163     For the given 'request', write an iCalendar summary of the event data found   164     in the categories specified via the "category" request parameter, using the   165     "start" and "end" parameters (if specified). Multiple "category" parameters   166     can be specified.   167     """   168    169     form = request.form   170    171     category_names = form.get("category", [])   172     format = form.get("format", ["iCalendar"])[0]   173     descriptions = form.get("descriptions", ["page"])[0]   174    175     # Otherwise, produce an iCalendar resource.   176    177     calendar_start = EventAggregatorSupport.getFormMonth(request, None, "start")   178     calendar_end = EventAggregatorSupport.getFormMonth(request, None, "end")   179    180     # Look for separate start and end years and months.   181    182     if calendar_start is None:   183         calendar_start = EventAggregatorSupport.getFormMonthPair(request, "start-year", "start-month")   184    185     if calendar_end is None:   186         calendar_end = EventAggregatorSupport.getFormMonthPair(request, "end-year", "end-month")   187    188     events, shown_events, all_shown_events, earliest, latest = \   189         EventAggregatorSupport.getEvents(request, category_names, calendar_start, calendar_end)   190    191     latest_timestamp = EventAggregatorSupport.setEventTimestamps(request, all_shown_events)   192    193     # Output summary data...   194    195     if EventAggregatorSupport.isMoin15():   196         send_headers = request.http_headers   197     else:   198         send_headers = request.emit_http_headers   199    200     # Define headers.   201    202     if format == "iCalendar":   203         headers = ["Content-Type: text/calendar; charset=%s" % config.charset]   204     elif format == "RSS":   205         headers = ["Content-Type: application/rss+xml; charset=%s" % config.charset]   206    207     # Define the last modified time.   208    209     if latest_timestamp is not None:   210         headers.append("Last-Modified: %s" % EventAggregatorSupport.getHTTPTimeString(latest_timestamp))   211    212     send_headers(headers)   213    214     # iCalendar output...   215    216     if format == "iCalendar":   217         request.write("BEGIN:VCALENDAR\r\n")   218         request.write("PRODID:-//MoinMoin//EventAggregatorSummary\r\n")   219         request.write("VERSION:2.0\r\n")   220    221         for event_page, event_details in all_shown_events:   222    223             # Get the summary details.   224    225             event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)   226             link = EventAggregatorSupport.getPageURL(request, event_page)   227    228             # Output the event details.   229    230             request.write("BEGIN:VEVENT\r\n")   231             request.write("UID:%s\r\n" % link)   232             request.write("URL:%s\r\n" % link)   233             request.write("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["created"][:6])   234             request.write("LAST-MODIFIED:%04d%02d%02dT%02d%02d%02dZ\r\n" % event_details["last-modified"][:6])   235             request.write("SEQUENCE:%d\r\n" % event_details["sequence"])   236             request.write("DTSTART;VALUE=DATE:%04d%02d%02d\r\n" % event_details["start"])   237             request.write("DTEND;VALUE=DATE:%04d%02d%02d\r\n" % EventAggregatorSupport.nextdate(event_details["end"]))   238             request.write("SUMMARY:%s\r\n" % getQuotedText(event_summary))   239    240             # Optional details.   241    242             if event_details.has_key("topics") or event_details.has_key("categories"):   243                 request.write("CATEGORIES:%s\r\n" % ",".join(   244                     [getQuotedText(topic) for topic in event_details.get("topics") or event_details.get("categories")]   245                     ))   246             if event_details.has_key("location"):   247                 request.write("LOCATION:%s\r\n" % getQuotedText(event_details["location"]))   248    249             request.write("END:VEVENT\r\n")   250    251         request.write("END:VCALENDAR\r\n")   252    253     elif format == "RSS":   254         request.write('<rss version="2.0">\r\n')   255         request.write('<channel>\r\n')   256         request.write('<title>Events</title>\r\n')   257         request.write('<link>%s</link>\r\n' % request.getBaseURL())   258         request.write('<description>Events published on %s</description>\r\n' % request.getBaseURL())   259         request.write('<lastBuildDate>%s</lastBuildDate>\r\n' % EventAggregatorSupport.getHTTPTimeString(latest_timestamp))   260    261         for event_page, event_details in all_shown_events:   262    263             # Get the summary details.   264    265             event_summary = EventAggregatorSupport.getEventSummary(event_page, event_details)   266             link = EventAggregatorSupport.getPageURL(request, event_page)   267    268             request.write('<item>\r\n')   269             request.write('<title>%s</title>\r\n' % wikiutil.escape(event_summary))   270             request.write('<link>%s</link>\r\n' % link)   271    272             # Write a description according to the preferred source of   273             # descriptions.   274    275             if descriptions == "page":   276                 description = event_details.get("description", "")   277             else:   278                 description = event_details["last-comment"]   279    280             request.write('<description>%s</description>\r\n' % wikiutil.escape(description))   281    282             for topic in event_details.get("topics") or event_details.get("categories") or []:   283                 request.write('<category>%s</category>\r\n' % topic)   284    285             request.write('<pubDate>%s</pubDate>\r\n' % EventAggregatorSupport.getHTTPTimeString(event_details["created"]))   286             request.write('<guid>%s#%s</guid>\r\n' % (link, event_details["sequence"]))   287             request.write('</item>\r\n')   288    289         request.write('</channel>\r\n')   290         request.write('</rss>\r\n')   291    292     if EventAggregatorSupport.isMoin15():   293         raise MoinMoin.util.MoinMoinNoFooter   294    295 # Action function.   296    297 def execute(pagename, request):   298     EventAggregatorSummary(pagename, request).render()   299    300 # vim: tabstop=4 expandtab shiftwidth=4