1.1 --- a/imiptools/data.py Sat May 16 20:03:34 2015 +0200
1.2 +++ b/imiptools/data.py Sun May 17 00:14:36 2015 +0200
1.3 @@ -43,6 +43,14 @@
1.4 def __init__(self, fragment):
1.5 self.objtype, (self.details, self.attr) = fragment.items()[0]
1.6
1.7 + def get_uid(self):
1.8 + return self.get_value("UID")
1.9 +
1.10 + def get_recurrenceid(self):
1.11 + return format_datetime(self.get_utc_datetime("RECURRENCE-ID"))
1.12 +
1.13 + # Structure access.
1.14 +
1.15 def copy(self):
1.16 return Object(to_dict(self.to_node()))
1.17
1.18 @@ -117,7 +125,7 @@
1.19 # Computed results.
1.20
1.21 def has_recurrence(self, tzid, recurrence):
1.22 - recurrences = [p.start for p in get_periods(self, tzid, recurrence, inclusive=True)]
1.23 + recurrences = [p.get_start() for p in get_periods(self, tzid, recurrence, inclusive=True)]
1.24 return recurrence in recurrences
1.25
1.26 def get_periods(self, tzid, end):
1.27 @@ -511,8 +519,8 @@
1.28
1.29 def __call__(self, first, second):
1.30 return cmp(
1.31 - (to_datetime(first.start, self.tzid), to_datetime(first.end, self.tzid)),
1.32 - (to_datetime(second.start, self.tzid), to_datetime(second.end, self.tzid))
1.33 + (to_datetime(first.get_start(), self.tzid), to_datetime(first.get_end(), self.tzid)),
1.34 + (to_datetime(second.get_start(), self.tzid), to_datetime(second.get_end(), self.tzid))
1.35 )
1.36
1.37 def get_periods_for_freebusy(obj, periods, tzid):
1.38 @@ -522,21 +530,12 @@
1.39 using the indicated 'tzid' to convert dates to datetimes.
1.40 """
1.41
1.42 - start, start_attr = obj.get_datetime_item("DTSTART")
1.43 - if obj.has_key("DTEND"):
1.44 - end, end_attr = obj.get_datetime_item("DTEND")
1.45 - elif obj.has_key("DURATION"):
1.46 - duration = obj.get_duration("DURATION")
1.47 - end = start + duration
1.48 - else:
1.49 - end, end_attr = start, start_attr
1.50 -
1.51 - tzid = get_tzid(start_attr, end_attr) or tzid
1.52 + tzid = obj.get_tzid() or tzid
1.53
1.54 l = []
1.55
1.56 for p in periods:
1.57 - start, end = get_freebusy_period(p.start, p.end, tzid)
1.58 + start, end = get_freebusy_period(p.get_start(), p.get_end(), tzid)
1.59 start, end = [to_timezone(x, "UTC") for x in start, end]
1.60
1.61 # Create a new period for free/busy purposes with the converted
5.1 --- a/imipweb/event.py Sat May 16 20:03:34 2015 +0200
5.2 +++ b/imipweb/event.py Sun May 17 00:14:36 2015 +0200
5.3 @@ -23,7 +23,7 @@
5.4 from imiptools.client import update_attendees, update_participation
5.5 from imiptools.data import get_uri, uri_dict, uri_values
5.6 from imiptools.dates import format_datetime, to_date, get_datetime, \
5.7 - get_datetime_item, get_period_item, \
5.8 + get_datetime_item, get_period_item, to_datetime, \
5.9 to_recurrence_start, to_timezone, to_utc_datetime
5.10 from imiptools.mail import Messenger
5.11 from imiptools.period import have_conflict
5.12 @@ -64,33 +64,35 @@
5.13 def is_organiser(self, obj):
5.14 return get_uri(obj.get_value("ORGANIZER")) == self.user
5.15
5.16 - def get_recurrence_key(self, period):
5.17 - return format_datetime(to_utc_datetime(period.get_start(), self.get_tzid()))
5.18 -
5.19 - def get_recurrence_keys(self, recurrenceids):
5.20 - return [to_recurrence_start(s, self.get_tzid()) for s in recurrenceids]
5.21 -
5.22 - def is_replaced(self, period, recurrenceid, recurrenceids):
5.23 - start_utc = self.get_recurrence_key(period)
5.24 - return not recurrenceid and recurrenceids and start_utc in self.get_recurrence_keys(recurrenceids) and "replaced" or ""
5.25 + def is_replaced(self, period, recurrenceids):
5.26 + for s in recurrenceids:
5.27 + dt = to_timezone(get_datetime(s), self.get_tzid())
5.28 + if to_datetime(period.get_start(), self.get_tzid()) == dt:
5.29 + return s
5.30 + return None
5.31
5.32 def is_affected(self, period, recurrenceid):
5.33 - start_utc = self.get_recurrence_key(period)
5.34 - return recurrenceid and start_utc == to_recurrence_start(recurrenceid, self.get_tzid()) and "affected" or ""
5.35 + if not recurrenceid:
5.36 + return None
5.37 + dt = to_timezone(get_datetime(recurrenceid), self.get_tzid())
5.38 + if to_datetime(period.get_start(), self.get_tzid()) == dt:
5.39 + return recurrenceid
5.40 + return None
5.41
5.42 # Request logic methods.
5.43
5.44 - def handle_request(self, uid, recurrenceid, obj):
5.45 + def handle_request(self, obj):
5.46
5.47 """
5.48 - Handle actions involving the given 'uid', 'recurrenceid', and 'obj' as
5.49 - the object's representation, returning an error if one occurred, or None
5.50 - if the request was successfully handled.
5.51 + Handle actions involving the given 'obj' as an object's representation,
5.52 + returning an error if one occurred, or None if the request was
5.53 + successfully handled.
5.54 """
5.55
5.56 # Handle a submitted form.
5.57
5.58 args = self.env.get_args()
5.59 + uid = obj.get_uid()
5.60
5.61 # Get the possible actions.
5.62
5.63 @@ -477,7 +479,7 @@
5.64
5.65 attendees = self.get_current_attendees(obj)
5.66 is_attendee = self.user in attendees
5.67 - is_request = (obj.get_value("UID"), obj.get_value("RECURRENCE-ID")) in self._get_requests()
5.68 + is_request = (obj.get_uid(), obj.get_recurrenceid()) in self._get_requests()
5.69 sequence = obj.get_value("SEQUENCE")
5.70
5.71 # Show appropriate options depending on the role of the user.
5.72 @@ -509,12 +511,12 @@
5.73 self._control("save", "submit", "Save without sending")
5.74 page.p.close()
5.75
5.76 - def show_object_on_page(self, uid, obj, errors=None):
5.77 + def show_object_on_page(self, obj, errors=None):
5.78
5.79 """
5.80 - Show the calendar object with the given 'uid' and representation 'obj'
5.81 - on the current page. If 'errors' is given, show a suitable message for
5.82 - the different errors provided.
5.83 + Show the calendar object with the representation 'obj' on the current
5.84 + page. If 'errors' is given, show a suitable message for the different
5.85 + errors provided.
5.86 """
5.87
5.88 page = self.page
5.89 @@ -522,6 +524,7 @@
5.90
5.91 self._control("editing", "hidden", "true")
5.92
5.93 + uid = obj.get_uid()
5.94 args = self.env.get_args()
5.95
5.96 # Obtain basic event information, generating any necessary editing controls.
5.97 @@ -538,9 +541,9 @@
5.98
5.99 # Obtain any separate recurrences for this event.
5.100
5.101 - recurrenceid = format_datetime(obj.get_utc_datetime("RECURRENCE-ID"))
5.102 + recurrenceid = obj.get_recurrenceid()
5.103 recurrenceids = self._get_recurrences(uid)
5.104 - replaced = self.is_replaced(p, recurrenceid, recurrenceids)
5.105 + replaced = not recurrenceid and self.is_replaced(p, recurrenceids)
5.106
5.107 # Provide a summary of the object.
5.108
5.109 @@ -583,7 +586,7 @@
5.110
5.111 elif name == "DTSTART":
5.112 page.td(class_="objectvalue %s replaced" % field, rowspan=2)
5.113 - page.a("First occurrence replaced by a separate event", href=self.link_to(uid, self.get_recurrence_key(p)))
5.114 + page.a("First occurrence replaced by a separate event", href=self.link_to(uid, replaced))
5.115 page.td.close()
5.116
5.117 page.tr.close()
5.118 @@ -650,7 +653,7 @@
5.119 page.table.close()
5.120
5.121 self.show_recurrences(obj, errors)
5.122 - self.show_conflicting_events(uid, obj)
5.123 + self.show_conflicting_events(obj)
5.124 self.show_request_controls(obj)
5.125
5.126 page.form.close()
5.127 @@ -721,8 +724,8 @@
5.128
5.129 # Obtain any parent object if this object is a specific recurrence.
5.130
5.131 - uid = obj.get_value("UID")
5.132 - recurrenceid = format_datetime(obj.get_utc_datetime("RECURRENCE-ID"))
5.133 + uid = obj.get_uid()
5.134 + recurrenceid = obj.get_recurrenceid()
5.135
5.136 if recurrenceid:
5.137 parent = self._get_object(uid)
5.138 @@ -792,7 +795,7 @@
5.139 sequence = obj.get_value("SEQUENCE")
5.140
5.141 p = event_period_from_period(period)
5.142 - replaced = self.is_replaced(p, recurrenceid, recurrenceids)
5.143 + replaced = not recurrenceid and self.is_replaced(p, recurrenceids)
5.144
5.145 # Isolate the controls from neighbouring tables.
5.146
5.147 @@ -838,15 +841,15 @@
5.148
5.149 page.div.close()
5.150
5.151 - def show_conflicting_events(self, uid, obj):
5.152 + def show_conflicting_events(self, obj):
5.153
5.154 """
5.155 - Show conflicting events for the object having the given 'uid' and
5.156 - representation 'obj'.
5.157 + Show conflicting events for the object having the representation 'obj'.
5.158 """
5.159
5.160 page = self.page
5.161 - recurrenceid = format_datetime(obj.get_utc_datetime("RECURRENCE-ID"))
5.162 + uid = obj.get_uid()
5.163 + recurrenceid = obj.get_recurrenceid()
5.164 recurrenceids = self._get_recurrences(uid)
5.165
5.166 # Obtain the user's timezone.
5.167 @@ -875,7 +878,7 @@
5.168 # Show any conflicts with periods of actual attendance.
5.169
5.170 for p in have_conflict(freebusy, periods, True):
5.171 - if self.is_replaced(p, recurrenceid, recurrenceids):
5.172 + if not recurrenceid and self.is_replaced(p, recurrenceids):
5.173 continue
5.174 if (p.uid != uid or (recurrenceid and p.recurrenceid) and p.recurrenceid != recurrenceid) and p.transp != "ORG":
5.175 conflicts.append(p)
5.176 @@ -901,8 +904,8 @@
5.177
5.178 # Provide details of any conflicting event.
5.179
5.180 - start = self.format_datetime(p.get_start(tzid), "long")
5.181 - end = self.format_datetime(p.get_end(tzid), "long")
5.182 + start = self.format_datetime(to_timezone(p.get_start(), tzid), "long")
5.183 + end = self.format_datetime(to_timezone(p.get_end(), tzid), "long")
5.184
5.185 page.tr()
5.186
5.187 @@ -1036,7 +1039,7 @@
5.188 ssn = self._simple_suffixed_name
5.189
5.190 p = event_period_from_period(period)
5.191 - replaced = self.is_replaced(p, recurrenceid, recurrenceids)
5.192 + replaced = not recurrenceid and self.is_replaced(p, recurrenceids)
5.193
5.194 # Show controls for editing as organiser.
5.195
5.196 @@ -1091,11 +1094,11 @@
5.197 page = self.page
5.198
5.199 p = event_period_from_period(period)
5.200 - replaced = self.is_replaced(p, recurrenceid, recurrenceids)
5.201 + replaced = not recurrenceid and self.is_replaced(p, recurrenceids)
5.202
5.203 css = " ".join([
5.204 - replaced,
5.205 - self.is_affected(p, recurrenceid)
5.206 + replaced and "replaced" or "",
5.207 + self.is_affected(p, recurrenceid) and "affected" or ""
5.208 ])
5.209
5.210 formdate = show_start and p.get_form_start() or p.get_form_end()
5.211 @@ -1117,13 +1120,13 @@
5.212 if not obj:
5.213 return False
5.214
5.215 - errors = self.handle_request(uid, recurrenceid, obj)
5.216 + errors = self.handle_request(obj)
5.217
5.218 if not errors:
5.219 return True
5.220
5.221 self.new_page(title="Event")
5.222 - self.show_object_on_page(uid, obj, errors)
5.223 + self.show_object_on_page(obj, errors)
5.224
5.225 return True
5.226