1.1 --- a/imiptools/__init__.py Tue Oct 03 21:36:04 2017 +0200
1.2 +++ b/imiptools/__init__.py Tue Oct 03 21:36:58 2017 +0200
1.3 @@ -362,12 +362,10 @@
1.4 # Handle parts.
1.5
1.6 for part in msg.walk():
1.7 - if have_itip_part(part):
1.8 - if self.debug:
1.9 - print >>sys.stderr, "Handle method %s..." % part.get_param("method")
1.10 + if self.debug and have_itip_part(part):
1.11 + print >>sys.stderr, "Handle method %s..." % part.get_param("method")
1.12
1.13 - handle_itip_part(part, handlers)
1.14 - handled = True
1.15 + handled = handle_itip_part(part, handlers) or handled
1.16
1.17 # When processing outgoing messages, no replies or deliveries are
1.18 # performed.
2.1 --- a/imiptools/content.py Tue Oct 03 21:36:04 2017 +0200
2.2 +++ b/imiptools/content.py Tue Oct 03 21:36:58 2017 +0200
2.3 @@ -70,12 +70,16 @@
2.4
2.5 """
2.6 Parse the given message 'part' and return a dictionary mapping calendar
2.7 - object type names to lists of fragments, along with the method employed by
2.8 - the parsed calendar object.
2.9 + object type names to lists of fragments.
2.10
2.11 If no iTIP content is found, None is returned.
2.12 """
2.13
2.14 + # Ignore the part if not iTIP-related.
2.15 +
2.16 + if not have_itip_part(part):
2.17 + return None
2.18 +
2.19 # Decode the data and parse it.
2.20
2.21 f = StringIO(part.get_payload(decode=True))
2.22 @@ -95,51 +99,62 @@
2.23 if not consistent_methods(itip_method, method):
2.24 return None
2.25
2.26 - # Assert the object's method as the definitive one.
2.27 + return itip
2.28 +
2.29 +def get_objects_from_itip(itip, handlers):
2.30 +
2.31 + """
2.32 + Return all objects provided by the given 'itip' mapping supported by the
2.33 + given 'handlers'.
2.34 + """
2.35
2.36 - return itip, itip_method
2.37 + objects = []
2.38 +
2.39 + # Look for different kinds of sections.
2.40 +
2.41 + if itip:
2.42 + for name, items in itip.items():
2.43 + if name in handlers:
2.44 + for item in items:
2.45 + objects.append(Object({name : item}))
2.46 +
2.47 + return objects
2.48
2.49 def handle_itip_part(part, handlers):
2.50
2.51 """
2.52 Handle the given iTIP 'part' using the given 'handlers' dictionary.
2.53 - Responses are set in each handler used to handle a message.
2.54 + Responses are set in each handler used to handle a message. Return whether
2.55 + the part could be handled.
2.56 """
2.57
2.58 - itip_details = parse_itip_part(part)
2.59 - if not itip_details:
2.60 - return
2.61 -
2.62 - itip, method = itip_details
2.63 -
2.64 - # Look for different kinds of sections.
2.65 + itip = parse_itip_part(part)
2.66 + method = itip and get_value(itip, "METHOD")
2.67
2.68 - all_results = []
2.69 -
2.70 - for name, items in itip.items():
2.71 + for obj in get_objects_from_itip(itip, handlers):
2.72
2.73 - # Get a handler for the given section.
2.74 + # Get a handler for the given object type.
2.75
2.76 - handler = handlers.get(name)
2.77 + handler = handlers.get(obj.objtype)
2.78 if not handler:
2.79 continue
2.80
2.81 - for item in items:
2.82 + # Dispatch to a handler and obtain any response.
2.83
2.84 - # Dispatch to a handler and obtain any response.
2.85 + handler.set_object(obj)
2.86 + handler.set_identity(method)
2.87
2.88 - handler.set_object(Object({name : item}))
2.89 - handler.set_identity(method)
2.90 + if handler.is_usable(method):
2.91
2.92 - if handler.is_usable(method):
2.93 -
2.94 - # Perform the method in a critical section.
2.95 + # Perform the method in a critical section.
2.96
2.97 - handler.acquire_lock()
2.98 - try:
2.99 - methods[method](handler)()
2.100 - finally:
2.101 - handler.release_lock()
2.102 + handler.acquire_lock()
2.103 + try:
2.104 + methods[method](handler)()
2.105 + finally:
2.106 + handler.release_lock()
2.107 +
2.108 + return not not itip
2.109
2.110 # Handler registry.
2.111