Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for local / personnal aliases #29

Merged
merged 13 commits into from
Jul 30, 2014
5 changes: 5 additions & 0 deletions doc/tksrc.sample
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ auto_add = auto
# empty
# auto_fill_days = 0,1,2,3,4


# Defines a list of local aliases that you will be able to use in your timesheets
# but that will never be pushed to Zebra
local_aliases = _lunch, _coffee_break

# This section contains your project name <-> id mapping. The format is:
# project_name = project_id/activity_id
[wrmap]
Expand Down
8 changes: 7 additions & 1 deletion taxi/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,16 @@ def run(self):
r = remote.ZebraRemote(self.settings.get('site'),
self.settings.get('username'),
self.settings.get('password'))
entries_to_push = t.get_entries(self.options.date, exclude_ignored=True)
entries_to_push = t.get_entries(self.options.date, exclude_ignored=True, exclude_local=True)
(pushed_entries, failed_entries) = r.send_entries(entries_to_push,
self._entry_pushed)

local_entries = t.get_local_entries(self.options.date)
local_entries_list = []
for (date, entries) in local_entries.iteritems():
local_entries_list.extend(entries)
t.comment_entries(local_entries_list)

t.fix_entries_start_time()
t.comment_entries(pushed_entries)
t.save()
Expand Down
37 changes: 31 additions & 6 deletions taxi/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from taxi.parser import DateLine, EntryLine, TextLine, ParseError
from taxi.utils import date as date_utils


class Entry:
def __init__(self, date, project_name, hours, description, id=None):
self.project_name = project_name
Expand All @@ -18,13 +19,16 @@ def __init__(self, date, project_name, hours, description, id=None):
self.date = date
self.pushed = False
self.ignored = False
self.local = False
self.project_id = None
self.activity_id = None
self.id = id

def __unicode__(self):
if self.is_ignored():
project_name = u'%s (ignored)' % (self.project_name)
elif self.is_local():
project_name = u'%s (local)' % (self.project_name)
else:
project_name = u'%s (%s/%s)' % (self.project_name, self.project_id, self.activity_id)

Expand All @@ -33,6 +37,12 @@ def __unicode__(self):
def is_ignored(self):
return self.ignored or self.get_duration() == 0

def is_local(self):
return self.local

def is_selected(self, exclude_ignored, exclude_local):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment that explains what this method is doing would be great

return not (exclude_ignored and self.is_ignored()) and not (exclude_local and self.is_local())

def get_duration(self):
if isinstance(self.duration, tuple):
if None in self.duration:
Expand All @@ -50,6 +60,7 @@ def get_duration(self):

return self.duration


class Project:
STATUS_NOT_STARTED = 0
STATUS_ACTIVE = 1
Expand Down Expand Up @@ -221,13 +232,15 @@ def _update_entries(self):
if entry.project_name in self.mappings:
entry.project_id = self.mappings[entry.project_name][0]
entry.activity_id = self.mappings[entry.project_name][1]
if(entry.project_id < 0 or entry.activity_id < 0):
entry.local = True
else:
if not entry.is_ignored():
raise UndefinedAliasError(line.get_alias())

self.entries[current_date].append(entry)

def get_entries(self, date=None, exclude_ignored=False):
def get_entries(self, date=None, exclude_ignored=False, exclude_local=False):
entries_dict = {}

# Date can either be a single date (only 1 day) or a tuple for a
Expand All @@ -240,14 +253,26 @@ def get_entries(self, date=None, exclude_ignored=False):
if entrydate not in entries_dict:
entries_dict[entrydate] = []

if not exclude_ignored:
entries_dict[entrydate].extend(entries)
else:
d_list = [entry for entry in entries if not entry.is_ignored()]
entries_dict[entrydate].extend(d_list)
d_list = [entry for entry in entries if entry.is_selected(exclude_ignored, exclude_local)]
entries_dict[entrydate].extend(d_list)

return entries_dict

def get_local_entries(self, date=None):
entries_dict = self.get_entries(date, False)
local_entries = {}

for (date, entries) in entries_dict.iteritems():
local_entries_list = []
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this?

local_entries_list = [entry for entry in entries if entry.is_local()]

for entry in entries:
if entry.is_local():
local_entries_list.append(entry)

if local_entries_list:
local_entries[date] = local_entries_list

return local_entries

def get_ignored_entries(self, date=None):
entries_dict = self.get_entries(date, False)
ignored_entries = {}
Expand Down
6 changes: 5 additions & 1 deletion taxi/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def get_auto_fill_days(self):

return [int(e.strip()) for e in auto_fill_days.split(',')]

def get_aliases(self, include_shared=True):
def get_aliases(self, include_shared=True, include_local=True):
aliases = {}
config_aliases = self.config.items('wrmap')
shared_config_aliases = (self.config.items('shared_wrmap')
Expand All @@ -68,6 +68,10 @@ def get_aliases(self, include_shared=True):
(alias, mapping)
)

if include_local:
for(alias) in self.config.get('default', 'local_aliases').split(','):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the parentheses around (alias)

aliases[alias.strip()] = (-1, -1)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we use None instead of -1?


return aliases

def get_reversed_aliases(self, include_shared=True):
Expand Down
3 changes: 2 additions & 1 deletion taxi/ui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ def show_status(self, entries_dict):
date_utils.unicode_strftime(date, '%A %d %B').capitalize())
for entry in entries:
self.msg(unicode(entry))
subtotal_hours += entry.get_duration() or 0
if not entry.is_local():
subtotal_hours += entry.get_duration() or 0

self.msg(u'%-29s %5.2f\n' % ('', subtotal_hours))
total_hours += subtotal_hours
Expand Down