cronrec.py
author Eugen Sawin <sawine@me73.com>
Tue, 05 Oct 2010 15:38:38 +0200
changeset 11 8a99ccb99361
parent 10 37ab6d0ddb30
child 12 28c80ae695dc
permissions -rwxr-xr-x
Added add break command.
     1 #!/usr/local/bin/python
     2 
     3 """
     4 tim - A time recording tool, because time is money.
     5 Author: Eugen Sawin (sawine@me73.com)
     6 Dependencies: Python 2.7 and libsqlite3-dev
     7 """
     8 
     9 import os
    10 import sys
    11 import argparse
    12 from datetime import datetime
    13 
    14 import db
    15 
    16 WD = "working_path"
    17 CONFIG = {WD: str}
    18 CONFIG_SEP = "="
    19 DB_FILE = "cronrec.db"
    20 
    21 config = {}
    22 
    23 # Try to get the user's home directory path
    24 try: # Windows
    25 	from win32com.shell import shellcon, shell
    26 	HOMEDIR	= shell.SHGetFolderPath(0, shellcon.CSIDL_LOCAL_APPDATA, 0, 0)
    27 except ImportError: # Linux (hopefully)
    28 	HOMEDIR = os.path.expanduser("~")
    29 
    30 CONFIG_FILE = "%s/.cronrecrc" % HOMEDIR
    31 
    32 DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
    33 
    34 def read_config():
    35 	config = {}
    36 	with open(CONFIG_FILE, "r") as config_stream:
    37 		config_lines = [l.split(CONFIG_SEP) for l in config_stream.readlines() 
    38 						if CONFIG_SEP in l]
    39 		for key, value in config_lines:
    40 			key = key.strip().lower()
    41 			value = value.strip()
    42 			if key in CONFIG:
    43 				config[key] = CONFIG[key](value)
    44 	return config
    45 
    46 def write_config(config):
    47 	with open(CONFIG_FILE, "w") as config_input:
    48 		config_input.write("\n".join([CONFIG_SEP.join((k, v)) 
    49 							for k, v in config.iteritems() if k in CONFIG]))
    50 
    51 def db_file():
    52 	global config
    53 	if WD not in config:
    54 		print "Working directory path is not configured. \
    55 Please use the init command."
    56 		return None
    57 	return config[WD] + "/" + DB_FILE
    58 	
    59 def init(args):
    60 	global config
    61 	last_wd = None
    62 	if WD in config:
    63 		last_wd = config[WD]
    64 	config[WD] = args.working_path
    65 	write_config(config)
    66 	path_exists = os.path.exists(config[WD]) and os.path.isdir(config[WD])
    67 	db_exists = path_exists and os.path.exists(db_file())\
    68 				and os.path.isfile(db_file())
    69 	if last_wd != config[WD]:		
    70 		print "Changed working directory from %s to %s." % (last_wd, config[WD])
    71 	else:
    72 		print "Working directory remains at %s." % config[WD]
    73 	if not path_exists:
    74 		print "Warning: working directory %s does not exist." % config[WD]
    75 		os.makedirs(config[WD])
    76 		print "Working directory %s created." % config[WD]
    77 	elif db_exists:
    78 		print "Database file %s already exists, please delete it before \
    79 initiating a new database at this location." % db_file()
    80 	if not db_exists:
    81 		db.init(db_file())	
    82 
    83 def parse_label(label):
    84 	label = label.strip()
    85 	if ":" in label:
    86 		project, activity = label.split(":")
    87 	else:
    88 		project, activity = (label, None)
    89 	return project, activity
    90 
    91 def begin(args):
    92 	project, activity = parse_label(args.label)
    93 	time = datetime.now()
    94 	db.resume(db_file(), None, None, time)
    95 	db.begin(db_file(), project, activity, time)	
    96     
    97 def end(args):
    98 	project, activity = parse_label(args.label)
    99 	log = args.m	
   100 	time = datetime.now()
   101 	db.resume(db_file(), db.find_active_task(db_file()), time, log)
   102 	db.end(db_file(), project, activity, time, log)	
   103 
   104 def pause(args):
   105 	db.pause(db_file(), datetime.now())	 
   106 
   107 def resume(args):
   108 	db.resume(db_file(), None, datetime.now(), args.m)	
   109 
   110 def add_task(args):
   111 	project, activity = parse_label(args.label)
   112 	log = args.m
   113 	begin = datetime.strptime(args.begin, DATETIME_FORMAT)
   114 	end = datetime.strptime(args.end, DATETIME_FORMAT)
   115 	db.begin(db_file(), project, activity, begin)
   116 	db.end(db_file(), project, activity, end, log)
   117 
   118 def add_break(args):
   119 	log = args.m
   120 	begin = datetime.strptime(args.begin, DATETIME_FORMAT)
   121 	end = datetime.strptime(args.end, DATETIME_FORMAT)
   122 	db.pause(db_file(), begin)
   123 	db.resume(db_file(), db.find_active_task(db_file(), begin), end, log)
   124 
   125 def status(args):
   126 	task = db.status(db_file())
   127 	if task:
   128 		print "Currently active task"
   129 		print "Project: %s Activity: %s" % task
   130 	else:
   131 		print "There is no active task."
   132 
   133 def main():
   134 	global config
   135 	config = read_config()
   136 	parser = argparse.ArgumentParser(description="Records time.")
   137 	subs = parser.add_subparsers()
   138 
   139 	sub_init = subs.add_parser("init")
   140 	sub_init.add_argument("working_path", type=str)
   141 	sub_init.set_defaults(func=init)
   142 
   143 	sub_begin = subs.add_parser("begin")
   144 	sub_begin.add_argument("label", type=str)
   145 	sub_begin.set_defaults(func=begin)
   146 
   147 	sub_end = subs.add_parser("end")
   148 	sub_end.add_argument("label", type=str, nargs="?", default="all:all")
   149 	sub_end.add_argument("-m", type=str)
   150 	sub_end.set_defaults(func=end)
   151 
   152 	sub_pause = subs.add_parser("pause")
   153 	sub_pause.set_defaults(func=pause)
   154 
   155 	sub_resume = subs.add_parser("resume")
   156 	sub_resume.add_argument("-m", type=str)
   157 	sub_resume.set_defaults(func=resume)
   158 
   159 	sub_add = subs.add_parser("add")
   160 	sub_add_subs = sub_add.add_subparsers()
   161 
   162 	sub_add_task = sub_add_subs.add_parser("task")
   163 	sub_add_task.add_argument("label", type=str)
   164 	sub_add_task.add_argument("begin", type=str)
   165 	sub_add_task.add_argument("end", type=str)
   166 	sub_add_task.add_argument("-m", type=str)
   167 	sub_add_task.set_defaults(func=add_task)
   168 	
   169 	sub_add_break = sub_add_subs.add_parser("break")
   170 	sub_add_break.add_argument("begin", type=str)
   171 	sub_add_break.add_argument("end", type=str)
   172 	sub_add_break.add_argument("-m", type=str)
   173 	sub_add_break.set_defaults(func=add_break)
   174 
   175 	sub_status = subs.add_parser("status")
   176 	sub_status.set_defaults(func=status)
   177 
   178 	args = parser.parse_args()
   179 	args.func(args)
   180     
   181 if __name__ == "__main__":
   182 	main()