htx-cli 0.1.0__py3-none-any.whl
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.
- disk_cli/__init__.py +3 -0
- disk_cli/__main__.py +5 -0
- disk_cli/api.py +368 -0
- disk_cli/cli.py +775 -0
- disk_cli/config.py +67 -0
- htx_cli-0.1.0.dist-info/METADATA +157 -0
- htx_cli-0.1.0.dist-info/RECORD +10 -0
- htx_cli-0.1.0.dist-info/WHEEL +5 -0
- htx_cli-0.1.0.dist-info/entry_points.txt +2 -0
- htx_cli-0.1.0.dist-info/top_level.txt +1 -0
disk_cli/config.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from dataclasses import asdict, dataclass, field
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
from urllib.parse import urlencode
|
|
9
|
+
|
|
10
|
+
DEFAULT_APP_ID = "R41nXZEwpfl6tw6KYyoEZ4FYST4BXPlF"
|
|
11
|
+
DEFAULT_BACKEND_URL = "https://disk.6-79.cn"
|
|
12
|
+
DEFAULT_QINIU_UPLOAD_URL = "https://up.qiniup.com"
|
|
13
|
+
DEFAULT_SSO_URL = "https://sso.6-79.cn/oauth/"
|
|
14
|
+
DEFAULT_STATE_PATH = Path.home() / ".config" / "htx-cli" / "state.json"
|
|
15
|
+
LEGACY_STATE_PATH = Path.home() / ".config" / "disk-cli" / "state.json"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class DiskSettings:
|
|
20
|
+
backend_url: str = field(default_factory=lambda: os.getenv("DISK_BACKEND_URL", DEFAULT_BACKEND_URL))
|
|
21
|
+
sso_url: str = field(default_factory=lambda: os.getenv("DISK_SSO_URL", DEFAULT_SSO_URL))
|
|
22
|
+
sso_app_id: str = field(default_factory=lambda: os.getenv("DISK_SSO_APP_ID", DEFAULT_APP_ID))
|
|
23
|
+
qiniu_upload_url: str = field(default_factory=lambda: os.getenv("DISK_QINIU_UPLOAD_URL", DEFAULT_QINIU_UPLOAD_URL))
|
|
24
|
+
token: str | None = None
|
|
25
|
+
user: dict[str, Any] | None = None
|
|
26
|
+
state_path: Path = DEFAULT_STATE_PATH
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def load(cls, state_path: Path | None = None) -> "DiskSettings":
|
|
30
|
+
resolved_path = (state_path or DEFAULT_STATE_PATH).expanduser()
|
|
31
|
+
if state_path is None and not resolved_path.exists() and LEGACY_STATE_PATH.exists():
|
|
32
|
+
resolved_path = LEGACY_STATE_PATH
|
|
33
|
+
if not resolved_path.exists():
|
|
34
|
+
return cls(state_path=resolved_path)
|
|
35
|
+
|
|
36
|
+
data = json.loads(resolved_path.read_text(encoding="utf-8"))
|
|
37
|
+
return cls(
|
|
38
|
+
backend_url=data.get("backend_url", os.getenv("DISK_BACKEND_URL", DEFAULT_BACKEND_URL)),
|
|
39
|
+
sso_url=data.get("sso_url", os.getenv("DISK_SSO_URL", DEFAULT_SSO_URL)),
|
|
40
|
+
sso_app_id=data.get("sso_app_id", os.getenv("DISK_SSO_APP_ID", DEFAULT_APP_ID)),
|
|
41
|
+
qiniu_upload_url=data.get(
|
|
42
|
+
"qiniu_upload_url",
|
|
43
|
+
os.getenv("DISK_QINIU_UPLOAD_URL", DEFAULT_QINIU_UPLOAD_URL),
|
|
44
|
+
),
|
|
45
|
+
token=data.get("token"),
|
|
46
|
+
user=data.get("user"),
|
|
47
|
+
state_path=resolved_path,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def save(self) -> None:
|
|
51
|
+
self.state_path.parent.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
payload = asdict(self)
|
|
53
|
+
payload["state_path"] = str(self.state_path)
|
|
54
|
+
self.state_path.write_text(
|
|
55
|
+
json.dumps(payload, ensure_ascii=False, indent=2) + "\n",
|
|
56
|
+
encoding="utf-8",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def clear_auth(self) -> None:
|
|
60
|
+
self.token = None
|
|
61
|
+
self.user = None
|
|
62
|
+
|
|
63
|
+
def oauth_authorize_url(self, *, state: str | None = "htx-cli") -> str:
|
|
64
|
+
params = {"app_id": self.sso_app_id}
|
|
65
|
+
if state:
|
|
66
|
+
params["state"] = state
|
|
67
|
+
return f"{self.sso_url}?{urlencode(params)}"
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: htx-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: htx-cli command-line client for the Disk backend API
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: rich<14,>=13.9
|
|
8
|
+
Requires-Dist: requests<3,>=2.32
|
|
9
|
+
|
|
10
|
+
# htx-cli
|
|
11
|
+
|
|
12
|
+
`htx-cli` is a command-line client for the Disk backend API. It supports:
|
|
13
|
+
|
|
14
|
+
- SSO-based login by exchanging an authorization `code` for the backend JWT token
|
|
15
|
+
- Listing remote Disk directories
|
|
16
|
+
- Uploading a local file into a remote Disk directory
|
|
17
|
+
- Uploading a local directory recursively while recreating its folder structure remotely
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
source /Users/jyonn/Projects/venv/django/bin/activate
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Commands
|
|
27
|
+
|
|
28
|
+
Print the SSO authorization URL:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
htx login --print-url
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Interactive login:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
htx login
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
You can also paste the full callback URL directly:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
htx login --code 'https://d.6-79.cn/oauth/qtb/callback?code=...'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Show the authenticated user:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
htx whoami
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
List the root directory:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
htx ls
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
List a nested remote directory by path:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
htx ls /Photos/2024
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
List a remote resource directly by resource ID:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
htx ls id:Ab12Cd
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The shorter `@资源ID` form works too:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
htx ls @Ab12Cd
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Upload a local file into a remote directory:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
htx upload ./report.pdf /Docs
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Upload a local directory recursively. The local directory name is created or reused under the target remote directory:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
htx upload ./albums /Photos
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Create a directory under the remote root:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
htx mkdir Projects
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Create a directory under a specific remote folder:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
htx mkdir 2026 /Photos
|
|
98
|
+
htx mkdir Archive @Ab12Cd
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Rename a remote resource:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
htx rename /Photos/old-name.jpg new-name.jpg
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Move a remote resource into another remote directory:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
htx mv /Photos/new-name.jpg /Archive
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Delete a remote file:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
htx rm /Archive/new-name.jpg
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Delete a non-empty remote directory recursively:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
htx rm --recursive /Archive
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Download a remote file to the current directory:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
htx download /Docs/report.pdf
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Download a remote file into a chosen local path:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
htx download @Ab12Cd ./downloads/report.pdf
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Download a remote directory recursively:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
htx download @Ab12Cd ./downloads/Archive
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Create a remote link resource:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
htx link Search https://www.google.com /Bookmarks
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## State File
|
|
150
|
+
|
|
151
|
+
The CLI stores the backend JWT token and the last fetched user payload in:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
~/.config/htx-cli/state.json
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Use `--config` to point to a different state file.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
disk_cli/__init__.py,sha256=4t_crzhrLum--oyowUMxtjBTzUtWp7oRTF22ewEvJG4,49
|
|
2
|
+
disk_cli/__main__.py,sha256=PSQ4rpL0dG6f-qH4N7H-gD9igQkdHzH4yVZDcW8lfZo,80
|
|
3
|
+
disk_cli/api.py,sha256=xUeBfjK9peyQJQ8kTA64-OuTax9uDO6X3rJO36WQ4-A,13259
|
|
4
|
+
disk_cli/cli.py,sha256=MmTHHSmE4pd4-FTsjHd5rL953K7VwbKJzpyKNtlAqng,27521
|
|
5
|
+
disk_cli/config.py,sha256=FEon2w6BxY7LnaQg2dvHMRhnerkqzhXtl_tAl9IPnU0,2772
|
|
6
|
+
htx_cli-0.1.0.dist-info/METADATA,sha256=6YvLBN--qRU_Zkh6hGo6WlqVM1ArA5b2AwP2lcEwGqE,2620
|
|
7
|
+
htx_cli-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
8
|
+
htx_cli-0.1.0.dist-info/entry_points.txt,sha256=30CRqDTSLDcKllLPd2VuweGtRGaMwBT0BdhbcMk-jMQ,42
|
|
9
|
+
htx_cli-0.1.0.dist-info/top_level.txt,sha256=-48I7cKRUrqajp2Wa_N_lJBGALIsBzP2WsdnC7IGRMM,9
|
|
10
|
+
htx_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
disk_cli
|