Example #1
0
    def getVToDos(self, only_due, all_dates, upto_due_date, list):
        # Get current date-time less one day to test for completed events during the last day
        minusoneday = DateTime()
        minusoneday.setNowUTC()
        minusoneday.offsetDay(-1)

        today = DateTime()
        today.setToday()

        # Look at each VToDo
        for vtodo in self.getComponents(definitions.cICalComponent_VTODO):

            # Filter out done (that were complted more than a day ago) or cancelled to dos if required
            if only_due:
                if vtodo.getStatus() == definitions.eStatus_VToDo_Cancelled:
                    continue
                elif (
                    (vtodo.getStatus() == definitions.eStatus_VToDo_Completed) and
                    (not vtodo.hasCompleted() or (vtodo.getCompleted() < minusoneday))
                ):
                    continue

            # Filter out those with end after chosen date if required
            if not all_dates:
                if vtodo.hasEnd() and (vtodo.getEnd() > upto_due_date):
                    continue
                elif not vtodo.hasEnd() and (today > upto_due_date):
                    continue
Example #2
0
    def getVToDos(self, only_due, all_dates, upto_due_date, list):
        # Get current date-time less one day to test for completed events during the last day
        minusoneday = DateTime()
        minusoneday.setNowUTC()
        minusoneday.offsetDay(-1)

        today = DateTime()
        today.setToday()

        # Look at each VToDo
        for vtodo in self.getComponents(definitions.cICalComponent_VTODO):

            # Filter out done (that were complted more than a day ago) or cancelled to dos if required
            if only_due:
                if vtodo.getStatus() == definitions.eStatus_VToDo_Cancelled:
                    continue
                elif (
                    (vtodo.getStatus() == definitions.eStatus_VToDo_Completed) and
                    (not vtodo.hasCompleted() or (vtodo.getCompleted() < minusoneday))
                ):
                    continue

            # Filter out those with end after chosen date if required
            if not all_dates:
                if vtodo.hasEnd() and (vtodo.getEnd() > upto_due_date):
                    continue
                elif not vtodo.hasEnd() and (today > upto_due_date):
                    continue
Example #3
0
class VToDo(ComponentRecur):

    OVERDUE = 0
    DUE_NOW = 1
    DUE_LATER = 2
    DONE = 3
    CANCELLED = 4

    @staticmethod
    def sort_for_display(e1, e2):
        s1 = e1.getMaster()
        s2 = e2.getMaster()

        # Check status first (convert None -> Needs action for tests)
        status1 = s1.self.mStatus
        status2 = s2.self.mStatus
        if status1 == definitions.eStatus_VToDo_None:
            status1 = definitions.eStatus_VToDo_NeedsAction
        if status2 == definitions.eStatus_VToDo_None:
            status2 = definitions.eStatus_VToDo_NeedsAction
        if status1 != status2:
            # More important ones at the top
            return status1 < status2

        # At this point the status of each is the same

        # If status is cancelled sort by start time
        if s1.self.mStatus == definitions.eStatus_VToDo_Cancelled:
            # Older ones at the bottom
            return s1.mStart > s2.mStart

        # If status is completed sort by completion time
        if s1.self.mStatus == definitions.eStatus_VToDo_Completed:
            # Older ones at the bottom
            return s1.self.mCompleted > s2.self.mCompleted

        # Check due date exists
        if s1.mHasEnd != s2.mHasEnd:
            now = DateTime()
            now.setToday()

            # Ones with due dates after today below ones without due dates
            if s1.hasEnd():
                return s1.mEnd <= now
            elif s2.hasEnd():
                return now < s2.mEnd

        # Check due dates if present
        if s1.mHasEnd:
            if s1.mEnd != s2.mEnd:
                # Soonest dues dates above later ones
                return s1.mEnd < s2.mEnd

        # Check priority next
        if s1.self.mPriority != s2.self.mPriority:
            # Higher priority above lower ones
            return s1.self.mPriority < s2.self.mPriority

        # Just use start time - older ones at the top
        return s1.mStart < s2.mStart

    propertyCardinality_1 = (
        definitions.cICalProperty_DTSTAMP,
        definitions.cICalProperty_UID,
    )

    propertyCardinality_0_1 = (
        definitions.cICalProperty_CLASS,
        definitions.cICalProperty_COMPLETED,
        definitions.cICalProperty_CREATED,
        definitions.cICalProperty_DESCRIPTION,
        definitions.cICalProperty_DTSTART,
        definitions.cICalProperty_GEO,
        definitions.cICalProperty_LAST_MODIFIED,
        definitions.cICalProperty_LOCATION,
        definitions.cICalProperty_ORGANIZER,
        definitions.cICalProperty_PERCENT_COMPLETE,
        definitions.cICalProperty_PRIORITY,
        definitions.cICalProperty_RECURRENCE_ID,
        definitions.cICalProperty_SEQUENCE,
        # definitions.cICalProperty_STATUS, # Special fix done for multiple STATUS
        definitions.cICalProperty_SUMMARY,
        definitions.cICalProperty_URL,
        definitions.cICalProperty_RRULE,
        definitions.cICalProperty_DUE,
        definitions.cICalProperty_DURATION,
    )

    propertyValueChecks = ICALENDAR_VALUE_CHECKS

    def __init__(self, parent=None):
        super(VToDo, self).__init__(parent=parent)
        self.mPriority = 0
        self.mStatus = definitions.eStatus_VToDo_None
        self.mPercentComplete = 0
        self.mCompleted = DateTime()
        self.mHasCompleted = False

    def duplicate(self, parent=None):
        other = super(VToDo, self).duplicate(parent=parent)
        other.mPriority = self.mPriority
        other.mStatus = self.mStatus
        other.mPercentComplete = self.mPercentComplete
        other.mCompleted = self.mCompleted.duplicate()
        other.mHasCompleted = self.mHasCompleted
        return other

    def getType(self):
        return definitions.cICalComponent_VTODO

    def getMimeComponentName(self):
        return itipdefinitions.cICalMIMEComponent_VTODO

    def addComponent(self, comp):
        # We can embed the alarm components only
        if comp.getType() == definitions.cICalComponent_VALARM:
            super(VToDo, self).addComponent(comp)
        else:
            raise ValueError("Only 'VALARM' components allowed in 'VTODO'")

    def getStatus(self):
        return self.mStatus

    def setStatus(self, status):
        self.mStatus = status

    def getStatusText(self):
        sout = StringIO()

        if self.mStatus in (definitions.eStatus_VToDo_NeedsAction,
                            definitions.eStatus_VToDo_InProcess):
            if self.hasEnd():
                # Check due date
                today = DateTime()
                today.setToday()
                if self.getEnd() > today:
                    sout.append("Due: ")
                    whendue = self.getEnd() - today
                    if (whendue.getDays() > 0) and (whendue.getDays() <= 7):
                        sout.write(whendue.getDays())
                        sout.write(" days")
                    else:
                        sout.write(self.getEnd().getLocaleDate(
                            DateTime.NUMERICDATE))
                elif self.getEnd() == today:
                    sout.write("Due today")
                else:
                    sout.write("Overdue: ")
                    overdue = today - self.getEnd()
                    if overdue.getWeeks() != 0:
                        sout.write(overdue.getWeeks())
                        sout.write(" weeks")
                    else:
                        sout.write(overdue.getDays() + 1)
                        sout.write(" days")
            else:
                sout.write("Not Completed")
        elif self.mStatus == definitions.eStatus_VToDo_Completed:
            if self.hasCompleted():
                sout.write("Completed: ")
                sout.write(self.getCompleted().getLocaleDate(
                    DateTime.NUMERICDATE))
            else:
                sout.write("Completed")
        elif definitions.eStatus_VToDo_Cancelled:
            sout.write("Cancelled")

        return sout.toString()

    def getCompletionState(self):
        if self.mStatus in (definitions.eStatus_VToDo_NeedsAction,
                            definitions.eStatus_VToDo_InProcess):
            if self.hasEnd():
                # Check due date
                today = DateTime()
                today.setToday()
                if self.getEnd() > today:
                    return VToDo.DUE_LATER
                elif self.getEnd() == today:
                    return VToDo.DUE_NOW
                else:
                    return VToDo.OVERDUE
            else:
                return VToDo.DUE_NOW
        elif self.mStatus == definitions.eStatus_VToDo_Completed:
            return VToDo.DONE
        elif self.mStatus == definitions.eStatus_VToDo_Cancelled:
            return VToDo.CANCELLED

    def getPriority(self):
        return self.mPriority

    def setPriority(self, priority):
        self.mPriority = priority

    def getCompleted(self):
        return self.mCompleted

    def hasCompleted(self):
        return self.mHasCompleted

    def finalise(self):
        # Do inherited
        super(VToDo, self).finalise()

        # Get DUE
        temp = self.loadValueDateTime(definitions.cICalProperty_DUE)
        if temp is None:
            # Try DURATION instead
            temp = self.loadValueDuration(definitions.cICalProperty_DURATION)
            if temp is not None:
                self.mEnd = self.mStart + temp
                self.mHasEnd = True
            else:
                self.mHasEnd = False
        else:
            self.mHasEnd = True
            self.mEnd = temp

        # Get PRIORITY
        self.mPriority = self.loadValueInteger(
            definitions.cICalProperty_PRIORITY)

        # Get STATUS
        temp = self.loadValueString(definitions.cICalProperty_STATUS)
        if temp is not None:
            if temp == definitions.cICalProperty_STATUS_NEEDS_ACTION:
                self.mStatus = definitions.eStatus_VToDo_NeedsAction
            elif temp == definitions.cICalProperty_STATUS_COMPLETED:
                self.mStatus = definitions.eStatus_VToDo_Completed
            elif temp == definitions.cICalProperty_STATUS_IN_PROCESS:
                self.mStatus = definitions.eStatus_VToDo_InProcess
            elif temp == definitions.cICalProperty_STATUS_CANCELLED:
                self.mStatus = definitions.eStatus_VToDo_Cancelled

        # Get PERCENT-COMPLETE
        self.mPercentComplete = self.loadValueInteger(
            definitions.cICalProperty_PERCENT_COMPLETE)

        # Get COMPLETED
        temp = self.loadValueDateTime(definitions.cICalProperty_COMPLETED)
        self.mHasCompleted = temp is not None
        if self.mHasCompleted:
            self.mCompleted = temp

    def validate(self, doFix=False):
        """
        Validate the data in this component and optionally fix any problems, else raise. If
        loggedProblems is not None it must be a C{list} and problem descriptions are appended
        to that.
        """

        fixed, unfixed = super(VToDo, self).validate(doFix)

        # Extra constraint: only one of DUE or DURATION
        if self.hasProperty(
                definitions.cICalProperty_DUE) and self.hasProperty(
                    definitions.cICalProperty_DURATION):
            # Fix by removing the DURATION
            logProblem = "[%s] Properties must not both be present: %s, %s" % (
                self.getType(),
                definitions.cICalProperty_DUE,
                definitions.cICalProperty_DURATION,
            )
            if doFix:
                self.removeProperties(definitions.cICalProperty_DURATION)
                fixed.append(logProblem)
            else:
                unfixed.append(logProblem)

        # Extra constraint: DTSTART must be present if DURATION is present
        if self.hasProperty(
                definitions.cICalProperty_DURATION) and not self.hasProperty(
                    definitions.cICalProperty_DTSTART):
            # Cannot fix this one
            logProblem = "[%s] Property must be present: %s with %s" % (
                self.getType(),
                definitions.cICalProperty_DTSTART,
                definitions.cICalProperty_DURATION,
            )
            unfixed.append(logProblem)

        return fixed, unfixed

    # Editing
    def editStatus(self, status):
        # Only if it is different
        if self.mStatus != status:
            # Updated cached values
            self.mStatus = status

            # Remove existing STATUS & COMPLETED items
            self.removeProperties(definitions.cICalProperty_STATUS)
            self.removeProperties(definitions.cICalProperty_COMPLETED)
            self.mHasCompleted = False

            # Now create properties
            value = None
            if status == definitions.eStatus_VToDo_NeedsAction:
                value = definitions.cICalProperty_STATUS_NEEDS_ACTION
            if status == definitions.eStatus_VToDo_Completed:
                value = definitions.cICalProperty_STATUS_COMPLETED
                # Add the completed item
                self.mCompleted.setNowUTC()
                self.mHasCompleted = True
                prop = Property(definitions.cICalProperty_STATUS_COMPLETED,
                                self.mCompleted)
                self.addProperty(prop)
            elif status == definitions.eStatus_VToDo_InProcess:
                value = definitions.cICalProperty_STATUS_IN_PROCESS
            elif status == definitions.eStatus_VToDo_Cancelled:
                value = definitions.cICalProperty_STATUS_CANCELLED
            prop = Property(definitions.cICalProperty_STATUS, value)
            self.addProperty(prop)

    def editCompleted(self, completed):
        # Remove existing COMPLETED item
        self.removeProperties(definitions.cICalProperty_COMPLETED)
        self.mHasCompleted = False

        # Always UTC
        self.mCompleted = completed.duplicate()
        self.mCompleted.adjustToUTC()
        self.mHasCompleted = True
        prop = Property(definitions.cICalProperty_STATUS_COMPLETED,
                        self.mCompleted)
        self.addProperty(prop)

    def sortedPropertyKeyOrder(self):
        return (
            definitions.cICalProperty_UID,
            definitions.cICalProperty_RECURRENCE_ID,
            definitions.cICalProperty_DTSTART,
            definitions.cICalProperty_DURATION,
            definitions.cICalProperty_DUE,
            definitions.cICalProperty_COMPLETED,
        )
Example #4
0
class VToDo(ComponentRecur):

    OVERDUE = 0
    DUE_NOW = 1
    DUE_LATER = 2
    DONE = 3
    CANCELLED = 4

    @staticmethod
    def sort_for_display(e1, e2):
        s1 = e1.getMaster()
        s2 = e2.getMaster()

        # Check status first (convert None -> Needs action for tests)
        status1 = s1.self.mStatus
        status2 = s2.self.mStatus
        if status1 == definitions.eStatus_VToDo_None:
            status1 = definitions.eStatus_VToDo_NeedsAction
        if status2 == definitions.eStatus_VToDo_None:
            status2 = definitions.eStatus_VToDo_NeedsAction
        if status1 != status2:
            # More important ones at the top
            return status1 < status2

        # At this point the status of each is the same

        # If status is cancelled sort by start time
        if s1.self.mStatus == definitions.eStatus_VToDo_Cancelled:
            # Older ones at the bottom
            return s1.mStart > s2.mStart

        # If status is completed sort by completion time
        if s1.self.mStatus == definitions.eStatus_VToDo_Completed:
            # Older ones at the bottom
            return s1.self.mCompleted > s2.self.mCompleted

        # Check due date exists
        if s1.mHasEnd != s2.mHasEnd:
            now = DateTime()
            now.setToday()

            # Ones with due dates after today below ones without due dates
            if s1.hasEnd():
                return s1.mEnd <= now
            elif s2.hasEnd():
                return now < s2.mEnd

        # Check due dates if present
        if s1.mHasEnd:
            if s1.mEnd != s2.mEnd:
                # Soonest dues dates above later ones
                return s1.mEnd < s2.mEnd

        # Check priority next
        if s1.self.mPriority != s2.self.mPriority:
            # Higher priority above lower ones
            return s1.self.mPriority < s2.self.mPriority

        # Just use start time - older ones at the top
        return s1.mStart < s2.mStart

    propertyCardinality_1 = (
        definitions.cICalProperty_DTSTAMP,
        definitions.cICalProperty_UID,
    )

    propertyCardinality_0_1 = (
        definitions.cICalProperty_CLASS,
        definitions.cICalProperty_COMPLETED,
        definitions.cICalProperty_CREATED,
        definitions.cICalProperty_DESCRIPTION,
        definitions.cICalProperty_DTSTART,
        definitions.cICalProperty_GEO,
        definitions.cICalProperty_LAST_MODIFIED,
        definitions.cICalProperty_LOCATION,
        definitions.cICalProperty_ORGANIZER,
        definitions.cICalProperty_PERCENT_COMPLETE,
        definitions.cICalProperty_PRIORITY,
        definitions.cICalProperty_RECURRENCE_ID,
        definitions.cICalProperty_SEQUENCE,
        # definitions.cICalProperty_STATUS, # Special fix done for multiple STATUS
        definitions.cICalProperty_SUMMARY,
        definitions.cICalProperty_URL,
        definitions.cICalProperty_RRULE,
        definitions.cICalProperty_DUE,
        definitions.cICalProperty_DURATION,
    )

    propertyValueChecks = ICALENDAR_VALUE_CHECKS

    def __init__(self, parent=None):
        super(VToDo, self).__init__(parent=parent)
        self.mPriority = 0
        self.mStatus = definitions.eStatus_VToDo_None
        self.mPercentComplete = 0
        self.mCompleted = DateTime()
        self.mHasCompleted = False


    def duplicate(self, parent=None):
        other = super(VToDo, self).duplicate(parent=parent)
        other.mPriority = self.mPriority
        other.mStatus = self.mStatus
        other.mPercentComplete = self.mPercentComplete
        other.mCompleted = self.mCompleted.duplicate()
        other.mHasCompleted = self.mHasCompleted
        return other


    def getType(self):
        return definitions.cICalComponent_VTODO


    def getMimeComponentName(self):
        return itipdefinitions.cICalMIMEComponent_VTODO


    def addComponent(self, comp):
        # We can embed the alarm components only
        if comp.getType() == definitions.cICalComponent_VALARM:
            super(VToDo, self).addComponent(comp)
        else:
            raise ValueError


    def getStatus(self):
        return self.mStatus


    def setStatus(self, status):
        self.mStatus = status


    def getStatusText(self):
        sout = StringIO()

        if self.mStatus in (definitions.eStatus_VToDo_NeedsAction, definitions.eStatus_VToDo_InProcess):
            if self.hasEnd():
                # Check due date
                today = DateTime()
                today.setToday()
                if self.getEnd() > today:
                    sout.append("Due: ")
                    whendue = self.getEnd() - today
                    if (whendue.getDays() > 0) and (whendue.getDays() <= 7):
                        sout.write(whendue.getDays())
                        sout.write(" days")
                    else:
                        sout.write(self.getEnd().getLocaleDate(DateTime.NUMERICDATE))
                elif self.getEnd() == today:
                    sout.write("Due today")
                else:
                    sout.write("Overdue: ")
                    overdue = today - self.getEnd()
                    if overdue.getWeeks() != 0:
                        sout.write(overdue.getWeeks())
                        sout.write(" weeks")
                    else:
                        sout.write(overdue.getDays() + 1)
                        sout.write(" days")
            else:
                sout.write("Not Completed")
        elif self.mStatus == definitions.eStatus_VToDo_Completed:
            if self.hasCompleted():
                sout.write("Completed: ")
                sout.write(self.getCompleted().getLocaleDate(DateTime.NUMERICDATE))
            else:
                sout.write("Completed")
        elif definitions.eStatus_VToDo_Cancelled:
            sout.write("Cancelled")

        return sout.toString()


    def getCompletionState(self):
        if self.mStatus in (definitions.eStatus_VToDo_NeedsAction, definitions.eStatus_VToDo_InProcess):
            if self.hasEnd():
                # Check due date
                today = DateTime()
                today.setToday()
                if self.getEnd() > today:
                    return VToDo.DUE_LATER
                elif self.getEnd() == today:
                    return VToDo.DUE_NOW
                else:
                    return VToDo.OVERDUE
            else:
                return VToDo.DUE_NOW
        elif self.mStatus == definitions.eStatus_VToDo_Completed:
            return VToDo.DONE
        elif self.mStatus == definitions.eStatus_VToDo_Cancelled:
            return VToDo.CANCELLED


    def getPriority(self):
        return self.mPriority


    def setPriority(self, priority):
        self.mPriority = priority


    def getCompleted(self):
        return self.mCompleted


    def hasCompleted(self):
        return self.mHasCompleted


    def finalise(self):
        # Do inherited
        super(VToDo, self).finalise()

        # Get DUE
        temp = self.loadValueDateTime(definitions.cICalProperty_DUE)
        if temp is None:
            # Try DURATION instead
            temp = self.loadValueDuration(definitions.cICalProperty_DURATION)
            if temp is not None:
                self.mEnd = self.mStart + temp
                self.mHasEnd = True
            else:
                self.mHasEnd = False
        else:
            self.mHasEnd = True
            self.mEnd = temp

        # Get PRIORITY
        self.mPriority = self.loadValueInteger(definitions.cICalProperty_PRIORITY)

        # Get STATUS
        temp = self.loadValueString(definitions.cICalProperty_STATUS)
        if temp is not None:
            if temp == definitions.cICalProperty_STATUS_NEEDS_ACTION:
                self.mStatus = definitions.eStatus_VToDo_NeedsAction
            elif temp == definitions.cICalProperty_STATUS_COMPLETED:
                self.mStatus = definitions.eStatus_VToDo_Completed
            elif temp == definitions.cICalProperty_STATUS_IN_PROCESS:
                self.mStatus = definitions.eStatus_VToDo_InProcess
            elif temp == definitions.cICalProperty_STATUS_CANCELLED:
                self.mStatus = definitions.eStatus_VToDo_Cancelled

        # Get PERCENT-COMPLETE
        self.mPercentComplete = self.loadValueInteger(definitions.cICalProperty_PERCENT_COMPLETE)

        # Get COMPLETED
        temp = self.loadValueDateTime(definitions.cICalProperty_COMPLETED)
        self.mHasCompleted = temp is not None
        if self.mHasCompleted:
            self.mCompleted = temp


    def validate(self, doFix=False):
        """
        Validate the data in this component and optionally fix any problems, else raise. If
        loggedProblems is not None it must be a C{list} and problem descriptions are appended
        to that.
        """

        fixed, unfixed = super(VToDo, self).validate(doFix)

        # Extra constraint: only one of DUE or DURATION
        if self.hasProperty(definitions.cICalProperty_DUE) and self.hasProperty(definitions.cICalProperty_DURATION):
            # Fix by removing the DURATION
            logProblem = "[%s] Properties must not both be present: %s, %s" % (
                self.getType(),
                definitions.cICalProperty_DUE,
                definitions.cICalProperty_DURATION,
            )
            if doFix:
                self.removeProperties(definitions.cICalProperty_DURATION)
                fixed.append(logProblem)
            else:
                unfixed.append(logProblem)

        # Extra constraint: DTSTART must be present if DURATION is present
        if self.hasProperty(definitions.cICalProperty_DURATION) and not self.hasProperty(definitions.cICalProperty_DTSTART):
            # Cannot fix this one
            logProblem = "[%s] Property must be present: %s with %s" % (
                self.getType(),
                definitions.cICalProperty_DTSTART,
                definitions.cICalProperty_DURATION,
            )
            unfixed.append(logProblem)

        return fixed, unfixed


    # Editing
    def editStatus(self, status):
        # Only if it is different
        if self.mStatus != status:
            # Updated cached values
            self.mStatus = status

            # Remove existing STATUS & COMPLETED items
            self.removeProperties(definitions.cICalProperty_STATUS)
            self.removeProperties(definitions.cICalProperty_COMPLETED)
            self.mHasCompleted = False

            # Now create properties
            value = None
            if status == definitions.eStatus_VToDo_NeedsAction:
                value = definitions.cICalProperty_STATUS_NEEDS_ACTION
            if status == definitions.eStatus_VToDo_Completed:
                value = definitions.cICalProperty_STATUS_COMPLETED
                # Add the completed item
                self.mCompleted.setNowUTC()
                self.mHasCompleted = True
                prop = Property(definitions.cICalProperty_STATUS_COMPLETED, self.mCompleted)
                self.addProperty(prop)
            elif status == definitions.eStatus_VToDo_InProcess:
                value = definitions.cICalProperty_STATUS_IN_PROCESS
            elif status == definitions.eStatus_VToDo_Cancelled:
                value = definitions.cICalProperty_STATUS_CANCELLED
            prop = Property(definitions.cICalProperty_STATUS, value)
            self.addProperty(prop)


    def editCompleted(self, completed):
        # Remove existing COMPLETED item
        self.removeProperties(definitions.cICalProperty_COMPLETED)
        self.mHasCompleted = False

        # Always UTC
        self.mCompleted = completed.duplicate()
        self.mCompleted.adjustToUTC()
        self.mHasCompleted = True
        prop = Property(definitions.cICalProperty_STATUS_COMPLETED, self.mCompleted)
        self.addProperty(prop)


    def sortedPropertyKeyOrder(self):
        return (
            definitions.cICalProperty_UID,
            definitions.cICalProperty_RECURRENCE_ID,
            definitions.cICalProperty_DTSTART,
            definitions.cICalProperty_DURATION,
            definitions.cICalProperty_DUE,
            definitions.cICalProperty_COMPLETED,
        )