# HG changeset patch # User Paul Boddie # Date 1505079901 -7200 # Node ID 792f00676d622d4e935532510e685d39580e4ab6 # Parent d219182e1817ce79a6125d7bae735e70bacb02a4 Moved form period and date construction into the data module, simplifying the event and resource module code. diff -r d219182e1817 -r 792f00676d62 imipweb/data.py --- a/imipweb/data.py Wed Jun 14 00:30:32 2017 +0200 +++ b/imipweb/data.py Sun Sep 10 23:45:01 2017 +0200 @@ -3,7 +3,7 @@ """ Web interface data abstractions. -Copyright (C) 2014, 2015 Paul Boddie +Copyright (C) 2014, 2015, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -323,4 +323,130 @@ else: return event_period_from_period(period).as_form_period() +# Form field extraction and serialisation. + +def get_date_control_values(args, name, multiple=False, tzid_name=None, tzid=None): + + """ + Return a form date object representing fields taken from 'args' starting + with 'name'. + + If 'multiple' is set to a true value, many date objects will be returned + corresponding to a collection of datetimes. + + If 'tzid_name' is specified, the time zone information will be acquired + from fields starting with 'tzid_name' instead of 'name'. + + If 'tzid' is specified, it will provide the time zone where no explicit + time zone information is indicated in the field data. + """ + + dates = args.get("%s-date" % name, []) + hours = args.get("%s-hour" % name, []) + minutes = args.get("%s-minute" % name, []) + seconds = args.get("%s-second" % name, []) + tzids = args.get("%s-tzid" % (tzid_name or name), []) + + # Handle absent values by employing None values. + + field_values = map(None, dates, hours, minutes, seconds, tzids) + + if not field_values and not multiple: + all_values = FormDate() + else: + all_values = [] + for date, hour, minute, second, tzid_field in field_values: + value = FormDate(date, hour, minute, second, tzid_field or tzid) + + # Return a single value or append to a collection of all values. + + if not multiple: + return value + else: + all_values.append(value) + + return all_values + +def set_date_control_values(args, name, formdates, tzid_name=None): + + """ + Replace form fields in 'args' starting with 'name' using the values of the + given 'formdates'. + + If 'tzid_name' is specified, the time zone information will be stored in + fields starting with 'tzid_name' instead of 'name'. + """ + + args["%s-date" % name] = [] + args["%s-hour" % name] = [] + args["%s-minute" % name] = [] + args["%s-second" % name] = [] + args["%s-tzid" % (tzid_name or name)] = [] + + for d in formdates: + args["%s-date" % name].append(d.date) + args["%s-hour" % name].append(d.hour) + args["%s-minute" % name].append(d.minute) + args["%s-second" % name].append(d.second) + args["%s-tzid" % (tzid_name or name)].append(d.tzid) + +def get_period_control_values(args, start_name, end_name, + end_enabled_name, times_enabled_name, + origin=None, origin_name=None, + replaced_name=None, tzid=None): + + """ + Return period values from fields found in 'args' containing the given + 'start_name' (for start dates), 'end_name' (for end dates), + 'end_enabled_name' (to enable end dates for periods), 'times_enabled_name' + (to enable times for periods). + + If 'origin' is specified, a single period with the given origin is + returned. If 'origin_name' is specified, fields containing the name will + provide origin information, and fields containing 'replaced_name' will + indicate periods that are replaced. + + If 'tzid' is specified, it will provide the time zone where no explicit + time zone information is indicated in the field data. + """ + + # Get the end datetime and time presence settings. + + all_end_enabled = args.get(end_enabled_name, []) + all_times_enabled = args.get(times_enabled_name, []) + + # Get the origins of period data and whether the periods are replaced. + + if origin: + all_origins = [origin] + else: + all_origins = origin_name and args.get(origin_name, []) or [] + + all_replaced = replaced_name and args.get(replaced_name, []) or [] + + # Get the start and end datetimes. + + all_starts = get_date_control_values(args, start_name, True, tzid=tzid) + all_ends = get_date_control_values(args, end_name, True, start_name, tzid=tzid) + + periods = [] + + for index, (start, end, found_origin) in \ + enumerate(map(None, all_starts, all_ends, all_origins)): + + end_enabled = str(index) in all_end_enabled + times_enabled = str(index) in all_times_enabled + replaced = str(index) in all_replaced + + period = FormPeriod(start, end, end_enabled, times_enabled, tzid, + found_origin or origin, replaced) + periods.append(period) + + # Return a single period if a single origin was specified. + + if origin: + return periods[0] + else: + return periods + # vim: tabstop=4 expandtab shiftwidth=4 diff -r d219182e1817 -r 792f00676d62 imipweb/event.py --- a/imipweb/event.py Wed Jun 14 00:30:32 2017 +0200 +++ b/imipweb/event.py Sun Sep 10 23:45:01 2017 +0200 @@ -3,7 +3,7 @@ """ A Web interface to a calendar event. -Copyright (C) 2014, 2015, 2016 Paul Boddie +Copyright (C) 2014, 2015, 2016, 2017 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -23,7 +23,8 @@ uri_parts, uri_values from imiptools.dates import format_datetime, to_timezone from imiptools.mail import Messenger -from imipweb.data import EventPeriod, event_period_from_period, FormPeriod, PeriodError +from imipweb.data import EventPeriod, event_period_from_period, \ + get_period_control_values, PeriodError from imipweb.resource import DateTimeFormUtilities, FormUtilities, ResourceClientForObject # Fake gettext method for strings to be translated later. @@ -312,13 +313,9 @@ elif name == "ATTENDEE": attendee_map = dict(items) - first = True for i, value in enumerate(attendees): - if not first: - page.tr() - else: - first = False + if i: page.tr() # Obtain details of attendees to supply attributes. @@ -327,8 +324,7 @@ # Allow more attendees to be specified. - if not first: - page.tr() + if i: page.tr() page.td(colspan=2) self.control("add", "submit", "add", id="add", class_="add") @@ -339,13 +335,8 @@ # Handle potentially many values of other kinds. else: - first = True - for i, (value, attr) in enumerate(items): - if not first: - page.tr() - else: - first = False + if i: page.tr() page.td(class_="objectvalue %s" % field, colspan=2) if name == "ORGANIZER": @@ -1009,14 +1000,11 @@ "Return the main period defined in the event form." - args = self.env.get_args() - - dtend_enabled = args.get("dtend-control", [None])[0] - dttimes_enabled = args.get("dttimes-control", [None])[0] - start = self.get_date_control_values("dtstart") - end = self.get_date_control_values("dtend") - - period = FormPeriod(start, end, dtend_enabled, dttimes_enabled, self.get_tzid(), "DTSTART") + period = get_period_control_values(self.env.get_args(), + "dtstart", "dtend", + "dtend-control", "dttimes-control", + origin="DTSTART", + tzid=self.get_tzid()) # Handle absent main period details. @@ -1029,28 +1017,11 @@ "Return the recurrences defined in the event form." - args = self.env.get_args() - - all_dtend_enabled = args.get("dtend-control-recur", []) - all_dttimes_enabled = args.get("dttimes-control-recur", []) - all_starts = self.get_date_control_values("dtstart-recur", multiple=True) - all_ends = self.get_date_control_values("dtend-recur", multiple=True, tzid_name="dtstart-recur") - all_origins = args.get("recur-origin", []) - all_replaced = args.get("recur-replaced", []) - - periods = [] - - for index, (start, end, origin) in \ - enumerate(map(None, all_starts, all_ends, all_origins)): - - dtend_enabled = str(index) in all_dtend_enabled - dttimes_enabled = str(index) in all_dttimes_enabled - replaced = str(index) in all_replaced - - period = FormPeriod(start, end, dtend_enabled, dttimes_enabled, self.get_tzid(), origin, replaced) - periods.append(period) - - return periods + return get_period_control_values(self.env.get_args(), + "dtstart-recur", "dtend-recur", + "dtend-control-recur", "dttimes-control-recur", + origin_name="recur-origin", replaced_name="recur-replaced", + tzid=self.get_tzid()) def set_recurrences_in_page(self, recurrences): diff -r d219182e1817 -r 792f00676d62 imipweb/resource.py --- a/imipweb/resource.py Wed Jun 14 00:30:32 2017 +0200 +++ b/imipweb/resource.py Sun Sep 10 23:45:01 2017 +0200 @@ -25,7 +25,8 @@ from imiptools.dates import format_datetime, to_date from imiptools.freebusy import FreeBusyCollection from imipweb.data import event_period_from_period, form_period_from_period, \ - FormDate, PeriodError + get_date_control_values, set_date_control_values, \ + PeriodError from imipweb.env import CGIEnvironment from urllib import urlencode import babel.dates @@ -432,7 +433,7 @@ return index is not None and "%s-%s" % (name, suffix) or name def element_enable(self, index=None): - return index is not None and str(index) or "enable" + return str(index or 0) def show_object_datetime_controls(self, period, index=None): @@ -445,7 +446,6 @@ p = form_period_from_period(period) page = self.page - args = self.env.get_args() _id = self.element_identifier _name = self.element_name _enable = self.element_enable @@ -632,33 +632,7 @@ from fields starting with 'tzid_name' instead of 'name'. """ - args = self.env.get_args() - - dates = args.get("%s-date" % name, []) - hours = args.get("%s-hour" % name, []) - minutes = args.get("%s-minute" % name, []) - seconds = args.get("%s-second" % name, []) - tzids = args.get("%s-tzid" % (tzid_name or name), []) - - # Handle absent values by employing None values. - - field_values = map(None, dates, hours, minutes, seconds, tzids) - - if not field_values and not multiple: - all_values = FormDate() - else: - all_values = [] - for date, hour, minute, second, tzid in field_values: - value = FormDate(date, hour, minute, second, tzid or self.get_tzid()) - - # Return a single value or append to a collection of all values. - - if not multiple: - return value - else: - all_values.append(value) - - return all_values + get_date_control_values(self.env.get_args(), name, multiple, tzid_name, self.get_tzid()) def set_date_control_values(self, name, formdates, tzid_name=None): @@ -670,12 +644,6 @@ fields starting with 'tzid_name' instead of 'name'. """ - args = self.env.get_args() - - args["%s-date" % name] = [d.date for d in formdates] - args["%s-hour" % name] = [d.hour for d in formdates] - args["%s-minute" % name] = [d.minute for d in formdates] - args["%s-second" % name] = [d.second for d in formdates] - args["%s-tzid" % (tzid_name or name)] = [d.tzid for d in formdates] + set_date_control_values(self.env.get_args(), name, formdates, tzid_name) # vim: tabstop=4 expandtab shiftwidth=4