~nedrlab/mactimelog/main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import datetime
from config import DATE_FORMAT, TIME_FORMAT, TASK_SEP, DEFAULT_PRJ

from DataManager import dataManager
from Settings import settings
from utils import appendTimes, toPmAm, sec2hm

class TimeManager:
    
    def __init__(self):
        self._prevDate = None
        self._dayLogLines = dataManager.logAfterDate(TimeManager.workingDayStart())
        self._currentTask = ""
        self.workDayLen = long(settings.get("work_day_length")) 
        self.currentTime = 0 # Time spent on work
        self.slackingTime = 0 
    
    def _str2date(self, s):
        return datetime.datetime.strptime(s, DATE_FORMAT)
        
    def _genTaskString(self, task, sec):
        """ Generate task string """
        h, m = sec2hm(sec)
        ts =  TIME_FORMAT + "  >>  %s"  
        ts = ts % (h, m, task)
        return ts
        
    def _possibleTime(self):
        """ 
        Return possible work time, by the information that is currently  
        typed in the input box.    
        """
        if self._currentTask and self._prevDate:
            return (datetime.datetime.now() - self._prevDate).seconds
        return 0
     
    def _possibleWorkTime(self):
        """ Possible time spent on work """
        t = self._possibleTime()
        if not TimeManager.isWorkTask(self._currentTask):
            t = 0
        return t
    
    def _possibleSlackTime(self):
        """ Possible slack time """
        t = self._possibleTime()
        if TimeManager.isWorkTask(self._currentTask):
            t = 0
        return t
            
    def onAppendTask(self, taskString, isWorkingTask):
        """ Virtual method """
        pass
        
    def setCurrentTask(self, task): 
        self._currentTask = task
        
    def countTimings(self):
        """ Search all day log and count times """
        if self._dayLogLines:
            for date, task in self._dayLogLines:
                taskString = self.processTask(date, task)
                self._prevDate = date
                self.onAppendTask(taskString, TimeManager.isWorkTask(task))
                
    @staticmethod        
    def isWorkTask(task):
        """ Check if task is work """
        return task.find("**") == -1
        
    @staticmethod
    def workingDayStart(now=None):
        """ Return datetime object that represents start of the working day """
        if now is None:
            now = datetime.datetime.now()
        workEndTime = settings.get("work_end_time").toTime()
        cd = datetime.datetime.combine(now.date(), 
                                       workEndTime)
        if now.time() < workEndTime:
            cd -= datetime.timedelta(days=1)
        return cd    
    
    def now(self):
        """ Return string representing current datetime """
        return datetime.datetime.now().strftime(DATE_FORMAT)
            
    def timeSpentCurrent(self):
        """ Return time spent on current task """
        if self._prevDate:
            return sec2hm((datetime.datetime.now() - self._prevDate).seconds)
        else:
            return (0, 0)
        
    def timeSpent(self):
        """ Return time spent on work """
        return sec2hm(self.currentTime + self._possibleWorkTime())
        
    def timeSlacking(self):
        """ Return slacking time """
        return sec2hm(self.slackingTime + self._possibleSlackTime()) 
        
    def timeLeft(self):
        """ Return how much time left to work """
        t = sec2hm(self.workDayLen - self.currentTime - self._possibleWorkTime())
        if t[0] < 0 or t[1] < 0:
            t = (0, 0)
        return t
        
    def workTill(self):
        """ Return suggested end of work time """
        now = datetime.datetime.now()
        hc = int(datetime.datetime.now().strftime("%H")) 
        mc = int(datetime.datetime.now().strftime("%M"))
        hl, ml = self.timeLeft()
        return toPmAm(appendTimes((hl,ml), (hc, mc)))
            
    def log(self):
        """ Return day log text """
        return self._dayLogLines
        
    def processTask(self, now, task):
        """ Get task values and process it """
        taskTime, isWork = self.countTaskValues(now, self._prevDate, task)
        if isWork:
            self.currentTime += taskTime
        else:
            self.slackingTime += taskTime
            
        if self._prevDate:
            taskString =  self._genTaskString(task, taskTime)
        else:
            taskString = "Your working day started on %s, %s at %s" % (now.strftime("%A"), 
                        now.strftime("%m-%d-%Y"), now.strftime("%H:%M"))

        return taskString
        
    @staticmethod    
    def countTaskValues(now, prevDate, task):
        """ Count task values and return it """
        sec = 0
        isWork = False
        if prevDate:
            taskTime =  now - prevDate
            sec = taskTime.seconds
            if TimeManager.isWorkTask(task):
                isWork = True
        return sec, isWork
        
    def finishTask(self, prj, task):
        """ Finish nad process task """
        now = datetime.datetime.now()
        if prj and not DEFAULT_PRJ.lower() == prj.lower():
            task = "%s %s %s" % (prj, TASK_SEP, task)
        taskString = self.processTask(now, task)
        dataManager.addTask(now, task)
        self._prevDate = now
        
        
        return taskString, TimeManager.isWorkTask(task)