Set license using %license
[platform/upstream/libical.git] / src / python / Property.py
1 #!/usr/bin/env python 
2 # -*- Mode: python -*-
3 #======================================================================
4 # FILE: Property.py
5 # CREATOR: eric 
6 #
7 # DESCRIPTION:
8 #   
9 #
10 #  $Id: Property.py,v 1.13 2002-10-24 13:44:30 acampi Exp $
11 #  $Locker:  $
12 #
13 # (C) COPYRIGHT 2001, Eric Busboom <eric@softwarestudio.org>
14 # (C) COPYRIGHT 2001, Patrick Lewis <plewis@inetarena.com>  
15 #
16 # This program is free software; you can redistribute it and/or modify
17 # it under the terms of either: 
18 #
19 #    The LGPL as published by the Free Software Foundation, version
20 #    2.1, available at: http://www.fsf.org/copyleft/lesser.html
21 #
22 #  Or:
23 #
24 #    The Mozilla Public License Version 1.0. You may obtain a copy of
25 #    the License at http://www.mozilla.org/MPL/
26 #======================================================================
27
28 from LibicalWrap import *
29 import re
30 import base64
31 from string import index, upper, split
32 from types import StringType
33
34 #def icalerror_supress(arg): 
35 #    pass
36
37 #def icalerror_restore(a,b):
38 #    pass
39
40 def error_type():
41     error = icalerror_perror()
42     return error[:index(error,':')]
43
44 def test_enum(prop,enum):
45
46     vkind = icalvalue_string_to_kind(prop)
47     e = icalproperty_kind_and_string_to_enum(vkind, enum)
48
49     if e != 0:
50         return 1
51     
52     return None
53
54
55 class Property(object):
56     """ Represent any iCalendar Property.
57
58     Usage:
59     Property(dict)
60
61     Where:
62     dict is a dictionary with keys of 'name', 'value_type', and 'value'.
63     In addition, parameter:parameter value entries may be included.
64     """
65
66     class ConstructorFailedError(Exception):
67         "Failed to construct a property"
68
69     class UpdateFailedError(Exception):
70         "Failed to update the value of a property"
71         
72
73     def __init__(self, type = None, ref = None):
74
75
76         #~ assert(ref == None or isinstance(ref,StringType))
77         #~ assert(type == None or isinstance(type,StringType))
78
79         self._ref = None
80         
81         if ref != None:
82             self._ref = ref
83         elif type != None:
84             kind  = icalproperty_string_to_kind(type)
85             self._ref = icalproperty_new(kind)
86
87             if type.find("X-") == 0:
88                 icalproperty_set_x_name(self._ref, type)
89
90         if self._ref == None or self._ref == 'NULL':
91             raise Property.ConstructorFailedError("Failed to construct Property: %s (%s)"%(type, ref))
92             
93         self._deleted = 0;
94
95         # Initialize all of the required keys
96
97
98     def __del__(self):
99
100         self._deleted = 1;
101
102         if not self._deleted and \
103            self.ref() and \
104            icalproperty_get_parent(self.ref()) == 'NULL':
105             
106             icalproperty_free(self.ref())
107             
108     def name(self,v=None):
109         """ Return the name of the property """
110         return icalproperty_get_property_name(self._ref)
111
112     def ref(self,v=None):
113         """ Return the internal reference to the libical icalproperty """
114         if(v != None):
115
116             if not self._deleted and self._ref and \
117                icalproperty_get_parent(self._ref) == 'NULL':
118                 
119                 icalproperty_free(self._ref)
120
121             self._ref = v
122
123         return self._ref
124
125
126     def value(self,v=None, kind = None):
127         """ Return the RFC2445 representation of the value """
128
129         if(v != None):
130             
131             if kind != None:
132                 # Get the default kind of value for this property 
133                 default_kind = icalvalue_kind_to_string(
134                     icalproperty_kind_to_value_kind(
135                         icalproperty_string_to_kind(self.name())))
136
137                 if(kind != default_kind):
138                     self.__setitem__('VALUE',kind)
139                 vt = kind
140             elif self.__getitem__('VALUE'):
141                 vt = self.__getitem__('VALUE')
142                 print "###########", self
143             else:
144                 vt = 'NO' # Use the kind of the existing value
145
146
147             icalerror_clear_errno()
148
149             #e1=icalerror_supress("MALFORMEDDATA")
150             if (self.name() == None or self.name().find("X-") == 0) and type(v) is StringType:
151                 v = icallangbind_quote_as_ical(v)
152
153             if isinstance(v, unicode):
154                 v = v.encode('utf8')
155
156             icalproperty_set_value_from_string(self._ref,str(v),vt)
157             #icalerror_restore("MALFORMEDDATA",e1)
158
159             if error_type() != "NO":
160                 raise Property.UpdateFailedError(error_type())
161
162             s = icalproperty_get_value_as_string(self._ref)
163
164         return icalproperty_get_value_as_string(self._ref)
165
166     def parameters(self):
167         """
168         Return a list of parameters
169         """
170
171         params = [] 
172
173         p = icallangbind_get_first_parameter(self._ref) 
174         
175         while p != None:
176                 kv = split(icalparameter_as_ical_string(p),'=',2)
177                 params.append(kv[0])
178                 p = icallangbind_get_next_parameter(self._ref)
179
180         return params
181
182     def as_ical_string(self):
183         "Return the property in iCalendar text format."
184         return icalproperty_as_ical_string(self._ref)
185
186     def __getitem__(self,key):
187         """ Return property values by name """
188         key = upper(key)
189         str = icalproperty_get_parameter_as_string(self._ref,key)
190         
191         if(str == 'NULL'): return None
192
193         return str
194
195     def __setitem__(self,key,value):
196         """ Set Property Values by Name """
197         key = upper(key)
198
199         icalproperty_set_parameter_from_string(self._ref,key,value)
200
201         return self.__getitem__(key)
202
203     def __delitem__(self,key):
204         """ Remove Property Values by Name """
205         key = upper(key)
206
207         if self.__getitem__(key):
208                 icalproperty_remove_parameter_by_name(self._ref,key)
209
210     def __str__(self):
211
212         str = self.as_ical_string()
213         return re.sub('\r?\n ?','',str)
214
215     def __cmp__(self, other):
216         s_str = str(self)
217         o_str = str(other)
218
219         return cmp(s_str,o_str)
220
221
222 class RecurrenceSet: 
223     """
224     Represents a set of event occurrences. This
225     class controls a component's RRULE, EXRULE, RDATE and EXDATE
226     properties and can produce from them a set of occurrences. 
227     """
228
229     def __init__(self):
230         pass
231
232     def include(self, **params): 
233         """ 
234         Include a date or rule to the set. 
235
236         Use date= or pass in a
237         Time instance to include a date. Included dates will add an
238         RDATE property or will remove an EXDATE property of the same
239         date.
240
241         Use rule= or pass in a string to include a rule. Included
242         rules with either add a RRULE property or remove an EXRULE
243         property.
244
245         """
246         pass
247
248     def exclude(self, **params): 
249         """ 
250         Exclude date or rule to the set. 
251
252         Use date= or pass in a Time instance to exclude a
253         date. Excluded dates will add an EXDATE property or will remove
254         an RDATE property of the same date.
255
256         Use rule= or pass in a string to exclude a rule. Excluded
257         rules with either add an EXRULE property or remove an RRULE
258         property.
259
260         """
261         pass
262         
263     def occurrences(self, count=None):
264         """
265         Return 'count' occurrences as a tuple of Time instances.
266         """
267         pass
268
269