e3cli 0.3.2__tar.gz → 0.4.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.
- e3cli-0.4.0/CLAUDE.md +41 -0
- e3cli-0.4.0/PKG-INFO +346 -0
- e3cli-0.4.0/README.md +312 -0
- e3cli-0.4.0/README_zh-TW.md +312 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/__init__.py +1 -1
- e3cli-0.4.0/e3cli/agent_prompt.md +132 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/api/courses.py +6 -13
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/cli.py +2 -0
- e3cli-0.4.0/e3cli/commands/courses.py +63 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/download.py +72 -31
- e3cli-0.4.0/e3cli/commands/interactive.py +589 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/sync.py +56 -6
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/i18n.py +52 -0
- e3cli-0.4.0/e3cli/semester.py +93 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/pyproject.toml +1 -1
- e3cli-0.3.2/PKG-INFO +0 -369
- e3cli-0.3.2/README.md +0 -335
- e3cli-0.3.2/e3cli/commands/courses.py +0 -39
- {e3cli-0.3.2 → e3cli-0.4.0}/.github/workflows/ci.yml +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/.github/workflows/release.yml +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/.gitignore +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/Formula/e3cli.rb +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/LICENSE +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/Makefile +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/__main__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/ai/__init__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/api/__init__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/api/assignments.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/api/client.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/api/files.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/api/site.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/auth.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/__init__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/_common.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/assignments.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/login.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/logout.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/schedule.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/setup.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/commands/submit.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/config.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/credential.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/scheduler/__init__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/scheduler/cron.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/storage/__init__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/storage/db.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/storage/models.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/e3cli/storage/tracking.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/tests/__init__.py +0 -0
- {e3cli-0.3.2 → e3cli-0.4.0}/tests/test_basic.py +0 -0
e3cli-0.4.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# E3CLI — Claude Code Integration
|
|
2
|
+
|
|
3
|
+
## What is this?
|
|
4
|
+
|
|
5
|
+
e3cli is a CLI tool for NYCU's E3 Moodle platform. It can sync courses, download materials, check assignments, and submit homework.
|
|
6
|
+
|
|
7
|
+
## How to use e3cli in this project
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Check for new assignments
|
|
11
|
+
e3cli sync
|
|
12
|
+
|
|
13
|
+
# List upcoming assignments
|
|
14
|
+
e3cli assignments --due-soon 7
|
|
15
|
+
|
|
16
|
+
# Download course materials
|
|
17
|
+
e3cli download --course "COURSE_NAME"
|
|
18
|
+
|
|
19
|
+
# Submit completed assignment
|
|
20
|
+
e3cli submit <ASSIGNMENT_ID> <FILE_PATH>
|
|
21
|
+
|
|
22
|
+
# Interactive mode
|
|
23
|
+
e3cli i
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## When a new assignment is detected
|
|
27
|
+
|
|
28
|
+
1. Run `e3cli sync` to pull latest data
|
|
29
|
+
2. Run `e3cli assignments` to see what's new
|
|
30
|
+
3. Check `~/e3-downloads/` for assignment descriptions
|
|
31
|
+
4. **Always confirm with the user before submitting**
|
|
32
|
+
|
|
33
|
+
## Token expired?
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
e3cli login --refresh
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Full agent instructions
|
|
40
|
+
|
|
41
|
+
See `e3cli/agent_prompt.md` for detailed automation workflow.
|
e3cli-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: e3cli
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: NYCU E3 Moodle automation CLI — sync courses, download materials, submit assignments.
|
|
5
|
+
Project-URL: Homepage, https://github.com/junlinwk/e3cli
|
|
6
|
+
Project-URL: Repository, https://github.com/junlinwk/e3cli
|
|
7
|
+
Project-URL: Issues, https://github.com/junlinwk/e3cli/issues
|
|
8
|
+
Author: E3CLI Contributors
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: automation,cli,e3,moodle,nycu
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Education
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: MacOS
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Education
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: requests>=2.31
|
|
24
|
+
Requires-Dist: rich>=13.0
|
|
25
|
+
Requires-Dist: typer>=0.9
|
|
26
|
+
Provides-Extra: ai
|
|
27
|
+
Requires-Dist: anthropic>=0.18; extra == 'ai'
|
|
28
|
+
Requires-Dist: pymupdf>=1.23; extra == 'ai'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://img.shields.io/badge/python-3.11+-blue?logo=python&logoColor=white" alt="Python">
|
|
37
|
+
<img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey?logo=apple&logoColor=white" alt="Platform">
|
|
38
|
+
<img src="https://img.shields.io/github/license/junlinwk/e3cli?color=green" alt="License">
|
|
39
|
+
<img src="https://img.shields.io/github/v/tag/junlinwk/e3cli?label=version&color=orange" alt="Version">
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<h1 align="center">e3cli</h1>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<b>NYCU E3 Moodle automation CLI</b><br>
|
|
46
|
+
Sync courses, download materials, submit assignments — all from your terminal.
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<a href="#installation">Install</a> •
|
|
51
|
+
<a href="#quick-start">Quick Start</a> •
|
|
52
|
+
<a href="#commands">Commands</a> •
|
|
53
|
+
<a href="#security">Security</a> •
|
|
54
|
+
<a href="./README_zh-TW.md">繁體中文</a>
|
|
55
|
+
</p>
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
> **Intended use:** Finished your homework? Too lazy to open the browser? Submit it from CLI.
|
|
60
|
+
>
|
|
61
|
+
> ~~**Unintended use:** Let Claude Code auto-pull new assignments, finish them, and upload. (Please don't.)~~
|
|
62
|
+
|
|
63
|
+
## Features
|
|
64
|
+
|
|
65
|
+
- **Login** — Moodle Web Service API authentication with encrypted credential storage
|
|
66
|
+
- **Courses** — List all enrolled courses
|
|
67
|
+
- **Assignments** — View assignments, deadlines, and submission status
|
|
68
|
+
- **Download** — Batch download course materials, skip already-downloaded files
|
|
69
|
+
- **Submit** — Upload and submit assignments directly from CLI
|
|
70
|
+
- **Sync** — One command to pull everything new (materials + assignment status)
|
|
71
|
+
- **Schedule** — Cron-based automatic sync
|
|
72
|
+
- **Bilingual** — Full Chinese/English support
|
|
73
|
+
|
|
74
|
+
## Supported Platforms
|
|
75
|
+
|
|
76
|
+
| Platform | Architecture | Status |
|
|
77
|
+
|----------|-------------|--------|
|
|
78
|
+
| macOS | Apple Silicon (ARM64) | :white_check_mark: Supported |
|
|
79
|
+
| macOS | Intel (x86_64) | :white_check_mark: Supported |
|
|
80
|
+
| Linux | x86_64 | :white_check_mark: Supported |
|
|
81
|
+
| Linux | ARM64 | :white_check_mark: Supported |
|
|
82
|
+
|
|
83
|
+
Requires **Python 3.11+**.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
### Homebrew (recommended)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
brew tap junlinwk/e3cli
|
|
93
|
+
brew install e3cli
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### pipx
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
pipx install git+https://github.com/junlinwk/e3cli.git
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### pip
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pip install git+https://github.com/junlinwk/e3cli.git
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### From source
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
git clone https://github.com/junlinwk/e3cli.git
|
|
112
|
+
cd e3cli
|
|
113
|
+
pip install -e ".[dev]"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
> After installation, `e3cli` is available as a system-wide command.
|
|
117
|
+
|
|
118
|
+
### Upgrade
|
|
119
|
+
|
|
120
|
+
| Method | Command |
|
|
121
|
+
|--------|---------|
|
|
122
|
+
| Homebrew | `brew update && brew upgrade e3cli` |
|
|
123
|
+
| pipx (GitHub) | `pipx install git+https://github.com/junlinwk/e3cli.git --force` |
|
|
124
|
+
| pipx (PyPI) | `pipx upgrade e3cli` |
|
|
125
|
+
| pip (PyPI) | `pip install e3cli --upgrade` |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Quick Start
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# 1. Login (first time — interactive setup wizard will guide you)
|
|
133
|
+
e3cli login --save
|
|
134
|
+
|
|
135
|
+
# 2. List your courses
|
|
136
|
+
e3cli courses
|
|
137
|
+
|
|
138
|
+
# 3. Download all course materials
|
|
139
|
+
e3cli download --all
|
|
140
|
+
|
|
141
|
+
# 4. Check assignments and deadlines
|
|
142
|
+
e3cli assignments
|
|
143
|
+
|
|
144
|
+
# 5. Submit an assignment
|
|
145
|
+
e3cli submit <assignment-id> homework.pdf
|
|
146
|
+
|
|
147
|
+
# 6. Enable automatic sync (every hour)
|
|
148
|
+
e3cli schedule enable
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Commands
|
|
154
|
+
|
|
155
|
+
### `e3cli login`
|
|
156
|
+
|
|
157
|
+
Authenticate with your Moodle account and store the API token.
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
e3cli login # Interactive prompt
|
|
161
|
+
e3cli login -u <student-id> # Specify username
|
|
162
|
+
e3cli login --save # Save credentials (encrypted) for auto-refresh
|
|
163
|
+
e3cli login --refresh # Re-authenticate using saved credentials
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### `e3cli logout`
|
|
167
|
+
|
|
168
|
+
Securely erase all stored credentials and tokens.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
e3cli logout
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### `e3cli courses`
|
|
175
|
+
|
|
176
|
+
List all enrolled courses in a formatted table.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
e3cli courses
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### `e3cli assignments`
|
|
183
|
+
|
|
184
|
+
View assignments with deadlines and submission status.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
e3cli assignments # All assignments
|
|
188
|
+
e3cli assignments --due-soon 7 # Due within 7 days
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `e3cli download`
|
|
192
|
+
|
|
193
|
+
Download course materials to local disk.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
e3cli download --all # All courses
|
|
197
|
+
e3cli download --course "OS" # Filter by course name/code
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Files are saved to `~/e3-downloads/<course>/<section>/` by default. Already-downloaded files are skipped automatically (tracked via SQLite).
|
|
201
|
+
|
|
202
|
+
### `e3cli submit`
|
|
203
|
+
|
|
204
|
+
Upload and submit an assignment.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
e3cli submit <assignment-id> file1.pdf file2.zip
|
|
208
|
+
e3cli submit <assignment-id> report.pdf --text "Some notes"
|
|
209
|
+
e3cli submit <assignment-id> late-hw.pdf --force # Submit past deadline
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `e3cli sync`
|
|
213
|
+
|
|
214
|
+
Pull all new materials and update assignment status in one command.
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
e3cli sync # Interactive output
|
|
218
|
+
e3cli sync --quiet # Silent mode (for cron)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### `e3cli schedule`
|
|
222
|
+
|
|
223
|
+
Manage automatic sync via system crontab.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
e3cli schedule enable # Default: every 60 minutes
|
|
227
|
+
e3cli schedule enable --interval 30 # Every 30 minutes
|
|
228
|
+
e3cli schedule disable # Remove cron job
|
|
229
|
+
e3cli schedule status # Show current schedule
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### `e3cli setup`
|
|
233
|
+
|
|
234
|
+
Re-run the interactive setup wizard (language, Moodle URL, download directory, login).
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
e3cli setup
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### `e3cli version`
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
e3cli version
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Configuration
|
|
249
|
+
|
|
250
|
+
Config file location: `~/.e3cli/config.toml`
|
|
251
|
+
|
|
252
|
+
```toml
|
|
253
|
+
[moodle]
|
|
254
|
+
url = "https://e3p.nycu.edu.tw"
|
|
255
|
+
service = "moodle_mobile_app"
|
|
256
|
+
|
|
257
|
+
[storage]
|
|
258
|
+
download_dir = "~/e3-downloads"
|
|
259
|
+
|
|
260
|
+
[schedule]
|
|
261
|
+
interval_minutes = 60
|
|
262
|
+
notify = true
|
|
263
|
+
|
|
264
|
+
[general]
|
|
265
|
+
lang = "zh" # "zh" or "en", or omit for auto-detect
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Auto-created with defaults on first run. Edit to customize, or run `e3cli setup` to reconfigure interactively.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Security
|
|
273
|
+
|
|
274
|
+
### Credential Storage
|
|
275
|
+
|
|
276
|
+
e3cli uses **PBKDF2-HMAC-SHA256** key derivation with integrity verification to protect stored credentials:
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
~/.e3cli/
|
|
280
|
+
key # 256-bit random encryption key (chmod 600)
|
|
281
|
+
credentials.enc # Encrypted username + password (chmod 600)
|
|
282
|
+
token # Moodle API token (chmod 600)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
| Measure | Detail |
|
|
286
|
+
|---------|--------|
|
|
287
|
+
| Encryption | PBKDF2-HMAC-SHA256 (100k iterations) + XOR stream cipher |
|
|
288
|
+
| Integrity | HMAC-SHA256 verification on every read |
|
|
289
|
+
| File permissions | `chmod 600` — owner-only read/write |
|
|
290
|
+
| Password input | `getpass` — never appears in shell history or CLI args |
|
|
291
|
+
| Logout | `e3cli logout` overwrites files with zeros before deletion |
|
|
292
|
+
| Key separation | Encryption key and encrypted data stored in separate files |
|
|
293
|
+
|
|
294
|
+
### What's NOT Stored
|
|
295
|
+
|
|
296
|
+
- :x: No plaintext passwords on disk
|
|
297
|
+
- :x: No credentials in `config.toml`
|
|
298
|
+
- :x: No credentials in environment variables
|
|
299
|
+
- :x: No credentials in shell history
|
|
300
|
+
|
|
301
|
+
### Recommendations
|
|
302
|
+
|
|
303
|
+
- Use `e3cli login --save` only on machines you trust
|
|
304
|
+
- Run `e3cli logout` when done on shared machines
|
|
305
|
+
- The `~/.e3cli/` directory is in `.gitignore` — never commit it
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Local Data
|
|
310
|
+
|
|
311
|
+
| Path | Purpose |
|
|
312
|
+
|------|---------|
|
|
313
|
+
| `~/.e3cli/config.toml` | User configuration |
|
|
314
|
+
| `~/.e3cli/token` | Moodle API token (chmod 600) |
|
|
315
|
+
| `~/.e3cli/key` | Encryption key (chmod 600) |
|
|
316
|
+
| `~/.e3cli/credentials.enc` | Encrypted credentials (chmod 600) |
|
|
317
|
+
| `~/.e3cli/data/e3cli.db` | SQLite tracking DB |
|
|
318
|
+
| `~/e3-downloads/` | Downloaded course materials |
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Development
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
git clone https://github.com/junlinwk/e3cli.git
|
|
326
|
+
cd e3cli
|
|
327
|
+
make dev # pip install -e ".[dev]"
|
|
328
|
+
make lint # ruff check
|
|
329
|
+
make test # pytest
|
|
330
|
+
make build # python -m build
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Roadmap
|
|
334
|
+
|
|
335
|
+
- [ ] AI-powered material summarization
|
|
336
|
+
- [ ] AI-assisted assignment drafting
|
|
337
|
+
- [ ] Smart deadline notifications with priority scoring
|
|
338
|
+
- [ ] Desktop notifications (Linux `notify-send`, macOS `osascript`)
|
|
339
|
+
- [ ] Course filtering by semester
|
|
340
|
+
- [ ] Parallel downloads
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
[MIT](./LICENSE)
|
e3cli-0.4.0/README.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://img.shields.io/badge/python-3.11+-blue?logo=python&logoColor=white" alt="Python">
|
|
3
|
+
<img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey?logo=apple&logoColor=white" alt="Platform">
|
|
4
|
+
<img src="https://img.shields.io/github/license/junlinwk/e3cli?color=green" alt="License">
|
|
5
|
+
<img src="https://img.shields.io/github/v/tag/junlinwk/e3cli?label=version&color=orange" alt="Version">
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<h1 align="center">e3cli</h1>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<b>NYCU E3 Moodle automation CLI</b><br>
|
|
12
|
+
Sync courses, download materials, submit assignments — all from your terminal.
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="#installation">Install</a> •
|
|
17
|
+
<a href="#quick-start">Quick Start</a> •
|
|
18
|
+
<a href="#commands">Commands</a> •
|
|
19
|
+
<a href="#security">Security</a> •
|
|
20
|
+
<a href="./README_zh-TW.md">繁體中文</a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
> **Intended use:** Finished your homework? Too lazy to open the browser? Submit it from CLI.
|
|
26
|
+
>
|
|
27
|
+
> ~~**Unintended use:** Let Claude Code auto-pull new assignments, finish them, and upload. (Please don't.)~~
|
|
28
|
+
|
|
29
|
+
## Features
|
|
30
|
+
|
|
31
|
+
- **Login** — Moodle Web Service API authentication with encrypted credential storage
|
|
32
|
+
- **Courses** — List all enrolled courses
|
|
33
|
+
- **Assignments** — View assignments, deadlines, and submission status
|
|
34
|
+
- **Download** — Batch download course materials, skip already-downloaded files
|
|
35
|
+
- **Submit** — Upload and submit assignments directly from CLI
|
|
36
|
+
- **Sync** — One command to pull everything new (materials + assignment status)
|
|
37
|
+
- **Schedule** — Cron-based automatic sync
|
|
38
|
+
- **Bilingual** — Full Chinese/English support
|
|
39
|
+
|
|
40
|
+
## Supported Platforms
|
|
41
|
+
|
|
42
|
+
| Platform | Architecture | Status |
|
|
43
|
+
|----------|-------------|--------|
|
|
44
|
+
| macOS | Apple Silicon (ARM64) | :white_check_mark: Supported |
|
|
45
|
+
| macOS | Intel (x86_64) | :white_check_mark: Supported |
|
|
46
|
+
| Linux | x86_64 | :white_check_mark: Supported |
|
|
47
|
+
| Linux | ARM64 | :white_check_mark: Supported |
|
|
48
|
+
|
|
49
|
+
Requires **Python 3.11+**.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
### Homebrew (recommended)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
brew tap junlinwk/e3cli
|
|
59
|
+
brew install e3cli
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### pipx
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pipx install git+https://github.com/junlinwk/e3cli.git
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### pip
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install git+https://github.com/junlinwk/e3cli.git
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### From source
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/junlinwk/e3cli.git
|
|
78
|
+
cd e3cli
|
|
79
|
+
pip install -e ".[dev]"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
> After installation, `e3cli` is available as a system-wide command.
|
|
83
|
+
|
|
84
|
+
### Upgrade
|
|
85
|
+
|
|
86
|
+
| Method | Command |
|
|
87
|
+
|--------|---------|
|
|
88
|
+
| Homebrew | `brew update && brew upgrade e3cli` |
|
|
89
|
+
| pipx (GitHub) | `pipx install git+https://github.com/junlinwk/e3cli.git --force` |
|
|
90
|
+
| pipx (PyPI) | `pipx upgrade e3cli` |
|
|
91
|
+
| pip (PyPI) | `pip install e3cli --upgrade` |
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Quick Start
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 1. Login (first time — interactive setup wizard will guide you)
|
|
99
|
+
e3cli login --save
|
|
100
|
+
|
|
101
|
+
# 2. List your courses
|
|
102
|
+
e3cli courses
|
|
103
|
+
|
|
104
|
+
# 3. Download all course materials
|
|
105
|
+
e3cli download --all
|
|
106
|
+
|
|
107
|
+
# 4. Check assignments and deadlines
|
|
108
|
+
e3cli assignments
|
|
109
|
+
|
|
110
|
+
# 5. Submit an assignment
|
|
111
|
+
e3cli submit <assignment-id> homework.pdf
|
|
112
|
+
|
|
113
|
+
# 6. Enable automatic sync (every hour)
|
|
114
|
+
e3cli schedule enable
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Commands
|
|
120
|
+
|
|
121
|
+
### `e3cli login`
|
|
122
|
+
|
|
123
|
+
Authenticate with your Moodle account and store the API token.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
e3cli login # Interactive prompt
|
|
127
|
+
e3cli login -u <student-id> # Specify username
|
|
128
|
+
e3cli login --save # Save credentials (encrypted) for auto-refresh
|
|
129
|
+
e3cli login --refresh # Re-authenticate using saved credentials
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `e3cli logout`
|
|
133
|
+
|
|
134
|
+
Securely erase all stored credentials and tokens.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
e3cli logout
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `e3cli courses`
|
|
141
|
+
|
|
142
|
+
List all enrolled courses in a formatted table.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
e3cli courses
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `e3cli assignments`
|
|
149
|
+
|
|
150
|
+
View assignments with deadlines and submission status.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
e3cli assignments # All assignments
|
|
154
|
+
e3cli assignments --due-soon 7 # Due within 7 days
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### `e3cli download`
|
|
158
|
+
|
|
159
|
+
Download course materials to local disk.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
e3cli download --all # All courses
|
|
163
|
+
e3cli download --course "OS" # Filter by course name/code
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Files are saved to `~/e3-downloads/<course>/<section>/` by default. Already-downloaded files are skipped automatically (tracked via SQLite).
|
|
167
|
+
|
|
168
|
+
### `e3cli submit`
|
|
169
|
+
|
|
170
|
+
Upload and submit an assignment.
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
e3cli submit <assignment-id> file1.pdf file2.zip
|
|
174
|
+
e3cli submit <assignment-id> report.pdf --text "Some notes"
|
|
175
|
+
e3cli submit <assignment-id> late-hw.pdf --force # Submit past deadline
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### `e3cli sync`
|
|
179
|
+
|
|
180
|
+
Pull all new materials and update assignment status in one command.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
e3cli sync # Interactive output
|
|
184
|
+
e3cli sync --quiet # Silent mode (for cron)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### `e3cli schedule`
|
|
188
|
+
|
|
189
|
+
Manage automatic sync via system crontab.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
e3cli schedule enable # Default: every 60 minutes
|
|
193
|
+
e3cli schedule enable --interval 30 # Every 30 minutes
|
|
194
|
+
e3cli schedule disable # Remove cron job
|
|
195
|
+
e3cli schedule status # Show current schedule
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### `e3cli setup`
|
|
199
|
+
|
|
200
|
+
Re-run the interactive setup wizard (language, Moodle URL, download directory, login).
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
e3cli setup
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `e3cli version`
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
e3cli version
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Configuration
|
|
215
|
+
|
|
216
|
+
Config file location: `~/.e3cli/config.toml`
|
|
217
|
+
|
|
218
|
+
```toml
|
|
219
|
+
[moodle]
|
|
220
|
+
url = "https://e3p.nycu.edu.tw"
|
|
221
|
+
service = "moodle_mobile_app"
|
|
222
|
+
|
|
223
|
+
[storage]
|
|
224
|
+
download_dir = "~/e3-downloads"
|
|
225
|
+
|
|
226
|
+
[schedule]
|
|
227
|
+
interval_minutes = 60
|
|
228
|
+
notify = true
|
|
229
|
+
|
|
230
|
+
[general]
|
|
231
|
+
lang = "zh" # "zh" or "en", or omit for auto-detect
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Auto-created with defaults on first run. Edit to customize, or run `e3cli setup` to reconfigure interactively.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Security
|
|
239
|
+
|
|
240
|
+
### Credential Storage
|
|
241
|
+
|
|
242
|
+
e3cli uses **PBKDF2-HMAC-SHA256** key derivation with integrity verification to protect stored credentials:
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
~/.e3cli/
|
|
246
|
+
key # 256-bit random encryption key (chmod 600)
|
|
247
|
+
credentials.enc # Encrypted username + password (chmod 600)
|
|
248
|
+
token # Moodle API token (chmod 600)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
| Measure | Detail |
|
|
252
|
+
|---------|--------|
|
|
253
|
+
| Encryption | PBKDF2-HMAC-SHA256 (100k iterations) + XOR stream cipher |
|
|
254
|
+
| Integrity | HMAC-SHA256 verification on every read |
|
|
255
|
+
| File permissions | `chmod 600` — owner-only read/write |
|
|
256
|
+
| Password input | `getpass` — never appears in shell history or CLI args |
|
|
257
|
+
| Logout | `e3cli logout` overwrites files with zeros before deletion |
|
|
258
|
+
| Key separation | Encryption key and encrypted data stored in separate files |
|
|
259
|
+
|
|
260
|
+
### What's NOT Stored
|
|
261
|
+
|
|
262
|
+
- :x: No plaintext passwords on disk
|
|
263
|
+
- :x: No credentials in `config.toml`
|
|
264
|
+
- :x: No credentials in environment variables
|
|
265
|
+
- :x: No credentials in shell history
|
|
266
|
+
|
|
267
|
+
### Recommendations
|
|
268
|
+
|
|
269
|
+
- Use `e3cli login --save` only on machines you trust
|
|
270
|
+
- Run `e3cli logout` when done on shared machines
|
|
271
|
+
- The `~/.e3cli/` directory is in `.gitignore` — never commit it
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Local Data
|
|
276
|
+
|
|
277
|
+
| Path | Purpose |
|
|
278
|
+
|------|---------|
|
|
279
|
+
| `~/.e3cli/config.toml` | User configuration |
|
|
280
|
+
| `~/.e3cli/token` | Moodle API token (chmod 600) |
|
|
281
|
+
| `~/.e3cli/key` | Encryption key (chmod 600) |
|
|
282
|
+
| `~/.e3cli/credentials.enc` | Encrypted credentials (chmod 600) |
|
|
283
|
+
| `~/.e3cli/data/e3cli.db` | SQLite tracking DB |
|
|
284
|
+
| `~/e3-downloads/` | Downloaded course materials |
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Development
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
git clone https://github.com/junlinwk/e3cli.git
|
|
292
|
+
cd e3cli
|
|
293
|
+
make dev # pip install -e ".[dev]"
|
|
294
|
+
make lint # ruff check
|
|
295
|
+
make test # pytest
|
|
296
|
+
make build # python -m build
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Roadmap
|
|
300
|
+
|
|
301
|
+
- [ ] AI-powered material summarization
|
|
302
|
+
- [ ] AI-assisted assignment drafting
|
|
303
|
+
- [ ] Smart deadline notifications with priority scoring
|
|
304
|
+
- [ ] Desktop notifications (Linux `notify-send`, macOS `osascript`)
|
|
305
|
+
- [ ] Course filtering by semester
|
|
306
|
+
- [ ] Parallel downloads
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
[MIT](./LICENSE)
|