diff --git a/ctt b/ctt new file mode 100755 index 0000000..666b678 --- /dev/null +++ b/ctt @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# 2012 Nico Schottelius (nico-ctt at schottelius.org) +# +# This file is part of ctt. +# +# ctt is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ctt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ctt. If not, see . +# +# + +import argparse +import calendar +import datetime + +#import signal + +import locale +import logging +import time + +import os +import os.path +import sys + +log = logging.getLogger(__name__) + +# Setup locale for calendar printing +# Setup locale to get Timezone information? +#print(locale.getlocale()) + +# Record tags + +def cmd_track(args): + """Command line handler for time tracking""" + tracker = Tracker(args.project[0]) + tracker.track_time() + tracker.write_time() + print(tracker.delta()) + +def cmd_report(args): + """Command line handler for time reporting""" + print(args) + report = Report(args.project[0], args.start, args.end) + print(Report.default_dates()) + +def parse_argv(argv): + parser = {} + parser['main'] = argparse.ArgumentParser(description='ctt ' + VERSION) + parser['sub'] = parser['main'].add_subparsers(title="Commands") + + parser['track'] = parser['sub'].add_parser('track') + parser['track'].set_defaults(func=cmd_track) + parser['track'].add_argument("project", help="Project to track time for", nargs=1) + + parser['report'] = parser['sub'].add_parser('report') + parser['report'].set_defaults(func=cmd_report) + parser['report'].add_argument("project", help="Project to report time for", nargs=1) + parser['report'].add_argument("-s", "--start", help="Start datetime (first of last month)", + nargs=1) + parser['report'].add_argument("-e", "--end", help="End datetime (last of last month)", nargs=1, + default=None) + + #parser['track'].add_argument("-t", "--tag", help="Add tags", + # action="store_true") + + args = parser['main'].parse_args() + print(args) + + args.func(args) + +if __name__ == "__main__": + # Ensure our /lib/ is included into PYTHON_PATH + sys.path.insert(0, os.path.abspath( + os.path.join(os.path.dirname(os.path.realpath(__file__)), '../lib'))) + + from ctt.tracker import Tracker + from ctt.report import Report + + parse_argv(sys.argv[1:]) + sys.exit(0) + +# Setup signal handler +# Start tracking +# Save stuff to our home directory + +# Create datetime from userinput +# Wed Aug 1 23:35:53 2012 diff --git a/ctt.py b/ctt.py deleted file mode 100755 index 4e8400a..0000000 --- a/ctt.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import calendar -import datetime - -#import signal - -import locale -import logging -import time - -import os -import os.path -import sys - -log = logging.getLogger(__name__) - -VERSION = "0.1" - -# Our output format -def user_datetime(when): - """Print time for the user""" - return when.ctime() - -class Tracker: - def __init__(self, project): - self.project = project - self.tracked_time = False - - self._init_home() - - - def _init_home(self): - # Create output directory - home = os.environ['HOME'] - self.ctt_dir = os.path.join(home, ".ctt") - self.project_dir = os.path.join(self.ctt_dir, self.project) - - - # Track time and return information from tracking - def track_time(self): - self.start = datetime.datetime.now() - - try: - # Wait for the exception to pop up - FIXME: find better method - - # Using input, Ctrl-C is displayed as ^C on the screen - ugly - #input() - - # Sleep 42 years - should be longer than anybody trying to track time - time.sleep(86400 * 365 * 42) - - except KeyboardInterrupt: - pass - - self.stop = datetime.datetime.now() - - self.tracked_time = True - - def write_time(self): - if not self.tracked_time: - return - - start_seconds = self.start.strftime("%s") - stop_seconds = self.stop.strftime("%s") - delta_seconds = self.delta() - - time_dir = os.path.join(self.project_dir, start_seconds) - os.makedirs(time_dir, mode=0o700, exist_ok=True) - filename = os.path.join(time_dir, "delta") - - with open(filename, "w") as fd: - fd.write("%s\n" % delta_seconds) - - def delta(self, in_seconds=True): - if self.tracked_time: - delta = self.stop - self.start - else: - delta = datetime.timedelta() - - if in_seconds: - delta = delta.total_seconds() - - return delta - - -class Report(object): - """Create a report on tracked time""" - - def __init__(self, args): - pass - - @staticmethod - def default_dates(): - """Return default start and end of of time - start: first of last month - end: last of last month - """ - - now = datetime.datetime.now() - first_day = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) - end_date = first_day - datetime.timedelta(days=1) - start_date = end_date.replace(day=1) - - return (start_date, end_date) - - -# Setup locale for calendar printing -# Setup locale to get Timezone information? -#print(locale.getlocale()) - -# Record project -# Record tags - -def cmd_track(args): - """Command line handler for time tracking""" - tracker = Tracker(args.project[0]) - tracker.track_time() - tracker.write_time() - print(tracker.delta()) - -def cmd_report(args): - """Command line handler for time reporting""" - #report = Report(args.project[0]) - print(Report.default_dates()) - -def parse_argv(argv): - parser = {} - parser['main'] = argparse.ArgumentParser(description='ctt ' + VERSION) - parser['sub'] = parser['main'].add_subparsers(title="Commands") - - parser['track'] = parser['sub'].add_parser('track') - parser['track'].set_defaults(func=cmd_track) - parser['track'].add_argument("project", help="Project to track time for", nargs=1) - - parser['report'] = parser['sub'].add_parser('report') - parser['report'].set_defaults(func=cmd_report) - parser['report'].add_argument("project", help="Project to report time for", nargs=1) - parser['report'].add_argument("-s", "--start", help="Start datetime (first of last month)", nargs=1) - parser['report'].add_argument("-e", "--end", help="End datetime (last of last month)", nargs=1) - - #parser['track'].add_argument("-t", "--tag", help="Add tags", - # action="store_true") - - args = parser['main'].parse_args() - print(args) - - args.func(args) - -if __name__ == "__main__": - parse_argv(sys.argv[1:]) - sys.exit(0) - -# Setup signal handler -# Start tracking -# Save stuff to our home directory - -# Create datetime from userinput -# Wed Aug 1 23:35:53 2012 diff --git a/lib/ctt/__init__.py b/lib/ctt/__init__.py new file mode 100644 index 0000000..7d6496e --- /dev/null +++ b/lib/ctt/__init__.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# 2012 Nico Schottelius (nico-ctt at schottelius.org) +# +# This file is part of ctt. +# +# ctt is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ctt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ctt. If not, see . +# +# + +VERSION = "0.1" +FILE_DELTA = "delta" + + +# Our output format +def user_datetime(when): + """Print time for the user""" + return when.ctime() + +def project_dir(project): + home = os.environ['HOME'] + ctt_dir = os.path.join(home, ".ctt") + project_dir = os.path.join(ctt_dir, project) + + return project_dir diff --git a/lib/ctt/report.py b/lib/ctt/report.py new file mode 100755 index 0000000..d87c36b --- /dev/null +++ b/lib/ctt/report.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# 2012 Nico Schottelius (nico-ctt at schottelius.org) +# +# This file is part of ctt. +# +# ctt is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ctt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ctt. If not, see . +# +# + +import calendar +import datetime + +import logging +import time + +import os +import os.path +import sys + +log = logging.getLogger(__name__) + +class Report(object): + """Create a report on tracked time""" + + def __init__(self, project, start_date, end_date): + + # Setup default values + if not start_date and not end_date: + start_date, end_date = self.default_dates() + + self.start_seconds = start_date.strftime("%s") + self.end_seconds = end_date.strftime("%s") + + self.project = project + self.project_dir = project_dir(self.project) + + self._init_report_db() + + def _init_report_db(self): + """Read all contents from db""" + + self._report_db = {} + for dirname in os.listdir(self.project_dir): + print("%s:%s:%s" % (self.start_seconds, dirname, self.end_seconds)) + if dirname >= self.start_seconds and dirname <= self.end_seconds: + filename = os.path.join(self.project_dir, dirname, FILE_DELTA) + with open(filename, "r") as fd: + self._report_db[dirname] = fd.read().rstrip('\n') + + print("%s: %s" % (dirname, self._report_db[dirname])) + + def total_time(self): + """Return total time tracked""" + pass + + @staticmethod + def default_dates(): + """Return default start and end of of time + start: first of last month + end: last of last month + """ + + now = datetime.datetime.now() + first_day = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0) + end_date = first_day - datetime.timedelta(days=1) + start_date = end_date.replace(day=1) + + return (start_date, end_date) diff --git a/lib/ctt/tracker.py b/lib/ctt/tracker.py new file mode 100755 index 0000000..44004e7 --- /dev/null +++ b/lib/ctt/tracker.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# 2012 Nico Schottelius (nico-ctt at schottelius.org) +# +# This file is part of ctt. +# +# ctt is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ctt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ctt. If not, see . +# +# + +import datetime + +#import signal + +import locale +import logging +import time + +import os +import os.path +import sys + +log = logging.getLogger(__name__) + +class Tracker: + def __init__(self, project): + self.project = project + self.tracked_time = False + + self._init_home() + + self.project_dir = project_dir(project) + + + # Track time and return information from tracking + def track_time(self): + self.start = datetime.datetime.now() + + try: + # Wait for the exception to pop up - FIXME: find better method + + # Using input, Ctrl-C is displayed as ^C on the screen - ugly + #input() + + # Sleep 42 years - should be longer than anybody trying to track time + time.sleep(86400 * 365 * 42) + + except KeyboardInterrupt: + pass + + self.stop = datetime.datetime.now() + + self.tracked_time = True + + def write_time(self): + if not self.tracked_time: + return + + start_seconds = self.start.strftime("%s") + stop_seconds = self.stop.strftime("%s") + delta_seconds = self.delta() + + time_dir = os.path.join(self.project_dir, start_seconds) + os.makedirs(time_dir, mode=0o700, exist_ok=True) + filename = os.path.join(time_dir, FILE_DELTA) + + with open(filename, "w") as fd: + fd.write("%s\n" % delta_seconds) + + def delta(self, in_seconds=True): + if self.tracked_time: + delta = self.stop - self.start + else: + delta = datetime.timedelta() + + if in_seconds: + delta = delta.total_seconds() + + return delta