switching to new GUI, remove CmdWindow
This commit is contained in:
parent
9af4c655b1
commit
5fc2cb8a53
103
CmdWindow.py
103
CmdWindow.py
@ -1,103 +0,0 @@
|
|||||||
|
|
||||||
import gtk
|
|
||||||
import gobject
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class CmdWindow:
|
|
||||||
def __init__(self, handle_activated):
|
|
||||||
self.starttime = None
|
|
||||||
self.handle_activated = handle_activated
|
|
||||||
|
|
||||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
|
||||||
self.window.set_geometry_hints(min_width = 350);
|
|
||||||
self.window.connect("delete_event", self.delete_event)
|
|
||||||
self.window.connect("destroy", self.destroy_event)
|
|
||||||
self.entry = gtk.Entry()
|
|
||||||
self.entry.connect("activate", self.activate_event)
|
|
||||||
self.button = gtk.Button(stock = gtk.STOCK_OK)
|
|
||||||
self.button.connect("clicked", self.activate_event)
|
|
||||||
|
|
||||||
self.status_hbox = gtk.HBox()
|
|
||||||
self.status_label = gtk.Label('')
|
|
||||||
self.elapsed_label = gtk.Label('')
|
|
||||||
self.status_hbox.pack_start(self.status_label, expand = False)
|
|
||||||
self.status_hbox.pack_end(self.elapsed_label, expand = False)
|
|
||||||
|
|
||||||
self.error_label = gtk.Label('')
|
|
||||||
|
|
||||||
self.formatted_label = gtk.Label('')
|
|
||||||
|
|
||||||
vbox = gtk.VBox()
|
|
||||||
vbox.pack_start(self.status_hbox)
|
|
||||||
vbox.pack_start(self.error_label)
|
|
||||||
vbox.pack_start(self.formatted_label)
|
|
||||||
gobject.timeout_add(1000, self.updateElapsed)
|
|
||||||
|
|
||||||
hbox = gtk.HBox()
|
|
||||||
hbox.pack_start(self.entry)
|
|
||||||
hbox.pack_start(self.button, expand = False)
|
|
||||||
hbox.show_all()
|
|
||||||
vbox.pack_start(hbox)
|
|
||||||
|
|
||||||
vbox.show()
|
|
||||||
|
|
||||||
self.window.add(vbox)
|
|
||||||
|
|
||||||
def main(self):
|
|
||||||
self.window.show()
|
|
||||||
gtk.main()
|
|
||||||
|
|
||||||
def delete_event(self, widget, event, data=None):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def destroy_event(self, widget, data=None):
|
|
||||||
gtk.main_quit()
|
|
||||||
|
|
||||||
def activate_event(self, widget, data=None):
|
|
||||||
if not self.handle_activated(self.entry.get_text(), self):
|
|
||||||
self.window.destroy()
|
|
||||||
self.entry.set_text('')
|
|
||||||
|
|
||||||
def getElapsed(self):
|
|
||||||
if self.starttime is None:
|
|
||||||
return ''
|
|
||||||
delta = datetime.now() - self.starttime
|
|
||||||
days = delta.days
|
|
||||||
dsecs = delta.seconds
|
|
||||||
hours = dsecs / (60 * 60)
|
|
||||||
dsecs -= hours * 60 * 60
|
|
||||||
minutes = dsecs / 60
|
|
||||||
dsecs -= minutes * 60
|
|
||||||
seconds = dsecs
|
|
||||||
elapsed = ''
|
|
||||||
if days != 0:
|
|
||||||
elapsed = '%dd ' % days
|
|
||||||
elapsed += '%d:%02d:%02d' % (hours, minutes, seconds)
|
|
||||||
return elapsed
|
|
||||||
|
|
||||||
def updateElapsed(self):
|
|
||||||
self.elapsed_label.set_text(self.getElapsed())
|
|
||||||
return True
|
|
||||||
|
|
||||||
def setStatus(self, status, starttime):
|
|
||||||
if status != '':
|
|
||||||
self.status_label.set_text(status)
|
|
||||||
self.starttime = starttime
|
|
||||||
self.updateElapsed()
|
|
||||||
self.status_hbox.show_all()
|
|
||||||
else:
|
|
||||||
self.status_hbox.hide_all()
|
|
||||||
|
|
||||||
def setError(self, error):
|
|
||||||
self.error_label.set_text(error)
|
|
||||||
if error != '':
|
|
||||||
self.error_label.show()
|
|
||||||
else:
|
|
||||||
self.error_label.hide()
|
|
||||||
|
|
||||||
def setFormatted(self, formatted):
|
|
||||||
self.formatted_label.set_text(formatted)
|
|
||||||
if formatted != '':
|
|
||||||
self.formatted_label.show()
|
|
||||||
else:
|
|
||||||
self.formatted_label.hide()
|
|
116
Command.py
116
Command.py
@ -1,116 +0,0 @@
|
|||||||
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import re
|
|
||||||
|
|
||||||
class Command:
|
|
||||||
def __init__(self, cmdline, default_time = None):
|
|
||||||
if default_time is None:
|
|
||||||
self.time = datetime.now()
|
|
||||||
else:
|
|
||||||
self.time = default_time
|
|
||||||
self.command = 'start'
|
|
||||||
self.argstr = ''
|
|
||||||
self.parseCommandLine(cmdline)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "{'time' => '%s', 'command' => '%s', 'argstr' => '%s'}" % \
|
|
||||||
(self.time, self.command, self.argstr)
|
|
||||||
|
|
||||||
def parseCommandLine(self, cmdline):
|
|
||||||
COMMANDS = {
|
|
||||||
'out' : 1,
|
|
||||||
'report' : 1,
|
|
||||||
'status' : 1,
|
|
||||||
'fill' : 1,
|
|
||||||
'adjust' : 1,
|
|
||||||
'start' : 1,
|
|
||||||
'task' : 1
|
|
||||||
}
|
|
||||||
ALIASES = {
|
|
||||||
'rpt' : 'report',
|
|
||||||
'adj' : 'adjust',
|
|
||||||
'end' : 'out',
|
|
||||||
'st' : 'status',
|
|
||||||
'show' : 'status',
|
|
||||||
'f' : 'fill'
|
|
||||||
}
|
|
||||||
args = []
|
|
||||||
foundArgs = False
|
|
||||||
|
|
||||||
while True:
|
|
||||||
cmdline = cmdline.strip()
|
|
||||||
if len(cmdline) < 1:
|
|
||||||
break
|
|
||||||
parts = cmdline.split(None, 1)
|
|
||||||
token = parts[0]
|
|
||||||
if not foundArgs:
|
|
||||||
if self.parseDate(token):
|
|
||||||
pass
|
|
||||||
elif self.parseTime(token):
|
|
||||||
pass
|
|
||||||
elif token in COMMANDS:
|
|
||||||
self.command = token
|
|
||||||
foundArgs = True
|
|
||||||
elif token in ALIASES:
|
|
||||||
self.command = ALIASES[token]
|
|
||||||
foundArgs = True
|
|
||||||
else:
|
|
||||||
foundArgs = True
|
|
||||||
args.append(token)
|
|
||||||
else:
|
|
||||||
args.append(token)
|
|
||||||
if len(parts) < 2:
|
|
||||||
break
|
|
||||||
cmdline = parts[1]
|
|
||||||
|
|
||||||
self.argstr = ' '.join(args)
|
|
||||||
|
|
||||||
def parseDate(self, dt):
|
|
||||||
if dt.lower() == "yesterday":
|
|
||||||
today = datetime.today()
|
|
||||||
y = today - timedelta(days = 1)
|
|
||||||
self.time = self.time.replace(
|
|
||||||
year = y.year, month = y.month, day = y.day)
|
|
||||||
return True
|
|
||||||
m = re.match('^(?:(\d{4})[-/])?(\d{1,2})[-/](\d{1,2})$', dt)
|
|
||||||
if m is not None:
|
|
||||||
# dt was a date string
|
|
||||||
if m.group(1) is not None:
|
|
||||||
self.time = self.time.replace(year = int(m.group(1)))
|
|
||||||
month, day = int(m.group(2)), int(m.group(3))
|
|
||||||
self.time = self.time.replace(month = month, day = day)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def parseTime(self, timespec):
|
|
||||||
m = re.match('^(\d{1,2}):?(\d{2})?(am?|pm?)?$', timespec, re.I)
|
|
||||||
if m is not None:
|
|
||||||
# an absolute time was given
|
|
||||||
h = int(m.group(1))
|
|
||||||
mins = 0 if m.group(2) is None else int(m.group(2))
|
|
||||||
am_pm = '' if m.group(3) is None else m.group(3)[0].lower()
|
|
||||||
if am_pm == 'p' and h < 12:
|
|
||||||
h += 12
|
|
||||||
elif am_pm == 'a' and h == 12:
|
|
||||||
h = 0
|
|
||||||
self.time = self.time.replace(hour = h, minute = mins, second = 0)
|
|
||||||
return True
|
|
||||||
m = re.match('^([-+])(\d+(?:\.\d+)?)([hms])?$', timespec, re.I)
|
|
||||||
if m is not None:
|
|
||||||
# a relative time was given
|
|
||||||
plus_minus = m.group(1)
|
|
||||||
hms = '' if m.group(3) is None else m.group(3)
|
|
||||||
count = int(m.group(2))
|
|
||||||
if hms == 'm':
|
|
||||||
seconds = count * 60
|
|
||||||
elif hms == 's':
|
|
||||||
seconds = count
|
|
||||||
else: # hours
|
|
||||||
seconds = count * 60 * 60
|
|
||||||
delta = timedelta(seconds = seconds)
|
|
||||||
if plus_minus == '-':
|
|
||||||
self.time -= delta
|
|
||||||
else:
|
|
||||||
self.time += delta
|
|
||||||
return True
|
|
||||||
return False
|
|
267
DataStore.py
267
DataStore.py
@ -1,267 +0,0 @@
|
|||||||
|
|
||||||
import sqlite3
|
|
||||||
import os
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
HISTORY_DT_FMT = '%Y-%m-%d %H:%M:%S'
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
def __init__(self, taskid, name, longname, parentid):
|
|
||||||
self.taskid = taskid
|
|
||||||
self.name = name
|
|
||||||
self.longname = longname
|
|
||||||
self.parentid = parentid
|
|
||||||
|
|
||||||
class TaskRef:
|
|
||||||
def __init__(self, taskid, time):
|
|
||||||
self.taskid = taskid
|
|
||||||
self.time = time
|
|
||||||
|
|
||||||
class Entry:
|
|
||||||
def __init__(self, date, seconds, taskid):
|
|
||||||
self.date = date
|
|
||||||
self.seconds = seconds
|
|
||||||
self.taskid = taskid
|
|
||||||
|
|
||||||
class DataStore:
|
|
||||||
def __init__(self, dbfile):
|
|
||||||
if not os.path.exists(dbfile):
|
|
||||||
self.createdb(dbfile)
|
|
||||||
self.conn = sqlite3.connect(dbfile)
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
self.conn.close()
|
|
||||||
|
|
||||||
def createdb(self, dbfile):
|
|
||||||
conn = sqlite3.connect(dbfile)
|
|
||||||
c = conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
CREATE TABLE tasks (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT,
|
|
||||||
longname TEXT,
|
|
||||||
parentid INTEGER,
|
|
||||||
FOREIGN KEY (parentid) REFERENCES tasks(id)
|
|
||||||
)''')
|
|
||||||
c.execute('''
|
|
||||||
CREATE TABLE entries (
|
|
||||||
date TEXT,
|
|
||||||
taskid INTEGER,
|
|
||||||
seconds INTEGER,
|
|
||||||
PRIMARY KEY (date, taskid),
|
|
||||||
FOREIGN KEY (taskid) REFERENCES tasks(id)
|
|
||||||
)''')
|
|
||||||
c.execute('''
|
|
||||||
CREATE TABLE history (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
taskid INTEGER,
|
|
||||||
datetime TEXT,
|
|
||||||
FOREIGN KEY (taskid) REFERENCES tasks(id)
|
|
||||||
)''')
|
|
||||||
conn.commit()
|
|
||||||
c.close()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
def getCurrentTask(self):
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
SELECT taskid, datetime
|
|
||||||
FROM history
|
|
||||||
WHERE id = 0
|
|
||||||
''')
|
|
||||||
ct = None
|
|
||||||
for row in c:
|
|
||||||
taskid = row[0]
|
|
||||||
dt = datetime.strptime(row[1], HISTORY_DT_FMT)
|
|
||||||
ct = TaskRef(taskid, dt)
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return ct
|
|
||||||
|
|
||||||
def updateCurrentTask(self, ct):
|
|
||||||
self.clearCurrentTask()
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
INSERT INTO history
|
|
||||||
VALUES (0, ?, ?)
|
|
||||||
''', (ct.taskid, ct.time.strftime(HISTORY_DT_FMT)))
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
|
|
||||||
def clearCurrentTask(self):
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
DELETE FROM history
|
|
||||||
WHERE id = 0
|
|
||||||
''')
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
|
|
||||||
def updateTask(self, taskid, name, longname):
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
UPDATE tasks
|
|
||||||
SET name = ?, longname = ?
|
|
||||||
WHERE id = ?
|
|
||||||
''', (name, longname, taskid))
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def getTaskByID(self, taskid):
|
|
||||||
t = None
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
SELECT name, longname, parentid
|
|
||||||
FROM tasks
|
|
||||||
WHERE id = ?
|
|
||||||
''', (taskid,))
|
|
||||||
for row in c:
|
|
||||||
t = Task(taskid, row[0], row[1], row[2])
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return t
|
|
||||||
|
|
||||||
def getTaskByNameParent(self, name, parentid):
|
|
||||||
t = None
|
|
||||||
c = self.conn.cursor()
|
|
||||||
name = name.strip()
|
|
||||||
if parentid is None:
|
|
||||||
c.execute('''
|
|
||||||
SELECT id, name, longname, parentid
|
|
||||||
FROM tasks
|
|
||||||
WHERE name = ? AND parentid IS NULL
|
|
||||||
''', (name,))
|
|
||||||
else:
|
|
||||||
c.execute('''
|
|
||||||
SELECT id, name, longname, parentid
|
|
||||||
FROM tasks
|
|
||||||
WHERE name = ? AND parentid = ?
|
|
||||||
''', (name, parentid))
|
|
||||||
for row in c:
|
|
||||||
t = Task(*row)
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return t
|
|
||||||
|
|
||||||
def getTaskByName(self, name):
|
|
||||||
parts = name.split(':')
|
|
||||||
parentid = None
|
|
||||||
task = None
|
|
||||||
for p in parts:
|
|
||||||
p = p.strip()
|
|
||||||
task = self.getTaskByNameParent(p, parentid)
|
|
||||||
if task is None:
|
|
||||||
break
|
|
||||||
parentid = task.taskid
|
|
||||||
return task
|
|
||||||
|
|
||||||
def getTaskByShortName(self, name):
|
|
||||||
if name.find(':') >= 0:
|
|
||||||
return self.getTaskByName(name)
|
|
||||||
task = None
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
SELECT id, name, longname, parentid
|
|
||||||
FROM tasks
|
|
||||||
WHERE name = ?
|
|
||||||
''', (name,))
|
|
||||||
count = 0
|
|
||||||
for row in c:
|
|
||||||
count += 1
|
|
||||||
task = Task(*row)
|
|
||||||
if count > 1:
|
|
||||||
return None
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return task
|
|
||||||
|
|
||||||
def getParentTaskByName(self, name):
|
|
||||||
parts = name.split(':')
|
|
||||||
parentname = ':'.join(parts[:-1])
|
|
||||||
return self.getTaskByName(parentname)
|
|
||||||
|
|
||||||
def getParentTaskByShortName(self, name):
|
|
||||||
parts = name.split(':')
|
|
||||||
parentname = ':'.join(parts[:-1])
|
|
||||||
return self.getTaskByShortName(parentname)
|
|
||||||
|
|
||||||
def getTaskPath(self, task):
|
|
||||||
path = task.name
|
|
||||||
if task.parentid is not None:
|
|
||||||
parenttask = self.getTaskByID(task.parentid)
|
|
||||||
if parenttask is not None:
|
|
||||||
parentpath = self.getTaskPath(parenttask)
|
|
||||||
path = parentpath + ':' + path
|
|
||||||
return path
|
|
||||||
|
|
||||||
def createTask(self, name, longname, parentid):
|
|
||||||
c = self.conn.cursor()
|
|
||||||
if parentid is not None and parentid != '':
|
|
||||||
c.execute('''
|
|
||||||
SELECT *
|
|
||||||
FROM tasks
|
|
||||||
WHERE id = ?
|
|
||||||
''', (parentid,))
|
|
||||||
found = False
|
|
||||||
for row in c:
|
|
||||||
found = True
|
|
||||||
if not found:
|
|
||||||
return 0
|
|
||||||
c.execute('''
|
|
||||||
SELECT MAX(id)
|
|
||||||
FROM tasks
|
|
||||||
''')
|
|
||||||
nextid = 1
|
|
||||||
for row in c:
|
|
||||||
if row[0] is not None:
|
|
||||||
nextid = row[0] + 1
|
|
||||||
c.execute('''
|
|
||||||
INSERT INTO tasks
|
|
||||||
VALUES (?, ?, ?, ?)
|
|
||||||
''', (nextid, name.strip(), longname.strip(), parentid))
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return nextid
|
|
||||||
|
|
||||||
def addTime(self, date, taskid, seconds):
|
|
||||||
c = self.conn.cursor()
|
|
||||||
exists = False
|
|
||||||
oldseconds = 0
|
|
||||||
c.execute('''
|
|
||||||
SELECT seconds
|
|
||||||
FROM entries
|
|
||||||
WHERE date = ? AND taskid = ?
|
|
||||||
''', (date, taskid))
|
|
||||||
for row in c:
|
|
||||||
if row[0] is not None:
|
|
||||||
exists = True
|
|
||||||
oldseconds = row[0]
|
|
||||||
if exists:
|
|
||||||
c.execute('''
|
|
||||||
UPDATE entries
|
|
||||||
SET seconds = ?
|
|
||||||
WHERE date = ? AND taskid = ?
|
|
||||||
''', (oldseconds + seconds, date, taskid))
|
|
||||||
else:
|
|
||||||
c.execute('''
|
|
||||||
INSERT INTO entries
|
|
||||||
VALUES(?, ?, ?)
|
|
||||||
''', (date, taskid, seconds))
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
|
|
||||||
def getEntriesInDateRange(self, date1, date2):
|
|
||||||
entries = []
|
|
||||||
c = self.conn.cursor()
|
|
||||||
c.execute('''
|
|
||||||
SELECT date, seconds, taskid
|
|
||||||
FROM entries
|
|
||||||
WHERE date >= ? AND date <= ?
|
|
||||||
ORDER BY taskid, date
|
|
||||||
''', (date1.strftime('%Y-%m-%d'), date2.strftime('%Y-%m-%d')))
|
|
||||||
for row in c:
|
|
||||||
entries.append(Entry(*row))
|
|
||||||
c.close()
|
|
||||||
self.conn.commit()
|
|
||||||
return entries
|
|
20
Window.py
Normal file
20
Window.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
|
||||||
|
class Window:
|
||||||
|
def __init__(self):
|
||||||
|
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
|
self.window.set_geometry_hints();
|
||||||
|
self.window.connect("delete_event", self.delete_event)
|
||||||
|
self.window.connect("destroy", self.destroy_event)
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
self.window.show()
|
||||||
|
gtk.main()
|
||||||
|
|
||||||
|
def delete_event(self, widget, event, data=None):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def destroy_event(self, widget, data=None):
|
||||||
|
gtk.main_quit()
|
136
dwtt
136
dwtt
@ -3,11 +3,8 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
from CmdWindow import CmdWindow
|
from Window import *
|
||||||
from Command import Command
|
|
||||||
from DataStore import DataStore, TaskRef
|
|
||||||
|
|
||||||
PROGRAM_NAME = 'dwtt'
|
PROGRAM_NAME = 'dwtt'
|
||||||
|
|
||||||
@ -32,135 +29,8 @@ def main(argv):
|
|||||||
usage()
|
usage()
|
||||||
sys.exit(3)
|
sys.exit(3)
|
||||||
|
|
||||||
timedbfile = os.path.expanduser('~') + os.path.sep + '.dwtt.db'
|
w = Window()
|
||||||
if len(args) >= 1:
|
w.main()
|
||||||
timedbfile = args[0]
|
|
||||||
|
|
||||||
ds = DataStore(timedbfile)
|
|
||||||
|
|
||||||
def handleActivated(cmdline, cw):
|
|
||||||
if cmdline.strip() == '':
|
|
||||||
return False
|
|
||||||
ct = ds.getCurrentTask()
|
|
||||||
if ct is not None:
|
|
||||||
task = ds.getTaskByID(ct.taskid)
|
|
||||||
status = 'Task: ' + ds.getTaskPath(task)
|
|
||||||
if task.longname != '':
|
|
||||||
status += ' (%s)' % task.longname
|
|
||||||
cw.setStatus(status, ct.time)
|
|
||||||
else:
|
|
||||||
cw.setStatus('', None)
|
|
||||||
cmd = Command(cmdline)
|
|
||||||
res = processCommand(cmd, ds)
|
|
||||||
if not res.keepwindow:
|
|
||||||
return False
|
|
||||||
cw.setError(res.error)
|
|
||||||
cw.setFormatted(res.formatted)
|
|
||||||
return True
|
|
||||||
|
|
||||||
cw = CmdWindow(handleActivated)
|
|
||||||
ct = ds.getCurrentTask()
|
|
||||||
if ct is not None:
|
|
||||||
task = ds.getTaskByID(ct.taskid)
|
|
||||||
status = 'Task: ' + ds.getTaskPath(task)
|
|
||||||
if task.longname != '':
|
|
||||||
status += ' (%s)' % task.longname
|
|
||||||
cw.setStatus(status, ct.time)
|
|
||||||
cw.main()
|
|
||||||
|
|
||||||
class Result:
|
|
||||||
def __init__(self):
|
|
||||||
self.keepwindow = False
|
|
||||||
self.error = ''
|
|
||||||
self.message = ''
|
|
||||||
self.formatted = ''
|
|
||||||
|
|
||||||
def processStart(cmd, store):
|
|
||||||
res = Result()
|
|
||||||
task = store.getTaskByShortName(cmd.argstr)
|
|
||||||
if task is None:
|
|
||||||
parent = store.getParentTaskByShortName(cmd.argstr)
|
|
||||||
if parent is None:
|
|
||||||
res.error = 'Could not find task "%s"' % \
|
|
||||||
(':'.join(cmd.argstr.split(':')[:-1]))
|
|
||||||
res.keepwindow = True
|
|
||||||
return res
|
|
||||||
taskid = store.createTask(cmd.argstr.split(':')[-1], '', parent.taskid)
|
|
||||||
else:
|
|
||||||
taskid = task.taskid
|
|
||||||
processOut(cmd, store)
|
|
||||||
store.updateCurrentTask(TaskRef(taskid, cmd.time))
|
|
||||||
return res
|
|
||||||
|
|
||||||
def processOut(cmd, store):
|
|
||||||
res = Result()
|
|
||||||
ct = store.getCurrentTask()
|
|
||||||
if ct is None:
|
|
||||||
res.error = 'No current task defined'
|
|
||||||
res.keepwindow = True
|
|
||||||
return res
|
|
||||||
seconds = (cmd.time - ct.time).seconds
|
|
||||||
if seconds > 0:
|
|
||||||
store.addTime(cmd.time.strftime('%Y-%m-%d'), ct.taskid, seconds)
|
|
||||||
store.clearCurrentTask()
|
|
||||||
return res
|
|
||||||
|
|
||||||
def processTask(cmd, store):
|
|
||||||
res = Result()
|
|
||||||
res.keepwindow = True
|
|
||||||
parts = cmd.argstr.split(',', 1)
|
|
||||||
fullname = parts[0].strip()
|
|
||||||
longname = '' if len(parts) < 2 else parts[1].strip()
|
|
||||||
nameparts = fullname.split(':')
|
|
||||||
task = store.getTaskByName(fullname)
|
|
||||||
if task is not None:
|
|
||||||
# the task already exists, update it
|
|
||||||
store.updateTask(task.taskid, nameparts[-1], longname)
|
|
||||||
res.message = 'Task "%s" updated' % fullname
|
|
||||||
return res
|
|
||||||
if len(nameparts) > 1:
|
|
||||||
parenttask = store.getParentTaskByShortName(fullname)
|
|
||||||
if parenttask is None:
|
|
||||||
res.error = 'Parent task of "%s" not found' % fullname
|
|
||||||
return res
|
|
||||||
store.createTask(nameparts[-1].strip(), longname, parenttask.taskid)
|
|
||||||
else:
|
|
||||||
store.createTask(nameparts[-1].strip(), longname, None)
|
|
||||||
res.message = 'Task "%s" created' % fullname
|
|
||||||
return res
|
|
||||||
|
|
||||||
def processStatus(cmd, store):
|
|
||||||
res = Result()
|
|
||||||
res.keepwindow = True
|
|
||||||
now = datetime.now()
|
|
||||||
monday = now - timedelta(now.weekday())
|
|
||||||
sunday = monday + timedelta(6)
|
|
||||||
entries = store.getEntriesInDateRange(monday, sunday)
|
|
||||||
prevtask = 0
|
|
||||||
for ent in entries:
|
|
||||||
if ent.taskid != prevtask:
|
|
||||||
prevtask = ent.taskid
|
|
||||||
task = store.getTaskByID(ent.taskid)
|
|
||||||
print store.getTaskPath(task) + ':'
|
|
||||||
hours = round(float(ent.seconds) / (60 * 60), 1)
|
|
||||||
print ' %s: %0.1f' % (ent.date, hours)
|
|
||||||
return res
|
|
||||||
|
|
||||||
COMMAND_HANDLERS = {
|
|
||||||
'start' : processStart,
|
|
||||||
'out' : processOut,
|
|
||||||
'task' : processTask,
|
|
||||||
'status' : processStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
# Returns boolean for whether the command prompt should be displayed again
|
|
||||||
def processCommand(cmd, store):
|
|
||||||
if cmd.command in COMMAND_HANDLERS:
|
|
||||||
return COMMAND_HANDLERS[cmd.command](cmd, store)
|
|
||||||
res = Result()
|
|
||||||
res.error = 'Unknown command: %s' % cmd.command
|
|
||||||
res.keepwindow = True
|
|
||||||
return res
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
49
test
49
test
@ -1,49 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
from Command import Command
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
n_tests = 0
|
|
||||||
n_pass = 0
|
|
||||||
|
|
||||||
def testcmd(cmdline, cmd, argstr):
|
|
||||||
global n_tests, n_pass
|
|
||||||
n_tests += 1
|
|
||||||
print "Testing command line '%s'" % cmdline
|
|
||||||
c = Command(cmdline)
|
|
||||||
if c.command == cmd and c.argstr == argstr:
|
|
||||||
n_pass += 1
|
|
||||||
else:
|
|
||||||
print " **** testcmd FAILED ****"
|
|
||||||
print " command:"
|
|
||||||
print " expected: '%s'" % cmd
|
|
||||||
print " actual: '%s'" % c.command
|
|
||||||
print " argstr:"
|
|
||||||
print " expected: '%s'" % argstr
|
|
||||||
print " actual: '%s'" % c.argstr
|
|
||||||
print " ************************"
|
|
||||||
|
|
||||||
def main():
|
|
||||||
global n_tests, n_pass
|
|
||||||
testcmd('out', 'out', '')
|
|
||||||
testcmd('fill', 'fill', '')
|
|
||||||
testcmd('adjust', 'adjust', '')
|
|
||||||
testcmd('2 report', 'report', '')
|
|
||||||
testcmd('show', 'status', '')
|
|
||||||
testcmd('5pm out', 'out', '')
|
|
||||||
testcmd('st 45h', 'status', '45h')
|
|
||||||
testcmd('fill 40h', 'fill', '40h')
|
|
||||||
testcmd('-10m arlx', 'start', 'arlx')
|
|
||||||
testcmd(' adjust -10m ', 'adjust', '-10m')
|
|
||||||
testcmd(' 9:45 wr: nog: pbit ram test ',
|
|
||||||
'start', 'wr: nog: pbit ram test')
|
|
||||||
testcmd('12/14 3pm start arlx', 'start', 'arlx')
|
|
||||||
testcmd('yesterday 7P out', 'out', '')
|
|
||||||
if n_tests == n_pass:
|
|
||||||
print " >= SUCCESS <="
|
|
||||||
else:
|
|
||||||
print " >= FAIL <="
|
|
||||||
print "%d of %d tests pass" % (n_pass, n_tests)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main();
|
|
Loading…
x
Reference in New Issue
Block a user