...
 
Commits (3)
......@@ -2,9 +2,12 @@
[run]
branch = True
omit =
src/twc/_version.py
[report]
exclude_lines =
exclude_lines =
pragma: no cover
def __repr__
......
# Copyright (C) 2019 Michał Góral.
#
# This file is part of TWC
#
# TWC 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.
#
# TWC 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 TWC. If not, see <http://www.gnu.org/licenses/>.
'''Definition of Task wrapper for dictionaries returned by taskw'''
import weakref
class Task(dict):
def __init__(self, *a, **kw):
super().__init__(*a, **kw)
self._parent = None
self._children = []
@property
def children(self):
return self._children
@property
def parent(self):
if self._parent:
return self._parent()
return None
@parent.setter
def parent(self, val):
self._parent = weakref.ref(val)
@property
def depth(self):
i = 0
w = self
while w.parent:
i += 1
w = w.parent
return i
def add_child(self, child):
self.children.append(child)
child.parent = self
......@@ -21,6 +21,8 @@ import shlex
import functools
from collections import OrderedDict, deque
from twc.task import Task
class TaskComparer:
'''Class which can be used as a key in all Python sort methods for sorting
......@@ -72,10 +74,15 @@ def _process_sort_string(sort_string):
return cmp
def export_tasks(tw, *query):
tasks = tw._get_task_objects(*query, 'export') # pylint: disable=protected-access
return [Task(**t) for t in tasks]
def filter_tasks(filter_string, tw):
'''Returns a list of tasks filtered by a given TW-compatible string'''
query = _process_filter(filter_string)
return tw._get_task_objects(*query, 'export') # pylint: disable=protected-access
return export_tasks(tw, *query)
def sort_tasks(tasks, sort_string):
......@@ -97,14 +104,12 @@ def group_tasks(tasks):
children.'''
grouped = OrderedDict([(t['uuid'], t) for t in tasks])
for t in tasks:
depth = t.setdefault('_depth', 0)
deps = t.get('depends')
if deps:
for dep_uuid in deps.split(','):
dep = grouped.get(dep_uuid)
if dep:
dep['_depth'] = depth + 1
t.setdefault('_children', []).append(dep)
t.add_child(dep)
del grouped[dep_uuid]
return grouped
......@@ -116,4 +121,4 @@ def dfs(tasks):
while stack:
task = stack.pop()
yield task
stack.extend(task.get('_children', []))
stack.extend(task.children)
......@@ -72,7 +72,7 @@ class BlockView(urwid.BoxAdapter):
textboxes = []
for task in twutils.dfs(list(self.tasks.values())):
indent = ' ' * task['_depth'] * 2
indent = ' ' * task.depth * 2
fmt = indent + self.block.fmt
textboxes.append(
urwid.AttrMap(TaskView(task, fmt), None, focus_map))
......
......@@ -4,18 +4,21 @@ from collections import OrderedDict
import pytest
import twc.twutils as twutils
from twc.task import Task
def perms(*a, **kw):
return list(itertools.permutations(*a, **kw))
def _gen_tasks():
return perms([
{'uuid': '0'},
{'uuid': '1', 'depends': '2,3,4'}, # p
{'uuid': '2', 'depends': '5'}, # p, ch
{'uuid': '4'}, # ch
{'uuid': '5', 'depends': '6'}, # ch, 2nd level
{'uuid': '6'}, # ch, 3rd level
Task(uuid='0'),
Task(uuid='1', depends='2,3,4'), # p, task 3 doesn't exist
Task(uuid='2', depends='5'), # p, ch
Task(uuid='4'), # ch
Task(uuid='5', depends='6'), # ch, 2nd level
Task(uuid='6'), # ch, 3rd level
])
......@@ -43,20 +46,26 @@ def test_grouping(tasks):
assert tuple(grouped.keys()) in perms(['0', '1'])
assert grouped['0']['_depth'] == 0
assert '_children' not in grouped['0']
assert td['0'].depth == 0
assert td['0'].parent is None
assert not td['0'].children
assert grouped['1']['_depth'] == 0
assert tuple(grouped['1']['_children']) in perms([td['2'], td['4']])
assert td['1'].depth == 0
assert td['1'].parent is None
assert tuple(td['1'].children) in perms([td['2'], td['4']])
assert td['2']['_depth'] == 1
assert td['2']['_children'] == [td['5']]
assert td['2'].depth == 1
assert td['2'].parent is td['1']
assert td['2'].children == [td['5']]
assert td['4']['_depth'] == 1
assert '_children' not in td['4']
assert td['4'].depth == 1
assert td['4'].parent is td['1']
assert not td['4'].children
assert td['5']['_depth'] == 2
assert td['5']['_children'] == [td['6']]
assert td['5'].depth == 2
assert td['5'].parent is td['2']
assert td['5'].children == [td['6']]
assert td['6']['_depth'] == 3
assert '_children' not in td['6']
assert td['6'].depth == 3
assert td['6'].parent is td['5']
assert not td['6'].children