2.1 --- a/imip_manager.py Sun Feb 08 01:24:49 2015 +0100
2.2 +++ b/imip_manager.py Sun Feb 08 01:26:33 2015 +0100
2.3 @@ -307,11 +307,6 @@
2.4 isinstance(dt, datetime) and babel.dates.format_datetime or babel.dates.format_date,
2.5 dt, format)
2.6
2.7 - def format_end_datetime(self, dt, format):
2.8 - if isinstance(dt, date) and not isinstance(dt, datetime):
2.9 - dt = dt - timedelta(1)
2.10 - return self.format_datetime(dt, format)
2.11 -
2.12 def _format_datetime(self, fn, dt, format):
2.13 return fn(dt, format=format, locale=self.get_user_locale())
2.14
2.15 @@ -485,27 +480,40 @@
2.16 # Obtain the user's timezone and process datetime values.
2.17
2.18 update = False
2.19 - error = False
2.20
2.21 if is_organiser:
2.22 t = self.handle_date_controls("dtstart")
2.23 if t:
2.24 - dtstart, tzid = t
2.25 - update = update or self.set_datetime_in_object(dtstart, tzid, "DTSTART", obj)
2.26 + dtstart, attr = t
2.27 + update = update or self.set_datetime_in_object(dtstart, attr["TZID"], "DTSTART", obj)
2.28 else:
2.29 - error = True
2.30 + return False
2.31 +
2.32 + # Handle specified end datetimes.
2.33 +
2.34 + if args.get("dtend-control", [None])[0] == "enable":
2.35 + t = self.handle_date_controls("dtend")
2.36 + if t:
2.37 + dtend, attr = t
2.38 +
2.39 + # Convert end dates to iCalendar "next day" dates.
2.40
2.41 - t = self.handle_date_controls("dtend")
2.42 - if t:
2.43 - dtend, tzid = t
2.44 - update = update or self.set_datetime_in_object(dtend, tzid, "DTEND", obj)
2.45 + if not isinstance(dtend, datetime):
2.46 + dtend += timedelta(1)
2.47 + update = update or self.set_datetime_in_object(dtend, attr["TZID"], "DTEND", obj)
2.48 + else:
2.49 + return False
2.50 +
2.51 + # Otherwise, treat the end date as the start date. Datetimes cannot
2.52 + # be duplicated in such a way.
2.53 +
2.54 else:
2.55 - error = True
2.56 + if isinstance(dtstart, datetime):
2.57 + return False
2.58 + dtend = dtstart + timedelta(1)
2.59 + update = update or self.set_datetime_in_object(dtend, attr["TZID"], "DTEND", obj)
2.60
2.61 - if not error:
2.62 - error = dtstart > dtend
2.63 -
2.64 - if error:
2.65 + if dtstart >= dtend:
2.66 return False
2.67
2.68 # Process any action.
2.69 @@ -554,7 +562,7 @@
2.70
2.71 """
2.72 Handle date control information for fields starting with 'name',
2.73 - returning a (datetime, tzid) tuple or None if the fields cannot be used
2.74 + returning a (datetime, attr) tuple or None if the fields cannot be used
2.75 to construct a datetime object.
2.76 """
2.77
2.78 @@ -570,9 +578,10 @@
2.79
2.80 time = (hour or minute or second) and "T%s%s%s" % (hour, minute, second) or ""
2.81 value = "%s%s" % (date, time)
2.82 - dt = get_datetime(value, {"TZID" : tzid})
2.83 + attr = {"TZID" : tzid}
2.84 + dt = get_datetime(value, attr)
2.85 if dt:
2.86 - return dt, tzid
2.87 + return dt, attr
2.88
2.89 return None
2.90
2.91 @@ -668,6 +677,38 @@
2.92
2.93 tzid = self.get_tzid()
2.94
2.95 + # Provide controls to change the displayed object.
2.96 +
2.97 + args = self.env.get_args()
2.98 +
2.99 + t = self.handle_date_controls("dtstart")
2.100 + if t:
2.101 + dtstart, dtstart_attr = t
2.102 + else:
2.103 + dtstart, dtstart_attr = obj.get_datetime_item("DTSTART")
2.104 +
2.105 + dtend, dtend_attr = None, None
2.106 +
2.107 + if args.get("dtend-control", [None])[0] == "enable":
2.108 + t = self.handle_date_controls("dtend")
2.109 + if t:
2.110 + dtend, dtend_attr = t
2.111 + elif not args.has_key("dtend-control"):
2.112 + dtend, dtend_attr = obj.get_datetime_item("DTEND")
2.113 +
2.114 + # Change end dates to refer to the actual dates, not the iCalendar
2.115 + # "next day" dates.
2.116 +
2.117 + if dtend and not isinstance(dtend, datetime):
2.118 + dtend -= timedelta(1)
2.119 +
2.120 + if isinstance(dtend, datetime) or dtstart != dtend:
2.121 + page.input(name="dtend-control", type="radio", value="enable", id="dtend-enable", checked="checked")
2.122 + page.input(name="dtend-control", type="radio", value="disable", id="dtend-disable")
2.123 + else:
2.124 + page.input(name="dtend-control", type="radio", value="enable", id="dtend-enable")
2.125 + page.input(name="dtend-control", type="radio", value="disable", id="dtend-disable", checked="checked")
2.126 +
2.127 # Provide a summary of the object.
2.128
2.129 page.table(class_="object", cellspacing=5, cellpadding=5)
2.130 @@ -686,16 +727,30 @@
2.131 # Handle datetimes specially.
2.132
2.133 if name in ["DTSTART", "DTEND"]:
2.134 - value, attr = obj.get_item(name)
2.135 - event_tzid = attr.get("TZID", tzid)
2.136 - strvalue = (
2.137 - name == "DTSTART" and self.format_datetime or self.format_end_datetime
2.138 - )(to_timezone(get_datetime(value), event_tzid), "full")
2.139 - page.th(label, class_="objectheading")
2.140 +
2.141 + page.th(label, class_="objectheading %s" % name.lower())
2.142 +
2.143 + if name == "DTSTART":
2.144 + dt, attr, event_tzid = dtstart, dtstart_attr, dtstart_attr.get("TZID", tzid)
2.145 + else:
2.146 + dt, attr, event_tzid = dtend, dtend_attr, dtend_attr.get("TZID", tzid)
2.147 +
2.148 + strvalue = self.format_datetime(dt, "full")
2.149 + value = format_datetime(dt)
2.150
2.151 if is_organiser:
2.152 - page.td()
2.153 + page.td(class_="objectvalue %s" % name.lower())
2.154 + if name == "DTEND":
2.155 + page.div(class_="disabled")
2.156 + page.label("Specify end date", for_="dtend-enable", class_="enable")
2.157 + page.div.close()
2.158 +
2.159 + page.div(class_="enabled")
2.160 self._show_date_controls(name.lower(), value, attr, tzid)
2.161 + if name == "DTEND":
2.162 + page.label("End on same day", for_="dtend-disable", class_="disable")
2.163 + page.div.close()
2.164 +
2.165 page.td.close()
2.166 else:
2.167 page.td(strvalue)
2.168 @@ -705,7 +760,8 @@
2.169 # Handle the summary specially.
2.170
2.171 elif name == "SUMMARY":
2.172 - value = obj.get_value(name)
2.173 + value = args.get("summary", [obj.get_value(name)])[0]
2.174 +
2.175 page.th(label, class_="objectheading")
2.176 page.td()
2.177 if is_organiser: