1.1 --- a/vCalendar.py Sun Nov 02 00:32:48 2008 +0100
1.2 +++ b/vCalendar.py Sun Nov 02 04:06:23 2008 +0100
1.3 @@ -34,27 +34,42 @@
1.4 except NameError:
1.5 from sets import Set as set
1.6
1.7 +# Format details.
1.8 +
1.9 +QUOTED_PARAMETERS = set([
1.10 + "ALTREP", "DELEGATED-FROM", "DELEGATED-TO", "DIR", "MEMBER", "SENT-BY"
1.11 + ])
1.12 +MULTIVALUED_PARAMETERS = set([
1.13 + "DELEGATED-FROM", "DELEGATED-TO", "MEMBER"
1.14 + ])
1.15 +QUOTED_TYPES = set(["URI"])
1.16 +
1.17 +# Parser classes.
1.18 +
1.19 class vCalendarStreamParser(vContent.StreamParser):
1.20
1.21 "A stream parser specifically for vCalendar/iCalendar."
1.22
1.23 - quoted_parameters = set([
1.24 - "ALTREP", "DELEGATED-FROM", "DELEGATED-TO", "DIR", "MEMBER", "SENT-BY"
1.25 - ])
1.26 - multivalued_parameters = set([
1.27 - "DELEGATED-FROM", "DELEGATED-TO", "MEMBER"
1.28 - ])
1.29 - quoted_types = set(["URI"])
1.30 -
1.31 def next(self):
1.32
1.33 """
1.34 Return the next content item in the file as a tuple of the form
1.35 - (name, parameters, values).
1.36 + (name, parameters, value).
1.37 """
1.38
1.39 - name, parameters, values = vContent.StreamParser.next(self)
1.40 - return name, self.decode_parameters(parameters), values
1.41 + name, parameters, value = vContent.StreamParser.next(self)
1.42 + return name, self.decode_parameters(parameters), self.decode_content(value)
1.43 +
1.44 + def decode_content(self, value):
1.45 +
1.46 + "Decode the given 'value', replacing quoted separator characters."
1.47 +
1.48 + # Replace quoted characters (see 4.3.11 in RFC 2445).
1.49 +
1.50 + value = vContent.StreamParser.decode_content(self, value)
1.51 + return value.replace("\\,", ",").replace("\\;", ";")
1.52 +
1.53 + # Internal methods.
1.54
1.55 def decode_quoted_value(self, value):
1.56
1.57 @@ -74,12 +89,12 @@
1.58 decoded_parameters = {}
1.59
1.60 for param_name, param_value in parameters.items():
1.61 - if param_name in self.quoted_parameters:
1.62 + if param_name in QUOTED_PARAMETERS:
1.63 param_value = self.decode_quoted_value(param_value)
1.64 separator = '","'
1.65 else:
1.66 separator = ","
1.67 - if param_name in self.multivalued_parameters:
1.68 + if param_name in MULTIVALUED_PARAMETERS:
1.69 param_value = param_value.split(separator)
1.70 decoded_parameters[param_name] = param_value
1.71
1.72 @@ -92,6 +107,58 @@
1.73 def parse(self, f, parser_cls=None):
1.74 return vContent.Parser.parse(self, f, vCalendarStreamParser)
1.75
1.76 +# Writer classes.
1.77 +
1.78 +class vCalendarStreamWriter(vContent.StreamWriter):
1.79 +
1.80 + "A stream writer specifically for vCard."
1.81 +
1.82 + def write(self, name, parameters, value):
1.83 +
1.84 + """
1.85 + Write a content line for the given 'name', 'parameters' and 'value'
1.86 + information.
1.87 + """
1.88 +
1.89 + vContent.StreamWriter.write(self, name, self.encode_parameters(parameters), value)
1.90 +
1.91 + # Internal methods.
1.92 +
1.93 + def encode_quoted_value(self, value):
1.94 +
1.95 + "Encode the given 'value'."
1.96 +
1.97 + return '"%s"' % value
1.98 +
1.99 + def encode_parameters(self, parameters):
1.100 +
1.101 + """
1.102 + Encode the given 'parameters' according to the vCalendar specification.
1.103 + """
1.104 +
1.105 + encoded_parameters = {}
1.106 +
1.107 + for param_name, param_value in parameters.items():
1.108 + if param_name in QUOTED_PARAMETERS:
1.109 + param_value = self.encode_quoted_value(param_value)
1.110 + separator = '","'
1.111 + else:
1.112 + separator = ","
1.113 + if param_name in MULTIVALUED_PARAMETERS:
1.114 + param_value = separator.join(param_value)
1.115 + encoded_parameters[param_name] = param_value
1.116 +
1.117 + return encoded_parameters
1.118 +
1.119 + def encode_content(self, value):
1.120 +
1.121 + "Encode the given 'value', replacing separator characters."
1.122 +
1.123 + # Replace quoted characters (see 4.3.11 in RFC 2445).
1.124 +
1.125 + value = vContent.StreamWriter.encode_content(self, value)
1.126 + return value.replace(";", "\\;").replace(",", "\\,")
1.127 +
1.128 # Public functions.
1.129
1.130 def parse(f, non_standard_newline=0):