split off ctt into lib
Signed-off-by: Nico Schottelius <nico@brief.schottelius.org>
This commit is contained in:
parent
73e9e8c3c6
commit
082c316f3c
5 changed files with 308 additions and 160 deletions
99
ctt
Executable file
99
ctt
Executable file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
|
||||
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
|
160
ctt.py
160
ctt.py
|
@ -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
|
37
lib/ctt/__init__.py
Normal file
37
lib/ctt/__init__.py
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
|
||||
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
|
81
lib/ctt/report.py
Executable file
81
lib/ctt/report.py
Executable file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
|
||||
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)
|
91
lib/ctt/tracker.py
Executable file
91
lib/ctt/tracker.py
Executable file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
|
||||
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
|
Loading…
Reference in a new issue