kanban-python 0.3.2__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {kanban-python-0.3.2 → kanban-python-0.3.4}/CHANGELOG.md +13 -0
  2. {kanban-python-0.3.2/src/kanban_python.egg-info → kanban-python-0.3.4}/PKG-INFO +12 -12
  3. {kanban-python-0.3.2 → kanban-python-0.3.4}/README.md +10 -10
  4. kanban-python-0.3.4/images/image_header.PNG +0 -0
  5. kanban-python-0.3.4/images/image_kanban.PNG +0 -0
  6. kanban-python-0.3.4/images/image_kanban_configure.PNG +0 -0
  7. {kanban-python-0.3.2 → kanban-python-0.3.4}/setup.cfg +1 -1
  8. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/app.py +5 -4
  9. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/config.py +15 -0
  10. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/controls.py +128 -45
  11. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/interface.py +107 -45
  12. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/utils.py +26 -0
  13. {kanban-python-0.3.2 → kanban-python-0.3.4/src/kanban_python.egg-info}/PKG-INFO +12 -12
  14. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python.egg-info/requires.txt +1 -1
  15. {kanban-python-0.3.2 → kanban-python-0.3.4}/tests/test_utils.py +20 -0
  16. kanban-python-0.3.2/images/image_header.PNG +0 -0
  17. kanban-python-0.3.2/images/image_kanban.PNG +0 -0
  18. kanban-python-0.3.2/images/image_kanban_configure.PNG +0 -0
  19. {kanban-python-0.3.2 → kanban-python-0.3.4}/.coveragerc +0 -0
  20. {kanban-python-0.3.2 → kanban-python-0.3.4}/.github/workflows/ci.yml +0 -0
  21. {kanban-python-0.3.2 → kanban-python-0.3.4}/.gitignore +0 -0
  22. {kanban-python-0.3.2 → kanban-python-0.3.4}/.isort.cfg +0 -0
  23. {kanban-python-0.3.2 → kanban-python-0.3.4}/.pre-commit-config.yaml +0 -0
  24. {kanban-python-0.3.2 → kanban-python-0.3.4}/.readthedocs.yml +0 -0
  25. {kanban-python-0.3.2 → kanban-python-0.3.4}/AUTHORS.md +0 -0
  26. {kanban-python-0.3.2 → kanban-python-0.3.4}/CONTRIBUTING.md +0 -0
  27. {kanban-python-0.3.2 → kanban-python-0.3.4}/LICENSE.txt +0 -0
  28. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/Makefile +0 -0
  29. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/_static/.gitignore +0 -0
  30. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/authors.md +0 -0
  31. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/changelog.md +0 -0
  32. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/conf.py +0 -0
  33. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/contributing.md +0 -0
  34. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/index.md +0 -0
  35. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/license.md +0 -0
  36. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/readme.md +0 -0
  37. {kanban-python-0.3.2 → kanban-python-0.3.4}/docs/requirements.txt +0 -0
  38. {kanban-python-0.3.2 → kanban-python-0.3.4}/images/image_config.PNG +0 -0
  39. {kanban-python-0.3.2 → kanban-python-0.3.4}/images/image_kanban_init.PNG +0 -0
  40. {kanban-python-0.3.2 → kanban-python-0.3.4}/images/image_scan_table.PNG +0 -0
  41. {kanban-python-0.3.2 → kanban-python-0.3.4}/images/image_scan_view.PNG +0 -0
  42. {kanban-python-0.3.2 → kanban-python-0.3.4}/images/image_task_example.PNG +0 -0
  43. {kanban-python-0.3.2 → kanban-python-0.3.4}/pyproject.toml +0 -0
  44. {kanban-python-0.3.2 → kanban-python-0.3.4}/setup.py +0 -0
  45. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/__init__.py +0 -0
  46. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/cli_parser.py +0 -0
  47. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python/constants.py +0 -0
  48. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python.egg-info/SOURCES.txt +0 -0
  49. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python.egg-info/dependency_links.txt +0 -0
  50. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python.egg-info/entry_points.txt +0 -0
  51. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python.egg-info/not-zip-safe +0 -0
  52. {kanban-python-0.3.2 → kanban-python-0.3.4}/src/kanban_python.egg-info/top_level.txt +0 -0
  53. {kanban-python-0.3.2 → kanban-python-0.3.4}/tests/conftest.py +0 -0
  54. {kanban-python-0.3.2 → kanban-python-0.3.4}/tests/test_config.py +0 -0
  55. {kanban-python-0.3.2 → kanban-python-0.3.4}/tests/test_interface.py +0 -0
  56. {kanban-python-0.3.2 → kanban-python-0.3.4}/tox.ini +0 -0
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.3.4
4
+ - Bug fix: default separator for `settings.scanner` Pattern setting was space separated not comma separated
5
+ - Fix Image for kanban configure to show right Pattern
6
+
7
+ ## Version 0.3.3
8
+ - Push lower bound Version of `platformdirs` dependency to be 3 or higher to include `ensure_exists` argument
9
+ in `user_data_dir` and `user_config_dir`.
10
+ - Update User Action Options with new option `Show Task Details`
11
+ - Change coloring and order of User Actions
12
+ - Added another Menu to configure settings when using `[6] Show Current Settings` or `kanban configure`
13
+ - Update DOCS/README and Images
14
+ - Bugfix for data type of min col width setter
15
+
3
16
  ## Version 0.3.2
4
17
  - Add `^D` besides `^C` as option to close app (on windows pwsh its `^Z`).
5
18
  - App closes now on `KeyboardInterrupt` and `EOFError`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kanban-python
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Terminal Kanban App written in Python
5
5
  Home-page: https://github.com/Zaloog/kanban-python
6
6
  Author: Zaloog
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
15
  License-File: LICENSE.txt
16
16
  Requires-Dist: importlib-metadata; python_version < "3.8"
17
17
  Requires-Dist: rich>=13.7.0
18
- Requires-Dist: platformdirs<4
18
+ Requires-Dist: platformdirs<4,>=3
19
19
  Provides-Extra: testing
20
20
  Requires-Dist: setuptools; extra == "testing"
21
21
  Requires-Dist: pytest; extra == "testing"
@@ -45,10 +45,12 @@ Welcome to **kanban-python**, your Terminal Kanban-Board Manager.
45
45
 
46
46
  ![header](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_header.PNG)
47
47
  The [clikan] Kanban App inspired me to write
48
- my own Terminal Kanban Application, since I preferred a more simple and guided workflow.
48
+ my own Terminal Kanban Application since I preferred a more simple and guided workflow.
49
49
 
50
- **kanban-python** also comes with more features and customization options.
51
- This package was developed with [pyscaffold], which provides nice project templates
50
+ **kanban-python** also comes with more features, like custom column creation,
51
+ automatic scanning and customizable config file to support you being productive.
52
+
53
+ This package was developed with [pyscaffold], which provides awesome project templates
52
54
  and takes over much of the boilerplate for python packaging.
53
55
  It was a great help for developing my first package and I can highly recommend it.
54
56
 
@@ -63,7 +65,7 @@ The config path in the table caption and the path for the task files can be foun
63
65
  - *automated scanning of files for task creation*: kanban-python can scan files of defined types for specific patterns at start of line.
64
66
  Check [Automatic Task Creation](#automatic-task-creation) for more Infos.
65
67
 
66
- - *configfile*: A `pykanban.ini` file gets created on first initialization in a `.kanban-python` folder in your `Home`-Directory.
68
+ - *configfile*: A `pykanban.ini` file gets created on first initialization in a `kanban-python` folder in your `user_config_dir`-Directory.
67
69
  This can be edited manually or within the kanban-python application. It tracks the location for all your created boards. \
68
70
  ![configfile](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_config.PNG)
69
71
  * `Active_Board`: current board that is shown when using `kanban`-command
@@ -77,10 +79,10 @@ This can be edited manually or within the kanban-python application. It tracks t
77
79
  <br />
78
80
 
79
81
  - *storage-file for each board*: Each created board comes with its own name and `pykanban.json` file,
80
- which stores all tasks for that board. The files are stored in board specific folders under `.kanban-python/kanban_boards/<BOARDNAME>`
82
+ which stores all tasks for that board. The files are stored in board specific folders under `$USER_DATA_DIR/kanban-python/kanban_boards/<BOARDNAME>`
81
83
 
82
84
  - *column customization*: kanban-python comes with 5 pre-defined colored columns: [Ready, Doing, Done, Archived, Deleted]
83
- More column can be added manually in the `pykanban.ini`, also the visibility can be configured.
85
+ More column can be added manually in the `pykanban.ini`, also the visibility can be configured there.
84
86
 
85
87
  - *time-tracking*: for each task it is tracked, how long it was in the
86
88
  <span style="color:yellow">Doing</span> column, based on the moments when you update the task status.
@@ -102,7 +104,7 @@ After Installation of kanban-python, there are 4 commands available:
102
104
  kanban init
103
105
  ```
104
106
  Is used to create a new kanban board i.e. it asks for a name and then creates a `pykanban.json` file with a Welcome Task.
105
- On first use of any command, the `pykanban.ini` configfile and the `.kanban-python` folder will be created automatically.
107
+ On first use of any command, the `pykanban.ini` configfile and the `kanban-python` folder will be created automatically.
106
108
  ![init_file](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_kanban_init.PNG)
107
109
 
108
110
  ### Interact with Tasks/Boards
@@ -135,9 +137,7 @@ The filepath were the task was found will be added as description of the task.
135
137
  ![settings](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_kanban_configure.PNG)
136
138
 
137
139
  To create a new custom Columns, you have to edit the `pykanban.ini` manually and add a new column name + visibility status
138
- under the `settings.columns.visible` section. The same way you can also add more file endings or patterns for the `settings.scanner` section.
139
- Keep in mind the specific separators for that section.
140
- I am working on an option to customize those things in the future without the need to manual edit the file.
140
+ under the `settings.columns.visible` section. The other options are all customizable now via the new settings menu.
141
141
 
142
142
 
143
143
  ## Feedback and Issues
@@ -22,10 +22,12 @@ Welcome to **kanban-python**, your Terminal Kanban-Board Manager.
22
22
 
23
23
  ![header](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_header.PNG)
24
24
  The [clikan] Kanban App inspired me to write
25
- my own Terminal Kanban Application, since I preferred a more simple and guided workflow.
25
+ my own Terminal Kanban Application since I preferred a more simple and guided workflow.
26
26
 
27
- **kanban-python** also comes with more features and customization options.
28
- This package was developed with [pyscaffold], which provides nice project templates
27
+ **kanban-python** also comes with more features, like custom column creation,
28
+ automatic scanning and customizable config file to support you being productive.
29
+
30
+ This package was developed with [pyscaffold], which provides awesome project templates
29
31
  and takes over much of the boilerplate for python packaging.
30
32
  It was a great help for developing my first package and I can highly recommend it.
31
33
 
@@ -40,7 +42,7 @@ The config path in the table caption and the path for the task files can be foun
40
42
  - *automated scanning of files for task creation*: kanban-python can scan files of defined types for specific patterns at start of line.
41
43
  Check [Automatic Task Creation](#automatic-task-creation) for more Infos.
42
44
 
43
- - *configfile*: A `pykanban.ini` file gets created on first initialization in a `.kanban-python` folder in your `Home`-Directory.
45
+ - *configfile*: A `pykanban.ini` file gets created on first initialization in a `kanban-python` folder in your `user_config_dir`-Directory.
44
46
  This can be edited manually or within the kanban-python application. It tracks the location for all your created boards. \
45
47
  ![configfile](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_config.PNG)
46
48
  * `Active_Board`: current board that is shown when using `kanban`-command
@@ -54,10 +56,10 @@ This can be edited manually or within the kanban-python application. It tracks t
54
56
  <br />
55
57
 
56
58
  - *storage-file for each board*: Each created board comes with its own name and `pykanban.json` file,
57
- which stores all tasks for that board. The files are stored in board specific folders under `.kanban-python/kanban_boards/<BOARDNAME>`
59
+ which stores all tasks for that board. The files are stored in board specific folders under `$USER_DATA_DIR/kanban-python/kanban_boards/<BOARDNAME>`
58
60
 
59
61
  - *column customization*: kanban-python comes with 5 pre-defined colored columns: [Ready, Doing, Done, Archived, Deleted]
60
- More column can be added manually in the `pykanban.ini`, also the visibility can be configured.
62
+ More column can be added manually in the `pykanban.ini`, also the visibility can be configured there.
61
63
 
62
64
  - *time-tracking*: for each task it is tracked, how long it was in the
63
65
  <span style="color:yellow">Doing</span> column, based on the moments when you update the task status.
@@ -79,7 +81,7 @@ After Installation of kanban-python, there are 4 commands available:
79
81
  kanban init
80
82
  ```
81
83
  Is used to create a new kanban board i.e. it asks for a name and then creates a `pykanban.json` file with a Welcome Task.
82
- On first use of any command, the `pykanban.ini` configfile and the `.kanban-python` folder will be created automatically.
84
+ On first use of any command, the `pykanban.ini` configfile and the `kanban-python` folder will be created automatically.
83
85
  ![init_file](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_kanban_init.PNG)
84
86
 
85
87
  ### Interact with Tasks/Boards
@@ -112,9 +114,7 @@ The filepath were the task was found will be added as description of the task.
112
114
  ![settings](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_kanban_configure.PNG)
113
115
 
114
116
  To create a new custom Columns, you have to edit the `pykanban.ini` manually and add a new column name + visibility status
115
- under the `settings.columns.visible` section. The same way you can also add more file endings or patterns for the `settings.scanner` section.
116
- Keep in mind the specific separators for that section.
117
- I am working on an option to customize those things in the future without the need to manual edit the file.
117
+ under the `settings.columns.visible` section. The other options are all customizable now via the new settings menu.
118
118
 
119
119
 
120
120
  ## Feedback and Issues
@@ -25,7 +25,7 @@ package_dir =
25
25
  install_requires =
26
26
  importlib-metadata; python_version<"3.8"
27
27
  rich>=13.7.0
28
- platformdirs<4
28
+ platformdirs>=3,<4
29
29
 
30
30
  [options.packages.find]
31
31
  where = src
@@ -81,8 +81,7 @@ def main(args):
81
81
  controls.create_new_db()
82
82
 
83
83
  if args.command == "configure":
84
- controls.show_settings()
85
- return
84
+ controls.change_settings()
86
85
 
87
86
  if args.command == "scan":
88
87
  controls.add_todos_to_board()
@@ -98,9 +97,11 @@ def main(args):
98
97
  elif user_input == 3:
99
98
  controls.change_kanban_board()
100
99
  elif user_input == 4:
101
- controls.delete_kanban_board()
100
+ controls.show_tasks()
102
101
  elif user_input == 5:
103
- controls.show_settings()
102
+ controls.delete_kanban_board()
103
+ elif user_input == 6:
104
+ controls.change_settings()
104
105
 
105
106
 
106
107
  def run():
@@ -84,6 +84,11 @@ class KanbanConfig:
84
84
  def col_min_width(self) -> int:
85
85
  return int(self.config["settings.general"]["Column_Min_Width"])
86
86
 
87
+ @col_min_width.setter
88
+ def col_min_width(self, new_width: int) -> None:
89
+ self.config["settings.general"]["Column_Min_Width"] = str(new_width)
90
+ self.save()
91
+
87
92
  @property
88
93
  def kanban_columns_dict(self) -> dict:
89
94
  return self.config["settings.columns.visible"]
@@ -110,10 +115,20 @@ class KanbanConfig:
110
115
  def scanned_files(self) -> list:
111
116
  return self.config["settings.scanner"]["Files"].split(" ")
112
117
 
118
+ @scanned_files.setter
119
+ def scanned_files(self, new_files_to_scan: str) -> None:
120
+ self.config["settings.scanner"]["Files"] = new_files_to_scan
121
+ self.save()
122
+
113
123
  @property
114
124
  def scanned_patterns(self) -> list:
115
125
  return self.config["settings.scanner"]["Patterns"].split(",")
116
126
 
127
+ @scanned_patterns.setter
128
+ def scanned_patterns(self, new_patterns_to_scan: str) -> None:
129
+ self.config["settings.scanner"]["Patterns"] = new_patterns_to_scan
130
+ self.save()
131
+
117
132
 
118
133
  cfg = KanbanConfig(path=CONFIG_FILE_PATH)
119
134
 
@@ -1,5 +1,7 @@
1
1
  from json import dump, load
2
2
 
3
+ from rich.pretty import pprint
4
+
3
5
  from .config import (
4
6
  cfg,
5
7
  check_if_board_name_exists_in_config,
@@ -12,13 +14,19 @@ from .interface import (
12
14
  create_config_table,
13
15
  create_table,
14
16
  input_ask_for_action,
17
+ input_ask_for_action_settings,
15
18
  input_ask_for_change_board,
16
19
  input_ask_for_delete_board,
17
20
  input_ask_for_new_board_name,
18
21
  input_ask_which_task_to_update,
19
- input_change_settings,
22
+ input_ask_which_tasks_to_show,
23
+ input_change_column_settings,
24
+ input_change_done_limit_settings,
25
+ input_change_files_to_scan_settings,
26
+ input_change_footer_settings,
27
+ input_change_min_col_width_settings,
28
+ input_change_patterns_to_scan_settings,
20
29
  input_confirm_add_todos_to_board,
21
- input_confirm_change_current_settings,
22
30
  input_confirm_delete_board,
23
31
  input_confirm_set_board_active,
24
32
  input_create_new_task,
@@ -28,9 +36,12 @@ from .utils import (
28
36
  check_board_name_valid,
29
37
  check_if_done_col_leq_X,
30
38
  check_if_there_are_visible_tasks_in_board,
39
+ check_scanner_files_valid,
40
+ check_scanner_patterns_valid,
31
41
  console,
32
42
  current_time_to_str,
33
43
  delete_json_file,
44
+ get_tag_id_choices,
34
45
  move_first_done_task_to_archive,
35
46
  scan_files,
36
47
  scan_for_todos,
@@ -38,6 +49,8 @@ from .utils import (
38
49
  )
39
50
 
40
51
 
52
+ # DB Controls
53
+ #####################################################################################
41
54
  def create_new_db() -> None:
42
55
  while True:
43
56
  while True:
@@ -82,11 +95,6 @@ def save_db(data):
82
95
  dump(data, f, ensure_ascii=False, indent=4)
83
96
 
84
97
 
85
- def add_new_task_to_db():
86
- new_task = input_create_new_task()
87
- add_tasks_to_db(tasks=new_task)
88
-
89
-
90
98
  def add_tasks_to_db(tasks: dict | list[dict]) -> None:
91
99
  db_data = read_db()
92
100
  if isinstance(tasks, dict):
@@ -124,39 +132,20 @@ def read_single_board(path):
124
132
  return data
125
133
 
126
134
 
127
- def show():
128
- if not cfg.kanban_boards:
129
- console.print(":warning: [red]No Boards created yet[/]:warning:")
130
- console.print("Use 'kanban init' to create a new kanban board.")
131
- raise KeyboardInterrupt
132
-
133
- if not check_if_current_active_board_in_board_list():
134
- console.print(
135
- "[yellow]Hmm, Something went wrong.[/] "
136
- + f"The active board '{cfg.active_board}' is not in the list of boards."
137
- )
138
- change_kanban_board()
139
- show()
140
- return
141
- db_data = read_db()
142
- table = create_table(data=db_data)
143
- console.print(table)
144
-
145
-
146
- def change_kanban_board():
147
- new_active_board = input_ask_for_change_board()
148
- cfg.active_board = new_active_board
135
+ # User Action Controls
136
+ #####################################################################################
137
+ # Get User Action
138
+ def get_user_action():
139
+ return input_ask_for_action()
149
140
 
150
141
 
151
- def delete_kanban_board():
152
- board_to_delete = input_ask_for_delete_board()
153
- if input_confirm_delete_board(board_to_delete):
154
- board_to_delete_path = cfg.kanban_boards_dict[board_to_delete]
155
-
156
- delete_json_file(board_to_delete_path)
157
- delete_board_from_config(board_to_delete)
142
+ # Action 1
143
+ def add_new_task_to_db():
144
+ new_task = input_create_new_task()
145
+ add_tasks_to_db(tasks=new_task)
158
146
 
159
147
 
148
+ # Action 2
160
149
  def update_task_from_db():
161
150
  db_data = read_db()
162
151
  if not check_if_there_are_visible_tasks_in_board(db_data, cfg.vis_cols):
@@ -172,21 +161,64 @@ def update_task_from_db():
172
161
  save_db(data=db_data)
173
162
 
174
163
 
175
- def get_user_action():
176
- return input_ask_for_action()
164
+ # Action 3
165
+ def change_kanban_board():
166
+ new_active_board = input_ask_for_change_board()
167
+ cfg.active_board = new_active_board
177
168
 
178
169
 
179
- def change_settings():
180
- input_change_settings()
170
+ # Action 4
171
+ def show_tasks():
172
+ db_data = read_db()
173
+ choices = get_tag_id_choices(db_data, cfg.vis_cols)
174
+ selection_criteria = input_ask_which_tasks_to_show(choices)
175
+ for i, task in db_data.items():
176
+ if selection_criteria in [i, task["Tag"]]:
177
+ console.print(
178
+ 20 * "[bold blue]#[/]" + f" Task {i} " + 20 * "[bold blue]#[/]"
179
+ )
180
+ pprint(
181
+ {
182
+ key: val
183
+ for key, val in task.items()
184
+ if key in ["Title", "Description", "Tag", "Status"]
185
+ },
186
+ console=console,
187
+ expand_all=True,
188
+ )
189
+
190
+
191
+ # Action 5
192
+ def delete_kanban_board():
193
+ board_to_delete = input_ask_for_delete_board()
194
+ if input_confirm_delete_board(board_to_delete):
195
+ board_to_delete_path = cfg.kanban_boards_dict[board_to_delete]
181
196
 
197
+ delete_json_file(board_to_delete_path)
198
+ delete_board_from_config(board_to_delete)
182
199
 
183
- def show_settings():
184
- settings_table = create_config_table()
185
- console.print(settings_table)
186
- if input_confirm_change_current_settings():
187
- change_settings()
200
+
201
+ def show():
202
+ if not cfg.kanban_boards:
203
+ console.print(":warning: [red]No Boards created yet[/]:warning:")
204
+ console.print("Use 'kanban init' to create a new kanban board.")
205
+ raise KeyboardInterrupt
206
+
207
+ if not check_if_current_active_board_in_board_list():
208
+ console.print(
209
+ "[yellow]Hmm, Something went wrong.[/] "
210
+ + f"The active board '{cfg.active_board}' is not in the list of boards."
211
+ )
212
+ change_kanban_board()
213
+ show()
214
+ return
215
+ db_data = read_db()
216
+ table = create_table(data=db_data)
217
+ console.print(table)
188
218
 
189
219
 
220
+ # Scan Functionality
221
+ #####################################################################################
190
222
  def add_todos_to_board():
191
223
  files = scan_files(endings=cfg.scanned_files)
192
224
  todos = scan_for_todos(file_paths=files, patterns=cfg.scanned_patterns)
@@ -215,3 +247,54 @@ def add_todos_to_board():
215
247
 
216
248
  todo_task_list.append(new_task)
217
249
  add_tasks_to_db(tasks=todo_task_list)
250
+
251
+
252
+ # Config Settings
253
+ #####################################################################################
254
+ def change_settings():
255
+ while True:
256
+ show_settings()
257
+ settings_selection = input_ask_for_action_settings()
258
+
259
+ if settings_selection == 1:
260
+ change_kanban_board()
261
+
262
+ new_min_col_widths = input_change_min_col_width_settings()
263
+ cfg.col_min_width = new_min_col_widths
264
+
265
+ done_limit = input_change_done_limit_settings()
266
+ cfg.done_limit = done_limit
267
+
268
+ footer_visible = input_change_footer_settings()
269
+ cfg.show_footer = "True" if footer_visible else "False"
270
+
271
+ if settings_selection == 2:
272
+ updated_col_config = input_change_column_settings()
273
+ cfg.kanban_columns_dict = updated_col_config
274
+
275
+ if settings_selection == 3:
276
+ while True:
277
+ new_files_to_scan = input_change_files_to_scan_settings()
278
+ if check_scanner_files_valid(new_files_to_scan):
279
+ cfg.scanned_files = new_files_to_scan
280
+ break
281
+ console.print(
282
+ f":warning: '{new_files_to_scan}' is [red]not[/] a valid."
283
+ )
284
+
285
+ while True:
286
+ new_patterns_to_scan = input_change_patterns_to_scan_settings()
287
+ if check_scanner_patterns_valid(new_patterns_to_scan):
288
+ cfg.scanned_patterns = new_patterns_to_scan
289
+ break
290
+ console.print(
291
+ f":warning: '{new_patterns_to_scan}' is [red]not[/] a valid."
292
+ )
293
+
294
+ if settings_selection == 4:
295
+ break
296
+
297
+
298
+ def show_settings():
299
+ settings_table = create_config_table()
300
+ console.print(settings_table)
@@ -54,14 +54,18 @@ def input_ask_for_action():
54
54
  console.print(
55
55
  "\t[1] :clipboard: [green]Create new Task[/]"
56
56
  + 2 * "\t"
57
- + "[2] :clockwise_vertical_arrows: [bold blue]Update/Check Task[/]"
57
+ + "[2] :clockwise_vertical_arrows: [bold cornflower_blue]Update/Check Task[/]"
58
58
  )
59
59
  console.print(
60
60
  "\t[3] :bookmark_tabs: [bold yellow]Change Kanban Board[/]"
61
61
  + "\t"
62
- + "[4] :cross_mark: [red]Delete Kanban Board[/]"
62
+ + "[4] :magnifying_glass_tilted_left: [bold blue]Show Task Details[/]"
63
+ )
64
+ console.print(
65
+ "\t[5] :cross_mark: [red]Delete Kanban Board[/]"
66
+ + "\t"
67
+ + "[6] :hammer_and_wrench: [grey69]Show Current Settings[/]"
63
68
  )
64
- console.print("\t[5] :hammer_and_wrench: [grey69]Show Current Settings[/]")
65
69
  action = IntPrompt.ask(
66
70
  prompt="Choose wisely :books:",
67
71
  choices=[
@@ -70,6 +74,7 @@ def input_ask_for_action():
70
74
  "3",
71
75
  "4",
72
76
  "5",
77
+ "6",
73
78
  ],
74
79
  show_choices=False,
75
80
  )
@@ -185,7 +190,7 @@ def input_ask_which_task_to_update(data: dict) -> str:
185
190
  id for id, task in data.items() if task["Status"] in cfg.vis_cols
186
191
  ]
187
192
  task_id_to_update = IntPrompt.ask(
188
- prompt="Which Task to update?",
193
+ prompt="Which Task to update? Select an [[cyan]Id[/]]",
189
194
  choices=choice_task_ids,
190
195
  show_choices=False,
191
196
  )
@@ -296,31 +301,76 @@ def input_confirm_add_todos_to_board(todos) -> bool:
296
301
  )
297
302
 
298
303
 
304
+ def input_ask_which_tasks_to_show(choices):
305
+ return Prompt.ask(
306
+ prompt="What Task/s to show? Select an [[cyan]Id[/]] or ([orange3]Tag[/])?",
307
+ default=False,
308
+ show_default=False,
309
+ choices=choices,
310
+ show_choices=False,
311
+ )
312
+
313
+
299
314
  # Config Settings
300
315
  #####################################################################################
301
- def input_change_settings():
302
- updated_col_config = input_change_column_settings()
303
- cfg.kanban_columns_dict = updated_col_config
304
316
 
305
- footer_visible = input_change_footer_settings()
306
- done_limit = input_change_done_limit_settings()
307
- cfg.show_footer = "True" if footer_visible else "False"
308
- cfg.done_limit = done_limit
309
317
 
318
+ # Ask for Actions
319
+ def input_ask_for_action_settings():
320
+ console.print(
321
+ "[yellow]Not happy with current settings!?[/],"
322
+ + "which [blue]Section[/] do you want to change :hammer_and_wrench:?"
323
+ )
324
+ console.print(
325
+ "\t[1] :clipboard: [blue]settings.general[/]"
326
+ + 2 * "\t"
327
+ + "[2] :eye: [blue]settings.columns.visibility[/]"
328
+ )
329
+ console.print(
330
+ "\t[3] :magnifying_glass_tilted_left: [blue]settings.scanner[/]"
331
+ + 2 * "\t"
332
+ + "[4] :cross_mark: [red]Go back to Kanban Board[/]"
333
+ )
334
+ action = IntPrompt.ask(
335
+ prompt="Choose [blue]Section[/], where you want to change the Current Value",
336
+ choices=[
337
+ "1",
338
+ "2",
339
+ "3",
340
+ "4",
341
+ ],
342
+ show_choices=False,
343
+ )
344
+ return action
310
345
 
311
- def input_change_column_settings():
312
- updated_column_dict = {}
313
- for col, vis in cfg.kanban_columns_dict.items():
314
- new_visible = Confirm.ask(
315
- prompt=f"Should Column {COLOR_DICT.get(col,col)} be visible?",
316
- default=True if vis == "True" else False,
317
- show_default=True,
346
+
347
+ # Show current Config Table
348
+ def create_config_table():
349
+ settings_table = Table(
350
+ title=":hammer_and_wrench: [grey69]Settings Overview[/]:hammer_and_wrench:",
351
+ highlight=True,
352
+ show_header=True,
353
+ caption=f"Your config file is located under [light_green]{CONFIG_FILE_PATH}[/]",
354
+ )
355
+ for col in ["Option", "Current Value"]:
356
+ settings_table.add_column(
357
+ header=col,
358
+ header_style="bold",
359
+ justify="left",
360
+ overflow="fold",
361
+ min_width=30,
318
362
  )
319
- updated_column_dict[col] = "True" if new_visible else "False"
363
+ for section in cfg.config:
364
+ if section:
365
+ settings_table.add_section()
366
+ settings_table.add_row(f"[blue]{section}[/]", "")
367
+ for key, val in cfg.config[section].items():
368
+ settings_table.add_row(key, val)
320
369
 
321
- return updated_column_dict
370
+ return settings_table
322
371
 
323
372
 
373
+ # Change settings.general
324
374
  def input_change_footer_settings():
325
375
  footer_visible = Confirm.ask(
326
376
  prompt="Should Footer be visible?",
@@ -342,34 +392,46 @@ def input_change_done_limit_settings():
342
392
  return str(done_limit)
343
393
 
344
394
 
345
- def input_confirm_change_current_settings():
346
- return Confirm.ask(
347
- prompt="Do you want to change :hammer_and_wrench: [grey69]Settings[/]?",
348
- default=False,
395
+ def input_change_min_col_width_settings():
396
+ new_min_col_width = IntPrompt.ask(
397
+ prompt="What should the minimum Column Width be?",
398
+ default=cfg.col_min_width,
349
399
  show_default=True,
350
400
  )
351
401
 
402
+ return new_min_col_width
352
403
 
353
- def create_config_table():
354
- settings_table = Table(
355
- title=":hammer_and_wrench: [grey69]Settings Overview[/]:hammer_and_wrench:",
356
- highlight=True,
357
- show_header=True,
358
- caption=f"Your config file is located under [light_green]{CONFIG_FILE_PATH}[/]",
359
- )
360
- for col in ["Option", "Current Value"]:
361
- settings_table.add_column(
362
- header=col,
363
- header_style="bold",
364
- justify="left",
365
- overflow="fold",
366
- min_width=30,
404
+
405
+ # Change settings.columns.visible
406
+ def input_change_column_settings():
407
+ updated_column_dict = {}
408
+ for col, vis in cfg.kanban_columns_dict.items():
409
+ new_visible = Confirm.ask(
410
+ prompt=f"Should Column {COLOR_DICT.get(col,col)} be visible?",
411
+ default=True if vis == "True" else False,
412
+ show_default=True,
367
413
  )
368
- for section in cfg.config:
369
- if section:
370
- settings_table.add_section()
371
- settings_table.add_row(f"[blue]{section}[/]", "")
372
- for key, val in cfg.config[section].items():
373
- settings_table.add_row(key, val)
414
+ updated_column_dict[col] = "True" if new_visible else "False"
374
415
 
375
- return settings_table
416
+ return updated_column_dict
417
+
418
+
419
+ # Change settings.scanner
420
+ def input_change_files_to_scan_settings():
421
+ files_to_scan = Prompt.ask(
422
+ prompt="Which Files to scan? Enter [green]' '[/] separated File Endings",
423
+ default=" ".join(cfg.scanned_files),
424
+ show_default=True,
425
+ )
426
+
427
+ return files_to_scan
428
+
429
+
430
+ def input_change_patterns_to_scan_settings():
431
+ files_to_scan = Prompt.ask(
432
+ prompt="Which Patterns to scan? Enter [green]','[/] separated Patterns",
433
+ default=",".join(cfg.scanned_patterns),
434
+ show_default=True,
435
+ )
436
+
437
+ return files_to_scan
@@ -136,3 +136,29 @@ def split_todo_in_tag_and_title(todo: str, patterns: list):
136
136
  title = title[1:].strip() if title.startswith(":") else title
137
137
 
138
138
  return tag.upper(), title
139
+
140
+
141
+ def get_tag_id_choices(data_dict: dict, vis_cols: list) -> list:
142
+ valid_ids = [i for i, task in data_dict.items() if task["Status"] in vis_cols]
143
+ valid_tags = [
144
+ task["Tag"] for task in data_dict.values() if task["Status"] in vis_cols
145
+ ]
146
+
147
+ valid_choices = list(set(valid_ids + valid_tags))
148
+ return valid_choices
149
+
150
+
151
+ def check_scanner_files_valid(files: str) -> bool:
152
+ for file in files.split(" "):
153
+ if not file.startswith("."):
154
+ return False
155
+ if not all(char.isalpha() for char in file[1:]):
156
+ return False
157
+ return True
158
+
159
+
160
+ def check_scanner_patterns_valid(patterns: str) -> bool:
161
+ for pattern in patterns.split(","):
162
+ if not pattern.startswith("#"):
163
+ return False
164
+ return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kanban-python
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Terminal Kanban App written in Python
5
5
  Home-page: https://github.com/Zaloog/kanban-python
6
6
  Author: Zaloog
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
15
15
  License-File: LICENSE.txt
16
16
  Requires-Dist: importlib-metadata; python_version < "3.8"
17
17
  Requires-Dist: rich>=13.7.0
18
- Requires-Dist: platformdirs<4
18
+ Requires-Dist: platformdirs<4,>=3
19
19
  Provides-Extra: testing
20
20
  Requires-Dist: setuptools; extra == "testing"
21
21
  Requires-Dist: pytest; extra == "testing"
@@ -45,10 +45,12 @@ Welcome to **kanban-python**, your Terminal Kanban-Board Manager.
45
45
 
46
46
  ![header](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_header.PNG)
47
47
  The [clikan] Kanban App inspired me to write
48
- my own Terminal Kanban Application, since I preferred a more simple and guided workflow.
48
+ my own Terminal Kanban Application since I preferred a more simple and guided workflow.
49
49
 
50
- **kanban-python** also comes with more features and customization options.
51
- This package was developed with [pyscaffold], which provides nice project templates
50
+ **kanban-python** also comes with more features, like custom column creation,
51
+ automatic scanning and customizable config file to support you being productive.
52
+
53
+ This package was developed with [pyscaffold], which provides awesome project templates
52
54
  and takes over much of the boilerplate for python packaging.
53
55
  It was a great help for developing my first package and I can highly recommend it.
54
56
 
@@ -63,7 +65,7 @@ The config path in the table caption and the path for the task files can be foun
63
65
  - *automated scanning of files for task creation*: kanban-python can scan files of defined types for specific patterns at start of line.
64
66
  Check [Automatic Task Creation](#automatic-task-creation) for more Infos.
65
67
 
66
- - *configfile*: A `pykanban.ini` file gets created on first initialization in a `.kanban-python` folder in your `Home`-Directory.
68
+ - *configfile*: A `pykanban.ini` file gets created on first initialization in a `kanban-python` folder in your `user_config_dir`-Directory.
67
69
  This can be edited manually or within the kanban-python application. It tracks the location for all your created boards. \
68
70
  ![configfile](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_config.PNG)
69
71
  * `Active_Board`: current board that is shown when using `kanban`-command
@@ -77,10 +79,10 @@ This can be edited manually or within the kanban-python application. It tracks t
77
79
  <br />
78
80
 
79
81
  - *storage-file for each board*: Each created board comes with its own name and `pykanban.json` file,
80
- which stores all tasks for that board. The files are stored in board specific folders under `.kanban-python/kanban_boards/<BOARDNAME>`
82
+ which stores all tasks for that board. The files are stored in board specific folders under `$USER_DATA_DIR/kanban-python/kanban_boards/<BOARDNAME>`
81
83
 
82
84
  - *column customization*: kanban-python comes with 5 pre-defined colored columns: [Ready, Doing, Done, Archived, Deleted]
83
- More column can be added manually in the `pykanban.ini`, also the visibility can be configured.
85
+ More column can be added manually in the `pykanban.ini`, also the visibility can be configured there.
84
86
 
85
87
  - *time-tracking*: for each task it is tracked, how long it was in the
86
88
  <span style="color:yellow">Doing</span> column, based on the moments when you update the task status.
@@ -102,7 +104,7 @@ After Installation of kanban-python, there are 4 commands available:
102
104
  kanban init
103
105
  ```
104
106
  Is used to create a new kanban board i.e. it asks for a name and then creates a `pykanban.json` file with a Welcome Task.
105
- On first use of any command, the `pykanban.ini` configfile and the `.kanban-python` folder will be created automatically.
107
+ On first use of any command, the `pykanban.ini` configfile and the `kanban-python` folder will be created automatically.
106
108
  ![init_file](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_kanban_init.PNG)
107
109
 
108
110
  ### Interact with Tasks/Boards
@@ -135,9 +137,7 @@ The filepath were the task was found will be added as description of the task.
135
137
  ![settings](https://raw.githubusercontent.com/Zaloog/kanban-python/main/images/image_kanban_configure.PNG)
136
138
 
137
139
  To create a new custom Columns, you have to edit the `pykanban.ini` manually and add a new column name + visibility status
138
- under the `settings.columns.visible` section. The same way you can also add more file endings or patterns for the `settings.scanner` section.
139
- Keep in mind the specific separators for that section.
140
- I am working on an option to customize those things in the future without the need to manual edit the file.
140
+ under the `settings.columns.visible` section. The other options are all customizable now via the new settings menu.
141
141
 
142
142
 
143
143
  ## Feedback and Issues
@@ -1,5 +1,5 @@
1
1
  rich>=13.7.0
2
- platformdirs<4
2
+ platformdirs<4,>=3
3
3
 
4
4
  [:python_version < "3.8"]
5
5
  importlib-metadata
@@ -159,6 +159,26 @@ def test_split_todo_in_tag_and_title(todo, pattern, expected_result):
159
159
  assert title == expected_result[1]
160
160
 
161
161
 
162
+ @pytest.mark.parametrize(
163
+ "files, expected_result",
164
+ [(".md .py", True), (".py md", False), (".py .d3", False)],
165
+ )
166
+ def test_check_scanner_files_valid(files, expected_result):
167
+ result = utils.check_scanner_files_valid(files)
168
+
169
+ assert result is expected_result
170
+
171
+
172
+ @pytest.mark.parametrize(
173
+ "patterns, expected_result",
174
+ [("# TODO,#TODO", True), ("TODO,# BUG", False), ("TODO BUG", False)],
175
+ )
176
+ def test_check_scanner_patterns_valid(patterns, expected_result):
177
+ result = utils.check_scanner_patterns_valid(patterns)
178
+
179
+ assert result is expected_result
180
+
181
+
162
182
  # def test_main(capsys):
163
183
  # """CLI Tests"""
164
184
  # # capsys is a pytest fixture that allows asserts against stdout/stderr
Binary file
Binary file
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes