TimeTracker/TimeTrackEntry.py

Thu, 30 Dec 2021 11:20:04 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 30 Dec 2021 11:20:04 +0100
branch
eric7
changeset 105
44bfd9e7e65e
parent 98
693e42176007
child 106
6deb942739dc
permissions
-rw-r--r--

Updated copyright for 2022.

# -*- coding: utf-8 -*-

# Copyright (c) 2012 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the time track entry class.
"""

from PyQt6.QtCore import Qt, QDateTime, QTime


class TimeTrackEntry:
    """
    Class implementing the time track entry.
    """
    LineMarker = "Entry: "
    Separator = "@@"
    
    def __init__(self, plugin):
        """
        Constructor
        
        @param plugin reference to the plugin object
        @type TimeTrackerPlugin
        """
        self.__plugin = plugin
        
        self.__entryMembersCount = 5
        self.__id = -1
        self.__startDateTime = QDateTime()      # start date and time
        self.__duration = 0                     # duration in minutes
        self.__task = ""                        # task specification
        self.__comment = ""                     # comment string
        self.__valid = False                    # flag for a valid entry
        
        self.__continueDateTime = QDateTime()
        self.__paused = False
    
    def __lt__(self, other):
        """
        Special method implementing the less than function.
        
        @param other reference to the other object
        @type TimeTrackEntry
        @return flag indicating that self is less than other
        @rtype bool
        """
        return self.__startDateTime < other.getStartDateTime()
    
    def toDict(self):
        """
        Public method to convert the time track entry into a dictionary.
        
        @return dictionary containing the time track entry data
        @rtype dict
        """
        if self.__valid:
            return {
                "id": self.__id,
                "start": self.__startDateTime.toString(Qt.DateFormat.ISODate),
                "duration": self.__duration,
                "task": self.__task,
                "comment": self.__comment,
            }
        else:
            return {}
    
    def fromDict(self, data):
        """
        Public method to populate the time track entry from a dictionary.
        
        @param data dictionary containing the time track entry data
        @type dict
        @return ID of the tracker entry; -1 indicates an error
        @rtype int
        """
        if len(data) != self.__entryMembersCount:
            return -1
        
        self.__id = data["id"]
        
        dt = QDateTime.fromString(data["start"], Qt.DateFormat.ISODate)
        if not dt.isValid():
            return -1
        self.__startDateTime = dt
        
        self.__duration = data["duration"]
        self.__task = data["task"]
        self.__comment = data["comment"]
        
        self.__valid = True
        return self.__id
        
##    def toString(self):
##        """
##        Public method to get a string representation of the entry.
##        
##        @return string representation of the entry (string)
##        """
##        if self.__valid:
##            dataLine = TimeTrackEntry.Separator.join([
##                str(self.__id),
##                self.__startDateTime.toString(Qt.DateFormat.ISODate),
##                str(self.__duration),
##                self.__task,
##                self.__comment,
##            ])
##            return "{0}{1}".format(TimeTrackEntry.LineMarker, dataLine)
##        else:
##            return ""
##    
##    def fromString(self, line):
##        """
##        Public method to populate the entry from the given string.
##        
##        @param line stringified entry data as generated by toString() (string)
##        @return ID of the tracker entry; -1 indicates an error (integer)
##        """
##        if not line.startswith(TimeTrackEntry.LineMarker):
##            return -1
##        
##        line = line.replace(TimeTrackEntry.LineMarker, "")
##        dataList = line.split(TimeTrackEntry.Separator)
##        if len(dataList) != self.__entryMembersCount:
##            return -1
##        
##        try:
##            self.__id = int(dataList[0])
##        except ValueError:
##            return -1
##        
##        dt = QDateTime.fromString(dataList[1], Qt.DateFormat.ISODate)
##        if not dt.isValid():
##            return -1
##        self.__startDateTime = dt
##        
##        try:
##            dt = int(dataList[2])
##        except ValueError:
##            return -1
##        self.__duration = dt
##        
##        self.__task = dataList[3]
##        self.__comment = dataList[4]
##        
##        self.__valid = True
##        return self.__id
##    
    def isValid(self):
        """
        Public method to check the validity of the entry.
        
        @return validity of the entry
        @rtype bool
        """
        return self.__valid
    
    def start(self):
        """
        Public method to set the start time of this entry.
        """
        self.__startDateTime = self.__currentDateTime()
        self.__continueDateTime = QDateTime(self.__startDateTime)
    
    def stop(self):
        """
        Public method to stop this entry.
        """
        if not self.__paused:
            minutes = self.__calculateDuration(
                self.__continueDateTime, QDateTime.currentDateTime())
            self.__duration += minutes
        
        if self.__duration >= self.__plugin.getPreferences("MinimumDuration"):
            self.__valid = True
        else:
            self.__duration = 0
            self.__valid = False
    
    def pause(self):
        """
        Public method to pause the entry.
        """
        if not self.__paused:
            minutes = self.__calculateDuration(
                self.__continueDateTime, QDateTime.currentDateTime())
            self.__duration += minutes
            self.__paused = True
    
    def continue_(self):
        """
        Public method to continue the entry.
        """
        if self.__paused:
            self.__continueDateTime = self.__currentDateTime()
            self.__paused = False
    
    def isPaused(self):
        """
        Public method to check for a paused state.
        
        @return flag indicating a paused state
        @rtype bool
        """
        return self.__paused
    
    def __currentDateTime(self):
        """
        Private method to get the current date and time without milliseconds.
        
        @return current date and time
        @rtype QDateTime
        """
        dt = QDateTime.currentDateTime()
        t = dt.time()
        t2 = QTime(t.hour(), t.minute(), t.second())
        dt.setTime(t2)
        return dt
    
    def __calculateDuration(self, start, stop):
        """
        Private method to calculate the duration in minutes.
        
        @param start start date and time
        @type QDateTime
        @param stop end date and time
        @type QDateTime
        @return duration in minutes
        @rtype int
        """
        secs = start.secsTo(stop)
        minutes = secs // 60
        secsRemaining = secs % 60
        if secsRemaining >= 30:
            minutes += 1
        
        return minutes
    
    def getID(self):
        """
        Public method to get the ID of the entry.
        
        @return ID of the entry
        @rtype int
        """
        return self.__id
    
    def setID(self, eid):
        """
        Public method to assign an ID to the entry.
        
        @param eid ID for the entry
        @type int
        """
        self.__id = eid
    
    def getStartDateTime(self):
        """
        Public method to get the start date and time.
        
        @return start date and time
        @rtype QDateTime
        """
        return self.__startDateTime
    
    def setStartDateTime(self, startDateTime):
        """
        Public method to set the start date and time.
        
        @param startDateTime start date and time
        @type QDateTime
        """
        if startDateTime.isValid():
            self.__startDateTime = startDateTime
            self.__valid = (
                self.__startDateTime.isValid() and
                self.__duration >= self.__plugin.getPreferences(
                    "MinimumDuration")
            )
    
    def getDuration(self):
        """
        Public slot to get the duration.
        
        @return duration
        @rtype int
        """
        return self.__duration
    
    def setDuration(self, duration):
        """
        Public method to set the duration.
        
        @param duration duration in minutes
        @type int
        """
        if duration >= self.__plugin.getPreferences("MinimumDuration"):
            self.__duration = duration
            self.__valid = (
                self.__startDateTime.isValid() and
                self.__duration >= self.__plugin.getPreferences(
                    "MinimumDuration")
            )
    
    def addDuration(self, duration):
        """
        Public method to add a duration.
        
        @param duration duration to be added in minutes. Negative values are
            ignored.
        @type int
        """
        if duration > 0:
            self.__duration += duration
    
    def getTask(self):
        """
        Public method to get the task description.
        
        @return task description
        @rtype str
        """
        return self.__task
    
    def setTask(self, description):
        """
        Public method to set the task description.
        
        @param description task description
        @type str
        """
        self.__task = (
            description.replace("\r\n", " ").replace("\n", " ")
            .replace("\r", " ")
        )
    
    def getComment(self):
        """
        Public method to get the comment.
        
        @return comment
        @rtype str
        """
        return self.__comment
    
    def setComment(self, comment):
        """
        Public method to set a comment.
        
        @param comment comment to set
        @type str
        """
        self.__comment = (
            comment.replace("\r\n", " ").replace("\n", " ").replace("\r", " ")
        )
    
    def getEntryData(self):
        """
        Public method to get the entry data.
        
        @return entry data as a dictionary with keys 'id', 'paused',
            'start_date', 'start_time', 'duration', 'task' and 'comment'
            containing the entry ID, a flag indicating a paused
            state, the start date as a string, the start time as a string,
            the duration, the task and a comment
        @rtype dict
        """
        return {
            "id": self.__id,
            "paused": self.__paused,
            "start_date": self.__startDateTime.toString("yyyy-MM-dd"),
            "start_time": self.__startDateTime.toString("hh:mm:ss"),
            "duration": self.__duration,
            "task": self.__task,
            "comment": self.__comment,
        }

eric ide

mercurial