Skip to content

Commit 68af60a

Browse files
committed
Correctly handles custom priorities
1 parent 377aac6 commit 68af60a

File tree

5 files changed

+149
-21
lines changed

5 files changed

+149
-21
lines changed

taskwiki/regexp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
DUE = r'(?P<due>{0})'.format(DUE_UNNAMED)
1818
TEXT = r'(?P<text>.+?)'
1919
COMPLETION_MARK = r'(?P<completed>.)'
20-
PRIORITY = r'(?P<priority>!{1,3})'
20+
PRIORITY = r'(?P<priority>!+|¡+)'
2121

2222
GENERIC_TASK = re.compile(''.join([
2323
'^',

taskwiki/store.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,33 @@ def __init__(self, default_rc, default_data, extra_warrior_defs):
2222
current_kwargs.update(extra_warrior_defs[key])
2323
self.warriors[key] = TaskWarrior(**current_kwargs)
2424

25-
# Make sure context is not respected in any TaskWarrior
2625
for tw in self.warriors.values():
26+
# Make sure context is not respected in any TaskWarrior
2727
tw.overrides.update({'context':''})
2828

29+
# Read urgency levels once instead of at every task processing.
30+
_urgency_levels = tw.config.get("uda.priority.values") or "H,M,L,"
31+
tw._config = None # unset the config cache
32+
_urgency_levels = _urgency_levels.split(",")
33+
_urgency_levels.reverse()
34+
35+
# The empty urgency (priority:) is considered the zero point.
36+
# Priorities left of it in taskwarrior's conf are considered values
37+
# of insignificance, i.e. they have a negative weight.
38+
zero_point = _urgency_levels.index('')
39+
keys = [i - zero_point for i in range(0, len(_urgency_levels))]
40+
41+
urgency_levels = {}
42+
urgency_levels = {k:_urgency_levels[i] for i, k in enumerate(keys)}
43+
urgency_levels[0] = None
44+
# urgency_levels[None] = None
45+
# For the default urgency levels, this will be:
46+
# {0: None, 1: 'L', 2: 'M', 3: 'H'}
47+
48+
# Urgency levels need to be stored in the respective TaskWarrior
49+
# instance as they are specific to it.
50+
tw.urgency_levels = urgency_levels
51+
2952
def __getitem__(self, key):
3053
try:
3154
return self.warriors[key]

taskwiki/vwtask.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,6 @@
1111
from taskwiki.short import ShortUUID
1212

1313

14-
def convert_priority_from_tw_format(priority):
15-
return {None: None, 'L': 1, 'M': 2, 'H': 3}[priority]
16-
17-
18-
def convert_priority_to_tw_format(priority):
19-
return {0: None, 1: 'L', 2: 'M', 3: 'H'}[priority]
20-
21-
2214
class VimwikiTask(object):
2315
# Lists all data keys that are reflected in Vim representation
2416
buffer_keys = ('indent', 'description', 'uuid', 'completed_mark',
@@ -106,9 +98,11 @@ def from_line(cls, cache, number):
10698
else:
10799
self.task['description'] = match.group('text')
108100

109-
self.task['priority'] = convert_priority_to_tw_format(
110-
len(match.group('priority') or [])) # This is either 0,1,2 or 3
111-
101+
self.task['priority'] = tw.urgency_levels.get(
102+
0 if match.group('priority') is None
103+
else len(match.group('priority')) if '!' in match.group('priority')
104+
else -len(match.group('priority')) # if '¡' in match.group('priority')
105+
)
112106
# Also make sure changes in the progress field are reflected
113107
if self['completed_mark'] == 'X':
114108
self.task['status'] = 'completed'
@@ -241,11 +235,13 @@ def task(self, task):
241235

242236
@property
243237
def priority_from_tw_format(self):
244-
return convert_priority_from_tw_format(self.task['priority'])
238+
return list(self.tw.urgency_levels.keys())[
239+
list(self.tw.urgency_levels.values()).index(self.task["priority"])
240+
]
245241

246242
@property
247243
def priority_to_tw_format(self):
248-
return convert_priority_to_tw_format(self['priority'])
244+
return self.tw.urgency_levels[self['priority']]
249245

250246
def save_to_tw(self):
251247
# This method persumes all the dependencies have been created at the
@@ -328,14 +324,22 @@ def __str__(self):
328324
self['due'].strftime(regexp.DATE_FORMAT)
329325
) if self['due'] else ''
330326

327+
priority_str = (
328+
" " + "!" * self.priority_from_tw_format
329+
if self["priority"] and self.priority_from_tw_format > 0
330+
else " " + "¡" * self.priority_from_tw_format
331+
if self["priority"] and self.priority_from_tw_format < 0
332+
else ""
333+
)
334+
331335
return ''.join([
332336
self['indent'],
333337
'* [',
334338
self['completed_mark'],
335339
'] ',
336340
(self['description'].encode('utf-8') if six.PY2 else self['description'])
337341
if self['description'] else 'TEXT MISSING?',
338-
' ' + '!' * self.priority_from_tw_format if self['priority'] else '',
342+
priority_str,
339343
due_str,
340344
' #' + self.uuid.vim_representation(self.cache) if self.uuid else '',
341345
])

tests/base.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,32 @@ def reset(self):
387387
self.warriors.clear()
388388
self.warriors.update({'default': 'default'})
389389
self.buffer_has_authority = True
390+
391+
class MockCacheWithPriorities(object):
392+
default_urgency_levels = {0: None, 1: 'L', 2: 'M', 3: 'H'}
393+
394+
# Create a warrior object on the fly
395+
warriors = {"default": type("", (object,), {"urgency_levels": {}},)()}
396+
397+
buffer_has_authority = True
398+
399+
def __init__(self, urgency_levels=None):
400+
from taskwiki import store
401+
self.urgency_levels = urgency_levels
402+
self.warriors['default'].urgency_levels = urgency_levels or self.default_urgency_levels
403+
self.buffer = MockBuffer()
404+
self.line = store.LineStore(self)
405+
self.vwtask = dict()
406+
self.task = dict()
407+
self.viewport = dict()
408+
409+
def reset(self):
410+
self.warriors.clear()
411+
self.warriors.update(
412+
{
413+
"default": type(
414+
"", (object,), {"urgency_levels": self.urgency_levels}
415+
)()
416+
}
417+
)
418+
self.buffer_has_authority = True

tests/test_vwtask_parsing.py

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# -*- coding: utf-8 -*-
22
from datetime import datetime
3-
from tests.base import MockVim, MockCache
3+
from tests.base import MockVim, MockCacheWithPriorities
44
import sys
55

66
from tasklib import local_zone
77

88
class TestParsingVimwikiTask(object):
99
def setup(self):
1010
self.mockvim = MockVim()
11-
self.cache = MockCache()
11+
self.cache = MockCacheWithPriorities()
1212
sys.modules['vim'] = self.mockvim
1313
from taskwiki.vwtask import VimwikiTask
1414
self.VimwikiTask = VimwikiTask
@@ -56,23 +56,23 @@ def test_due_short(self):
5656
assert vwtask['priority'] == None
5757
assert vwtask['indent'] == ''
5858

59-
def test_priority_low(self):
59+
def test_default_priority_low(self):
6060
self.cache.buffer[0] = "* [ ] Semi-Important task !"
6161
vwtask = self.VimwikiTask.from_line(self.cache, 0)
6262

6363
assert vwtask['description'] == u"Semi-Important task"
6464
assert vwtask['priority'] == 'L'
6565
assert vwtask['uuid'] == None
6666

67-
def test_priority_medium(self):
67+
def test_default_priority_medium(self):
6868
self.cache.buffer[0] = "* [ ] Important task !!"
6969
vwtask = self.VimwikiTask.from_line(self.cache, 0)
7070

7171
assert vwtask['description'] == u"Important task"
7272
assert vwtask['priority'] == 'M'
7373
assert vwtask['uuid'] == None
7474

75-
def test_priority_high(self):
75+
def test_default_priority_high(self):
7676
self.cache.buffer[0] = "* [ ] Very important task !!!"
7777
vwtask = self.VimwikiTask.from_line(self.cache, 0)
7878

@@ -81,6 +81,78 @@ def test_priority_high(self):
8181
assert vwtask['uuid'] == None
8282
assert vwtask['due'] == None
8383

84+
def test_custom_priority_0(self):
85+
self.cache = MockCacheWithPriorities({
86+
-2: 0, -1: 'L', 0: None, 1: 'M', 2: 'H'
87+
})
88+
self.cache.buffer[0] = "* [ ] Very important task ¡¡"
89+
vwtask = self.VimwikiTask.from_line(self.cache, 0)
90+
91+
assert vwtask['description'] == u"Very important task"
92+
assert vwtask['priority'] == 0
93+
assert vwtask['uuid'] == None
94+
assert vwtask['due'] == None
95+
96+
def test_custom_priority_L(self):
97+
self.cache = MockCacheWithPriorities({
98+
-2: 0, -1: 'L', 0: None, 1: 'M', 2: 'H'
99+
})
100+
self.cache.buffer[0] = "* [ ] Very important task ¡"
101+
vwtask = self.VimwikiTask.from_line(self.cache, 0)
102+
103+
assert vwtask['description'] == u"Very important task"
104+
assert vwtask['priority'] == 'L'
105+
assert vwtask['uuid'] == None
106+
assert vwtask['due'] == None
107+
108+
def test_custom_priority_none(self):
109+
self.cache = MockCacheWithPriorities({
110+
-2: 0, -1: 'L', 0: None, 1: 'M', 2: 'H'
111+
})
112+
self.cache.buffer[0] = "* [ ] Very important task"
113+
vwtask = self.VimwikiTask.from_line(self.cache, 0)
114+
115+
assert vwtask['description'] == u"Very important task"
116+
assert vwtask['priority'] == None
117+
assert vwtask['uuid'] == None
118+
assert vwtask['due'] == None
119+
120+
def test_custom_priority_M(self):
121+
self.cache = MockCacheWithPriorities({
122+
-2: 0, -1: 'L', 0: None, 1: 'M', 2: 'H'
123+
})
124+
self.cache.buffer[0] = "* [ ] Very important task !"
125+
vwtask = self.VimwikiTask.from_line(self.cache, 0)
126+
127+
assert vwtask['description'] == u"Very important task"
128+
assert vwtask['priority'] == 'M'
129+
assert vwtask['uuid'] == None
130+
assert vwtask['due'] == None
131+
132+
def test_custom_priority_H(self):
133+
self.cache = MockCacheWithPriorities({
134+
-2: 0, -1: 'L', 0: None, 1: 'M', 2: 'H'
135+
})
136+
self.cache.buffer[0] = "* [ ] Very important task !!"
137+
vwtask = self.VimwikiTask.from_line(self.cache, 0)
138+
139+
assert vwtask['description'] == u"Very important task"
140+
assert vwtask['priority'] == 'H'
141+
assert vwtask['uuid'] == None
142+
assert vwtask['due'] == None
143+
144+
def test_custom_priority_no_three_exclamations(self):
145+
self.cache = MockCacheWithPriorities({
146+
-2: 0, -1: 'L', 0: None, 1: 'M', 2: 'H'
147+
})
148+
self.cache.buffer[0] = "* [ ] Very important task !!!"
149+
vwtask = self.VimwikiTask.from_line(self.cache, 0)
150+
151+
assert vwtask['description'] == u"Very important task"
152+
assert vwtask['priority'] == None
153+
assert vwtask['uuid'] == None
154+
assert vwtask['due'] == None
155+
84156
def test_priority_and_due(self):
85157
self.cache.buffer[0] = "* [ ] Due today !!! (2015-08-08)"
86158
vwtask = self.VimwikiTask.from_line(self.cache, 0)

0 commit comments

Comments
 (0)