1.1 --- a/imipweb/event.py Thu Oct 15 23:32:57 2015 +0200
1.2 +++ b/imipweb/event.py Fri Oct 16 00:01:10 2015 +0200
1.3 @@ -234,7 +234,7 @@
1.4 if name in "ATTENDEE":
1.5 rowspan = len(attendees) + 1
1.6 elif name == "DTEND":
1.7 - rowspan = 1
1.8 + rowspan = 2
1.9 elif not items:
1.10 continue
1.11
1.12 @@ -276,6 +276,16 @@
1.13
1.14 page.tr.close()
1.15
1.16 + # After the end datetime, show a control to add recurrences.
1.17 +
1.18 + if name == "DTEND":
1.19 + page.tr()
1.20 + page.td()
1.21 + self.control("recur-add", "submit", "add", id="recur-add", class_="add")
1.22 + page.label("Add a recurrence", for_="recur-add", class_="add")
1.23 + page.td.close()
1.24 + page.tr.close()
1.25 +
1.26 # Handle the summary specially.
1.27
1.28 elif name == "SUMMARY":
1.29 @@ -482,8 +492,13 @@
1.30 page = self.page
1.31 args = self.env.get_args()
1.32
1.33 - p = event_period_from_period(period)
1.34 - replaced = not recurrenceid and p.is_replaced(recurrenceids)
1.35 + try:
1.36 + p = event_period_from_period(period)
1.37 + except PeriodError, exc:
1.38 + replaced = False
1.39 + errors = list(errors or []) + [exc.args]
1.40 + else:
1.41 + replaced = not recurrenceid and p.is_replaced(recurrenceids)
1.42
1.43 # Isolate the controls from neighbouring tables.
1.44
1.45 @@ -1143,7 +1158,10 @@
1.46
1.47 recurrences = self.get_recurrences_from_page()
1.48
1.49 - # NOTE: Addition of recurrences to be supported.
1.50 + if args.has_key("recur-add"):
1.51 + period = self.get_current_main_period().as_form_period()
1.52 + period.origin = "RDATE"
1.53 + recurrences.append(period)
1.54
1.55 # Only actually remove recurrences if the event is unsent, or if the
1.56 # recurrence is new, but only for explicit recurrences.
2.1 --- a/imipweb/resource.py Thu Oct 15 23:32:57 2015 +0200
2.2 +++ b/imipweb/resource.py Fri Oct 16 00:01:10 2015 +0200
2.3 @@ -24,7 +24,8 @@
2.4 from imiptools.data import get_address, get_uri, uri_item, uri_values
2.5 from imiptools.dates import format_datetime, get_recurrence_start_point, to_date
2.6 from imiptools.period import remove_period, remove_affected_period
2.7 -from imipweb.data import event_period_from_period, form_period_from_period, FormDate
2.8 +from imipweb.data import event_period_from_period, form_period_from_period, \
2.9 + FormDate, PeriodError
2.10 from imipweb.env import CGIEnvironment
2.11 from urllib import urlencode
2.12 import babel.dates
2.13 @@ -654,20 +655,28 @@
2.14 _id = self.element_identifier
2.15 _name = self.element_name
2.16
2.17 - p = event_period_from_period(period)
2.18 - replaced = not recurrenceid and p.is_replaced(recurrenceids)
2.19 + try:
2.20 + p = event_period_from_period(period)
2.21 + except PeriodError, exc:
2.22 + replaced = False
2.23 + errors = exc.args
2.24 + else:
2.25 + replaced = not recurrenceid and p.is_replaced(recurrenceids)
2.26 + errors = []
2.27 +
2.28 + period = form_period_from_period(period)
2.29
2.30 # Show controls for editing as organiser.
2.31 - # NOTE: Allow attendees to edit datetimes for counter-proposals.
2.32
2.33 if self.can_change_object() and not replaced:
2.34 - page.td(class_="objectvalue dt%s" % (show_start and "start" or "end"))
2.35 + error = errors and (show_start and ("dtstart", index) in errors or not show_start and ("dtend", index) in errors) and " error" or ""
2.36 + page.td(class_="objectvalue dt%s%s" % (show_start and "start" or "end", error))
2.37
2.38 read_only = period.origin == "RRULE"
2.39
2.40 if show_start:
2.41 page.div(class_="dt enabled")
2.42 - self.date_controls(_name("dtstart", "recur", index), p.get_form_start(), index=index, read_only=read_only)
2.43 + self.date_controls(_name("dtstart", "recur", index), period.get_form_start(), index=index, read_only=read_only)
2.44 if not read_only:
2.45 page.br()
2.46 page.label("Specify times", for_=_id("dttimes-enable", index), class_="time disabled enable")
2.47 @@ -676,7 +685,7 @@
2.48
2.49 # Put the origin somewhere.
2.50
2.51 - self.control("recur-origin", "hidden", p.origin or "")
2.52 + self.control("recur-origin", "hidden", period.origin or "")
2.53
2.54 else:
2.55 page.div(class_="dt disabled")
2.56 @@ -684,7 +693,7 @@
2.57 page.label("Specify end date", for_=_id("dtend-enable", index), class_="enable")
2.58 page.div.close()
2.59 page.div(class_="dt enabled")
2.60 - self.date_controls(_name("dtend", "recur", index), p.get_form_end(), index=index, show_tzid=False, read_only=read_only)
2.61 + self.date_controls(_name("dtend", "recur", index), period.get_form_end(), index=index, show_tzid=False, read_only=read_only)
2.62 if not read_only:
2.63 page.br()
2.64 page.label("End on same day", for_=_id("dtend-enable", index), class_="disable")
2.65 @@ -710,15 +719,25 @@
2.66
2.67 page = self.page
2.68
2.69 - p = event_period_from_period(period)
2.70 - replaced = not recurrenceid and p.is_replaced(recurrenceids)
2.71 + try:
2.72 + p = event_period_from_period(period)
2.73 + except PeriodError, exc:
2.74 + replaced = False
2.75 + affected = False
2.76 + errors = exc.args
2.77 + else:
2.78 + replaced = not recurrenceid and p.is_replaced(recurrenceids)
2.79 + affected = p.is_affected(recurrenceid)
2.80 + errors = []
2.81 +
2.82 + period = form_period_from_period(period)
2.83
2.84 css = " ".join([
2.85 replaced and "replaced" or "",
2.86 - p.is_affected(recurrenceid) and "affected" or ""
2.87 + affected and "affected" or ""
2.88 ])
2.89
2.90 - formdate = show_start and p.get_form_start() or p.get_form_end()
2.91 + formdate = show_start and period.get_form_start() or period.get_form_end()
2.92 dt = formdate.as_datetime()
2.93 if dt:
2.94 page.td(self.format_datetime(dt, "long"), class_=css)