1.1 --- a/imipweb/data.py Wed Jun 14 00:30:32 2017 +0200
1.2 +++ b/imipweb/data.py Sun Sep 10 23:45:01 2017 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Web interface data abstractions.
1.6
1.7 -Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2014, 2015, 2017 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -323,4 +323,130 @@
1.13 else:
1.14 return event_period_from_period(period).as_form_period()
1.15
1.16 +# Form field extraction and serialisation.
1.17 +
1.18 +def get_date_control_values(args, name, multiple=False, tzid_name=None, tzid=None):
1.19 +
1.20 + """
1.21 + Return a form date object representing fields taken from 'args' starting
1.22 + with 'name'.
1.23 +
1.24 + If 'multiple' is set to a true value, many date objects will be returned
1.25 + corresponding to a collection of datetimes.
1.26 +
1.27 + If 'tzid_name' is specified, the time zone information will be acquired
1.28 + from fields starting with 'tzid_name' instead of 'name'.
1.29 +
1.30 + If 'tzid' is specified, it will provide the time zone where no explicit
1.31 + time zone information is indicated in the field data.
1.32 + """
1.33 +
1.34 + dates = args.get("%s-date" % name, [])
1.35 + hours = args.get("%s-hour" % name, [])
1.36 + minutes = args.get("%s-minute" % name, [])
1.37 + seconds = args.get("%s-second" % name, [])
1.38 + tzids = args.get("%s-tzid" % (tzid_name or name), [])
1.39 +
1.40 + # Handle absent values by employing None values.
1.41 +
1.42 + field_values = map(None, dates, hours, minutes, seconds, tzids)
1.43 +
1.44 + if not field_values and not multiple:
1.45 + all_values = FormDate()
1.46 + else:
1.47 + all_values = []
1.48 + for date, hour, minute, second, tzid_field in field_values:
1.49 + value = FormDate(date, hour, minute, second, tzid_field or tzid)
1.50 +
1.51 + # Return a single value or append to a collection of all values.
1.52 +
1.53 + if not multiple:
1.54 + return value
1.55 + else:
1.56 + all_values.append(value)
1.57 +
1.58 + return all_values
1.59 +
1.60 +def set_date_control_values(args, name, formdates, tzid_name=None):
1.61 +
1.62 + """
1.63 + Replace form fields in 'args' starting with 'name' using the values of the
1.64 + given 'formdates'.
1.65 +
1.66 + If 'tzid_name' is specified, the time zone information will be stored in
1.67 + fields starting with 'tzid_name' instead of 'name'.
1.68 + """
1.69 +
1.70 + args["%s-date" % name] = []
1.71 + args["%s-hour" % name] = []
1.72 + args["%s-minute" % name] = []
1.73 + args["%s-second" % name] = []
1.74 + args["%s-tzid" % (tzid_name or name)] = []
1.75 +
1.76 + for d in formdates:
1.77 + args["%s-date" % name].append(d.date)
1.78 + args["%s-hour" % name].append(d.hour)
1.79 + args["%s-minute" % name].append(d.minute)
1.80 + args["%s-second" % name].append(d.second)
1.81 + args["%s-tzid" % (tzid_name or name)].append(d.tzid)
1.82 +
1.83 +def get_period_control_values(args, start_name, end_name,
1.84 + end_enabled_name, times_enabled_name,
1.85 + origin=None, origin_name=None,
1.86 + replaced_name=None, tzid=None):
1.87 +
1.88 + """
1.89 + Return period values from fields found in 'args' containing the given
1.90 + 'start_name' (for start dates), 'end_name' (for end dates),
1.91 + 'end_enabled_name' (to enable end dates for periods), 'times_enabled_name'
1.92 + (to enable times for periods).
1.93 +
1.94 + If 'origin' is specified, a single period with the given origin is
1.95 + returned. If 'origin_name' is specified, fields containing the name will
1.96 + provide origin information, and fields containing 'replaced_name' will
1.97 + indicate periods that are replaced.
1.98 +
1.99 + If 'tzid' is specified, it will provide the time zone where no explicit
1.100 + time zone information is indicated in the field data.
1.101 + """
1.102 +
1.103 + # Get the end datetime and time presence settings.
1.104 +
1.105 + all_end_enabled = args.get(end_enabled_name, [])
1.106 + all_times_enabled = args.get(times_enabled_name, [])
1.107 +
1.108 + # Get the origins of period data and whether the periods are replaced.
1.109 +
1.110 + if origin:
1.111 + all_origins = [origin]
1.112 + else:
1.113 + all_origins = origin_name and args.get(origin_name, []) or []
1.114 +
1.115 + all_replaced = replaced_name and args.get(replaced_name, []) or []
1.116 +
1.117 + # Get the start and end datetimes.
1.118 +
1.119 + all_starts = get_date_control_values(args, start_name, True, tzid=tzid)
1.120 + all_ends = get_date_control_values(args, end_name, True, start_name, tzid=tzid)
1.121 +
1.122 + periods = []
1.123 +
1.124 + for index, (start, end, found_origin) in \
1.125 + enumerate(map(None, all_starts, all_ends, all_origins)):
1.126 +
1.127 + end_enabled = str(index) in all_end_enabled
1.128 + times_enabled = str(index) in all_times_enabled
1.129 + replaced = str(index) in all_replaced
1.130 +
1.131 + period = FormPeriod(start, end, end_enabled, times_enabled, tzid,
1.132 + found_origin or origin, replaced)
1.133 + periods.append(period)
1.134 +
1.135 + # Return a single period if a single origin was specified.
1.136 +
1.137 + if origin:
1.138 + return periods[0]
1.139 + else:
1.140 + return periods
1.141 +
1.142 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/imipweb/event.py Wed Jun 14 00:30:32 2017 +0200
2.2 +++ b/imipweb/event.py Sun Sep 10 23:45:01 2017 +0200
2.3 @@ -3,7 +3,7 @@
2.4 """
2.5 A Web interface to a calendar event.
2.6
2.7 -Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
2.8 +Copyright (C) 2014, 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
2.9
2.10 This program is free software; you can redistribute it and/or modify it under
2.11 the terms of the GNU General Public License as published by the Free Software
2.12 @@ -23,7 +23,8 @@
2.13 uri_parts, uri_values
2.14 from imiptools.dates import format_datetime, to_timezone
2.15 from imiptools.mail import Messenger
2.16 -from imipweb.data import EventPeriod, event_period_from_period, FormPeriod, PeriodError
2.17 +from imipweb.data import EventPeriod, event_period_from_period, \
2.18 + get_period_control_values, PeriodError
2.19 from imipweb.resource import DateTimeFormUtilities, FormUtilities, ResourceClientForObject
2.20
2.21 # Fake gettext method for strings to be translated later.
2.22 @@ -312,13 +313,9 @@
2.23
2.24 elif name == "ATTENDEE":
2.25 attendee_map = dict(items)
2.26 - first = True
2.27
2.28 for i, value in enumerate(attendees):
2.29 - if not first:
2.30 - page.tr()
2.31 - else:
2.32 - first = False
2.33 + if i: page.tr()
2.34
2.35 # Obtain details of attendees to supply attributes.
2.36
2.37 @@ -327,8 +324,7 @@
2.38
2.39 # Allow more attendees to be specified.
2.40
2.41 - if not first:
2.42 - page.tr()
2.43 + if i: page.tr()
2.44
2.45 page.td(colspan=2)
2.46 self.control("add", "submit", "add", id="add", class_="add")
2.47 @@ -339,13 +335,8 @@
2.48 # Handle potentially many values of other kinds.
2.49
2.50 else:
2.51 - first = True
2.52 -
2.53 for i, (value, attr) in enumerate(items):
2.54 - if not first:
2.55 - page.tr()
2.56 - else:
2.57 - first = False
2.58 + if i: page.tr()
2.59
2.60 page.td(class_="objectvalue %s" % field, colspan=2)
2.61 if name == "ORGANIZER":
2.62 @@ -1009,14 +1000,11 @@
2.63
2.64 "Return the main period defined in the event form."
2.65
2.66 - args = self.env.get_args()
2.67 -
2.68 - dtend_enabled = args.get("dtend-control", [None])[0]
2.69 - dttimes_enabled = args.get("dttimes-control", [None])[0]
2.70 - start = self.get_date_control_values("dtstart")
2.71 - end = self.get_date_control_values("dtend")
2.72 -
2.73 - period = FormPeriod(start, end, dtend_enabled, dttimes_enabled, self.get_tzid(), "DTSTART")
2.74 + period = get_period_control_values(self.env.get_args(),
2.75 + "dtstart", "dtend",
2.76 + "dtend-control", "dttimes-control",
2.77 + origin="DTSTART",
2.78 + tzid=self.get_tzid())
2.79
2.80 # Handle absent main period details.
2.81
2.82 @@ -1029,28 +1017,11 @@
2.83
2.84 "Return the recurrences defined in the event form."
2.85
2.86 - args = self.env.get_args()
2.87 -
2.88 - all_dtend_enabled = args.get("dtend-control-recur", [])
2.89 - all_dttimes_enabled = args.get("dttimes-control-recur", [])
2.90 - all_starts = self.get_date_control_values("dtstart-recur", multiple=True)
2.91 - all_ends = self.get_date_control_values("dtend-recur", multiple=True, tzid_name="dtstart-recur")
2.92 - all_origins = args.get("recur-origin", [])
2.93 - all_replaced = args.get("recur-replaced", [])
2.94 -
2.95 - periods = []
2.96 -
2.97 - for index, (start, end, origin) in \
2.98 - enumerate(map(None, all_starts, all_ends, all_origins)):
2.99 -
2.100 - dtend_enabled = str(index) in all_dtend_enabled
2.101 - dttimes_enabled = str(index) in all_dttimes_enabled
2.102 - replaced = str(index) in all_replaced
2.103 -
2.104 - period = FormPeriod(start, end, dtend_enabled, dttimes_enabled, self.get_tzid(), origin, replaced)
2.105 - periods.append(period)
2.106 -
2.107 - return periods
2.108 + return get_period_control_values(self.env.get_args(),
2.109 + "dtstart-recur", "dtend-recur",
2.110 + "dtend-control-recur", "dttimes-control-recur",
2.111 + origin_name="recur-origin", replaced_name="recur-replaced",
2.112 + tzid=self.get_tzid())
2.113
2.114 def set_recurrences_in_page(self, recurrences):
2.115
3.1 --- a/imipweb/resource.py Wed Jun 14 00:30:32 2017 +0200
3.2 +++ b/imipweb/resource.py Sun Sep 10 23:45:01 2017 +0200
3.3 @@ -25,7 +25,8 @@
3.4 from imiptools.dates import format_datetime, to_date
3.5 from imiptools.freebusy import FreeBusyCollection
3.6 from imipweb.data import event_period_from_period, form_period_from_period, \
3.7 - FormDate, PeriodError
3.8 + get_date_control_values, set_date_control_values, \
3.9 + PeriodError
3.10 from imipweb.env import CGIEnvironment
3.11 from urllib import urlencode
3.12 import babel.dates
3.13 @@ -432,7 +433,7 @@
3.14 return index is not None and "%s-%s" % (name, suffix) or name
3.15
3.16 def element_enable(self, index=None):
3.17 - return index is not None and str(index) or "enable"
3.18 + return str(index or 0)
3.19
3.20 def show_object_datetime_controls(self, period, index=None):
3.21
3.22 @@ -445,7 +446,6 @@
3.23 p = form_period_from_period(period)
3.24
3.25 page = self.page
3.26 - args = self.env.get_args()
3.27 _id = self.element_identifier
3.28 _name = self.element_name
3.29 _enable = self.element_enable
3.30 @@ -632,33 +632,7 @@
3.31 from fields starting with 'tzid_name' instead of 'name'.
3.32 """
3.33
3.34 - args = self.env.get_args()
3.35 -
3.36 - dates = args.get("%s-date" % name, [])
3.37 - hours = args.get("%s-hour" % name, [])
3.38 - minutes = args.get("%s-minute" % name, [])
3.39 - seconds = args.get("%s-second" % name, [])
3.40 - tzids = args.get("%s-tzid" % (tzid_name or name), [])
3.41 -
3.42 - # Handle absent values by employing None values.
3.43 -
3.44 - field_values = map(None, dates, hours, minutes, seconds, tzids)
3.45 -
3.46 - if not field_values and not multiple:
3.47 - all_values = FormDate()
3.48 - else:
3.49 - all_values = []
3.50 - for date, hour, minute, second, tzid in field_values:
3.51 - value = FormDate(date, hour, minute, second, tzid or self.get_tzid())
3.52 -
3.53 - # Return a single value or append to a collection of all values.
3.54 -
3.55 - if not multiple:
3.56 - return value
3.57 - else:
3.58 - all_values.append(value)
3.59 -
3.60 - return all_values
3.61 + get_date_control_values(self.env.get_args(), name, multiple, tzid_name, self.get_tzid())
3.62
3.63 def set_date_control_values(self, name, formdates, tzid_name=None):
3.64
3.65 @@ -670,12 +644,6 @@
3.66 fields starting with 'tzid_name' instead of 'name'.
3.67 """
3.68
3.69 - args = self.env.get_args()
3.70 -
3.71 - args["%s-date" % name] = [d.date for d in formdates]
3.72 - args["%s-hour" % name] = [d.hour for d in formdates]
3.73 - args["%s-minute" % name] = [d.minute for d in formdates]
3.74 - args["%s-second" % name] = [d.second for d in formdates]
3.75 - args["%s-tzid" % (tzid_name or name)] = [d.tzid for d in formdates]
3.76 + set_date_control_values(self.env.get_args(), name, formdates, tzid_name)
3.77
3.78 # vim: tabstop=4 expandtab shiftwidth=4