student-task-manager-cli 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.
- student_task_manager_cli-0.1.0/PKG-INFO +134 -0
- student_task_manager_cli-0.1.0/README.md +127 -0
- student_task_manager_cli-0.1.0/pyproject.toml +20 -0
- student_task_manager_cli-0.1.0/setup.cfg +4 -0
- student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/PKG-INFO +134 -0
- student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/SOURCES.txt +25 -0
- student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/dependency_links.txt +1 -0
- student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/entry_points.txt +2 -0
- student_task_manager_cli-0.1.0/src/student_task_manager_cli.egg-info/top_level.txt +1 -0
- student_task_manager_cli-0.1.0/src/task_manager/__init__.py +1 -0
- student_task_manager_cli-0.1.0/src/task_manager/__main__.py +5 -0
- student_task_manager_cli-0.1.0/src/task_manager/arguments.py +52 -0
- student_task_manager_cli-0.1.0/src/task_manager/cli.py +22 -0
- student_task_manager_cli-0.1.0/src/task_manager/commands.py +75 -0
- student_task_manager_cli-0.1.0/src/task_manager/demo.py +69 -0
- student_task_manager_cli-0.1.0/src/task_manager/input.py +36 -0
- student_task_manager_cli-0.1.0/src/task_manager/interactive.py +97 -0
- student_task_manager_cli-0.1.0/src/task_manager/productivity.py +37 -0
- student_task_manager_cli-0.1.0/src/task_manager/storage.py +78 -0
- student_task_manager_cli-0.1.0/src/task_manager/ui/__init__.py +0 -0
- student_task_manager_cli-0.1.0/src/task_manager/ui/animation.py +26 -0
- student_task_manager_cli-0.1.0/src/task_manager/ui/theme.py +57 -0
- student_task_manager_cli-0.1.0/src/task_manager/ui/views.py +123 -0
- student_task_manager_cli-0.1.0/tests/test_demo.py +43 -0
- student_task_manager_cli-0.1.0/tests/test_interactive.py +84 -0
- student_task_manager_cli-0.1.0/tests/test_productivity.py +36 -0
- student_task_manager_cli-0.1.0/tests/test_tasks.py +130 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: student-task-manager-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A simple command-line task manager
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
From the project directory, on macOS or Linux:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
python3 -m venv .venv
|
|
14
|
+
source .venv/bin/activate
|
|
15
|
+
python -m pip install -e .
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
On Windows PowerShell:
|
|
19
|
+
|
|
20
|
+
```powershell
|
|
21
|
+
py -m venv .venv
|
|
22
|
+
.venv\Scripts\Activate.ps1
|
|
23
|
+
python -m pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
After activation, run `task` to open the interactive terminal view.
|
|
27
|
+
Enter commands at the `❯` prompt, for example `add Write report`, `ls`, or `/help`.
|
|
28
|
+
`list` and `ls` are the same command. `list` shows To do tasks, `list --done` shows completed tasks, and `list --all` shows both.
|
|
29
|
+
Titles may contain spaces without quotes. `clear` and `cls` clear the interactive screen;
|
|
30
|
+
`clear-completed` removes completed tasks. Type `task` at the prompt to show the welcome view again.
|
|
31
|
+
|
|
32
|
+
Tab completes commands and the arrow keys recall history on terminals with readline.
|
|
33
|
+
The welcome screen shows your next task and a small activity chart.
|
|
34
|
+
|
|
35
|
+
You can also run single commands directly, such as:
|
|
36
|
+
`task add "Write report"` or `task --help`.
|
|
37
|
+
|
|
38
|
+
To leave the environment, run `deactivate`.
|
|
39
|
+
|
|
40
|
+
## Commands
|
|
41
|
+
|
|
42
|
+
| Command | Purpose |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `task add "Write report"` | Add a task |
|
|
45
|
+
| `task list` or `task ls` | List To do tasks |
|
|
46
|
+
| `task list --done` | List completed tasks |
|
|
47
|
+
| `task list --undone` | List To do tasks |
|
|
48
|
+
| `task list --all` | List every task |
|
|
49
|
+
| `task done 1` | Complete task 1 |
|
|
50
|
+
| `task undone 1` | Make task 1 pending |
|
|
51
|
+
| `task delete 1` | Delete task 1 |
|
|
52
|
+
| `task update 1 "New title"` | Change task 1's title |
|
|
53
|
+
| `task show 1` | Show task 1's details |
|
|
54
|
+
| `task clear` | Delete completed tasks |
|
|
55
|
+
| `task stats` | Show progress and a 7-day completion chart |
|
|
56
|
+
| `task demo` | Try 26 sample tasks in a temporary workspace |
|
|
57
|
+
| `task help` | Show all commands |
|
|
58
|
+
|
|
59
|
+
Also available: `task --help`, `task --version`, and `task <command> --help` (for example, `task add --help`). IDs are positive integers. After deletion or a status change, tasks are renumbered from 1, with To do tasks first. Use `list --all` to see current IDs. Existing task files are normalized when read; new IDs are saved on the next change. Titles cannot be blank.
|
|
60
|
+
|
|
61
|
+
## Try it with sample data
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
task demo
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or run `python test_task.py` from the project directory. Both open a separate
|
|
68
|
+
session with 8 pending and 18 completed tasks spread across the last week.
|
|
69
|
+
Try `ls`, `ls --done`, `done 1`, then `stats`. Type `/exit` to leave.
|
|
70
|
+
Demo changes are discarded; your own tasks stay untouched.
|
|
71
|
+
`task demo --preview` prints the sample list and chart without opening a prompt.
|
|
72
|
+
|
|
73
|
+
## Progress
|
|
74
|
+
|
|
75
|
+
`stats` shows task counts, completion percentage, and a daily chart:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
Progress ━━━━━━━━━━━━━━────── 69%
|
|
79
|
+
|
|
80
|
+
This week · completed tasks
|
|
81
|
+
|
|
82
|
+
Tue 06 ━━━━ 1
|
|
83
|
+
Wed 07 ━━━━━━━━━━━━ 3
|
|
84
|
+
Thu 08 ━━━━━━━━ 2
|
|
85
|
+
Fri 09 ━━━━━━━━━━━━━━━━ 4
|
|
86
|
+
Sat 10 ━━━━ 1
|
|
87
|
+
Sun 11 ━━━━━━━━━━━━ 3
|
|
88
|
+
Mon 12 ━━━━━━━━━━━━━━━━ 4
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Dates follow your local timezone. `done` records the completion time; `undone`
|
|
92
|
+
removes it. The chart counts tasks still in the file, so deleting completed tasks
|
|
93
|
+
also removes them from the chart. Older tasks without a completion date still
|
|
94
|
+
count toward the total, but not the daily chart.
|
|
95
|
+
|
|
96
|
+
## Project structure
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
src/task_manager/
|
|
100
|
+
cli.py Entry point: one command or interactive mode
|
|
101
|
+
arguments.py Command names, flags, and ls alias
|
|
102
|
+
commands.py Add, edit, complete, delete, list
|
|
103
|
+
storage.py JSON file, validation, task IDs
|
|
104
|
+
productivity.py Weekly counts and progress
|
|
105
|
+
input.py Parse commands typed at the prompt
|
|
106
|
+
interactive.py Input loop and command history
|
|
107
|
+
demo.py Sample tasks and temporary workspace
|
|
108
|
+
ui/
|
|
109
|
+
theme.py Colors and terminal sizing
|
|
110
|
+
animation.py Startup and result transitions
|
|
111
|
+
views.py Welcome screen, help, and task list
|
|
112
|
+
tests/ CLI, interactive, demo, and productivity tests
|
|
113
|
+
test_task.py Start the demo from the project directory
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
A command goes through `cli → arguments → commands → storage`.
|
|
117
|
+
Interactive mode adds `input` and `ui`; both modes use the same commands.
|
|
118
|
+
No runtime dependencies. Set `TASK_MANAGER_NO_ANIMATION=1` to disable motion,
|
|
119
|
+
or `NO_COLOR=1` for plain output. Redirected output has no colors or animation.
|
|
120
|
+
|
|
121
|
+
## Where tasks are stored
|
|
122
|
+
|
|
123
|
+
The file is `tasks.json` in `~/Library/Application Support/task-manager/` on macOS, `%APPDATA%\task-manager\` on Windows, or `${XDG_DATA_HOME:-~/.local/share}/task-manager/` on Linux. It is created when a command saves tasks. A missing or empty file means no tasks. If JSON is corrupted, the command reports an error and leaves the file intact.
|
|
124
|
+
|
|
125
|
+
## Run tests
|
|
126
|
+
|
|
127
|
+
With the virtual environment active, install pytest separately for development:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
python -m pip install pytest
|
|
131
|
+
python -m pytest
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Tests set `TASK_MANAGER_DATA_DIR` to a temporary directory. Your real task data is never cleared by the test suite.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
## Install
|
|
2
|
+
|
|
3
|
+
From the project directory, on macOS or Linux:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
python3 -m venv .venv
|
|
7
|
+
source .venv/bin/activate
|
|
8
|
+
python -m pip install -e .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
On Windows PowerShell:
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
py -m venv .venv
|
|
15
|
+
.venv\Scripts\Activate.ps1
|
|
16
|
+
python -m pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
After activation, run `task` to open the interactive terminal view.
|
|
20
|
+
Enter commands at the `❯` prompt, for example `add Write report`, `ls`, or `/help`.
|
|
21
|
+
`list` and `ls` are the same command. `list` shows To do tasks, `list --done` shows completed tasks, and `list --all` shows both.
|
|
22
|
+
Titles may contain spaces without quotes. `clear` and `cls` clear the interactive screen;
|
|
23
|
+
`clear-completed` removes completed tasks. Type `task` at the prompt to show the welcome view again.
|
|
24
|
+
|
|
25
|
+
Tab completes commands and the arrow keys recall history on terminals with readline.
|
|
26
|
+
The welcome screen shows your next task and a small activity chart.
|
|
27
|
+
|
|
28
|
+
You can also run single commands directly, such as:
|
|
29
|
+
`task add "Write report"` or `task --help`.
|
|
30
|
+
|
|
31
|
+
To leave the environment, run `deactivate`.
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
| Command | Purpose |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| `task add "Write report"` | Add a task |
|
|
38
|
+
| `task list` or `task ls` | List To do tasks |
|
|
39
|
+
| `task list --done` | List completed tasks |
|
|
40
|
+
| `task list --undone` | List To do tasks |
|
|
41
|
+
| `task list --all` | List every task |
|
|
42
|
+
| `task done 1` | Complete task 1 |
|
|
43
|
+
| `task undone 1` | Make task 1 pending |
|
|
44
|
+
| `task delete 1` | Delete task 1 |
|
|
45
|
+
| `task update 1 "New title"` | Change task 1's title |
|
|
46
|
+
| `task show 1` | Show task 1's details |
|
|
47
|
+
| `task clear` | Delete completed tasks |
|
|
48
|
+
| `task stats` | Show progress and a 7-day completion chart |
|
|
49
|
+
| `task demo` | Try 26 sample tasks in a temporary workspace |
|
|
50
|
+
| `task help` | Show all commands |
|
|
51
|
+
|
|
52
|
+
Also available: `task --help`, `task --version`, and `task <command> --help` (for example, `task add --help`). IDs are positive integers. After deletion or a status change, tasks are renumbered from 1, with To do tasks first. Use `list --all` to see current IDs. Existing task files are normalized when read; new IDs are saved on the next change. Titles cannot be blank.
|
|
53
|
+
|
|
54
|
+
## Try it with sample data
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
task demo
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or run `python test_task.py` from the project directory. Both open a separate
|
|
61
|
+
session with 8 pending and 18 completed tasks spread across the last week.
|
|
62
|
+
Try `ls`, `ls --done`, `done 1`, then `stats`. Type `/exit` to leave.
|
|
63
|
+
Demo changes are discarded; your own tasks stay untouched.
|
|
64
|
+
`task demo --preview` prints the sample list and chart without opening a prompt.
|
|
65
|
+
|
|
66
|
+
## Progress
|
|
67
|
+
|
|
68
|
+
`stats` shows task counts, completion percentage, and a daily chart:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
Progress ━━━━━━━━━━━━━━────── 69%
|
|
72
|
+
|
|
73
|
+
This week · completed tasks
|
|
74
|
+
|
|
75
|
+
Tue 06 ━━━━ 1
|
|
76
|
+
Wed 07 ━━━━━━━━━━━━ 3
|
|
77
|
+
Thu 08 ━━━━━━━━ 2
|
|
78
|
+
Fri 09 ━━━━━━━━━━━━━━━━ 4
|
|
79
|
+
Sat 10 ━━━━ 1
|
|
80
|
+
Sun 11 ━━━━━━━━━━━━ 3
|
|
81
|
+
Mon 12 ━━━━━━━━━━━━━━━━ 4
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Dates follow your local timezone. `done` records the completion time; `undone`
|
|
85
|
+
removes it. The chart counts tasks still in the file, so deleting completed tasks
|
|
86
|
+
also removes them from the chart. Older tasks without a completion date still
|
|
87
|
+
count toward the total, but not the daily chart.
|
|
88
|
+
|
|
89
|
+
## Project structure
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
src/task_manager/
|
|
93
|
+
cli.py Entry point: one command or interactive mode
|
|
94
|
+
arguments.py Command names, flags, and ls alias
|
|
95
|
+
commands.py Add, edit, complete, delete, list
|
|
96
|
+
storage.py JSON file, validation, task IDs
|
|
97
|
+
productivity.py Weekly counts and progress
|
|
98
|
+
input.py Parse commands typed at the prompt
|
|
99
|
+
interactive.py Input loop and command history
|
|
100
|
+
demo.py Sample tasks and temporary workspace
|
|
101
|
+
ui/
|
|
102
|
+
theme.py Colors and terminal sizing
|
|
103
|
+
animation.py Startup and result transitions
|
|
104
|
+
views.py Welcome screen, help, and task list
|
|
105
|
+
tests/ CLI, interactive, demo, and productivity tests
|
|
106
|
+
test_task.py Start the demo from the project directory
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
A command goes through `cli → arguments → commands → storage`.
|
|
110
|
+
Interactive mode adds `input` and `ui`; both modes use the same commands.
|
|
111
|
+
No runtime dependencies. Set `TASK_MANAGER_NO_ANIMATION=1` to disable motion,
|
|
112
|
+
or `NO_COLOR=1` for plain output. Redirected output has no colors or animation.
|
|
113
|
+
|
|
114
|
+
## Where tasks are stored
|
|
115
|
+
|
|
116
|
+
The file is `tasks.json` in `~/Library/Application Support/task-manager/` on macOS, `%APPDATA%\task-manager\` on Windows, or `${XDG_DATA_HOME:-~/.local/share}/task-manager/` on Linux. It is created when a command saves tasks. A missing or empty file means no tasks. If JSON is corrupted, the command reports an error and leaves the file intact.
|
|
117
|
+
|
|
118
|
+
## Run tests
|
|
119
|
+
|
|
120
|
+
With the virtual environment active, install pytest separately for development:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
python -m pip install pytest
|
|
124
|
+
python -m pytest
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Tests set `TASK_MANAGER_DATA_DIR` to a temporary directory. Your real task data is never cleared by the test suite.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "student-task-manager-cli"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A simple command-line task manager"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = []
|
|
12
|
+
|
|
13
|
+
[project.scripts]
|
|
14
|
+
task = "task_manager.cli:main"
|
|
15
|
+
|
|
16
|
+
[tool.setuptools.packages.find]
|
|
17
|
+
where = ["src"]
|
|
18
|
+
|
|
19
|
+
[tool.pytest.ini_options]
|
|
20
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: student-task-manager-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A simple command-line task manager
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
From the project directory, on macOS or Linux:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
python3 -m venv .venv
|
|
14
|
+
source .venv/bin/activate
|
|
15
|
+
python -m pip install -e .
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
On Windows PowerShell:
|
|
19
|
+
|
|
20
|
+
```powershell
|
|
21
|
+
py -m venv .venv
|
|
22
|
+
.venv\Scripts\Activate.ps1
|
|
23
|
+
python -m pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
After activation, run `task` to open the interactive terminal view.
|
|
27
|
+
Enter commands at the `❯` prompt, for example `add Write report`, `ls`, or `/help`.
|
|
28
|
+
`list` and `ls` are the same command. `list` shows To do tasks, `list --done` shows completed tasks, and `list --all` shows both.
|
|
29
|
+
Titles may contain spaces without quotes. `clear` and `cls` clear the interactive screen;
|
|
30
|
+
`clear-completed` removes completed tasks. Type `task` at the prompt to show the welcome view again.
|
|
31
|
+
|
|
32
|
+
Tab completes commands and the arrow keys recall history on terminals with readline.
|
|
33
|
+
The welcome screen shows your next task and a small activity chart.
|
|
34
|
+
|
|
35
|
+
You can also run single commands directly, such as:
|
|
36
|
+
`task add "Write report"` or `task --help`.
|
|
37
|
+
|
|
38
|
+
To leave the environment, run `deactivate`.
|
|
39
|
+
|
|
40
|
+
## Commands
|
|
41
|
+
|
|
42
|
+
| Command | Purpose |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `task add "Write report"` | Add a task |
|
|
45
|
+
| `task list` or `task ls` | List To do tasks |
|
|
46
|
+
| `task list --done` | List completed tasks |
|
|
47
|
+
| `task list --undone` | List To do tasks |
|
|
48
|
+
| `task list --all` | List every task |
|
|
49
|
+
| `task done 1` | Complete task 1 |
|
|
50
|
+
| `task undone 1` | Make task 1 pending |
|
|
51
|
+
| `task delete 1` | Delete task 1 |
|
|
52
|
+
| `task update 1 "New title"` | Change task 1's title |
|
|
53
|
+
| `task show 1` | Show task 1's details |
|
|
54
|
+
| `task clear` | Delete completed tasks |
|
|
55
|
+
| `task stats` | Show progress and a 7-day completion chart |
|
|
56
|
+
| `task demo` | Try 26 sample tasks in a temporary workspace |
|
|
57
|
+
| `task help` | Show all commands |
|
|
58
|
+
|
|
59
|
+
Also available: `task --help`, `task --version`, and `task <command> --help` (for example, `task add --help`). IDs are positive integers. After deletion or a status change, tasks are renumbered from 1, with To do tasks first. Use `list --all` to see current IDs. Existing task files are normalized when read; new IDs are saved on the next change. Titles cannot be blank.
|
|
60
|
+
|
|
61
|
+
## Try it with sample data
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
task demo
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or run `python test_task.py` from the project directory. Both open a separate
|
|
68
|
+
session with 8 pending and 18 completed tasks spread across the last week.
|
|
69
|
+
Try `ls`, `ls --done`, `done 1`, then `stats`. Type `/exit` to leave.
|
|
70
|
+
Demo changes are discarded; your own tasks stay untouched.
|
|
71
|
+
`task demo --preview` prints the sample list and chart without opening a prompt.
|
|
72
|
+
|
|
73
|
+
## Progress
|
|
74
|
+
|
|
75
|
+
`stats` shows task counts, completion percentage, and a daily chart:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
Progress ━━━━━━━━━━━━━━────── 69%
|
|
79
|
+
|
|
80
|
+
This week · completed tasks
|
|
81
|
+
|
|
82
|
+
Tue 06 ━━━━ 1
|
|
83
|
+
Wed 07 ━━━━━━━━━━━━ 3
|
|
84
|
+
Thu 08 ━━━━━━━━ 2
|
|
85
|
+
Fri 09 ━━━━━━━━━━━━━━━━ 4
|
|
86
|
+
Sat 10 ━━━━ 1
|
|
87
|
+
Sun 11 ━━━━━━━━━━━━ 3
|
|
88
|
+
Mon 12 ━━━━━━━━━━━━━━━━ 4
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Dates follow your local timezone. `done` records the completion time; `undone`
|
|
92
|
+
removes it. The chart counts tasks still in the file, so deleting completed tasks
|
|
93
|
+
also removes them from the chart. Older tasks without a completion date still
|
|
94
|
+
count toward the total, but not the daily chart.
|
|
95
|
+
|
|
96
|
+
## Project structure
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
src/task_manager/
|
|
100
|
+
cli.py Entry point: one command or interactive mode
|
|
101
|
+
arguments.py Command names, flags, and ls alias
|
|
102
|
+
commands.py Add, edit, complete, delete, list
|
|
103
|
+
storage.py JSON file, validation, task IDs
|
|
104
|
+
productivity.py Weekly counts and progress
|
|
105
|
+
input.py Parse commands typed at the prompt
|
|
106
|
+
interactive.py Input loop and command history
|
|
107
|
+
demo.py Sample tasks and temporary workspace
|
|
108
|
+
ui/
|
|
109
|
+
theme.py Colors and terminal sizing
|
|
110
|
+
animation.py Startup and result transitions
|
|
111
|
+
views.py Welcome screen, help, and task list
|
|
112
|
+
tests/ CLI, interactive, demo, and productivity tests
|
|
113
|
+
test_task.py Start the demo from the project directory
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
A command goes through `cli → arguments → commands → storage`.
|
|
117
|
+
Interactive mode adds `input` and `ui`; both modes use the same commands.
|
|
118
|
+
No runtime dependencies. Set `TASK_MANAGER_NO_ANIMATION=1` to disable motion,
|
|
119
|
+
or `NO_COLOR=1` for plain output. Redirected output has no colors or animation.
|
|
120
|
+
|
|
121
|
+
## Where tasks are stored
|
|
122
|
+
|
|
123
|
+
The file is `tasks.json` in `~/Library/Application Support/task-manager/` on macOS, `%APPDATA%\task-manager\` on Windows, or `${XDG_DATA_HOME:-~/.local/share}/task-manager/` on Linux. It is created when a command saves tasks. A missing or empty file means no tasks. If JSON is corrupted, the command reports an error and leaves the file intact.
|
|
124
|
+
|
|
125
|
+
## Run tests
|
|
126
|
+
|
|
127
|
+
With the virtual environment active, install pytest separately for development:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
python -m pip install pytest
|
|
131
|
+
python -m pytest
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Tests set `TASK_MANAGER_DATA_DIR` to a temporary directory. Your real task data is never cleared by the test suite.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/student_task_manager_cli.egg-info/PKG-INFO
|
|
4
|
+
src/student_task_manager_cli.egg-info/SOURCES.txt
|
|
5
|
+
src/student_task_manager_cli.egg-info/dependency_links.txt
|
|
6
|
+
src/student_task_manager_cli.egg-info/entry_points.txt
|
|
7
|
+
src/student_task_manager_cli.egg-info/top_level.txt
|
|
8
|
+
src/task_manager/__init__.py
|
|
9
|
+
src/task_manager/__main__.py
|
|
10
|
+
src/task_manager/arguments.py
|
|
11
|
+
src/task_manager/cli.py
|
|
12
|
+
src/task_manager/commands.py
|
|
13
|
+
src/task_manager/demo.py
|
|
14
|
+
src/task_manager/input.py
|
|
15
|
+
src/task_manager/interactive.py
|
|
16
|
+
src/task_manager/productivity.py
|
|
17
|
+
src/task_manager/storage.py
|
|
18
|
+
src/task_manager/ui/__init__.py
|
|
19
|
+
src/task_manager/ui/animation.py
|
|
20
|
+
src/task_manager/ui/theme.py
|
|
21
|
+
src/task_manager/ui/views.py
|
|
22
|
+
tests/test_demo.py
|
|
23
|
+
tests/test_interactive.py
|
|
24
|
+
tests/test_productivity.py
|
|
25
|
+
tests/test_tasks.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
task_manager
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
|
|
3
|
+
from . import __version__
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def positive_id(value: str) -> int:
|
|
7
|
+
try:
|
|
8
|
+
task_id = int(value)
|
|
9
|
+
except ValueError as error:
|
|
10
|
+
raise argparse.ArgumentTypeError("task ID must be a positive number") from error
|
|
11
|
+
if task_id < 1:
|
|
12
|
+
raise argparse.ArgumentTypeError("task ID must be a positive number")
|
|
13
|
+
return task_id
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def parser_for_cli() -> argparse.ArgumentParser:
|
|
17
|
+
parser = argparse.ArgumentParser(prog="task", description="Manage your tasks.")
|
|
18
|
+
parser.add_argument("--version", action="version", version=f"task {__version__}")
|
|
19
|
+
commands = parser.add_subparsers(dest="command", required=True)
|
|
20
|
+
descriptions = {
|
|
21
|
+
"add": "Add a new task",
|
|
22
|
+
"list": "List pending tasks (or filter by status)",
|
|
23
|
+
"done": "Mark a task as completed",
|
|
24
|
+
"undone": "Mark a task as pending",
|
|
25
|
+
"delete": "Delete a task",
|
|
26
|
+
"update": "Change a task title",
|
|
27
|
+
"show": "Show task details",
|
|
28
|
+
"clear": "Delete completed tasks",
|
|
29
|
+
"stats": "Show weekly productivity",
|
|
30
|
+
"demo": "Open a session with sample tasks",
|
|
31
|
+
"help": "Show all commands",
|
|
32
|
+
}
|
|
33
|
+
for name, description in descriptions.items():
|
|
34
|
+
command = commands.add_parser(
|
|
35
|
+
name, aliases=["ls"] if name == "list" else [],
|
|
36
|
+
help=description, description=description,
|
|
37
|
+
)
|
|
38
|
+
command.set_defaults(command=name)
|
|
39
|
+
if name in ("done", "undone", "delete", "update", "show"):
|
|
40
|
+
command.add_argument("id", type=positive_id, help="positive task ID")
|
|
41
|
+
if name in ("add", "update"):
|
|
42
|
+
command.add_argument("title", help="task title")
|
|
43
|
+
if name == "demo":
|
|
44
|
+
command.add_argument("--preview", action="store_true", help="print the demo and exit")
|
|
45
|
+
if name == "list":
|
|
46
|
+
filters = command.add_mutually_exclusive_group()
|
|
47
|
+
filters.add_argument("--done", action="store_true", help="show completed tasks")
|
|
48
|
+
filters.add_argument("--undone", action="store_true", help="show pending tasks")
|
|
49
|
+
filters.add_argument("--all", action="store_true", help="show every task")
|
|
50
|
+
return parser
|
|
51
|
+
|
|
52
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from .arguments import parser_for_cli
|
|
4
|
+
from .commands import execute
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main(argv: list[str] | None = None) -> int:
|
|
8
|
+
argv = sys.argv[1:] if argv is None else argv
|
|
9
|
+
if not argv:
|
|
10
|
+
from .interactive import run_interactive
|
|
11
|
+
|
|
12
|
+
return run_interactive(main)
|
|
13
|
+
parser = parser_for_cli()
|
|
14
|
+
args = parser.parse_args(argv)
|
|
15
|
+
if args.command == "help":
|
|
16
|
+
parser.print_help()
|
|
17
|
+
return 0
|
|
18
|
+
if args.command == "demo":
|
|
19
|
+
from .demo import run_demo
|
|
20
|
+
|
|
21
|
+
return run_demo(preview=args.preview)
|
|
22
|
+
return execute(args)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
|
|
4
|
+
from .productivity import format_stats
|
|
5
|
+
from .storage import StorageError, load_data, save_data
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def execute(args) -> int:
|
|
9
|
+
if args.command in ("add", "update"):
|
|
10
|
+
title = args.title.strip()
|
|
11
|
+
if not title:
|
|
12
|
+
print("Error: task title cannot be empty.", file=sys.stderr)
|
|
13
|
+
return 1
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
data = load_data()
|
|
17
|
+
tasks = data["tasks"]
|
|
18
|
+
|
|
19
|
+
if args.command == "add":
|
|
20
|
+
task = {
|
|
21
|
+
"id": data["next_id"],
|
|
22
|
+
"title": title,
|
|
23
|
+
"status": "pending",
|
|
24
|
+
"created_at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
|
25
|
+
}
|
|
26
|
+
tasks.append(task)
|
|
27
|
+
save_data(data)
|
|
28
|
+
print(f"Added task {task['id']}: {title}")
|
|
29
|
+
elif args.command == "list":
|
|
30
|
+
visible = [task for task in tasks if args.all or task["status"] == ("completed" if args.done else "pending")]
|
|
31
|
+
if not visible:
|
|
32
|
+
print("No tasks yet." if not tasks else "No completed tasks." if args.done else "No pending tasks.")
|
|
33
|
+
for task in visible:
|
|
34
|
+
print(f"{task['id']}. [{task['status']}] {task['title']}")
|
|
35
|
+
elif args.command == "stats":
|
|
36
|
+
print(format_stats(tasks))
|
|
37
|
+
elif args.command == "clear":
|
|
38
|
+
remaining = [task for task in tasks if task["status"] != "completed"]
|
|
39
|
+
removed = len(tasks) - len(remaining)
|
|
40
|
+
data["tasks"] = remaining
|
|
41
|
+
save_data(data)
|
|
42
|
+
print(f"Removed {removed} completed task(s).")
|
|
43
|
+
else:
|
|
44
|
+
task = next((task for task in tasks if task["id"] == args.id), None)
|
|
45
|
+
if task is None:
|
|
46
|
+
print(f"Error: task {args.id} not found.", file=sys.stderr)
|
|
47
|
+
return 1
|
|
48
|
+
if args.command == "show":
|
|
49
|
+
print(f"ID: {task['id']}\nTitle: {task['title']}\nStatus: {task['status']}\nCreated: {task['created_at']}")
|
|
50
|
+
if task.get("completed_at"):
|
|
51
|
+
print(f"Completed: {task['completed_at']}")
|
|
52
|
+
elif args.command == "delete":
|
|
53
|
+
tasks.remove(task)
|
|
54
|
+
save_data(data)
|
|
55
|
+
print(f"Deleted task {args.id}.")
|
|
56
|
+
else:
|
|
57
|
+
if args.command == "update":
|
|
58
|
+
task["title"] = title
|
|
59
|
+
else:
|
|
60
|
+
if args.command == "done" and task["status"] != "completed":
|
|
61
|
+
task["completed_at"] = datetime.now(timezone.utc).isoformat(timespec="seconds")
|
|
62
|
+
elif args.command == "undone":
|
|
63
|
+
task.pop("completed_at", None)
|
|
64
|
+
task["status"] = "completed" if args.command == "done" else "pending"
|
|
65
|
+
save_data(data)
|
|
66
|
+
if args.command == "done":
|
|
67
|
+
print(f"Completed: {task['title']}")
|
|
68
|
+
elif args.command == "undone":
|
|
69
|
+
print(f"Back to To do: {task['title']}")
|
|
70
|
+
else:
|
|
71
|
+
print(f"Renamed task {task['id']}: {task['title']}")
|
|
72
|
+
except StorageError as error:
|
|
73
|
+
print(f"Error: {error}", file=sys.stderr)
|
|
74
|
+
return 1
|
|
75
|
+
return 0
|