From 12596790abf6fa3a84b91fff4ce9c59e55d51ec9 Mon Sep 17 00:00:00 2001 From: Ana Date: Tue, 12 Jul 2022 17:33:39 +0200 Subject: [PATCH] tree-pick is pickpack --- Makefile | 2 +- README.md | 36 +++++++------- example/{basic-tree.gif => basic.gif} | Bin example/{basic-tree.py => basic.py} | 4 +- example/{custom-tree.py => custom.py} | 4 +- ...s_map_func-tree.py => options_map_func.py} | 4 +- example/{scroll-tree.py => scroll.py} | 4 +- pyproject.toml | 8 ++-- src/{tree_pick => pickpack}/__init__.py | 26 +++++------ src/{tree_pick => pickpack}/anytree_utils.py | 0 tests/{test_tree_pick.py => test_pickpack.py} | 44 +++++++++--------- 11 files changed, 66 insertions(+), 66 deletions(-) rename example/{basic-tree.gif => basic.gif} (100%) rename example/{basic-tree.py => basic.py} (84%) rename example/{custom-tree.py => custom.py} (91%) rename example/{options_map_func-tree.py => options_map_func.py} (78%) rename example/{scroll-tree.py => scroll.py} (66%) rename src/{tree_pick => pickpack}/__init__.py (96%) rename src/{tree_pick => pickpack}/anytree_utils.py (100%) rename tests/{test_tree_pick.py => test_pickpack.py} (82%) diff --git a/Makefile b/Makefile index 84560d1..b38ef97 100644 --- a/Makefile +++ b/Makefile @@ -9,4 +9,4 @@ test: .PHONY=clean clean: - rm -fr build dist tree_pick.egg-info + rm -fr build dist pickpack.egg-info diff --git a/README.md b/README.md index f41cbe1..795538b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# tree_pick +# pickpack -[![ci](https://github.com/anafvana/tree_pick/actions/workflows/ci.yml/badge.svg?event=status)](https://github.com/anafvana/tree_pick/actions/workflows/ci.yml) +[![ci](https://github.com/anafvana/pickpack/actions/workflows/ci.yml/badge.svg)](https://github.com/anafvana/pickpack/actions/workflows/ci.yml) -**tree_pick** is a small python library based on [wong2's pick](https://github.com/wong2/pick) which allows you to create a curses-based interactive selection tree in the terminal. +**pickpack** is a small python library based on [wong2's pick](https://github.com/wong2/pick) which allows you to create a curses-based interactive selection tree in the terminal. ![Demo](https://github.com/anafvana/pick/raw/master/example/basic-tree.gif) @@ -10,7 +10,7 @@ It was made with installation processes in mind, so that a user can select a par ## Installation - $ pip install tree-pick + $ pip install pickpack ## Options @@ -28,10 +28,10 @@ It was made with installation processes in mind, so that a user can select a par ## Usage -**tree_pick** can be used by creating a tree and passing it into tree_pick: +**pickpack** can be used by creating a tree and passing it into pickpack: from anytree import Node, RenderTree - from tree_pick import tree_pick + from pickpack import pickpack title = 'Please choose one: ' @@ -40,7 +40,7 @@ It was made with installation processes in mind, so that a user can select a par p1 = Node('parent', children=[c1,c2]) options = RenderTree(p1) - option, index = tree_pick(options, title) + option, index = pickpack(options, title) print(option, index) **outputs**: @@ -48,10 +48,10 @@ It was made with installation processes in mind, so that a user can select a par Node('/parent/child1', index=1) 1 -**tree_pick** multiselect example returning node-name and index: +**pickpack** multiselect example returning node-name and index: from anytree import Node, RenderTree - from tree_pick import tree_pick + from pickpack import pickpack title = 'Please choose one: ' @@ -60,7 +60,7 @@ It was made with installation processes in mind, so that a user can select a par p1 = Node('parent', children=[c1,c2]) options = RenderTree(p1) - option, index = tree_pick(options, title, multiselect=True, min_selection_count=1, output_format='nameindex') + option, index = pickpack(options, title, multiselect=True, min_selection_count=1, output_format='nameindex') print(option, index) **outputs**:: @@ -72,7 +72,7 @@ It was made with installation processes in mind, so that a user can select a par To register custom handlers for specific keyboard keypresses, you can use the `register_custom_handler` property: from anytree import Node, RenderTree - from tree_pick import TreePicker + from pickpack import PickPacker title = 'Please choose one: ' c1 = Node('child1') @@ -80,7 +80,7 @@ To register custom handlers for specific keyboard keypresses, you can use the `r p1 = Node('parent', children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options, title) + picker = PickPacker(options, title) def go_back(picker): return None, -1 picker.register_custom_handler(ord('h'), go_back) @@ -100,10 +100,10 @@ The function must take in elements of the type you passed into the options (`Nod You may also store any additional information as a custom property within the node. -**tree_pick** options map function example: +**pickpack** options map function example: from anytree import Node, RenderTree - from tree_pick import tree_pick + from pickpack import pickpack title = 'Please choose an option: ' options = [ @@ -115,7 +115,7 @@ You may also store any additional information as a custom property within the no def get_node(option): return Node(option.get('label'), abbreviation=option.get('abbreviation')) - picker = TreePicker(options, title, indicator='*', options_map_func=get_node, output_format='nameindex') + picker = PickPacker(options, title, indicator='*', options_map_func=get_node, output_format='nameindex') **displays**: @@ -132,10 +132,10 @@ You may also store any additional information as a custom property within the no #### Map function for nested lists -**tree_pick** options map function example for lists with **nesting**: +**pickpack** options map function example for lists with **nesting**: from anytree import Node, RenderTree - from tree_pick import tree_pick + from pickpack import pickpack title = 'Please choose an option: ' options = [ @@ -156,7 +156,7 @@ You may also store any additional information as a custom property within the no else: return Node(option.get('label'), children=None, abbreviation=option.get('abbreviation')) - picker = TreePicker(options, title, indicator='*', options_map_func=get_node, output_format='nameindex') + picker = PickPacker(options, title, indicator='*', options_map_func=get_node, output_format='nameindex') **displays**: diff --git a/example/basic-tree.gif b/example/basic.gif similarity index 100% rename from example/basic-tree.gif rename to example/basic.gif diff --git a/example/basic-tree.py b/example/basic.py similarity index 84% rename from example/basic-tree.py rename to example/basic.py index db2d3f6..388b9aa 100755 --- a/example/basic-tree.py +++ b/example/basic.py @@ -1,5 +1,5 @@ from anytree import Node, RenderTree -from tree_pick import tree_pick +from pickpack import pickpack title = 'Please choose your favorite programming language: ' java = Node("Java") @@ -18,5 +18,5 @@ root = Node("Select all", children=[fun, imp, oop, mul]) options = RenderTree(root) -option, index = tree_pick(options, title, indicator='=>', default_index=2) +option, index = pickpack(options, title, indicator='=>', default_index=2) print(option, index) diff --git a/example/custom-tree.py b/example/custom.py similarity index 91% rename from example/custom-tree.py rename to example/custom.py index 65df249..87d4384 100755 --- a/example/custom-tree.py +++ b/example/custom.py @@ -1,7 +1,7 @@ import curses from anytree import Node, RenderTree -from tree_pick import TreePicker +from pickpack import PickPacker def go_back(picker): @@ -25,7 +25,7 @@ def go_back(picker): options = RenderTree(root) -picker = TreePicker(options, title) +picker = PickPacker(options, title) picker.register_custom_handler(curses.KEY_LEFT, go_back) option, index = picker.start() print(option, index) diff --git a/example/options_map_func-tree.py b/example/options_map_func.py similarity index 78% rename from example/options_map_func-tree.py rename to example/options_map_func.py index add2792..1e7df7d 100755 --- a/example/options_map_func-tree.py +++ b/example/options_map_func.py @@ -1,5 +1,5 @@ from anytree import Node, RenderTree -from tree_pick import tree_pick +from pickpack import pickpack title = 'Please choose your favorite fruit: ' options = [ @@ -15,5 +15,5 @@ def get_description_for_display(option): # format the option data for display return Node('{0} (grow on {1})'.format(option.get('name'), option.get('grow_on'))) -option, index = tree_pick(options, title, indicator='=>', options_map_func=get_description_for_display) +option, index = pickpack(options, title, indicator='=>', options_map_func=get_description_for_display) print(option, index) diff --git a/example/scroll-tree.py b/example/scroll.py similarity index 66% rename from example/scroll-tree.py rename to example/scroll.py index 415a542..34c30b5 100755 --- a/example/scroll-tree.py +++ b/example/scroll.py @@ -1,10 +1,10 @@ from anytree import Node, RenderTree -from tree_pick import tree_pick +from pickpack import pickpack title = 'Select:' children = [Node('foo.bar%s.baz'%x, index=x) for x in range(1, 71)] root = Node("All", children=children) options = RenderTree(root) -option, index = tree_pick(options, title, indicator='=>', default_index=2) +option, index = pickpack(options, title, indicator='=>', default_index=2) print(option, index) diff --git a/pyproject.toml b/pyproject.toml index f3944f8..1cfce5f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] -name = "tree_pick" +name = "pickpack" version = "1.0.0" -description = "Based on wong2's pick, tree_pick is a terminal GUI which allows you to pick one or more options from a tree structure" +description = "Based on wong2's pick, pickpack is a terminal GUI which allows you to pick one or more options from a tree structure" authors = ["Ana ", "wong2 "] license = "MIT" readme = "README.md" -repository = "https://github.com/anafvana/tree_pick" -homepage = "https://github.com/anafvana/tree_pick" +repository = "https://github.com/anafvana/pickpack" +homepage = "https://github.com/anafvana/pickpack" keywords = ["terminal", "gui", "pick", "tree"] [tool.poetry.dependencies] diff --git a/src/tree_pick/__init__.py b/src/pickpack/__init__.py similarity index 96% rename from src/tree_pick/__init__.py rename to src/pickpack/__init__.py index 7da0a55..dd8007f 100644 --- a/src/tree_pick/__init__.py +++ b/src/pickpack/__init__.py @@ -1,4 +1,4 @@ -''' tree_pick.py ''' +''' pickpack.py ''' from __future__ import annotations @@ -9,11 +9,11 @@ from anytree import Node, RenderTree -from tree_pick.anytree_utils import (add_indices, count_leaves, count_nodes, - find_by_index, get_descendants, - get_leaves_only) +from pickpack.anytree_utils import (add_indices, count_leaves, count_nodes, + find_by_index, get_descendants, + get_leaves_only) -__all__ = ['TreePicker', 'tree_pick'] +__all__ = ['PickPacker', 'pickpack'] KEYS_ENTER = (curses.KEY_ENTER, ord('\n'), ord('\r')) @@ -30,8 +30,8 @@ class OutputMode(enum.Enum): @dataclass -class TreePicker: - """The :class:`TreePicker ` object +class PickPacker: + """The :class:`PickPacker ` object :param options: a RenderTree (anytree) or a list of options to choose from :param title: (optional) a title above options list @@ -59,7 +59,7 @@ class TreePicker: output_format: int|str = "nodeindex" options_map_func: Optional[Callable[[Dict], Node]] = None all_selected: List[str] = field(init=False, default_factory=list) - custom_handlers: Dict[str, Callable[["TreePicker"], str]] = field( + custom_handlers: Dict[str, Callable[["PickPacker"], str]] = field( init=False, default_factory=dict ) index: int = field(init=False, default=0) @@ -358,12 +358,12 @@ def _start(self, screen): def start(self): return curses.wrapper(self._start) -def tree_pick(*args, **kwargs): - """Construct and start a :class:`TreePicker `. +def pickpack(*args, **kwargs): + """Construct and start a :class:`PickPacker `. Usage:: - >>> from tree_pick import tree_pick + >>> from pickpack import pickpack >>> from anytree import Node, RenderTree >>> child = Node("Child") @@ -371,7 +371,7 @@ def tree_pick(*args, **kwargs): >>> options = RenderTree(root) >>> title = 'Please choose an option: ' - >>> option, index = tree_pick(options, title) + >>> option, index = pickpack(options, title) """ - picker = TreePicker(*args, **kwargs) + picker = PickPacker(*args, **kwargs) return picker.start() diff --git a/src/tree_pick/anytree_utils.py b/src/pickpack/anytree_utils.py similarity index 100% rename from src/tree_pick/anytree_utils.py rename to src/pickpack/anytree_utils.py diff --git a/tests/test_tree_pick.py b/tests/test_pickpack.py similarity index 82% rename from tests/test_tree_pick.py rename to tests/test_pickpack.py index 1ebae2b..a02eaa7 100644 --- a/tests/test_tree_pick.py +++ b/tests/test_pickpack.py @@ -1,6 +1,6 @@ import pytest from anytree import Node, RenderTree -from tree_pick import TreePicker +from pickpack import PickPacker def test_move_up_down(): @@ -9,7 +9,7 @@ def test_move_up_down(): c2 = Node("child2") p1 = Node("parent", children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options, title, output_format="nameindex") + picker = PickPacker(options, title, output_format="nameindex") picker.move_up() assert picker.get_selected() == ("child2", 2) picker.move_down() @@ -22,7 +22,7 @@ def test_default_index(): c2 = Node("child2") p1 = Node("parent", children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options, title, output_format="nameindex", default_index=1) + picker = PickPacker(options, title, output_format="nameindex", default_index=1) assert picker.get_selected() == ("child1", 1) def test_get_lines(): @@ -31,7 +31,7 @@ def test_get_lines(): c2 = Node("child2") p1 = Node("parent", children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options, title, indicator="*", indicator_parentheses=False) + picker = PickPacker(options, title, indicator="*", indicator_parentheses=False) lines, current_line = picker.get_lines() assert lines == [title, "", "* parent", " └── child1", " └── child2"] assert current_line == 3 @@ -42,7 +42,7 @@ def test_parenthesis(): c2 = Node("child2") p1 = Node("parent", children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options, title, indicator="*") + picker = PickPacker(options, title, indicator="*") lines, current_line = picker.get_lines() assert lines == [title, "", "(*) parent", "( ) └── child1", "( ) └── child2"] assert current_line == 3 @@ -53,7 +53,7 @@ def test_no_title(): c2 = Node("child2") p1 = Node("parent", children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options) + picker = PickPacker(options) lines, current_line = picker.get_lines() assert current_line == 1 @@ -63,7 +63,7 @@ def test_multi_select(): c2 = Node("child2") p1 = Node("parent", children=[c1,c2]) options = RenderTree(p1) - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format="nameindex") + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format="nameindex") assert picker.get_selected() == [] picker.mark_index() assert picker.get_selected() == [("parent", 0), ("child1", 1), ("child2", 2)] @@ -78,7 +78,7 @@ def test_options_map_func(): def get_node(option): return Node(option.get("label")) - picker = TreePicker(options, title, indicator="*", options_map_func=get_node, output_format="nameindex") + picker = PickPacker(options, title, indicator="*", options_map_func=get_node, output_format="nameindex") lines, current_line = picker.get_lines() assert lines == [title, "", "(*) Select all", "( ) └── option1", "( ) └── option2", "( ) └── option3"] assert picker.get_selected() == ("Select all", 0) @@ -87,8 +87,8 @@ def test_list_no_func(): title = "Please choose an option: " options = [{"label": "option1"}, {"label": "option2"}, {"label": "option3"}] - with pytest.raises(Exception): picker = TreePicker(options, title, indicator="*") - with pytest.raises(TypeError): picker = TreePicker(options, title, indicator="*", options_map_func="hello") + with pytest.raises(Exception): picker = PickPacker(options, title, indicator="*") + with pytest.raises(TypeError): picker = PickPacker(options, title, indicator="*", options_map_func="hello") def test_output_format(): title = "Please choose one or more options: " @@ -98,45 +98,45 @@ def test_output_format(): options = RenderTree(p1) # Default (nodeindex) - picker = TreePicker(options, title, multiselect=True, min_selection_count=1) + picker = PickPacker(options, title, multiselect=True, min_selection_count=1) assert picker.get_selected() == [] picker.move_down() picker.mark_index() assert picker.get_selected() == [(c1, 1)] # nodeindex - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format="nodeindex") + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format="nodeindex") assert picker.get_selected() == [] picker.move_down() picker.mark_index() assert picker.get_selected() == [(c1, 1)] # nameindex - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format="nameindex") + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format="nameindex") assert picker.get_selected() == [] picker.move_down() picker.mark_index() assert picker.get_selected() == [("child1", 1)] # nodeonly - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format="nodeonly") + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format="nodeonly") assert picker.get_selected() == [] picker.move_down() picker.mark_index() assert picker.get_selected() == [c1] # nameonly - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format="nameonly") + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format="nameonly") assert picker.get_selected() == [] picker.move_down() picker.mark_index() assert picker.get_selected() == ["child1"] with pytest.raises(ValueError): - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format="invalid") + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format="invalid") with pytest.raises(TypeError): - picker = TreePicker(options, title, multiselect=True, min_selection_count=1, output_format=1) + picker = PickPacker(options, title, multiselect=True, min_selection_count=1, output_format=1) def test_root_name(): title = "Please choose an option: " @@ -145,7 +145,7 @@ def test_root_name(): def get_node(option): return Node(option.get("label")) - picker = TreePicker(options, title, indicator="*", options_map_func=get_node, output_format="nameindex", root_name="EVERYTHING") + picker = PickPacker(options, title, indicator="*", options_map_func=get_node, output_format="nameindex", root_name="EVERYTHING") lines, current_line = picker.get_lines() assert lines == [title, "", "(*) EVERYTHING", "( ) └── option1", "( ) └── option2", "( ) └── option3"] assert picker.get_selected() == ("EVERYTHING", 0) @@ -158,16 +158,16 @@ def get_node(option): return Node(option.get("label")) # Multiselect - picker = TreePicker(options, title, multiselect=True, options_map_func=get_node, output_format="nameindex", output_leaves_only=True) + picker = PickPacker(options, title, multiselect=True, options_map_func=get_node, output_format="nameindex", output_leaves_only=True) assert picker.get_selected() == [] picker.mark_index() assert picker.get_selected() == [("option1", 1), ("option2", 2), ("option3", 3)] # Singleselect with pytest.raises(ValueError): - picker = TreePicker(options, title, options_map_func=get_node, output_format="nameindex", output_leaves_only=True) + picker = PickPacker(options, title, options_map_func=get_node, output_format="nameindex", output_leaves_only=True) - picker = TreePicker(options, title, options_map_func=get_node, output_format="nameindex", output_leaves_only=True, singleselect_output_include_children=True) + picker = PickPacker(options, title, options_map_func=get_node, output_format="nameindex", output_leaves_only=True, singleselect_output_include_children=True) assert picker.get_selected() == [("option1", 1), ("option2", 2), ("option3", 3)] def test_include_children(): @@ -177,7 +177,7 @@ def test_include_children(): def get_node(option): return Node(option.get("label")) - picker = TreePicker(options, title, options_map_func=get_node, output_format="nameindex", singleselect_output_include_children=True) + picker = PickPacker(options, title, options_map_func=get_node, output_format="nameindex", singleselect_output_include_children=True) assert picker.get_selected() == [("Select all", 0), ("option1", 1), ("option2", 2), ("option3", 3)] if __name__ == "__main__":