bdpan-cli 0.1.0__tar.gz → 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.
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/PKG-INFO +26 -11
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/README.md +25 -10
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/pyproject.toml +1 -1
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/pyproject.toml.orig +1 -1
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/__init__.py +16 -2
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_version.py +1 -1
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/auth.py +18 -6
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/cli.py +114 -5
- bdpan_cli-0.2.0/src/bdpan_cli/config.py +81 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/mcp_server.py +2 -1
- bdpan_cli-0.1.0/src/bdpan_cli/config.py +0 -26
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/__init__.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/__init__.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/__init__.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/auth_api.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/fileinfo_api.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/filemanager_api.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/fileupload_api.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/multimediafile_api.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/userinfo_api.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api_client.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/configuration.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/exceptions.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/__init__.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/oauth_token_authorization_code_response.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/oauth_token_device_code_response.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/oauth_token_device_token_response.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/oauth_token_refresh_token_response.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/quotaresponse.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/uinforesponse.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model_utils.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/rest.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/account.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/apply_scrape_rename.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/dedup.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/downloader.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/file_manager.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/foldering.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/logger.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/media_info.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/ops.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/organize.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/preview_scrape.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/scraper.py +0 -0
- {bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/uploader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: bdpan-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: 百度网盘工程化 CLI 管理工具
|
|
5
5
|
Keywords: baidu-pan,netdisk,cli,scraper,backup,cloud-storage
|
|
6
6
|
Author: CodingRookie98
|
|
@@ -57,11 +57,23 @@ pip install bdpan-cli
|
|
|
57
57
|
|
|
58
58
|
### 方式 4:跨平台单文件二进制(免 Python 运行时)
|
|
59
59
|
前往 [GitHub Releases](https://github.com/CodingRookie98/bdpan-cli/releases) 直接下载对应平台单文件二进制可执行包,加入 `PATH` 即可运行:
|
|
60
|
-
- `bdpan-linux-amd64`
|
|
61
|
-
- `bdpan-
|
|
62
|
-
- `bdpan-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
- `bdpan-linux-amd64` (Linux x86_64)
|
|
61
|
+
- `bdpan-macos-arm64` (macOS Apple Silicon)
|
|
62
|
+
- `bdpan-windows-amd64.exe` (Windows x86_64)
|
|
63
|
+
|
|
64
|
+
### 快速开始 (Quickstart)
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# 1. 配置百度开放平台凭证(仅需一次,保存在 ~/.config/bdpan/.env)
|
|
68
|
+
bdpan auth config --app-key <YOUR_APP_KEY> --secret-key <YOUR_SECRET_KEY>
|
|
69
|
+
|
|
70
|
+
# 2. 授权登录网盘账号(自动唤起默认浏览器打开授权页)
|
|
71
|
+
bdpan auth login
|
|
72
|
+
|
|
73
|
+
# 3. 立即使用
|
|
74
|
+
bdpan whoami
|
|
75
|
+
bdpan ls /
|
|
76
|
+
```
|
|
65
77
|
|
|
66
78
|
---
|
|
67
79
|
|
|
@@ -96,11 +108,14 @@ bdpan ops list [--limit 20] # 查看关键变更操作流水审计
|
|
|
96
108
|
bdpan ops show <op_id> # 查看某次操作的明细与映射清单
|
|
97
109
|
bdpan undo <op_id> [--dry-run] [-y] # 逆向撤销回滚指定批次操作(支持预演)
|
|
98
110
|
|
|
99
|
-
#
|
|
100
|
-
bdpan auth
|
|
101
|
-
bdpan auth
|
|
102
|
-
bdpan auth
|
|
103
|
-
bdpan --account <alias>
|
|
111
|
+
# 认证配置与多账号管理 (Auth & Multi-Account)
|
|
112
|
+
bdpan auth config --app-key <key> --secret-key <secret> # 快速写入全局开发者凭据 (~/.config/bdpan/.env)
|
|
113
|
+
bdpan auth config --show # 查看当前凭据来源与脱敏信息
|
|
114
|
+
bdpan auth config --path # 打印全局配置文件物理路径
|
|
115
|
+
bdpan auth login [--account <alias>] # 启动设备码授权(自动唤起默认浏览器并高亮授权码)
|
|
116
|
+
bdpan auth list # 查看本地保存的网盘账号及凭证有效性
|
|
117
|
+
bdpan auth switch <alias> # 切换当前默认活跃账号
|
|
118
|
+
bdpan --account <alias> <subcommand> # 临时以指定账号执行单次命令(多租户并发隔离)
|
|
104
119
|
|
|
105
120
|
# 媒体可观测性与全局选项 (Media Insights & Global Options)
|
|
106
121
|
bdpan info /影视/电影/Inception.mkv # 探测视频精准分辨率(4K/1080P)、时长、HEVC编码与音轨
|
|
@@ -29,11 +29,23 @@ pip install bdpan-cli
|
|
|
29
29
|
|
|
30
30
|
### 方式 4:跨平台单文件二进制(免 Python 运行时)
|
|
31
31
|
前往 [GitHub Releases](https://github.com/CodingRookie98/bdpan-cli/releases) 直接下载对应平台单文件二进制可执行包,加入 `PATH` 即可运行:
|
|
32
|
-
- `bdpan-linux-amd64`
|
|
33
|
-
- `bdpan-
|
|
34
|
-
- `bdpan-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
- `bdpan-linux-amd64` (Linux x86_64)
|
|
33
|
+
- `bdpan-macos-arm64` (macOS Apple Silicon)
|
|
34
|
+
- `bdpan-windows-amd64.exe` (Windows x86_64)
|
|
35
|
+
|
|
36
|
+
### 快速开始 (Quickstart)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 1. 配置百度开放平台凭证(仅需一次,保存在 ~/.config/bdpan/.env)
|
|
40
|
+
bdpan auth config --app-key <YOUR_APP_KEY> --secret-key <YOUR_SECRET_KEY>
|
|
41
|
+
|
|
42
|
+
# 2. 授权登录网盘账号(自动唤起默认浏览器打开授权页)
|
|
43
|
+
bdpan auth login
|
|
44
|
+
|
|
45
|
+
# 3. 立即使用
|
|
46
|
+
bdpan whoami
|
|
47
|
+
bdpan ls /
|
|
48
|
+
```
|
|
37
49
|
|
|
38
50
|
---
|
|
39
51
|
|
|
@@ -68,11 +80,14 @@ bdpan ops list [--limit 20] # 查看关键变更操作流水审计
|
|
|
68
80
|
bdpan ops show <op_id> # 查看某次操作的明细与映射清单
|
|
69
81
|
bdpan undo <op_id> [--dry-run] [-y] # 逆向撤销回滚指定批次操作(支持预演)
|
|
70
82
|
|
|
71
|
-
#
|
|
72
|
-
bdpan auth
|
|
73
|
-
bdpan auth
|
|
74
|
-
bdpan auth
|
|
75
|
-
bdpan --account <alias>
|
|
83
|
+
# 认证配置与多账号管理 (Auth & Multi-Account)
|
|
84
|
+
bdpan auth config --app-key <key> --secret-key <secret> # 快速写入全局开发者凭据 (~/.config/bdpan/.env)
|
|
85
|
+
bdpan auth config --show # 查看当前凭据来源与脱敏信息
|
|
86
|
+
bdpan auth config --path # 打印全局配置文件物理路径
|
|
87
|
+
bdpan auth login [--account <alias>] # 启动设备码授权(自动唤起默认浏览器并高亮授权码)
|
|
88
|
+
bdpan auth list # 查看本地保存的网盘账号及凭证有效性
|
|
89
|
+
bdpan auth switch <alias> # 切换当前默认活跃账号
|
|
90
|
+
bdpan --account <alias> <subcommand> # 临时以指定账号执行单次命令(多租户并发隔离)
|
|
76
91
|
|
|
77
92
|
# 媒体可观测性与全局选项 (Media Insights & Global Options)
|
|
78
93
|
bdpan info /影视/电影/Inception.mkv # 探测视频精准分辨率(4K/1080P)、时长、HEVC编码与音轨
|
|
@@ -7,9 +7,23 @@ from bdpan_cli._vendor.openapi_client.api.fileinfo_api import FileinfoApi
|
|
|
7
7
|
from bdpan_cli._vendor.openapi_client.rest import ApiException
|
|
8
8
|
|
|
9
9
|
from bdpan_cli.auth import TokenManager
|
|
10
|
-
from bdpan_cli.config import
|
|
10
|
+
from bdpan_cli.config import (
|
|
11
|
+
AppConfig,
|
|
12
|
+
ConfigError,
|
|
13
|
+
get_global_config_path,
|
|
14
|
+
load_config,
|
|
15
|
+
save_global_config,
|
|
16
|
+
)
|
|
11
17
|
from bdpan_cli._version import __version__
|
|
12
18
|
|
|
13
19
|
from bdpan_cli.cli import main
|
|
14
20
|
|
|
15
|
-
__all__ = [
|
|
21
|
+
__all__ = [
|
|
22
|
+
"main",
|
|
23
|
+
"__version__",
|
|
24
|
+
"AppConfig",
|
|
25
|
+
"ConfigError",
|
|
26
|
+
"load_config",
|
|
27
|
+
"get_global_config_path",
|
|
28
|
+
"save_global_config",
|
|
29
|
+
]
|
|
@@ -16,7 +16,7 @@ from bdpan_cli._vendor.openapi_client.rest import ApiException
|
|
|
16
16
|
from bdpan_cli.config import AppConfig
|
|
17
17
|
|
|
18
18
|
# 默认用户端 Token 凭据路径遵循 XDG 规范 (~/.config/bdpan/tokens.json)
|
|
19
|
-
DEFAULT_CONFIG_DIR = Path.home() / ".config" / "bdpan"
|
|
19
|
+
DEFAULT_CONFIG_DIR = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")) / "bdpan"
|
|
20
20
|
DEFAULT_TOKEN_FILE = DEFAULT_CONFIG_DIR / "tokens.json"
|
|
21
21
|
LEGACY_TOKEN_CACHE = Path(__file__).resolve().parents[2] / ".baidupan_tokens.json"
|
|
22
22
|
|
|
@@ -193,10 +193,22 @@ class TokenManager:
|
|
|
193
193
|
device = auth.oauth_token_device_code(self._config.app_key, SCOPE)
|
|
194
194
|
interval = max(int(device.interval or 5), 3)
|
|
195
195
|
deadline = time.time() + int(device.expires_in or 300)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
196
|
+
|
|
197
|
+
# 尝试自动在默认浏览器中打开授权页面
|
|
198
|
+
try:
|
|
199
|
+
import webbrowser
|
|
200
|
+
webbrowser.open(device.verification_url)
|
|
201
|
+
except Exception:
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
print("\n" + "=" * 66, flush=True)
|
|
205
|
+
print("🔗 请在浏览器中打开授权页面完成登录:", flush=True)
|
|
206
|
+
print(f" {device.verification_url}", flush=True)
|
|
207
|
+
print("\n🔑 您的设备授权码 (User Code):", flush=True)
|
|
208
|
+
print(f" 👉 {device.user_code} 👈", flush=True)
|
|
209
|
+
print("\n(系统已尝试唤起默认浏览器;如未弹出,请手动复制上述链接访问并输入授权码)", flush=True)
|
|
210
|
+
print("=" * 66 + "\n", flush=True)
|
|
211
|
+
print("⏳ 正在等待网页端授权确认...", flush=True)
|
|
200
212
|
while time.time() < deadline:
|
|
201
213
|
time.sleep(interval)
|
|
202
214
|
try:
|
|
@@ -213,6 +225,6 @@ class TokenManager:
|
|
|
213
225
|
interval += 5
|
|
214
226
|
continue
|
|
215
227
|
raise RuntimeError(f"设备码授权失败:{body}") from e
|
|
216
|
-
print("
|
|
228
|
+
print("🎉 授权成功!", flush=True)
|
|
217
229
|
return self._save_cache(self._to_cache(response))
|
|
218
230
|
raise AuthorizationNeeded("设备码已过期,请重新运行")
|
|
@@ -8,11 +8,17 @@ import logging
|
|
|
8
8
|
import os
|
|
9
9
|
import sys
|
|
10
10
|
from datetime import datetime
|
|
11
|
+
from pathlib import Path
|
|
11
12
|
from typing import Any
|
|
12
13
|
|
|
13
14
|
from bdpan_cli.account import AccountClient, AccountError
|
|
14
15
|
from bdpan_cli.auth import TOKEN_CACHE, TokenManager
|
|
15
|
-
from bdpan_cli.config import
|
|
16
|
+
from bdpan_cli.config import (
|
|
17
|
+
ConfigError,
|
|
18
|
+
get_global_config_path,
|
|
19
|
+
load_config,
|
|
20
|
+
save_global_config,
|
|
21
|
+
)
|
|
16
22
|
from bdpan_cli.dedup import execute_dedup, plan_dedup
|
|
17
23
|
from bdpan_cli.downloader import DownloadError, Downloader
|
|
18
24
|
from bdpan_cli.file_manager import FileManager, FileManagerError
|
|
@@ -761,6 +767,85 @@ def cmd_undo(args: argparse.Namespace) -> int:
|
|
|
761
767
|
def cmd_auth(args: argparse.Namespace) -> int:
|
|
762
768
|
"""网盘账号认证与多租户管理。"""
|
|
763
769
|
subcmd = getattr(args, "auth_subcmd", None)
|
|
770
|
+
|
|
771
|
+
if subcmd == "config":
|
|
772
|
+
# 1. 打印全局配置文件路径
|
|
773
|
+
if getattr(args, "path", False):
|
|
774
|
+
print(str(get_global_config_path()))
|
|
775
|
+
return 0
|
|
776
|
+
|
|
777
|
+
# 2. 显示当前配置状态(脱敏)
|
|
778
|
+
if getattr(args, "show", False):
|
|
779
|
+
global_path = get_global_config_path()
|
|
780
|
+
local_path = Path.cwd() / ".env"
|
|
781
|
+
has_env = bool(os.getenv("BAIDU_APP_KEY") and os.getenv("BAIDU_SECRET_KEY"))
|
|
782
|
+
|
|
783
|
+
try:
|
|
784
|
+
cfg = load_config()
|
|
785
|
+
app_key = cfg.app_key
|
|
786
|
+
secret_key = cfg.secret_key
|
|
787
|
+
masked_app = app_key[:3] + "..." + app_key[-3:] if len(app_key) > 6 else "***"
|
|
788
|
+
masked_secret = secret_key[:3] + "..." + secret_key[-3:] if len(secret_key) > 6 else "***"
|
|
789
|
+
|
|
790
|
+
source = "环境变量" if has_env else ("当前目录 .env" if local_path.exists() else f"全局配置 ({global_path})")
|
|
791
|
+
if getattr(args, "json", False):
|
|
792
|
+
return _output_envelope({
|
|
793
|
+
"source": source,
|
|
794
|
+
"global_path": str(global_path),
|
|
795
|
+
"app_key": masked_app,
|
|
796
|
+
"secret_key": masked_secret,
|
|
797
|
+
})
|
|
798
|
+
print("\n📋 百度网盘开放平台开发者凭证配置状态:")
|
|
799
|
+
print(f" • 配置来源: {source}")
|
|
800
|
+
print(f" • BAIDU_APP_KEY: {masked_app}")
|
|
801
|
+
print(f" • BAIDU_SECRET_KEY: {masked_secret}")
|
|
802
|
+
print(f" • 全局配置文件位置: {global_path}\n")
|
|
803
|
+
return 0
|
|
804
|
+
except ConfigError as e:
|
|
805
|
+
if getattr(args, "json", False):
|
|
806
|
+
return _output_envelope(None, success=False, code=1, error=str(e))
|
|
807
|
+
print("\n⚠️ 尚未检测到有效开发者凭证配置。", file=sys.stderr)
|
|
808
|
+
print(f" 全局配置文件位置: {global_path}", file=sys.stderr)
|
|
809
|
+
print(" 提示:请运行 'bdpan auth config --app-key <KEY> --secret-key <SECRET>' 写入全局配置。\n", file=sys.stderr)
|
|
810
|
+
return 1
|
|
811
|
+
|
|
812
|
+
# 3. 写入配置
|
|
813
|
+
app_key = getattr(args, "app_key", None)
|
|
814
|
+
secret_key = getattr(args, "secret_key", None)
|
|
815
|
+
|
|
816
|
+
if not app_key or not secret_key:
|
|
817
|
+
if sys.stdin.isatty() and not getattr(args, "json", False):
|
|
818
|
+
print("请输入百度网盘开放平台的开发者凭证(可从 https://pan.baidu.com/union 获取):")
|
|
819
|
+
if not app_key:
|
|
820
|
+
try:
|
|
821
|
+
app_key = input(" BAIDU_APP_KEY: ").strip()
|
|
822
|
+
except (EOFError, KeyboardInterrupt):
|
|
823
|
+
print("\n操作已取消。")
|
|
824
|
+
return 1
|
|
825
|
+
if not secret_key:
|
|
826
|
+
try:
|
|
827
|
+
secret_key = input(" BAIDU_SECRET_KEY: ").strip()
|
|
828
|
+
except (EOFError, KeyboardInterrupt):
|
|
829
|
+
print("\n操作已取消。")
|
|
830
|
+
return 1
|
|
831
|
+
|
|
832
|
+
if not app_key or not secret_key:
|
|
833
|
+
msg = (
|
|
834
|
+
"缺少凭据参数。请提供 --app-key 与 --secret-key,例如:\n"
|
|
835
|
+
" bdpan auth config --app-key YOUR_APP_KEY --secret-key YOUR_SECRET_KEY"
|
|
836
|
+
)
|
|
837
|
+
if getattr(args, "json", False):
|
|
838
|
+
return _output_envelope(None, success=False, code=1, error=msg)
|
|
839
|
+
print(f"❌ {msg}", file=sys.stderr)
|
|
840
|
+
return 1
|
|
841
|
+
|
|
842
|
+
saved_path = save_global_config(app_key, secret_key)
|
|
843
|
+
if getattr(args, "json", False):
|
|
844
|
+
return _output_envelope({"saved_path": str(saved_path)})
|
|
845
|
+
print(f"✅ 开发者凭证已成功保存至全局配置: {saved_path}")
|
|
846
|
+
print("💡 您现在可以在任意目录直接运行 'bdpan auth login' 或其他 bdpan 命令。")
|
|
847
|
+
return 0
|
|
848
|
+
|
|
764
849
|
tm = _get_token_manager(args)
|
|
765
850
|
|
|
766
851
|
if subcmd == "switch":
|
|
@@ -1320,14 +1405,32 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
1320
1405
|
p_auth = subparsers.add_parser(
|
|
1321
1406
|
"auth",
|
|
1322
1407
|
help="网盘账号认证与多账号管理",
|
|
1323
|
-
description="
|
|
1408
|
+
description="百度网盘多账号认证管理系统,支持多租户凭证隔离存储、活跃账号切换、快速配置与单独授权。",
|
|
1324
1409
|
epilog="""示例:
|
|
1410
|
+
bdpan auth config --app-key YOUR_KEY --secret-key YOUR_SECRET
|
|
1411
|
+
bdpan auth config --show
|
|
1412
|
+
bdpan auth login
|
|
1325
1413
|
bdpan auth list
|
|
1326
|
-
bdpan auth switch work_pan
|
|
1327
|
-
bdpan auth login --account personal_pan""",
|
|
1414
|
+
bdpan auth switch work_pan""",
|
|
1328
1415
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
1329
1416
|
)
|
|
1330
1417
|
auth_sub = p_auth.add_subparsers(dest="auth_subcmd", help="认证子命令")
|
|
1418
|
+
p_auth_config = auth_sub.add_parser(
|
|
1419
|
+
"config",
|
|
1420
|
+
help="配置或查看百度网盘开发者凭据 (AppKey / SecretKey)",
|
|
1421
|
+
description="配置或查看百度网盘开放平台开发者凭据。凭据将安全保存在用户全局配置目录中 (~/.config/bdpan/.env)。",
|
|
1422
|
+
epilog="""示例:
|
|
1423
|
+
bdpan auth config --app-key YOUR_KEY --secret-key YOUR_SECRET
|
|
1424
|
+
bdpan auth config --show
|
|
1425
|
+
bdpan auth config --path""",
|
|
1426
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
1427
|
+
)
|
|
1428
|
+
p_auth_config.add_argument("--app-key", help="百度开放平台 App Key (Client ID)")
|
|
1429
|
+
p_auth_config.add_argument("--secret-key", help="百度开放平台 Secret Key (Client Secret)")
|
|
1430
|
+
p_auth_config.add_argument("--show", action="store_true", help="显示当前配置来源与脱敏凭证")
|
|
1431
|
+
p_auth_config.add_argument("--path", action="store_true", help="输出全局配置文件存储路径")
|
|
1432
|
+
p_auth_config.set_defaults(func=cmd_auth)
|
|
1433
|
+
|
|
1331
1434
|
p_auth_list = auth_sub.add_parser(
|
|
1332
1435
|
"list",
|
|
1333
1436
|
help="列出本地所有网盘账号与到期状态",
|
|
@@ -1421,7 +1524,13 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1421
1524
|
parser.print_help()
|
|
1422
1525
|
return 0
|
|
1423
1526
|
|
|
1424
|
-
|
|
1527
|
+
try:
|
|
1528
|
+
return args.func(args)
|
|
1529
|
+
except ConfigError as e:
|
|
1530
|
+
if getattr(args, "json", False):
|
|
1531
|
+
return _output_envelope(None, success=False, code=1, error=str(e))
|
|
1532
|
+
print(f"\n❌ 配置缺失: {e}\n", file=sys.stderr)
|
|
1533
|
+
return 1
|
|
1425
1534
|
|
|
1426
1535
|
|
|
1427
1536
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""应用配置:从环境变量、本地 .env 或 XDG 全局配置读取百度网盘开放平台凭证。"""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from dotenv import load_dotenv
|
|
8
|
+
|
|
9
|
+
# XDG 全局配置目录与文件 (~/.config/bdpan/.env)
|
|
10
|
+
DEFAULT_CONFIG_DIR = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")) / "bdpan"
|
|
11
|
+
DEFAULT_CONFIG_FILE = DEFAULT_CONFIG_DIR / ".env"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ConfigError(RuntimeError):
|
|
15
|
+
"""应用配置缺失或无效异常。"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class AppConfig:
|
|
20
|
+
app_key: str
|
|
21
|
+
secret_key: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_global_config_path() -> Path:
|
|
25
|
+
"""获取全局 .env 配置文件的实际路径。"""
|
|
26
|
+
custom = os.environ.get("BDPAN_CONFIG_PATH")
|
|
27
|
+
if custom:
|
|
28
|
+
return Path(custom)
|
|
29
|
+
return DEFAULT_CONFIG_FILE
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def load_config() -> AppConfig:
|
|
33
|
+
"""按优先级检索并加载百度开放平台凭证:
|
|
34
|
+
1. 进程内既有环境变量 (os.environ)
|
|
35
|
+
2. 当前工作目录下的 .env 文件
|
|
36
|
+
3. 全局 XDG 配置文件 (~/.config/bdpan/.env)
|
|
37
|
+
|
|
38
|
+
若全部未配置,抛出友好的 ConfigError。
|
|
39
|
+
"""
|
|
40
|
+
# 1. 尝试从当前目录加载 .env (override=False 保护已存在的环境变量)
|
|
41
|
+
local_env = Path.cwd() / ".env"
|
|
42
|
+
if local_env.is_file():
|
|
43
|
+
load_dotenv(dotenv_path=local_env, override=False)
|
|
44
|
+
|
|
45
|
+
# 2. 尝试从全局 XDG 配置加载 .env (override=False 保护优先由本地 .env 或环境变量指定的值)
|
|
46
|
+
global_env = get_global_config_path()
|
|
47
|
+
if global_env.is_file():
|
|
48
|
+
load_dotenv(dotenv_path=global_env, override=False)
|
|
49
|
+
|
|
50
|
+
values = {
|
|
51
|
+
"BAIDU_APP_KEY": os.getenv("BAIDU_APP_KEY", "").strip(),
|
|
52
|
+
"BAIDU_SECRET_KEY": os.getenv("BAIDU_SECRET_KEY", "").strip(),
|
|
53
|
+
}
|
|
54
|
+
missing = [name for name, value in values.items() if not value]
|
|
55
|
+
if missing:
|
|
56
|
+
raise ConfigError(
|
|
57
|
+
f"缺少必要配置项:{'、'.join(missing)}。\n"
|
|
58
|
+
"请通过以下任一方式配置:\n"
|
|
59
|
+
" 1. 快速配置(推荐):bdpan auth config --app-key <KEY> --secret-key <SECRET>\n"
|
|
60
|
+
f" 2. 全局配置文件:在 {global_env} 中填写\n"
|
|
61
|
+
" 3. 当前目录:在当前工作目录下 .env 中填写\n"
|
|
62
|
+
" 4. 环境变量:export BAIDU_APP_KEY=... BAIDU_SECRET_KEY=..."
|
|
63
|
+
)
|
|
64
|
+
return AppConfig(values["BAIDU_APP_KEY"], values["BAIDU_SECRET_KEY"])
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def save_global_config(app_key: str, secret_key: str, path: Path | None = None) -> Path:
|
|
68
|
+
"""将 AppKey 和 SecretKey 保存至全局 .env 配置文件(强制权限 0o600)。"""
|
|
69
|
+
target_path = path or get_global_config_path()
|
|
70
|
+
target_path.parent.mkdir(parents=True, exist_ok=True)
|
|
71
|
+
content = (
|
|
72
|
+
f"# 百度网盘开放平台开发者凭证 (XDG 全局配置)\n"
|
|
73
|
+
f"BAIDU_APP_KEY={app_key.strip()}\n"
|
|
74
|
+
f"BAIDU_SECRET_KEY={secret_key.strip()}\n"
|
|
75
|
+
)
|
|
76
|
+
target_path.write_text(content, encoding="utf-8")
|
|
77
|
+
try:
|
|
78
|
+
target_path.chmod(0o600)
|
|
79
|
+
except OSError:
|
|
80
|
+
pass
|
|
81
|
+
return target_path
|
|
@@ -12,6 +12,7 @@ import os
|
|
|
12
12
|
import sys
|
|
13
13
|
from typing import Any, Callable
|
|
14
14
|
|
|
15
|
+
from bdpan_cli._version import __version__
|
|
15
16
|
from bdpan_cli.account import AccountClient
|
|
16
17
|
from bdpan_cli.file_manager import FileManager, FileManagerError
|
|
17
18
|
from bdpan_cli.media_info import MediaInfoClient, MediaInfoError
|
|
@@ -39,7 +40,7 @@ class BdpanMcpServer:
|
|
|
39
40
|
self.protocol_version = "2024-11-05"
|
|
40
41
|
self.server_info = {
|
|
41
42
|
"name": "bdpan-mcp",
|
|
42
|
-
"version":
|
|
43
|
+
"version": __version__,
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
def _get_file_manager(self) -> FileManager:
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"""应用配置:从 .env 读取百度网盘开放平台凭证。"""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
from dataclasses import dataclass
|
|
5
|
-
|
|
6
|
-
from dotenv import load_dotenv
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@dataclass(frozen=True)
|
|
10
|
-
class AppConfig:
|
|
11
|
-
app_key: str
|
|
12
|
-
secret_key: str
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def load_config() -> AppConfig:
|
|
16
|
-
load_dotenv()
|
|
17
|
-
values = {
|
|
18
|
-
"BAIDU_APP_KEY": os.getenv("BAIDU_APP_KEY", "").strip(),
|
|
19
|
-
"BAIDU_SECRET_KEY": os.getenv("BAIDU_SECRET_KEY", "").strip(),
|
|
20
|
-
}
|
|
21
|
-
missing = [name for name, value in values.items() if not value]
|
|
22
|
-
if missing:
|
|
23
|
-
raise RuntimeError(
|
|
24
|
-
f"缺少配置项:{'、'.join(missing)},请在 .env 中填写(参考 .env.example)"
|
|
25
|
-
)
|
|
26
|
-
return AppConfig(values["BAIDU_APP_KEY"], values["BAIDU_SECRET_KEY"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/fileinfo_api.py
RENAMED
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/filemanager_api.py
RENAMED
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/fileupload_api.py
RENAMED
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/multimediafile_api.py
RENAMED
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/api/userinfo_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/quotaresponse.py
RENAMED
|
File without changes
|
{bdpan_cli-0.1.0 → bdpan_cli-0.2.0}/src/bdpan_cli/_vendor/openapi_client/model/uinforesponse.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|