Bläddra i källkod

Match time against all components

Unrud 8 år sedan
förälder
incheckning
f9d299fbb9
1 ändrade filer med 146 tillägg och 140 borttagningar
  1. 146 140
      radicale/xmlutils.py

+ 146 - 140
radicale/xmlutils.py

@@ -289,7 +289,9 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
     # if they are used.
     # TODO: Single recurrences can be overwritten by components with
     # RECURRENCE-ID (http://www.kanzaki.com/docs/ical/recurrenceId.html). They
-    # are currently ignored but can change the start and end time.
+    # may overwrite the start and end time. Currently these components and
+    # the overwritten recurrences are both considered. The overwritten
+    # recurrence should be ignored instead.
 
     def getrruleset(child):
         try:
@@ -310,168 +312,172 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
 
     # Comments give the lines in the tables of the specification
     if child_name == "VEVENT":
-        # TODO: check if there's a timezone
-        dtstart = child.dtstart.value
+        for child in vobject_item.vevent_list:
+            # TODO: check if there's a timezone
+            dtstart = child.dtstart.value
 
-        if child.rruleset:
-            dtstarts, infinity = getrruleset(child)
-            if infinity:
-                return
-        else:
-            dtstarts = (dtstart,)
+            if child.rruleset:
+                dtstarts, infinity = getrruleset(child)
+                if infinity:
+                    return
+            else:
+                dtstarts = (dtstart,)
 
-        dtend = getattr(child, "dtend", None)
-        if dtend is not None:
-            dtend = dtend.value
-            original_duration = (dtend - dtstart).total_seconds()
-            dtend = _date_to_datetime(dtend)
+            dtend = getattr(child, "dtend", None)
+            if dtend is not None:
+                dtend = dtend.value
+                original_duration = (dtend - dtstart).total_seconds()
+                dtend = _date_to_datetime(dtend)
 
-        duration = getattr(child, "duration", None)
-        if duration is not None:
-            original_duration = duration = duration.value
+            duration = getattr(child, "duration", None)
+            if duration is not None:
+                original_duration = duration = duration.value
 
-        for dtstart in dtstarts:
-            dtstart_is_datetime = isinstance(dtstart, datetime)
-            dtstart = _date_to_datetime(dtstart)
+            for dtstart in dtstarts:
+                dtstart_is_datetime = isinstance(dtstart, datetime)
+                dtstart = _date_to_datetime(dtstart)
 
-            if dtend is not None:
-                # Line 1
-                dtend = dtstart + timedelta(seconds=original_duration)
-                if range_fn(dtstart, dtend):
-                    return
-            elif duration is not None:
-                if original_duration is None:
-                    original_duration = duration.seconds
-                if duration.seconds > 0:
-                    # Line 2
-                    if range_fn(dtstart, dtstart + duration):
+                if dtend is not None:
+                    # Line 1
+                    dtend = dtstart + timedelta(seconds=original_duration)
+                    if range_fn(dtstart, dtend):
                         return
-                else:
-                    # Line 3
+                elif duration is not None:
+                    if original_duration is None:
+                        original_duration = duration.seconds
+                    if duration.seconds > 0:
+                        # Line 2
+                        if range_fn(dtstart, dtstart + duration):
+                            return
+                    else:
+                        # Line 3
+                        if range_fn(dtstart, dtstart + SECOND):
+                            return
+                elif dtstart_is_datetime:
+                    # Line 4
                     if range_fn(dtstart, dtstart + SECOND):
                         return
-            elif dtstart_is_datetime:
-                # Line 4
-                if range_fn(dtstart, dtstart + SECOND):
-                    return
-            else:
-                # Line 5
-                if range_fn(dtstart, dtstart + DAY):
-                    return
+                else:
+                    # Line 5
+                    if range_fn(dtstart, dtstart + DAY):
+                        return
 
     elif child_name == "VTODO":
-        dtstart = getattr(child, "dtstart", None)
-        duration = getattr(child, "duration", None)
-        due = getattr(child, "due", None)
-        completed = getattr(child, "completed", None)
-        created = getattr(child, "created", None)
-
-        if dtstart is not None:
-            dtstart = _date_to_datetime(dtstart.value)
-        if duration is not None:
-            duration = duration.value
-        if due is not None:
-            due = _date_to_datetime(due.value)
-            if dtstart is not None:
-                original_duration = (due - dtstart).total_seconds()
-        if completed is not None:
-            completed = _date_to_datetime(completed.value)
-            if created is not None:
-                created = _date_to_datetime(created.value)
-                original_duration = (completed - created).total_seconds()
-        elif created is not None:
-            created = _date_to_datetime(created.value)
-
-        if child.rruleset:
-            reference_dates, infinity = getrruleset(child)
-            if infinity:
-                return
-        else:
-            if dtstart is not None:
-                reference_dates = (dtstart,)
-            elif due is not None:
-                reference_dates = (due,)
-            elif completed is not None:
-                reference_dates = (completed,)
-            elif created is not None:
-                reference_dates = (created,)
-            else:
-                # Line 8
-                if range_fn(DATETIME_MIN, DATETIME_MAX):
-                    return
-                reference_dates = ()
-
-        for reference_date in reference_dates:
-            reference_date = _date_to_datetime(reference_date)
+        for child in vobject_item.vtodo_list:
+            dtstart = getattr(child, "dtstart", None)
+            duration = getattr(child, "duration", None)
+            due = getattr(child, "due", None)
+            completed = getattr(child, "completed", None)
+            created = getattr(child, "created", None)
 
-            if dtstart is not None and duration is not None:
-                # Line 1
-                if range_fn(reference_date,
-                            reference_date + duration + SECOND):
-                    return
-                if range_fn(reference_date + duration - SECOND,
-                            reference_date + duration + SECOND):
-                    return
-            elif dtstart is not None and due is not None:
-                # Line 2
-                due = reference_date + timedelta(seconds=original_duration)
-                if (range_fn(reference_date, due) or
-                        range_fn(reference_date, reference_date + SECOND) or
-                        range_fn(due - SECOND, due) or
-                        range_fn(due - SECOND, reference_date + SECOND)):
-                    return
-            elif dtstart is not None:
-                if range_fn(reference_date, reference_date + SECOND):
-                    return
-            elif due is not None:
-                # Line 4
-                if range_fn(reference_date - SECOND, reference_date):
-                    return
-            elif completed is not None and created is not None:
-                # Line 5
-                completed = reference_date + timedelta(
-                    seconds=original_duration)
-                if (range_fn(reference_date - SECOND,
-                             reference_date + SECOND) or
-                        range_fn(completed - SECOND, completed + SECOND) or
-                        range_fn(reference_date - SECOND,
-                                 reference_date + SECOND) or
-                        range_fn(completed - SECOND, completed + SECOND)):
-                    return
-            elif completed is not None:
-                # Line 6
-                if range_fn(reference_date - SECOND,
-                            reference_date + SECOND):
-                            return
+            if dtstart is not None:
+                dtstart = _date_to_datetime(dtstart.value)
+            if duration is not None:
+                duration = duration.value
+            if due is not None:
+                due = _date_to_datetime(due.value)
+                if dtstart is not None:
+                    original_duration = (due - dtstart).total_seconds()
+            if completed is not None:
+                completed = _date_to_datetime(completed.value)
+                if created is not None:
+                    created = _date_to_datetime(created.value)
+                    original_duration = (completed - created).total_seconds()
             elif created is not None:
-                # Line 7
-                if range_fn(reference_date, DATETIME_MAX):
-                    return
-
-    elif child_name == "VJOURNAL":
-        dtstart = getattr(child, "dtstart", None)
+                created = _date_to_datetime(created.value)
 
-        if dtstart is not None:
-            dtstart = dtstart.value
             if child.rruleset:
-                dtstarts, infinity = getrruleset(child)
+                reference_dates, infinity = getrruleset(child)
                 if infinity:
                     return
             else:
-                dtstarts = (dtstart,)
+                if dtstart is not None:
+                    reference_dates = (dtstart,)
+                elif due is not None:
+                    reference_dates = (due,)
+                elif completed is not None:
+                    reference_dates = (completed,)
+                elif created is not None:
+                    reference_dates = (created,)
+                else:
+                    # Line 8
+                    if range_fn(DATETIME_MIN, DATETIME_MAX):
+                        return
+                    reference_dates = ()
 
-            for dtstart in dtstarts:
-                dtstart_is_datetime = isinstance(dtstart, datetime)
-                dtstart = _date_to_datetime(dtstart)
+            for reference_date in reference_dates:
+                reference_date = _date_to_datetime(reference_date)
 
-                if dtstart_is_datetime:
+                if dtstart is not None and duration is not None:
                     # Line 1
-                    if range_fn(dtstart, dtstart + SECOND):
+                    if range_fn(reference_date,
+                                reference_date + duration + SECOND):
                         return
-                else:
+                    if range_fn(reference_date + duration - SECOND,
+                                reference_date + duration + SECOND):
+                        return
+                elif dtstart is not None and due is not None:
                     # Line 2
-                    if range_fn(dtstart, dtstart + DAY):
+                    due = reference_date + timedelta(seconds=original_duration)
+                    if (range_fn(reference_date, due) or
+                            range_fn(reference_date,
+                                     reference_date + SECOND) or
+                            range_fn(due - SECOND, due) or
+                            range_fn(due - SECOND, reference_date + SECOND)):
+                        return
+                elif dtstart is not None:
+                    if range_fn(reference_date, reference_date + SECOND):
                         return
+                elif due is not None:
+                    # Line 4
+                    if range_fn(reference_date - SECOND, reference_date):
+                        return
+                elif completed is not None and created is not None:
+                    # Line 5
+                    completed = reference_date + timedelta(
+                        seconds=original_duration)
+                    if (range_fn(reference_date - SECOND,
+                                 reference_date + SECOND) or
+                            range_fn(completed - SECOND, completed + SECOND) or
+                            range_fn(reference_date - SECOND,
+                                     reference_date + SECOND) or
+                            range_fn(completed - SECOND, completed + SECOND)):
+                        return
+                elif completed is not None:
+                    # Line 6
+                    if range_fn(reference_date - SECOND,
+                                reference_date + SECOND):
+                                return
+                elif created is not None:
+                    # Line 7
+                    if range_fn(reference_date, DATETIME_MAX):
+                        return
+
+    elif child_name == "VJOURNAL":
+        for child in vobject_item.vjournal_list:
+            dtstart = getattr(child, "dtstart", None)
+
+            if dtstart is not None:
+                dtstart = dtstart.value
+                if child.rruleset:
+                    dtstarts, infinity = getrruleset(child)
+                    if infinity:
+                        return
+                else:
+                    dtstarts = (dtstart,)
+
+                for dtstart in dtstarts:
+                    dtstart_is_datetime = isinstance(dtstart, datetime)
+                    dtstart = _date_to_datetime(dtstart)
+
+                    if dtstart_is_datetime:
+                        # Line 1
+                        if range_fn(dtstart, dtstart + SECOND):
+                            return
+                    else:
+                        # Line 2
+                        if range_fn(dtstart, dtstart + DAY):
+                            return
 
     elif isinstance(child, date):
         if range_fn(child, child + DAY):