EventAggregator

Changeset

437:62f611b64ff2
2014-04-07 Paul Boddie raw files shortlog changelog graph Added initial support for iTIP method display, fixing the iCalendar format retrieval of method information.
EventAggregatorSupport/Formatting.py (file) EventAggregatorSupport/Types.py (file) parsers/calendar.py (file) parsers/xcalendar.py (file)
     1.1 --- a/EventAggregatorSupport/Formatting.py	Sun Apr 06 23:35:52 2014 +0200
     1.2 +++ b/EventAggregatorSupport/Formatting.py	Mon Apr 07 23:16:49 2014 +0200
     1.3 @@ -79,7 +79,26 @@
     1.4  
     1.5      write(fmt.definition_list(on=0))
     1.6  
     1.7 -def formatEventsForOutputType(events, request, mimetype, parent=None, descriptions=None, latest_timestamp=None, write=None):
     1.8 +def formatMethod(resource, request, fmt, write=None):
     1.9 +
    1.10 +    "Where the 'resource' has a method, offer iTIP actions."
    1.11 +
    1.12 +    method = resource.getMethod()
    1.13 +
    1.14 +    if method:
    1.15 +        _ = request.getText
    1.16 +        write = write or request.write
    1.17 +        write(fmt.paragraph(on=1))
    1.18 +        write(fmt.span(on=1))
    1.19 +        write(fmt.text(_("iTIP method")))
    1.20 +        write(fmt.span(on=0))
    1.21 +        write(" ")
    1.22 +        write(fmt.span(on=1))
    1.23 +        write(fmt.text(method))
    1.24 +        write(fmt.span(on=0))
    1.25 +        write(fmt.paragraph(on=0))
    1.26 +
    1.27 +def formatEventsForOutputType(events, request, mimetype, parent=None, descriptions=None, latest_timestamp=None, write=None, resource=None):
    1.28  
    1.29      """
    1.30      Format the given 'events' using the 'request' for the given 'mimetype'.
    1.31 @@ -95,6 +114,9 @@
    1.32      of the page or event collection.
    1.33  
    1.34      If the 'write' parameter is specified, use it to write output.
    1.35 +
    1.36 +    If the 'resource' parameter is specified, use it to write any resource-level
    1.37 +    information such as iTIP method information.
    1.38      """
    1.39  
    1.40      write = write or request.write
    1.41 @@ -136,7 +158,7 @@
    1.42      # Output the collection one by one.
    1.43  
    1.44      for event in events:
    1.45 -        formatEventForOutputType(event, request, mimetype, parent, descriptions, write)
    1.46 +        formatEventForOutputType(event, request, mimetype, parent, descriptions, write, resource)
    1.47  
    1.48      # End the collection.
    1.49  
    1.50 @@ -151,7 +173,7 @@
    1.51          write('</body>')
    1.52          write('</html>')
    1.53  
    1.54 -def formatEventForOutputType(event, request, mimetype, parent=None, descriptions=None, write=None):
    1.55 +def formatEventForOutputType(event, request, mimetype, parent=None, descriptions=None, write=None, resource=None):
    1.56  
    1.57      """
    1.58      Format the given 'event' using the 'request' for the given 'mimetype'.
    1.59 @@ -164,6 +186,9 @@
    1.60      for events in the output resource.
    1.61  
    1.62      If the 'write' parameter is specified, use it to write output.
    1.63 +
    1.64 +    If the 'resource' parameter is specified, use it to write any resource-level
    1.65 +    information such as iTIP method information.
    1.66      """
    1.67  
    1.68      write = write or request.write
    1.69 @@ -260,6 +285,8 @@
    1.70          fmt = request.html_formatter
    1.71          fmt.setPage(request.page)
    1.72          formatEvent(event, request, fmt, write=write)
    1.73 +        if resource:
    1.74 +            formatMethod(resource, request, fmt, write)
    1.75  
    1.76  # iCalendar format helper functions.
    1.77  
     2.1 --- a/EventAggregatorSupport/Types.py	Sun Apr 06 23:35:52 2014 +0200
     2.2 +++ b/EventAggregatorSupport/Types.py	Mon Apr 07 23:16:49 2014 +0200
     2.3 @@ -352,6 +352,12 @@
     2.4  
     2.5          return self.metadata or {}
     2.6  
     2.7 +    def getMethod(self):
     2.8 +
     2.9 +        "Return the iTIP-related method associated with this resource."
    2.10 +
    2.11 +        return None
    2.12 +
    2.13      def getEvents(self):
    2.14  
    2.15          "Return a list of events from this resource."
    2.16 @@ -412,9 +418,15 @@
    2.17  
    2.18      "An iCalendar resource."
    2.19  
    2.20 +    calendar_properties = ("METHOD",)
    2.21 +
    2.22      def __init__(self, url, calendar, metadata):
    2.23          EventCalendarResource.__init__(self, url, metadata)
    2.24          self.calendar = calendar
    2.25 +        self.properties = {}
    2.26 +
    2.27 +    def getMethod(self):
    2.28 +        return self.properties.get("METHOD")
    2.29  
    2.30      def getEvents(self):
    2.31  
    2.32 @@ -482,6 +494,11 @@
    2.33  
    2.34                      self.events.append(CalendarEvent(self, details))
    2.35  
    2.36 +                # Obtain calendar-level information.
    2.37 +
    2.38 +                elif objtype in self.calendar_properties:
    2.39 +                    self.properties[objtype] = obj
    2.40 +
    2.41          return self.events
    2.42  
    2.43  class EventXMLCalendar(EventCalendarResource):
    2.44 @@ -492,7 +509,11 @@
    2.45  
    2.46      # See: http://tools.ietf.org/html/draft-daboo-et-al-icalendar-in-xml-11#section-3.4
    2.47  
    2.48 -    properties = [
    2.49 +    calendar_properties = [
    2.50 +        ("method",          "xcal:properties/xcal:method",          "getText"),
    2.51 +        ]
    2.52 +
    2.53 +    event_properties = [
    2.54          ("summary",         "xcal:properties/xcal:summary",         "getText"),
    2.55          ("location",        "xcal:properties/xcal:location",        "getText"),
    2.56          ("start",           "xcal:properties/xcal:dtstart",         "getDateTime"),
    2.57 @@ -509,6 +530,10 @@
    2.58      def __init__(self, url, doc, metadata):
    2.59          EventCalendarResource.__init__(self, url, metadata)
    2.60          self.doc = doc
    2.61 +        self.properties = self.getProperties(self.calendar_properties, doc)
    2.62 +
    2.63 +    def getMethod(self):
    2.64 +        return self.properties.get("method")
    2.65  
    2.66      def getEvents(self):
    2.67  
    2.68 @@ -518,28 +543,34 @@
    2.69              self.events = []
    2.70  
    2.71              for event in self.doc.xpath("//xcal:vevent", namespaces=self.XCAL):
    2.72 -                details = {}
    2.73 -
    2.74 -                for property, path, converter in self.properties:
    2.75 -                    values = event.xpath(path, namespaces=self.XCAL)
    2.76 -
    2.77 -                    try:
    2.78 -                        value = getattr(self, converter)(property, values)
    2.79 -                        details[property] = value
    2.80 -                    except (IndexError, ValueError):
    2.81 -                        pass
    2.82 -
    2.83 +                details = self.getProperties(self.event_properties, event)
    2.84                  self.events.append(CalendarEvent(self, details))
    2.85  
    2.86          return self.events
    2.87  
    2.88 +    # Retrieval methods.
    2.89 +
    2.90 +    def getProperties(self, definitions, root):
    2.91 +        details = {}
    2.92 +
    2.93 +        for property, path, converter in definitions:
    2.94 +            values = root.xpath(path, namespaces=self.XCAL)
    2.95 +
    2.96 +            try:
    2.97 +                value = getattr(self, converter)(property, values)
    2.98 +                details[property] = value
    2.99 +            except (IndexError, ValueError), exc:
   2.100 +                pass
   2.101 +
   2.102 +        return details
   2.103 +
   2.104      # Parsing methods.
   2.105  
   2.106      def _getValue(self, values, type):
   2.107 -        for element in values[0].xpath("xcal:%s" % type, namespaces=self.XCAL):
   2.108 -            return element.textContent
   2.109 -        else:
   2.110 -            return None
   2.111 +        if values:
   2.112 +            for element in values[0].xpath("xcal:%s" % type, namespaces=self.XCAL):
   2.113 +                return element.textContent
   2.114 +        return None
   2.115  
   2.116      def getText(self, property, values):
   2.117          return self._getValue(values, "text")
     3.1 --- a/parsers/calendar.py	Sun Apr 06 23:35:52 2014 +0200
     3.2 +++ b/parsers/calendar.py	Mon Apr 07 23:16:49 2014 +0200
     3.3 @@ -8,7 +8,7 @@
     3.4  
     3.5  from MoinSupport import parseAttributes, RawParser, getPageURL
     3.6  from EventAggregatorSupport.Formatting import formatEventsForOutputType, \
     3.7 -                                              formatEvent
     3.8 +                                              formatEvent, formatMethod
     3.9  from EventAggregatorSupport.Types import parseEventsInCalendar
    3.10  
    3.11  Dependencies = ["pages"]
    3.12 @@ -51,9 +51,13 @@
    3.13          using the request.
    3.14          """
    3.15  
    3.16 -        for event in parseEventsInCalendar(self.raw, getPageURL(self.request.page)).getEvents():
    3.17 +        resource = parseEventsInCalendar(self.raw, getPageURL(self.request.page))
    3.18 +
    3.19 +        for event in resource.getEvents():
    3.20              formatEvent(event, self.request, fmt, write=write, parser_cls=RawParser)
    3.21  
    3.22 +        formatMethod(resource, self.request, fmt, write)
    3.23 +
    3.24      # Extra API methods.
    3.25  
    3.26      def formatForOutputType(self, mimetype, write=None):
    3.27 @@ -69,8 +73,9 @@
    3.28          if mimetype == "text/calendar":
    3.29              (write or request.write)(self.raw)
    3.30          else:
    3.31 -            events = parseEventsInCalendar(self.raw, getPageURL(self.request.page)).getEvents()
    3.32 -            formatEventsForOutputType(events, self.request, mimetype, write=write)
    3.33 +            resource = parseEventsInCalendar(self.raw, getPageURL(self.request.page))
    3.34 +            events = resource.getEvents()
    3.35 +            formatEventsForOutputType(events, self.request, mimetype, write=write, resource=resource)
    3.36  
    3.37      # Class methods.
    3.38  
     4.1 --- a/parsers/xcalendar.py	Sun Apr 06 23:35:52 2014 +0200
     4.2 +++ b/parsers/xcalendar.py	Mon Apr 07 23:16:49 2014 +0200
     4.3 @@ -8,7 +8,7 @@
     4.4  
     4.5  from MoinSupport import parseAttributes, RawParser, getPageURL
     4.6  from EventAggregatorSupport.Formatting import formatEventsForOutputType, \
     4.7 -                                              formatEvent
     4.8 +                                              formatEvent, formatMethod
     4.9  from EventAggregatorSupport.Types import parseEventsInXMLCalendar
    4.10  
    4.11  Dependencies = ["pages"]
    4.12 @@ -51,9 +51,13 @@
    4.13          using the request.
    4.14          """
    4.15  
    4.16 -        for event in parseEventsInXMLCalendar(self.raw, getPageURL(self.request.page)).getEvents():
    4.17 +        resource = parseEventsInXMLCalendar(self.raw, getPageURL(self.request.page))
    4.18 +
    4.19 +        for event in resource.getEvents():
    4.20              formatEvent(event, self.request, fmt, write=write, parser_cls=RawParser)
    4.21  
    4.22 +        formatMethod(resource, self.request, fmt, write)
    4.23 +
    4.24      # Extra API methods.
    4.25  
    4.26      def formatForOutputType(self, mimetype, write=None):
    4.27 @@ -69,8 +73,9 @@
    4.28          if mimetype == "application/calendar+xml":
    4.29              (write or request.write)(self.raw)
    4.30          else:
    4.31 -            events = parseEventsInXMLCalendar(self.raw, getPageURL(self.request.page)).getEvents()
    4.32 -            formatEventsForOutputType(events, self.request, mimetype, write=write)
    4.33 +            resource = parseEventsInXMLCalendar(self.raw, getPageURL(self.request.page))
    4.34 +            events = resource.getEvents()
    4.35 +            formatEventsForOutputType(events, self.request, mimetype, write=write, resource=resource)
    4.36  
    4.37      # Class methods.
    4.38