cli-todo-jd 0.1.0__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.
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.4
2
+ Name: cli-todo-jd
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: questionary>=2.1.1
8
+ Requires-Dist: rich>=14.2.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: pre-commit; extra == "dev"
11
+ Requires-Dist: pytest; extra == "dev"
12
+ Requires-Dist: bump-my-version; extra == "dev"
13
+
14
+ # cli-todo-jd
15
+
16
+ A command line to do list with interactive menu
17
+
18
+ ## Getting started
19
+
20
+ To start using this project, first make sure your system meets its
21
+ requirements.
22
+
23
+ It's suggested that you install this package and its requirements within
24
+ a virtual environment.
25
+
26
+ ## Requirements
27
+
28
+ - Python 3.9+ installed
29
+
30
+ ## Installing the package
31
+
32
+ Whilst in the root folder, in a terminal, you can install the package and its
33
+ Python dependencies using:
34
+
35
+ ```shell
36
+ python -m pip install -U pip setuptools
37
+ pip install -e .
38
+ ```
39
+
40
+ ### Install for contributors/developers
41
+
42
+ To install the contributing requirements, use:
43
+ ```shell
44
+ python -m pip install -U pip setuptools
45
+ pip install -e .[dev]
46
+ pre-commit install
47
+ ```
48
+
49
+ This installs an editable version of the package. This means that when you update the
50
+ package code you do not have to reinstall it for the changes to take effect.
51
+ This saves a lot of time when you test your code.
52
+
53
+ Remember to update the setup and requirement files inline with any changes to your
54
+ package.
55
+
56
+
57
+ ## Licence
58
+
59
+ Unless stated otherwise, the codebase is released under the MIT License. This covers
60
+ both the codebase and any sample code in the documentation.
61
+
62
+ ## Contributing
63
+
64
+ If you want to help us build and improve `{{ cookiecutter.project_slug }}`, please take a look at our
65
+ [contributing guidelines][contributing].
66
+
67
+ ## Acknowledgements
68
+
69
+ This project structure is based on the [`govcookiecutter` template project][govcookiecutter].
70
+
71
+ [contributing]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/%7B%7B%20cookiecutter.repo_name%20%7D%7D/docs/contributor_guide/CONTRIBUTING.md
72
+ [govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter
@@ -0,0 +1,59 @@
1
+ # cli-todo-jd
2
+
3
+ A command line to do list with interactive menu
4
+
5
+ ## Getting started
6
+
7
+ To start using this project, first make sure your system meets its
8
+ requirements.
9
+
10
+ It's suggested that you install this package and its requirements within
11
+ a virtual environment.
12
+
13
+ ## Requirements
14
+
15
+ - Python 3.9+ installed
16
+
17
+ ## Installing the package
18
+
19
+ Whilst in the root folder, in a terminal, you can install the package and its
20
+ Python dependencies using:
21
+
22
+ ```shell
23
+ python -m pip install -U pip setuptools
24
+ pip install -e .
25
+ ```
26
+
27
+ ### Install for contributors/developers
28
+
29
+ To install the contributing requirements, use:
30
+ ```shell
31
+ python -m pip install -U pip setuptools
32
+ pip install -e .[dev]
33
+ pre-commit install
34
+ ```
35
+
36
+ This installs an editable version of the package. This means that when you update the
37
+ package code you do not have to reinstall it for the changes to take effect.
38
+ This saves a lot of time when you test your code.
39
+
40
+ Remember to update the setup and requirement files inline with any changes to your
41
+ package.
42
+
43
+
44
+ ## Licence
45
+
46
+ Unless stated otherwise, the codebase is released under the MIT License. This covers
47
+ both the codebase and any sample code in the documentation.
48
+
49
+ ## Contributing
50
+
51
+ If you want to help us build and improve `{{ cookiecutter.project_slug }}`, please take a look at our
52
+ [contributing guidelines][contributing].
53
+
54
+ ## Acknowledgements
55
+
56
+ This project structure is based on the [`govcookiecutter` template project][govcookiecutter].
57
+
58
+ [contributing]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/%7B%7B%20cookiecutter.repo_name%20%7D%7D/docs/contributor_guide/CONTRIBUTING.md
59
+ [govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter
File without changes
@@ -0,0 +1,75 @@
1
+ from argparse import ArgumentParser
2
+ from cli_todo_jd.main import (
3
+ add_item_to_list,
4
+ remove_item_from_list,
5
+ list_items_on_list,
6
+ clear_list_of_items,
7
+ )
8
+
9
+
10
+ def parser_optional_args(parser: ArgumentParser):
11
+ parser.add_argument(
12
+ "-f",
13
+ "--filepath",
14
+ help="Path to the file to process",
15
+ default="./.todo_list.json",
16
+ )
17
+
18
+
19
+ def add_item():
20
+ parser = ArgumentParser(description="Add a todo item")
21
+ parser.add_argument(
22
+ "item",
23
+ nargs="+",
24
+ help="The todo item to add (use quotes or multiple words)",
25
+ )
26
+ parser_optional_args(parser)
27
+
28
+ args = parser.parse_args()
29
+ args.item = " ".join(args.item)
30
+ add_item_to_list(args.item, args.filepath)
31
+
32
+
33
+ def remove_item():
34
+ parser = ArgumentParser(description="Remove a todo item by index")
35
+ parser.add_argument(
36
+ "index",
37
+ type=int,
38
+ help="The index of the todo item to remove (1-based)",
39
+ )
40
+ parser_optional_args(parser)
41
+
42
+ args = parser.parse_args()
43
+ remove_item_from_list(args.index, args.filepath)
44
+
45
+
46
+ def list_items():
47
+ parser = ArgumentParser(description="List all todo items")
48
+ parser_optional_args(parser)
49
+
50
+ args = parser.parse_args()
51
+ list_items_on_list(args.filepath)
52
+
53
+
54
+ def clear_list():
55
+ parser = ArgumentParser(description="Clear all todo items")
56
+ parser.add_argument(
57
+ "-y",
58
+ "--yes",
59
+ action="store_true",
60
+ help="Do not prompt for confirmation",
61
+ )
62
+ parser_optional_args(parser)
63
+
64
+ args = parser.parse_args()
65
+ list_items_on_list(args.filepath)
66
+
67
+ if not args.yes:
68
+ resp = (
69
+ input(f"Clear all todo items in '{args.filepath}'? [y/n]: ").strip().lower()
70
+ )
71
+ if resp not in ("y", "yes"):
72
+ return
73
+
74
+ # assuming remove_item_from_list(0/None) clears; otherwise replace with your clear implementation
75
+ clear_list_of_items(args.filepath)
@@ -0,0 +1,215 @@
1
+ import json
2
+ from pathlib import Path
3
+ import questionary
4
+ from rich.console import Console
5
+ from rich.table import Table
6
+ from rich.padding import Padding
7
+
8
+
9
+ def main():
10
+ TodoApp()
11
+
12
+
13
+ class TodoApp:
14
+ """
15
+ A simple command-line todo application.
16
+ """
17
+
18
+ def __init__(self, file_path_to_json="./.todo_list.json"):
19
+ self.todos = []
20
+ self.file_path_to_json = Path(file_path_to_json)
21
+ self._check_and_load_todos(self.file_path_to_json)
22
+ self._console = Console()
23
+
24
+ def add_todo(self, item):
25
+ self.todos.append(item)
26
+ print(f'Added todo: "{item}"')
27
+
28
+ def list_todos(self):
29
+ if not self.todos:
30
+ print("No todos found.")
31
+ return
32
+ self._table_print()
33
+
34
+ def remove_todo(self, index):
35
+ try:
36
+ removed = self.todos.pop(index - 1)
37
+ print(f'Removed todo: "{removed}"')
38
+ except IndexError:
39
+ print("Error: Invalid todo index.")
40
+
41
+ def _check_and_load_todos(self, file_path):
42
+ if file_path.exists():
43
+ try:
44
+ with file_path.open("r", encoding="utf-8") as f:
45
+ self.todos = json.load(f)
46
+ except (json.JSONDecodeError, OSError):
47
+ print("Warning: Failed to load existing todos. Starting fresh.")
48
+
49
+ def write_todos(self):
50
+ try:
51
+ with self.file_path_to_json.open("w", encoding="utf-8") as f:
52
+ json.dump(self.todos, f, ensure_ascii=False, indent=2)
53
+ except OSError as e:
54
+ print(f"Warning: failed to save todos: {e}")
55
+
56
+ def _table_print(
57
+ self,
58
+ title: str | None = None,
59
+ style: str = "bold cyan",
60
+ ):
61
+ table = Table(
62
+ title=title, header_style=style, border_style=style, show_lines=True
63
+ )
64
+ columns = ["ID", "Todo Item"]
65
+ for col in columns:
66
+ table.add_column(str(col))
67
+ for idx, todo in enumerate(self.todos, start=1):
68
+ table.add_row(f"{idx}.", todo)
69
+ self._console.print(Padding(table, (2, 2)))
70
+
71
+
72
+ def create_list(file_path_to_json: str = "./.todo_list.json"):
73
+ """
74
+ Create a new todo list.
75
+
76
+ Parameters
77
+ ----------
78
+ file_path_to_json : str, optional
79
+ The file path to the JSON file for storing todos, by default "./.todo_list.json"
80
+
81
+ Returns
82
+ -------
83
+ TodoApp
84
+ An instance of the TodoApp class.
85
+ """
86
+ app = TodoApp(file_path_to_json=file_path_to_json)
87
+ return app
88
+
89
+
90
+ def add_item_to_list(item: str, filepath: str):
91
+ """
92
+ Add a new item to the todo list.
93
+
94
+ Parameters
95
+ ----------
96
+ item : str
97
+ The todo item to add.
98
+ filepath : str
99
+ The file path to the JSON file for storing todos.
100
+ """
101
+ app = create_list(file_path_to_json=filepath)
102
+ app.add_todo(item)
103
+ app.list_todos()
104
+ app.write_todos()
105
+
106
+
107
+ def list_items_on_list(filepath: str):
108
+ """
109
+ List all items in the todo list.
110
+
111
+ Parameters
112
+ ----------
113
+ filepath : str
114
+ The file path to the JSON file for storing todos.
115
+ """
116
+ app = create_list(file_path_to_json=filepath)
117
+ app.list_todos()
118
+
119
+
120
+ def remove_item_from_list(index: int, filepath: str):
121
+ """
122
+ remove an item from the todo list using index
123
+
124
+ Parameters
125
+ ----------
126
+ index : int
127
+ The index of the todo item to remove.
128
+ filepath : str
129
+ The file path to the JSON file for storing todos.
130
+ """
131
+ app = create_list(file_path_to_json=filepath)
132
+ app.remove_todo(index)
133
+ app.list_todos()
134
+ app.write_todos()
135
+
136
+
137
+ def clear_list_of_items(filepath: str):
138
+ """
139
+ Clear all items from the todo list.
140
+
141
+ Parameters
142
+ ----------
143
+ filepath : str
144
+ The file path to the JSON file for storing todos.
145
+ """
146
+ app = create_list(file_path_to_json=filepath)
147
+ app.todos = []
148
+ print("Cleared all todos.")
149
+ app.write_todos()
150
+
151
+
152
+ def cli_menu(filepath="./.todo_list.json"):
153
+ """
154
+ Display the command-line interface menu for the todo list.
155
+
156
+ Parameters
157
+ ----------
158
+ filepath : str, optional
159
+ The file path to the JSON file for storing todos, by default "./.todo_list.json"
160
+ """
161
+ app = create_list(file_path_to_json=filepath)
162
+ while True:
163
+ action = questionary.select(
164
+ "What would you like to do?",
165
+ choices=[
166
+ "Add todo",
167
+ "List todos",
168
+ "Remove todo",
169
+ "Clear all todos",
170
+ "Exit",
171
+ ],
172
+ ).ask()
173
+
174
+ if action == "Add todo":
175
+ item = questionary.text("Enter the todo item:").ask()
176
+ app.add_todo(item)
177
+ app.write_todos()
178
+ elif action == "List todos":
179
+ app.list_todos()
180
+ elif action == "Remove todo":
181
+ if not app.todos:
182
+ print("No todos to remove.")
183
+ continue
184
+ todo_choice = questionary.select(
185
+ "Select the todo to remove:",
186
+ choices=["<Back>"] + app.todos,
187
+ ).ask()
188
+
189
+ if todo_choice == "<Back>":
190
+ continue
191
+
192
+ todo_to_remove = app.todos.index(todo_choice) + 1
193
+ app.remove_todo(todo_to_remove)
194
+ app.write_todos()
195
+
196
+ elif action == "Clear all todos":
197
+ confirm = questionary.confirm(
198
+ "Are you sure you want to clear all todos?"
199
+ ).ask()
200
+ if confirm:
201
+ app.todos = []
202
+ print("Cleared all todos.")
203
+ app.write_todos()
204
+ elif action == "Clear all todos":
205
+ confirm = questionary.confirm(
206
+ "Are you sure you want to clear all todos?"
207
+ ).ask()
208
+ if confirm:
209
+ app.todos = []
210
+ print("Cleared all todos.")
211
+ app.write_todos()
212
+ elif action == "Exit":
213
+ break
214
+ else:
215
+ break
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.4
2
+ Name: cli-todo-jd
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: questionary>=2.1.1
8
+ Requires-Dist: rich>=14.2.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: pre-commit; extra == "dev"
11
+ Requires-Dist: pytest; extra == "dev"
12
+ Requires-Dist: bump-my-version; extra == "dev"
13
+
14
+ # cli-todo-jd
15
+
16
+ A command line to do list with interactive menu
17
+
18
+ ## Getting started
19
+
20
+ To start using this project, first make sure your system meets its
21
+ requirements.
22
+
23
+ It's suggested that you install this package and its requirements within
24
+ a virtual environment.
25
+
26
+ ## Requirements
27
+
28
+ - Python 3.9+ installed
29
+
30
+ ## Installing the package
31
+
32
+ Whilst in the root folder, in a terminal, you can install the package and its
33
+ Python dependencies using:
34
+
35
+ ```shell
36
+ python -m pip install -U pip setuptools
37
+ pip install -e .
38
+ ```
39
+
40
+ ### Install for contributors/developers
41
+
42
+ To install the contributing requirements, use:
43
+ ```shell
44
+ python -m pip install -U pip setuptools
45
+ pip install -e .[dev]
46
+ pre-commit install
47
+ ```
48
+
49
+ This installs an editable version of the package. This means that when you update the
50
+ package code you do not have to reinstall it for the changes to take effect.
51
+ This saves a lot of time when you test your code.
52
+
53
+ Remember to update the setup and requirement files inline with any changes to your
54
+ package.
55
+
56
+
57
+ ## Licence
58
+
59
+ Unless stated otherwise, the codebase is released under the MIT License. This covers
60
+ both the codebase and any sample code in the documentation.
61
+
62
+ ## Contributing
63
+
64
+ If you want to help us build and improve `{{ cookiecutter.project_slug }}`, please take a look at our
65
+ [contributing guidelines][contributing].
66
+
67
+ ## Acknowledgements
68
+
69
+ This project structure is based on the [`govcookiecutter` template project][govcookiecutter].
70
+
71
+ [contributing]: https://github.com/best-practice-and-impact/govcookiecutter/blob/main/%7B%7B%20cookiecutter.repo_name%20%7D%7D/docs/contributor_guide/CONTRIBUTING.md
72
+ [govcookiecutter]: https://github.com/best-practice-and-impact/govcookiecutter
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ cli_todo_jd/__init__.py
4
+ cli_todo_jd/cli_entry.py
5
+ cli_todo_jd/main.py
6
+ cli_todo_jd.egg-info/PKG-INFO
7
+ cli_todo_jd.egg-info/SOURCES.txt
8
+ cli_todo_jd.egg-info/dependency_links.txt
9
+ cli_todo_jd.egg-info/entry_points.txt
10
+ cli_todo_jd.egg-info/requires.txt
11
+ cli_todo_jd.egg-info/top_level.txt
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ todo_add = cli_todo_jd.cli_entry:add_item
3
+ todo_clear = cli_todo_jd.cli_entry:clear_list
4
+ todo_list = cli_todo_jd.cli_entry:list_items
5
+ todo_menu = cli_todo_jd.main:cli_menu
6
+ todo_remove = cli_todo_jd.cli_entry:remove_item
@@ -0,0 +1,7 @@
1
+ questionary>=2.1.1
2
+ rich>=14.2.0
3
+
4
+ [dev]
5
+ pre-commit
6
+ pytest
7
+ bump-my-version
@@ -0,0 +1 @@
1
+ cli_todo_jd
@@ -0,0 +1,46 @@
1
+ [project]
2
+ name = "cli-todo-jd"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ dependencies = [
8
+ "questionary>=2.1.1",
9
+ "rich>=14.2.0",
10
+ ]
11
+
12
+ [project.optional-dependencies]
13
+ dev = [
14
+ "pre-commit",
15
+ "pytest",
16
+ "bump-my-version"
17
+ ]
18
+
19
+ [project.scripts]
20
+ todo_add = "cli_todo_jd.cli_entry:add_item"
21
+ todo_remove = "cli_todo_jd.cli_entry:remove_item"
22
+ todo_list = "cli_todo_jd.cli_entry:list_items"
23
+ todo_clear = "cli_todo_jd.cli_entry:clear_list"
24
+ todo_menu = "cli_todo_jd.main:cli_menu"
25
+
26
+ [tool.bumpversion]
27
+ current_version = "0.1.0"
28
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
29
+ serialize = ["{major}.{minor}.{patch}"]
30
+ search = "{current_version}"
31
+ replace = "{new_version}"
32
+ regex = false
33
+ ignore_missing_version = false
34
+ ignore_missing_files = false
35
+ tag = true
36
+ sign_tags = false
37
+ tag_name = "v{new_version}"
38
+ tag_message = "Bump version: {current_version} → {new_version}"
39
+ allow_dirty = false
40
+ commit = true
41
+ message = "Bump version: {current_version} → {new_version}"
42
+ moveable_tags = []
43
+ commit_args = "--no-verify"
44
+ setup_hooks = []
45
+ pre_commit_hooks = []
46
+ post_commit_hooks = []
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+