imip-agent

Change of imipweb/event.py

619:b021078b64d4
imipweb/event.py
     1.1 --- a/imipweb/event.py	Wed Jul 29 16:40:28 2015 +0200
     1.2 +++ b/imipweb/event.py	Wed Jul 29 18:41:11 2015 +0200
     1.3 @@ -20,7 +20,6 @@
     1.4  """
     1.5  
     1.6  from datetime import date, timedelta
     1.7 -from imiptools.client import update_attendees
     1.8  from imiptools.data import get_uri, uri_dict, uri_values
     1.9  from imiptools.dates import format_datetime, get_datetime_item, \
    1.10                              get_period_item, to_date, to_timezone
    1.11 @@ -60,11 +59,51 @@
    1.12          (None, "Not indicated"),
    1.13          ]
    1.14  
    1.15 +    # Access to stored object information.
    1.16 +
    1.17      def is_organiser(self, obj):
    1.18          return get_uri(obj.get_value("ORGANIZER")) == self.user
    1.19  
    1.20 +    def get_stored_attendees(self, obj):
    1.21 +        return uri_values(obj.get_values("ATTENDEE") or [])
    1.22 +
    1.23 +    def get_stored_main_period(self, obj):
    1.24 +
    1.25 +        """
    1.26 +        Return the main event period for the given 'obj'.
    1.27 +        """
    1.28 +
    1.29 +        dtstart, dtstart_attr = obj.get_datetime_item("DTSTART")
    1.30 +
    1.31 +        if obj.has_key("DTEND"):
    1.32 +            dtend, dtend_attr = obj.get_datetime_item("DTEND")
    1.33 +        elif obj.has_key("DURATION"):
    1.34 +            duration = obj.get_duration("DURATION")
    1.35 +            dtend = dtstart + duration
    1.36 +            dtend_attr = dtstart_attr
    1.37 +        else:
    1.38 +            dtend, dtend_attr = dtstart, dtstart_attr
    1.39 +
    1.40 +        return EventPeriod(dtstart, dtend, self.get_tzid(), None, dtstart_attr, dtend_attr)
    1.41 +
    1.42 +    def get_stored_recurrences(self, obj):
    1.43 +
    1.44 +        "Return recurrences computed using the given 'obj'."
    1.45 +
    1.46 +        recurrences = []
    1.47 +        for period in self.get_periods(obj):
    1.48 +            if period.origin != "DTSTART":
    1.49 +                recurrences.append(period)
    1.50 +        return recurrences
    1.51 +
    1.52      # Request logic methods.
    1.53  
    1.54 +    def is_initial_load(self):
    1.55 +
    1.56 +        "Return whether the event is being loaded and shown for the first time."
    1.57 +
    1.58 +        return not self.env.get_args().has_key("editing")
    1.59 +
    1.60      def handle_request(self, obj):
    1.61  
    1.62          """
    1.63 @@ -124,9 +163,7 @@
    1.64                  # Set the periods in the object, first obtaining removed and
    1.65                  # modified period information.
    1.66  
    1.67 -                to_unschedule = []
    1.68 -                for i in args.get("recur-remove", []):
    1.69 -                    to_unschedule.append(periods[int(i)])
    1.70 +                to_unschedule = self.get_removed_periods()
    1.71  
    1.72                  self.set_period_in_object(obj, period)
    1.73                  self.set_periods_in_object(obj, periods)
    1.74 @@ -138,9 +175,9 @@
    1.75  
    1.76                  # Obtain any participants and those to be removed.
    1.77  
    1.78 -                attendees = self.get_attendees()
    1.79 +                attendees = self.get_attendees_from_page()
    1.80                  removed = [attendees[int(i)] for i in args.get("remove", [])]
    1.81 -                to_cancel = update_attendees(obj, attendees, removed)
    1.82 +                to_cancel = self.update_attendees(obj, attendees, removed)
    1.83                  single_user = not attendees or attendees == [self.user]
    1.84  
    1.85              # Update attendee participation for the current user.
    1.86 @@ -291,29 +328,16 @@
    1.87          return all_values
    1.88  
    1.89      def get_current_main_period(self, obj):
    1.90 -        if self.is_initial_load() or not self.is_organiser(obj):
    1.91 -            return self.get_existing_main_period(obj)
    1.92 -        else:
    1.93 -            return self.get_main_period()
    1.94 -
    1.95 -    def get_existing_main_period(self, obj):
    1.96  
    1.97          """
    1.98 -        Return the main event period for the given 'obj'.
    1.99 +        Return the currently active main period for 'obj' depending on whether
   1.100 +        editing has begun or whether the object has just been loaded.
   1.101          """
   1.102  
   1.103 -        dtstart, dtstart_attr = obj.get_datetime_item("DTSTART")
   1.104 -
   1.105 -        if obj.has_key("DTEND"):
   1.106 -            dtend, dtend_attr = obj.get_datetime_item("DTEND")
   1.107 -        elif obj.has_key("DURATION"):
   1.108 -            duration = obj.get_duration("DURATION")
   1.109 -            dtend = dtstart + duration
   1.110 -            dtend_attr = dtstart_attr
   1.111 +        if self.is_initial_load() or not self.is_organiser(obj):
   1.112 +            return self.get_stored_main_period(obj)
   1.113          else:
   1.114 -            dtend, dtend_attr = dtstart, dtstart_attr
   1.115 -
   1.116 -        return EventPeriod(dtstart, dtend, self.get_tzid(), None, dtstart_attr, dtend_attr)
   1.117 +            return self.get_main_period()
   1.118  
   1.119      def get_main_period(self):
   1.120  
   1.121 @@ -336,20 +360,10 @@
   1.122          """
   1.123  
   1.124          if self.is_initial_load() or not self.is_organiser(obj):
   1.125 -            return self.get_existing_recurrences(obj)
   1.126 +            return self.get_stored_recurrences(obj)
   1.127          else:
   1.128              return self.get_recurrences()
   1.129  
   1.130 -    def get_existing_recurrences(self, obj):
   1.131 -
   1.132 -        "Return recurrences computed using the given 'obj'."
   1.133 -
   1.134 -        recurrences = []
   1.135 -        for period in self.get_periods(obj):
   1.136 -            if period.origin != "DTSTART":
   1.137 -                recurrences.append(period)
   1.138 -        return recurrences
   1.139 -
   1.140      def get_recurrences(self):
   1.141  
   1.142          "Return the recurrences defined in the event form."
   1.143 @@ -374,11 +388,15 @@
   1.144  
   1.145          return periods
   1.146  
   1.147 -    def is_initial_load(self):
   1.148 +    def get_removed_periods(self):
   1.149 +
   1.150 +        "Return a list of recurrence periods to remove upon updating an event."
   1.151  
   1.152 -        "Return whether the event is being loaded and shown for the first time."
   1.153 -
   1.154 -        return not self.env.get_args().has_key("editing")
   1.155 +        to_unschedule = []
   1.156 +        args = self.env.get_args()
   1.157 +        for i in args.get("recur-remove", []):
   1.158 +            to_unschedule.append(periods[int(i)])
   1.159 +        return to_unschedule
   1.160  
   1.161      def get_current_attendees(self, obj):
   1.162  
   1.163 @@ -388,14 +406,11 @@
   1.164          """
   1.165  
   1.166          if self.is_initial_load() or not self.is_organiser(obj):
   1.167 -            return self.get_existing_attendees(obj)
   1.168 +            return self.get_stored_attendees(obj)
   1.169          else:
   1.170 -            return self.get_attendees()
   1.171 +            return self.get_attendees_from_page()
   1.172  
   1.173 -    def get_existing_attendees(self, obj):
   1.174 -        return uri_values(obj.get_values("ATTENDEE") or [])
   1.175 -
   1.176 -    def get_attendees(self):
   1.177 +    def get_attendees_from_page(self):
   1.178  
   1.179          """
   1.180          Return attendees from the request, normalised for iCalendar purposes,
   1.181 @@ -418,15 +433,14 @@
   1.182  
   1.183          return ordered_attendees
   1.184  
   1.185 -    def update_attendees(self, obj):
   1.186 +    def update_attendees_from_page(self, obj):
   1.187  
   1.188          "Add or remove attendees. This does not affect the stored object."
   1.189  
   1.190          args = self.env.get_args()
   1.191  
   1.192 -        attendees = self.get_attendees()
   1.193 -        existing_attendees = self.get_existing_attendees(obj)
   1.194 -        sequence = obj.get_value("SEQUENCE")
   1.195 +        attendees = self.get_attendees_from_page()
   1.196 +        existing_attendees = self.get_stored_attendees(obj)
   1.197  
   1.198          if args.has_key("add"):
   1.199              attendees.append("")
   1.200 @@ -443,7 +457,7 @@
   1.201  
   1.202                  existing = attendee in existing_attendees
   1.203  
   1.204 -                if not existing or sequence is None or attendee == self.user:
   1.205 +                if not existing or not obj.is_shared() or attendee == self.user:
   1.206                      attendees.remove(attendee)
   1.207  
   1.208          return attendees
   1.209 @@ -460,7 +474,6 @@
   1.210          attendees = self.get_current_attendees(obj)
   1.211          is_attendee = self.user in attendees
   1.212          is_request = (obj.get_uid(), obj.get_recurrenceid()) in self._get_requests()
   1.213 -        sequence = obj.get_value("SEQUENCE")
   1.214  
   1.215          # Show appropriate options depending on the role of the user.
   1.216  
   1.217 @@ -479,10 +492,10 @@
   1.218              page.p("As organiser, you can perform the following:")
   1.219  
   1.220              page.p()
   1.221 -            self._control("create", "submit", sequence is None and "Create event" or "Update event")
   1.222 +            self._control("create", "submit", not obj.is_shared() and "Create event" or "Update event")
   1.223              page.add(" ")
   1.224  
   1.225 -            if sequence is not None and not is_request:
   1.226 +            if obj.is_shared() and not is_request:
   1.227                  self._control("cancel", "submit", "Cancel event")
   1.228              else:
   1.229                  self._control("discard", "submit", "Discard event")
   1.230 @@ -512,9 +525,9 @@
   1.231          # Obtain basic event information, generating any necessary editing controls.
   1.232  
   1.233          if self.is_initial_load() or not self.is_organiser(obj):
   1.234 -            attendees = self.get_existing_attendees(obj)
   1.235 +            attendees = self.get_stored_attendees(obj)
   1.236          else:
   1.237 -            attendees = self.update_attendees(obj)
   1.238 +            attendees = self.update_attendees_from_page(obj)
   1.239  
   1.240          p = self.get_current_main_period(obj)
   1.241          self.show_object_datetime_controls(p)
   1.242 @@ -650,13 +663,12 @@
   1.243  
   1.244          existing = attendee_attr is not None
   1.245          partstat = attendee_attr and attendee_attr.get("PARTSTAT")
   1.246 -        sequence = obj.get_value("SEQUENCE")
   1.247  
   1.248          page.td(class_="objectvalue")
   1.249  
   1.250          # Show a form control as organiser for new attendees.
   1.251  
   1.252 -        if self.is_organiser(obj) and (not existing or sequence is None):
   1.253 +        if self.is_organiser(obj) and (not existing or not obj.is_shared()):
   1.254              self._control("attendee", "value", attendee, size="40")
   1.255          else:
   1.256              self._control("attendee", "hidden", attendee)
   1.257 @@ -684,7 +696,7 @@
   1.258  
   1.259              # Permit the removal of newly-added attendees.
   1.260  
   1.261 -            remove_type = (not existing or sequence is None or attendee == self.user) and "submit" or "checkbox"
   1.262 +            remove_type = (not existing or not obj.is_shared() or attendee == self.user) and "submit" or "checkbox"
   1.263              self._control("remove", remove_type, str(i), str(i) in args.get("remove", []), id="remove-%d" % i, class_="remove")
   1.264  
   1.265              page.label("Remove", for_="remove-%d" % i, class_="remove")
   1.266 @@ -773,8 +785,6 @@
   1.267          page = self.page
   1.268          args = self.env.get_args()
   1.269  
   1.270 -        sequence = obj.get_value("SEQUENCE")
   1.271 -
   1.272          p = event_period_from_period(period)
   1.273          replaced = not recurrenceid and self.is_replaced(p, recurrenceids)
   1.274  
   1.275 @@ -806,7 +816,7 @@
   1.276              page.th("")
   1.277              page.td()
   1.278  
   1.279 -            remove_type = sequence is None or not period.origin and "submit" or "checkbox"
   1.280 +            remove_type = not obj.is_shared() or not period.origin and "submit" or "checkbox"
   1.281              self._control("recur-remove", remove_type, str(index),
   1.282                  str(index) in args.get("recur-remove", []),
   1.283                  id="recur-remove-%d" % index, class_="remove")