113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
|
|
from datetime import datetime, timedelta
|
|
import re
|
|
|
|
class Command:
|
|
def __init__(self, default_time, cmdline):
|
|
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
|
|
}
|
|
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
|