sawine@6: #!/usr/local/bin/python sawine@0: sawine@0: """ sawine@7: tim - A time recording tool, because time is money. sawine@0: Author: Eugen Sawin (sawine@me73.com) sawine@7: Dependencies: Python 2.7 and libsqlite3-dev sawine@0: """ sawine@0: sawine@1: import os sawine@2: import sys sawine@0: import argparse sawine@2: from datetime import datetime sawine@3: sawine@3: import db sawine@0: sawine@1: WD = "working_path" sawine@1: CONFIG = {WD: str} sawine@1: CONFIG_SEP = "=" sawine@2: DB_FILE = "cronrec.db" sawine@1: sawine@1: config = {} sawine@1: sawine@7: # Try to get the user's home directory path sawine@1: try: # Windows sawine@1: from win32com.shell import shellcon, shell sawine@1: HOMEDIR = shell.SHGetFolderPath(0, shellcon.CSIDL_LOCAL_APPDATA, 0, 0) sawine@2: except ImportError: # Linux (hopefully) sawine@1: HOMEDIR = os.path.expanduser("~") sawine@1: sawine@1: CONFIG_FILE = "%s/.cronrecrc" % HOMEDIR sawine@1: sawine@1: def read_config(): sawine@1: config = {} sawine@1: with open(CONFIG_FILE, "r") as config_stream: sawine@1: config_lines = [l.split(CONFIG_SEP) for l in config_stream.readlines() sawine@1: if CONFIG_SEP in l] sawine@1: for key, value in config_lines: sawine@1: key = key.strip().lower() sawine@1: value = value.strip() sawine@1: if key in CONFIG: sawine@1: config[key] = CONFIG[key](value) sawine@1: return config sawine@1: sawine@1: def write_config(config): sawine@1: with open(CONFIG_FILE, "w") as config_input: sawine@1: config_input.write("\n".join([CONFIG_SEP.join((k, v)) sawine@1: for k, v in config.iteritems() if k in CONFIG])) sawine@1: sawine@3: def db_file(): sawine@3: global config sawine@3: if WD not in config: sawine@3: print "Working directory path is not configured. \ sawine@3: Please use the init command." sawine@3: return None sawine@3: return config[WD] + "/" + DB_FILE sawine@3: sawine@1: def init(args): sawine@2: global config sawine@1: last_wd = None sawine@1: if WD in config: sawine@1: last_wd = config[WD] sawine@2: config[WD] = args.working_path sawine@1: write_config(config) sawine@2: path_exists = os.path.exists(config[WD]) and os.path.isdir(config[WD]) sawine@3: db_exists = path_exists and os.path.exists(db_file())\ sawine@3: and os.path.isfile(db_file()) sawine@2: if last_wd != config[WD]: sawine@2: print "Changed working directory from %s to %s." % (last_wd, config[WD]) sawine@1: else: sawine@2: print "Working directory remains at %s." % config[WD] sawine@2: if not path_exists: sawine@2: print "Warning: working directory %s does not exist." % config[WD] sawine@2: os.makedirs(config[WD]) sawine@2: print "Working directory %s created." % config[WD] sawine@2: elif db_exists: sawine@3: print "Database file %s already exists, please delete it before \ sawine@3: initiating a new database at this location." % db_file() sawine@2: if not db_exists: sawine@3: db.init(db_file()) sawine@1: sawine@0: def begin(args): sawine@2: project = None sawine@2: activity = None sawine@2: label = args.label.strip() sawine@2: if ":" in label: sawine@2: project, activity = label.split(":") sawine@2: else: sawine@2: project = label sawine@8: time = datetime.now() sawine@8: db.resume(db_file(), None, None, time) sawine@8: db.begin(db_file(), project, activity, time) sawine@0: sawine@0: def end(args): sawine@5: project = None sawine@5: activity = None sawine@5: label = args.label.strip() sawine@5: if ":" in label: sawine@5: project, activity = label.split(":") sawine@5: else: sawine@5: project = label sawine@8: time = datetime.now() sawine@8: db.resume(db_file(), None, None, time) sawine@8: db.end(db_file(), project, activity, time) sawine@8: sawine@8: def pause(args): sawine@8: db.pause(db_file(), None, None, datetime.now()) sawine@8: sawine@8: def resume(args): sawine@8: db.resume(db_file(), None, None, datetime.now()) sawine@2: sawine@7: def status(args): sawine@8: task = db.status(db_file()) sawine@8: if task: sawine@8: print "Currently active task" sawine@8: print "Project: %s Activity: %s" % task sawine@7: else: sawine@8: print "There is no active task." sawine@7: sawine@2: def main(): sawine@2: global config sawine@1: config = read_config() sawine@1: parser = argparse.ArgumentParser(description="Records time.") sawine@1: subs = parser.add_subparsers() sawine@1: sub_begin = subs.add_parser("init") sawine@2: sub_begin.add_argument("working_path", type=str) sawine@1: sub_begin.set_defaults(func=init) sawine@0: sawine@1: sub_begin = subs.add_parser("begin") sawine@2: sub_begin.add_argument("label", type=str) sawine@1: sub_begin.set_defaults(func=begin) sawine@0: sawine@1: sub_end = subs.add_parser("end") sawine@7: sub_end.add_argument("label", type=str, nargs="?", default="all:all") sawine@1: sub_end.set_defaults(func=end) sawine@0: sawine@8: sub_end = subs.add_parser("pause") sawine@8: sub_end.add_argument("-m", type=str) sawine@8: sub_end.set_defaults(func=pause) sawine@8: sawine@8: sub_end = subs.add_parser("resume") sawine@8: sub_end.add_argument("-m", type=str) sawine@8: sub_end.set_defaults(func=resume) sawine@8: sawine@7: sub_end = subs.add_parser("status") sawine@7: sub_end.set_defaults(func=status) sawine@7: sawine@1: args = parser.parse_args() sawine@1: args.func(args) sawine@2: sawine@2: if __name__ == "__main__": sawine@2: main()