easydone 0.2.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.
easydone-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pedro Alberto Rosquete Ares
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.4
2
+ Name: easydone
3
+ Version: 0.2.0
4
+ Summary: A CLI app made with python for easy tasks management.
5
+ Author-email: Pedro Alberto Rosquete Ares <rosquetearespedro06@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Pedro Alberto Rosquete Ares
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Documentation, https://github.com/prares-dev/easydone.git
29
+ Project-URL: Homepage, https://github.com/prares-dev/easydone.git
30
+ Project-URL: Repository, https://github.com/prares-dev/easydone.git
31
+ Requires-Python: >=3.9
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Requires-Dist: rich>=13.0
35
+ Provides-Extra: dev
36
+ Requires-Dist: pytest>=8.0; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # easydone - Task Tracker App
40
+
41
+ > A focused command-line task manager for turning a messy to-do list into a clear next action.
42
+
43
+ easydone is a lightweight Python CLI for creating, updating, completing, deleting, and filtering tasks directly from your terminal. Tasks are saved as readable JSON, and the storage layer now includes **automatic backups, corruption quarantine, and atomic writes** to keep your data safe.
44
+
45
+ ## Why easydone?
46
+
47
+ - Fast terminal-first workflow
48
+ - Statuses for work in motion: `not-done`, `in-progress`, and `done`
49
+ - Four priority levels: `low`, `normal`, `high`, and `urgent`
50
+ - Filter tasks by status, priority, or both
51
+ - Human-readable JSON storage with no database setup
52
+ - **Bulletproof data handling**: atomic writes, automatic `.bak` backups, and quarantine of corrupted files
53
+ - Pretty terminal output with [Rich](https://github.com/Textualize/rich) (falls back to plain text if unavailable)
54
+
55
+ ## Project Structure
56
+
57
+ ```text
58
+ easydone/
59
+ ├── easydone/
60
+ │ ├── __init__.py # Package metadata (version, etc.)
61
+ │ ├── __main__.py # Application entry point
62
+ │ ├── cli.py # Argument parser and command dispatch
63
+ │ ├── logic.py # Task-management operations
64
+ │ ├── storage.py # JSON loading/saving with backup & quarantine
65
+ │ └── format.py # Output formatting (Rich / plain)
66
+ ├── tests/
67
+ │ ├── test_cli.py
68
+ │ ├── test_logic.py
69
+ │ ├── test_storage.py
70
+ │ └── test_format.py
71
+ ├── LICENSE
72
+ ├── pyproject.toml # Packaging and pytest configuration
73
+ └── README.md
74
+ ```
75
+
76
+ ## Quick Start
77
+
78
+ ### Requirements
79
+
80
+ - Python 3.9 or newer
81
+ - Windows PowerShell, macOS, or Linux terminal
82
+
83
+ From the project root, create a virtual environment and install `easydone` in editable mode:
84
+
85
+ ```powershell
86
+ py -m venv .venv
87
+ .\.venv\Scripts\Activate.ps1
88
+ py -m pip install -e .
89
+ ```
90
+
91
+ On macOS or Linux:
92
+
93
+ ```bash
94
+ python3 -m venv .venv
95
+ source .venv/bin/activate
96
+ python -m pip install -e .
97
+ ```
98
+
99
+ Or install directly from PyPI:
100
+
101
+ ```powershell
102
+ py -m pip install easydone
103
+ ```
104
+
105
+ You can now run the application:
106
+
107
+ ```shell
108
+ easydone
109
+ ```
110
+
111
+ To see all available commands:
112
+
113
+ ```shell
114
+ easydone --help
115
+ ```
116
+
117
+ ## Everyday Workflow
118
+
119
+ Create a task:
120
+
121
+ ```shell
122
+ easydone new "Read a book"
123
+ ```
124
+
125
+ Create a task with a status and priority:
126
+
127
+ ```shell
128
+ easydone new "Finish project report" --status in-progress --priority high
129
+ ```
130
+
131
+ List everything:
132
+
133
+ ```shell
134
+ easydone list
135
+ ```
136
+
137
+ Focus on urgent unfinished work:
138
+
139
+ ```shell
140
+ easydone list --status not-done --priority urgent
141
+ ```
142
+
143
+ Mark a task as complete:
144
+
145
+ ```shell
146
+ easydone mark 123 done
147
+ ```
148
+
149
+ ## Command Reference
150
+
151
+ ### `new`
152
+
153
+ Create a task. The description is required.
154
+
155
+ ```shell
156
+ easydone new DESCRIPTION [--status STATUS] [--priority PRIORITY]
157
+ ```
158
+
159
+ Options:
160
+
161
+ - `-s`, `--status`: `not-done`, `done`, or `in-progress`; defaults to `not-done`
162
+ - `-p`, `--priority`: `low`, `normal`, `high`, or `urgent`; defaults to `low`
163
+
164
+ ### `update`
165
+
166
+ Change the description and/or priority of an existing task.
167
+ The `--priority` option now validates against the four allowed values.
168
+
169
+ ```shell
170
+ easydone update TASK_ID [--description NEW_DESCRIPTION] [--priority NEW_PRIORITY]
171
+ ```
172
+
173
+ Examples:
174
+
175
+ ```shell
176
+ easydone update 123 --description "Read a novel"
177
+ easydone update 123 --priority high
178
+ ```
179
+
180
+ ### `mark`
181
+
182
+ Change the status of an existing task.
183
+
184
+ ```shell
185
+ easydone mark TASK_ID new-status
186
+ ```
187
+
188
+ ### `delete`
189
+
190
+ Delete one or more existing tasks. easydone tasks for confirmation for each ID unless `-f` or `--forced` is used.
191
+
192
+ ```shell
193
+ easydone delete TASK_ID [TASK_ID ...]
194
+ easydone delete TASK_ID [TASK_ID ...] --forced
195
+ ```
196
+
197
+ If you supply multiple IDs, all of them are validated before any deletion occurs. If any ID is invalid, the entire operation is aborted and no tasks are removed.
198
+
199
+ ### `list`
200
+
201
+ List all tasks or filter them by status and priority. You can omit dates with the `--no-dates` option.
202
+
203
+ ```shell
204
+ easydone list [--status STATUS] [--priority PRIORITY] [--no-dates]
205
+ ```
206
+
207
+ When both filters are supplied, a task must match both of them.
208
+
209
+ ## Data Storage
210
+
211
+ `easydone` stores task data in a user‑scoped application directory so it does not depend on where the command is launched from.
212
+
213
+ - **Windows**: `%APPDATA%\easydone\tasks.json`
214
+ - **macOS**: `~/Library/Application Support/easydone/tasks.json`
215
+ - **Linux**: `~/.local/share/easydone/tasks.json`
216
+
217
+ The app writes a small metadata wrapper with the file schema version and the version of easydone that saved it. This makes future upgrades safer and compatibility warnings explicit.
218
+
219
+ ```json
220
+ {
221
+ "schema_version": 1,
222
+ "app_version": "0.2.0",
223
+ "saved_at": "2026-08-28",
224
+ "tasks": {
225
+ "123": {
226
+ "description": "Finish project report",
227
+ "status": "in-progress",
228
+ "priority": "high",
229
+ "created-at": "2026-08-28",
230
+ "updated-at": null
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ ### Safety & Recovery
237
+
238
+ `easydone` now protects your data in three ways:
239
+
240
+ 1. **Atomic writes**: Every save writes to a temporary file first, then swaps it atomically. A crash mid‑write never leaves a half‑written file.
241
+ 2. **Automatic backups**: Before every save, the current `tasks.json` is copied to `tasks.json.bak`. If something goes wrong, you can restore from this backup.
242
+ 3. **Corruption quarantine**: If easydone encounters an unreadable or malformed file on load, it copies that file to `tasks.corrupted-<timestamp>.json` instead of discarding it. You can inspect the quarantined file and recover data manually.
243
+
244
+ If an older file is found (different schema or app version), `easydone` still loads it but prints a detailed warning so you can review the data before saving again.
245
+
246
+ ## Development
247
+
248
+ Install the development dependency group:
249
+
250
+ ```shell
251
+ py -m pip install -e ".[dev]"
252
+ ```
253
+
254
+ Run the complete test suite:
255
+
256
+ ```shell
257
+ py -m pytest
258
+ ```
259
+
260
+ Run a specific test module:
261
+
262
+ ```shell
263
+ py -m pytest tests/logic_test.py
264
+ py -m pytest tests/storage_test.py
265
+ py -m pytest tests/format_test.py
266
+ ```
267
+
268
+ ## License
269
+
270
+ This project is available under the license in [LICENSE](LICENSE).
@@ -0,0 +1,232 @@
1
+ # easydone - Task Tracker App
2
+
3
+ > A focused command-line task manager for turning a messy to-do list into a clear next action.
4
+
5
+ easydone is a lightweight Python CLI for creating, updating, completing, deleting, and filtering tasks directly from your terminal. Tasks are saved as readable JSON, and the storage layer now includes **automatic backups, corruption quarantine, and atomic writes** to keep your data safe.
6
+
7
+ ## Why easydone?
8
+
9
+ - Fast terminal-first workflow
10
+ - Statuses for work in motion: `not-done`, `in-progress`, and `done`
11
+ - Four priority levels: `low`, `normal`, `high`, and `urgent`
12
+ - Filter tasks by status, priority, or both
13
+ - Human-readable JSON storage with no database setup
14
+ - **Bulletproof data handling**: atomic writes, automatic `.bak` backups, and quarantine of corrupted files
15
+ - Pretty terminal output with [Rich](https://github.com/Textualize/rich) (falls back to plain text if unavailable)
16
+
17
+ ## Project Structure
18
+
19
+ ```text
20
+ easydone/
21
+ ├── easydone/
22
+ │ ├── __init__.py # Package metadata (version, etc.)
23
+ │ ├── __main__.py # Application entry point
24
+ │ ├── cli.py # Argument parser and command dispatch
25
+ │ ├── logic.py # Task-management operations
26
+ │ ├── storage.py # JSON loading/saving with backup & quarantine
27
+ │ └── format.py # Output formatting (Rich / plain)
28
+ ├── tests/
29
+ │ ├── test_cli.py
30
+ │ ├── test_logic.py
31
+ │ ├── test_storage.py
32
+ │ └── test_format.py
33
+ ├── LICENSE
34
+ ├── pyproject.toml # Packaging and pytest configuration
35
+ └── README.md
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ### Requirements
41
+
42
+ - Python 3.9 or newer
43
+ - Windows PowerShell, macOS, or Linux terminal
44
+
45
+ From the project root, create a virtual environment and install `easydone` in editable mode:
46
+
47
+ ```powershell
48
+ py -m venv .venv
49
+ .\.venv\Scripts\Activate.ps1
50
+ py -m pip install -e .
51
+ ```
52
+
53
+ On macOS or Linux:
54
+
55
+ ```bash
56
+ python3 -m venv .venv
57
+ source .venv/bin/activate
58
+ python -m pip install -e .
59
+ ```
60
+
61
+ Or install directly from PyPI:
62
+
63
+ ```powershell
64
+ py -m pip install easydone
65
+ ```
66
+
67
+ You can now run the application:
68
+
69
+ ```shell
70
+ easydone
71
+ ```
72
+
73
+ To see all available commands:
74
+
75
+ ```shell
76
+ easydone --help
77
+ ```
78
+
79
+ ## Everyday Workflow
80
+
81
+ Create a task:
82
+
83
+ ```shell
84
+ easydone new "Read a book"
85
+ ```
86
+
87
+ Create a task with a status and priority:
88
+
89
+ ```shell
90
+ easydone new "Finish project report" --status in-progress --priority high
91
+ ```
92
+
93
+ List everything:
94
+
95
+ ```shell
96
+ easydone list
97
+ ```
98
+
99
+ Focus on urgent unfinished work:
100
+
101
+ ```shell
102
+ easydone list --status not-done --priority urgent
103
+ ```
104
+
105
+ Mark a task as complete:
106
+
107
+ ```shell
108
+ easydone mark 123 done
109
+ ```
110
+
111
+ ## Command Reference
112
+
113
+ ### `new`
114
+
115
+ Create a task. The description is required.
116
+
117
+ ```shell
118
+ easydone new DESCRIPTION [--status STATUS] [--priority PRIORITY]
119
+ ```
120
+
121
+ Options:
122
+
123
+ - `-s`, `--status`: `not-done`, `done`, or `in-progress`; defaults to `not-done`
124
+ - `-p`, `--priority`: `low`, `normal`, `high`, or `urgent`; defaults to `low`
125
+
126
+ ### `update`
127
+
128
+ Change the description and/or priority of an existing task.
129
+ The `--priority` option now validates against the four allowed values.
130
+
131
+ ```shell
132
+ easydone update TASK_ID [--description NEW_DESCRIPTION] [--priority NEW_PRIORITY]
133
+ ```
134
+
135
+ Examples:
136
+
137
+ ```shell
138
+ easydone update 123 --description "Read a novel"
139
+ easydone update 123 --priority high
140
+ ```
141
+
142
+ ### `mark`
143
+
144
+ Change the status of an existing task.
145
+
146
+ ```shell
147
+ easydone mark TASK_ID new-status
148
+ ```
149
+
150
+ ### `delete`
151
+
152
+ Delete one or more existing tasks. easydone tasks for confirmation for each ID unless `-f` or `--forced` is used.
153
+
154
+ ```shell
155
+ easydone delete TASK_ID [TASK_ID ...]
156
+ easydone delete TASK_ID [TASK_ID ...] --forced
157
+ ```
158
+
159
+ If you supply multiple IDs, all of them are validated before any deletion occurs. If any ID is invalid, the entire operation is aborted and no tasks are removed.
160
+
161
+ ### `list`
162
+
163
+ List all tasks or filter them by status and priority. You can omit dates with the `--no-dates` option.
164
+
165
+ ```shell
166
+ easydone list [--status STATUS] [--priority PRIORITY] [--no-dates]
167
+ ```
168
+
169
+ When both filters are supplied, a task must match both of them.
170
+
171
+ ## Data Storage
172
+
173
+ `easydone` stores task data in a user‑scoped application directory so it does not depend on where the command is launched from.
174
+
175
+ - **Windows**: `%APPDATA%\easydone\tasks.json`
176
+ - **macOS**: `~/Library/Application Support/easydone/tasks.json`
177
+ - **Linux**: `~/.local/share/easydone/tasks.json`
178
+
179
+ The app writes a small metadata wrapper with the file schema version and the version of easydone that saved it. This makes future upgrades safer and compatibility warnings explicit.
180
+
181
+ ```json
182
+ {
183
+ "schema_version": 1,
184
+ "app_version": "0.2.0",
185
+ "saved_at": "2026-08-28",
186
+ "tasks": {
187
+ "123": {
188
+ "description": "Finish project report",
189
+ "status": "in-progress",
190
+ "priority": "high",
191
+ "created-at": "2026-08-28",
192
+ "updated-at": null
193
+ }
194
+ }
195
+ }
196
+ ```
197
+
198
+ ### Safety & Recovery
199
+
200
+ `easydone` now protects your data in three ways:
201
+
202
+ 1. **Atomic writes**: Every save writes to a temporary file first, then swaps it atomically. A crash mid‑write never leaves a half‑written file.
203
+ 2. **Automatic backups**: Before every save, the current `tasks.json` is copied to `tasks.json.bak`. If something goes wrong, you can restore from this backup.
204
+ 3. **Corruption quarantine**: If easydone encounters an unreadable or malformed file on load, it copies that file to `tasks.corrupted-<timestamp>.json` instead of discarding it. You can inspect the quarantined file and recover data manually.
205
+
206
+ If an older file is found (different schema or app version), `easydone` still loads it but prints a detailed warning so you can review the data before saving again.
207
+
208
+ ## Development
209
+
210
+ Install the development dependency group:
211
+
212
+ ```shell
213
+ py -m pip install -e ".[dev]"
214
+ ```
215
+
216
+ Run the complete test suite:
217
+
218
+ ```shell
219
+ py -m pytest
220
+ ```
221
+
222
+ Run a specific test module:
223
+
224
+ ```shell
225
+ py -m pytest tests/logic_test.py
226
+ py -m pytest tests/storage_test.py
227
+ py -m pytest tests/format_test.py
228
+ ```
229
+
230
+ ## License
231
+
232
+ This project is available under the license in [LICENSE](LICENSE).
@@ -0,0 +1,8 @@
1
+ from importlib.metadata import version, PackageNotFoundError
2
+
3
+ try:
4
+ # use the distribution name from pyproject 'project.name' (make sure they match)
5
+ __version__ = version("easydone-task-tracker")
6
+ except PackageNotFoundError:
7
+ # Package isn't installed (dev environment). Optional fallback:
8
+ __version__ = "0.0.0+dev"
@@ -0,0 +1,25 @@
1
+ from .cli import Parser
2
+ from .logic import TasksManager
3
+ from .storage import JSONHandler
4
+ from .format import describe_load_result, report_backup
5
+
6
+ def main() -> None:
7
+ # JSONHandler instance for load/save in .json.
8
+ handler = JSONHandler()
9
+ load_result = handler.load()
10
+ describe_load_result(load_result)
11
+
12
+ # TasksManager instance based on tasks loaded
13
+ manager = TasksManager(tasks_from_file=load_result.tasks)
14
+
15
+ # Parser instance for cli interface and argumments
16
+ cli = Parser(manager)
17
+ mutated = cli.start_parsing()
18
+
19
+ # save tasks before exiting only if mutated status
20
+ if mutated:
21
+ backup_result = handler.save(manager.tasks)
22
+ report_backup(backup_result)
23
+
24
+ if __name__ == "__main__":
25
+ main()