sharept-dl 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.
- sharept_dl-0.1.0/LICENSE +21 -0
- sharept_dl-0.1.0/MANIFEST.in +5 -0
- sharept_dl-0.1.0/PKG-INFO +285 -0
- sharept_dl-0.1.0/README.md +248 -0
- sharept_dl-0.1.0/pyproject.toml +74 -0
- sharept_dl-0.1.0/requirements.txt +4 -0
- sharept_dl-0.1.0/setup.cfg +4 -0
- sharept_dl-0.1.0/sharepoint_dl/__init__.py +38 -0
- sharept_dl-0.1.0/sharepoint_dl/__main__.py +7 -0
- sharept_dl-0.1.0/sharepoint_dl/cli.py +462 -0
- sharept_dl-0.1.0/sharepoint_dl/i18n.py +244 -0
- sharept_dl-0.1.0/sharepoint_dl/session.py +328 -0
- sharept_dl-0.1.0/sharepoint_dl/ui.py +86 -0
- sharept_dl-0.1.0/sharepoint_dl/utils.py +77 -0
- sharept_dl-0.1.0/sharept_dl.egg-info/PKG-INFO +285 -0
- sharept_dl-0.1.0/sharept_dl.egg-info/SOURCES.txt +23 -0
- sharept_dl-0.1.0/sharept_dl.egg-info/dependency_links.txt +1 -0
- sharept_dl-0.1.0/sharept_dl.egg-info/entry_points.txt +2 -0
- sharept_dl-0.1.0/sharept_dl.egg-info/requires.txt +10 -0
- sharept_dl-0.1.0/sharept_dl.egg-info/top_level.txt +1 -0
- sharept_dl-0.1.0/tests/__init__.py +0 -0
- sharept_dl-0.1.0/tests/test_cli.py +189 -0
- sharept_dl-0.1.0/tests/test_i18n.py +122 -0
- sharept_dl-0.1.0/tests/test_session.py +469 -0
- sharept_dl-0.1.0/tests/test_utils.py +161 -0
sharept_dl-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Neal
|
|
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,285 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sharept-dl
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SharePoint 文件下载工具 — 纯 HTTP 实现,支持文件夹和单文件分享链接
|
|
5
|
+
Author: Neal
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/user/sharept-dl
|
|
8
|
+
Project-URL: Issues, https://github.com/user/sharept-dl/issues
|
|
9
|
+
Keywords: sharepoint,download,batch,cli,rest-api
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: System Administrators
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: requests>=2.28
|
|
28
|
+
Requires-Dist: rich>=13.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-mock>=3.10; extra == "dev"
|
|
33
|
+
Requires-Dist: requests-mock>=1.11; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.3; extra == "dev"
|
|
35
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# sharept-dl
|
|
39
|
+
|
|
40
|
+
Batch download files from SharePoint shared links — pure HTTP, zero browser dependencies.
|
|
41
|
+
|
|
42
|
+
[中文说明](#中文说明) below.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **No browser required** — uses plain HTTP, no Playwright, no Chromium
|
|
47
|
+
- **Pre-scan report** — shows file count and total size before downloading
|
|
48
|
+
- **Stable TUI** — Rich-powered terminal UI with real-time progress, no flickering
|
|
49
|
+
- **Resumable downloads** — interrupted transfers pick up where they left off via HTTP `Range` requests
|
|
50
|
+
- **Auto-skip** — already-downloaded files are detected and skipped instantly
|
|
51
|
+
- **Preserves folder structure** — subdirectories are recreated locally
|
|
52
|
+
- **Safe URL handling** — prevents double-encoding of paths with special/Chinese characters
|
|
53
|
+
- **Single file support** — handles `:w:` (Word), `:x:` (Excel), `:p:` (PowerPoint) share links via GUID lookup
|
|
54
|
+
- **Multi-language** — auto-detects system locale; displays Chinese or English based on your environment
|
|
55
|
+
|
|
56
|
+
## Supported share link types
|
|
57
|
+
|
|
58
|
+
| Type | URL pattern | How it works |
|
|
59
|
+
|------|-------------|--------------|
|
|
60
|
+
| Folder | `:f:` | Recursively enumerates files & subfolders via REST API |
|
|
61
|
+
| Word | `:w:` | Parses `sourcedoc` GUID, resolves via `GetFileById` API |
|
|
62
|
+
| Excel | `:x:` | Same as Word |
|
|
63
|
+
| PowerPoint | `:p:` | Same as Word |
|
|
64
|
+
|
|
65
|
+
## How it works
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
Folder share (:f:)
|
|
69
|
+
│
|
|
70
|
+
├─ [1] HTTP GET → 302 redirect → Set-Cookie (auth)
|
|
71
|
+
├─ [2] REST API: enumerate files & folders
|
|
72
|
+
└─ [3] Download each file (with Range support for resume)
|
|
73
|
+
|
|
74
|
+
Single file share (:w:/:x:/:p:)
|
|
75
|
+
│
|
|
76
|
+
├─ [1] HTTP GET → 302 redirect → Set-Cookie (auth)
|
|
77
|
+
├─ [2] Extract sourcedoc GUID from URL
|
|
78
|
+
├─ [3] REST API: GetFileById('<GUID>') → ServerRelativeUrl
|
|
79
|
+
└─ [4] Download via /_layouts/15/download.aspx
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
> **Limitation**: currently only supports "Anyone with the link" sharing links (anonymous access). Organization-internal links require additional OAuth2 authentication.
|
|
83
|
+
|
|
84
|
+
## Requirements
|
|
85
|
+
|
|
86
|
+
- Python >= 3.9
|
|
87
|
+
- [requests](https://pypi.org/project/requests/)
|
|
88
|
+
- [rich](https://pypi.org/project/rich/)
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
### Via pip
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install sharept-dl
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### From source
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
git clone <repo-url>
|
|
102
|
+
cd sharept-dl
|
|
103
|
+
pip install -e .
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Usage
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Folder share
|
|
110
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:f:/g/personal/...'
|
|
111
|
+
|
|
112
|
+
# Single file share (Word/Excel/PowerPoint)
|
|
113
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:w:/r/personal/.../Doc.aspx?sourcedoc=...&file=....docx'
|
|
114
|
+
|
|
115
|
+
# Specify output directory
|
|
116
|
+
sharept-dl -u '...' -o ./my_files
|
|
117
|
+
|
|
118
|
+
# Verbose mode
|
|
119
|
+
sharept-dl -u '...' -v
|
|
120
|
+
|
|
121
|
+
# Force re-download everything
|
|
122
|
+
sharept-dl -u '...' --no-resume
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
> **⚠️ Important**: Always wrap the URL in **single quotes** `'...'`, NOT double quotes.
|
|
126
|
+
> Double quotes allow the shell to interpret `$`, `\`, and other special characters,
|
|
127
|
+
> which will break the URL.
|
|
128
|
+
|
|
129
|
+
### Options
|
|
130
|
+
|
|
131
|
+
| Argument | Short | Required | Default | Description |
|
|
132
|
+
|----------|-------|----------|---------|-------------|
|
|
133
|
+
| `--url` | `-u` | Yes | — | SharePoint share link (`:f:` folder type) |
|
|
134
|
+
| `--output` | `-o` | No | `.` | Output directory |
|
|
135
|
+
| `--timeout` | `-t` | No | `60` | HTTP request timeout in seconds |
|
|
136
|
+
| `--delay` | `-d` | No | `0.3` | Delay between file downloads (to avoid rate limits) |
|
|
137
|
+
| `--no-resume` | | No | `false` | Disable resume — force re-download all files |
|
|
138
|
+
| `--verbose` | `-v` | No | `false` | Verbose logging (prints to stderr) |
|
|
139
|
+
|
|
140
|
+
### Interrupt & resume
|
|
141
|
+
|
|
142
|
+
If the download is interrupted (Ctrl+C, network failure, etc.), simply run the same command again. The tool will:
|
|
143
|
+
|
|
144
|
+
1. Skip all fully-downloaded files (instant)
|
|
145
|
+
2. Detect `.part` temporary files and resume from where they left off via HTTP `Range` requests
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# First run — interrupted at file 42/64
|
|
149
|
+
sharept-dl -u '...' -o ./downloads
|
|
150
|
+
# ... Ctrl+C ...
|
|
151
|
+
|
|
152
|
+
# Second run — skips 41 complete files, resumes file 42, continues from 43
|
|
153
|
+
sharept-dl -u '...' -o ./downloads
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pip install -e ".[dev]"
|
|
160
|
+
pytest tests/ -v
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Project structure
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
sharept-dl/
|
|
167
|
+
├── sharepoint_dl/
|
|
168
|
+
│ ├── __init__.py # Package exports
|
|
169
|
+
│ ├── __main__.py # python -m entry point
|
|
170
|
+
│ ├── cli.py # CLI argument parsing & main loop
|
|
171
|
+
│ ├── i18n.py # Multi-language support (zh/en)
|
|
172
|
+
│ ├── session.py # SharePoint authentication & REST API
|
|
173
|
+
│ ├── ui.py # Rich terminal UI rendering
|
|
174
|
+
│ └── utils.py # Utility functions & safe encoding
|
|
175
|
+
├── tests/
|
|
176
|
+
│ ├── test_utils.py # Utility function tests
|
|
177
|
+
│ ├── test_session.py # Session & API tests (mocked HTTP)
|
|
178
|
+
│ ├── test_cli.py # CLI argument parsing tests
|
|
179
|
+
│ └── test_i18n.py # i18n language detection tests
|
|
180
|
+
├── main.py # Legacy entry point (backward compatible)
|
|
181
|
+
├── pyproject.toml # Project metadata & build config
|
|
182
|
+
├── requirements.txt # pip dependency list
|
|
183
|
+
├── LICENSE # MIT license
|
|
184
|
+
└── README.md # This file
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Internationalization (i18n)
|
|
188
|
+
|
|
189
|
+
sharept-dl automatically detects your system language:
|
|
190
|
+
|
|
191
|
+
- **Chinese** (`zh_CN`, `zh_TW`, etc.) → displays Chinese messages
|
|
192
|
+
- **Anything else** → displays English messages
|
|
193
|
+
|
|
194
|
+
You can override the language in code:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from sharepoint_dl import set_language
|
|
198
|
+
set_language("en") # force English
|
|
199
|
+
set_language("zh") # force Chinese
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## License
|
|
203
|
+
|
|
204
|
+
MIT
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 中文说明
|
|
209
|
+
|
|
210
|
+
无需浏览器即可批量下载 SharePoint 分享文件。纯 HTTP 实现,零浏览器依赖。
|
|
211
|
+
|
|
212
|
+
### 功能特性
|
|
213
|
+
|
|
214
|
+
- **无需浏览器** — 纯 HTTP 请求,不依赖 Playwright / Chromium
|
|
215
|
+
- **预扫描报告** — 下载前展示文件总数和总大小
|
|
216
|
+
- **稳定终端界面** — Rich 驱动的 TUI,实时进度不闪烁
|
|
217
|
+
- **断点续传** — 中断后重新运行,通过 `.part` 临时文件 + HTTP `Range` 请求自动续传
|
|
218
|
+
- **自动跳过** — 已下载完成的文件即时跳过
|
|
219
|
+
- **保留目录结构** — 子文件夹按原始层级重建
|
|
220
|
+
- **安全编码处理** — 防止特殊字符/中文路径的双重编码问题
|
|
221
|
+
- **单文件支持** — 兼容 `:w:`(Word)、`:x:`(Excel)、`:p:`(PowerPoint)分享链接
|
|
222
|
+
- **多语言** — 自动检测系统语言,中文环境显示中文,其他显示英文
|
|
223
|
+
|
|
224
|
+
### 支持的分享链接类型
|
|
225
|
+
|
|
226
|
+
| 类型 | URL 特征 | 处理方式 |
|
|
227
|
+
|------|----------|----------|
|
|
228
|
+
| 文件夹 | `:f:` | 通过 REST API 递归枚举文件和子文件夹 |
|
|
229
|
+
| Word 文档 | `:w:` | 解析 `sourcedoc` GUID,通过 `GetFileById` API 获取文件路径 |
|
|
230
|
+
| Excel 表格 | `:x:` | 同上 |
|
|
231
|
+
| PowerPoint | `:p:` | 同上 |
|
|
232
|
+
|
|
233
|
+
### 原理
|
|
234
|
+
|
|
235
|
+
访问 SharePoint 分享链接(`?e=...`)后获取认证 cookie,随后通过 SharePoint REST API 获取文件信息并下载。文件夹分享会递归枚举子目录,单文件分享通过 GUID 定位文件。
|
|
236
|
+
|
|
237
|
+
> **局限**:当前仅支持「任何人可查看」类型的分享链接(匿名访问)。组织内部链接需额外 OAuth2 认证。
|
|
238
|
+
|
|
239
|
+
### 依赖
|
|
240
|
+
|
|
241
|
+
- Python >= 3.9
|
|
242
|
+
- [requests](https://pypi.org/project/requests/)
|
|
243
|
+
- [rich](https://pypi.org/project/rich/)
|
|
244
|
+
|
|
245
|
+
### 安装与使用
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
pip install sharept-dl
|
|
249
|
+
|
|
250
|
+
# 文件夹分享
|
|
251
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:f:/g/personal/...' -o ./downloads
|
|
252
|
+
|
|
253
|
+
# 单文件分享
|
|
254
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:w:/r/personal/.../Doc.aspx?sourcedoc=...&file=....docx'
|
|
255
|
+
|
|
256
|
+
# 详细日志
|
|
257
|
+
sharept-dl -u '...' -v
|
|
258
|
+
|
|
259
|
+
# 禁用断点续传(强制重新下载)
|
|
260
|
+
sharept-dl -u '...' --no-resume
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
> **⚠️ 重要**: URL 务必使用**单引号** `'...'` 包裹,不要用双引号。双引号会让 shell 解释 `$`、`\` 等特殊字符,导致 URL 被截断。
|
|
264
|
+
|
|
265
|
+
### 多语言
|
|
266
|
+
|
|
267
|
+
工具会根据系统语言自动选择提示语言,中文环境显示中文,其他环境显示英文。也可以通过代码手动设置:
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
from sharepoint_dl import set_language
|
|
271
|
+
set_language("en") # 强制英文
|
|
272
|
+
set_language("zh") # 强制中文
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 中断恢复
|
|
276
|
+
|
|
277
|
+
下载中断后,再次运行相同命令即可自动续传——已完成的文件直接跳过,未完成的从 `.part` 断点继续。
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# 首次运行 —— 在第 42/64 个文件时中断
|
|
281
|
+
sharept-dl -u '...' -o ./downloads
|
|
282
|
+
|
|
283
|
+
# 重新运行 —— 跳过前 41 个,续传第 42 个,继续下载后续文件
|
|
284
|
+
sharept-dl -u '...' -o ./downloads
|
|
285
|
+
```
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# sharept-dl
|
|
2
|
+
|
|
3
|
+
Batch download files from SharePoint shared links — pure HTTP, zero browser dependencies.
|
|
4
|
+
|
|
5
|
+
[中文说明](#中文说明) below.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **No browser required** — uses plain HTTP, no Playwright, no Chromium
|
|
10
|
+
- **Pre-scan report** — shows file count and total size before downloading
|
|
11
|
+
- **Stable TUI** — Rich-powered terminal UI with real-time progress, no flickering
|
|
12
|
+
- **Resumable downloads** — interrupted transfers pick up where they left off via HTTP `Range` requests
|
|
13
|
+
- **Auto-skip** — already-downloaded files are detected and skipped instantly
|
|
14
|
+
- **Preserves folder structure** — subdirectories are recreated locally
|
|
15
|
+
- **Safe URL handling** — prevents double-encoding of paths with special/Chinese characters
|
|
16
|
+
- **Single file support** — handles `:w:` (Word), `:x:` (Excel), `:p:` (PowerPoint) share links via GUID lookup
|
|
17
|
+
- **Multi-language** — auto-detects system locale; displays Chinese or English based on your environment
|
|
18
|
+
|
|
19
|
+
## Supported share link types
|
|
20
|
+
|
|
21
|
+
| Type | URL pattern | How it works |
|
|
22
|
+
|------|-------------|--------------|
|
|
23
|
+
| Folder | `:f:` | Recursively enumerates files & subfolders via REST API |
|
|
24
|
+
| Word | `:w:` | Parses `sourcedoc` GUID, resolves via `GetFileById` API |
|
|
25
|
+
| Excel | `:x:` | Same as Word |
|
|
26
|
+
| PowerPoint | `:p:` | Same as Word |
|
|
27
|
+
|
|
28
|
+
## How it works
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
Folder share (:f:)
|
|
32
|
+
│
|
|
33
|
+
├─ [1] HTTP GET → 302 redirect → Set-Cookie (auth)
|
|
34
|
+
├─ [2] REST API: enumerate files & folders
|
|
35
|
+
└─ [3] Download each file (with Range support for resume)
|
|
36
|
+
|
|
37
|
+
Single file share (:w:/:x:/:p:)
|
|
38
|
+
│
|
|
39
|
+
├─ [1] HTTP GET → 302 redirect → Set-Cookie (auth)
|
|
40
|
+
├─ [2] Extract sourcedoc GUID from URL
|
|
41
|
+
├─ [3] REST API: GetFileById('<GUID>') → ServerRelativeUrl
|
|
42
|
+
└─ [4] Download via /_layouts/15/download.aspx
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
> **Limitation**: currently only supports "Anyone with the link" sharing links (anonymous access). Organization-internal links require additional OAuth2 authentication.
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- Python >= 3.9
|
|
50
|
+
- [requests](https://pypi.org/project/requests/)
|
|
51
|
+
- [rich](https://pypi.org/project/rich/)
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
### Via pip
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install sharept-dl
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### From source
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone <repo-url>
|
|
65
|
+
cd sharept-dl
|
|
66
|
+
pip install -e .
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Folder share
|
|
73
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:f:/g/personal/...'
|
|
74
|
+
|
|
75
|
+
# Single file share (Word/Excel/PowerPoint)
|
|
76
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:w:/r/personal/.../Doc.aspx?sourcedoc=...&file=....docx'
|
|
77
|
+
|
|
78
|
+
# Specify output directory
|
|
79
|
+
sharept-dl -u '...' -o ./my_files
|
|
80
|
+
|
|
81
|
+
# Verbose mode
|
|
82
|
+
sharept-dl -u '...' -v
|
|
83
|
+
|
|
84
|
+
# Force re-download everything
|
|
85
|
+
sharept-dl -u '...' --no-resume
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> **⚠️ Important**: Always wrap the URL in **single quotes** `'...'`, NOT double quotes.
|
|
89
|
+
> Double quotes allow the shell to interpret `$`, `\`, and other special characters,
|
|
90
|
+
> which will break the URL.
|
|
91
|
+
|
|
92
|
+
### Options
|
|
93
|
+
|
|
94
|
+
| Argument | Short | Required | Default | Description |
|
|
95
|
+
|----------|-------|----------|---------|-------------|
|
|
96
|
+
| `--url` | `-u` | Yes | — | SharePoint share link (`:f:` folder type) |
|
|
97
|
+
| `--output` | `-o` | No | `.` | Output directory |
|
|
98
|
+
| `--timeout` | `-t` | No | `60` | HTTP request timeout in seconds |
|
|
99
|
+
| `--delay` | `-d` | No | `0.3` | Delay between file downloads (to avoid rate limits) |
|
|
100
|
+
| `--no-resume` | | No | `false` | Disable resume — force re-download all files |
|
|
101
|
+
| `--verbose` | `-v` | No | `false` | Verbose logging (prints to stderr) |
|
|
102
|
+
|
|
103
|
+
### Interrupt & resume
|
|
104
|
+
|
|
105
|
+
If the download is interrupted (Ctrl+C, network failure, etc.), simply run the same command again. The tool will:
|
|
106
|
+
|
|
107
|
+
1. Skip all fully-downloaded files (instant)
|
|
108
|
+
2. Detect `.part` temporary files and resume from where they left off via HTTP `Range` requests
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# First run — interrupted at file 42/64
|
|
112
|
+
sharept-dl -u '...' -o ./downloads
|
|
113
|
+
# ... Ctrl+C ...
|
|
114
|
+
|
|
115
|
+
# Second run — skips 41 complete files, resumes file 42, continues from 43
|
|
116
|
+
sharept-dl -u '...' -o ./downloads
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install -e ".[dev]"
|
|
123
|
+
pytest tests/ -v
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Project structure
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
sharept-dl/
|
|
130
|
+
├── sharepoint_dl/
|
|
131
|
+
│ ├── __init__.py # Package exports
|
|
132
|
+
│ ├── __main__.py # python -m entry point
|
|
133
|
+
│ ├── cli.py # CLI argument parsing & main loop
|
|
134
|
+
│ ├── i18n.py # Multi-language support (zh/en)
|
|
135
|
+
│ ├── session.py # SharePoint authentication & REST API
|
|
136
|
+
│ ├── ui.py # Rich terminal UI rendering
|
|
137
|
+
│ └── utils.py # Utility functions & safe encoding
|
|
138
|
+
├── tests/
|
|
139
|
+
│ ├── test_utils.py # Utility function tests
|
|
140
|
+
│ ├── test_session.py # Session & API tests (mocked HTTP)
|
|
141
|
+
│ ├── test_cli.py # CLI argument parsing tests
|
|
142
|
+
│ └── test_i18n.py # i18n language detection tests
|
|
143
|
+
├── main.py # Legacy entry point (backward compatible)
|
|
144
|
+
├── pyproject.toml # Project metadata & build config
|
|
145
|
+
├── requirements.txt # pip dependency list
|
|
146
|
+
├── LICENSE # MIT license
|
|
147
|
+
└── README.md # This file
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Internationalization (i18n)
|
|
151
|
+
|
|
152
|
+
sharept-dl automatically detects your system language:
|
|
153
|
+
|
|
154
|
+
- **Chinese** (`zh_CN`, `zh_TW`, etc.) → displays Chinese messages
|
|
155
|
+
- **Anything else** → displays English messages
|
|
156
|
+
|
|
157
|
+
You can override the language in code:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from sharepoint_dl import set_language
|
|
161
|
+
set_language("en") # force English
|
|
162
|
+
set_language("zh") # force Chinese
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 中文说明
|
|
172
|
+
|
|
173
|
+
无需浏览器即可批量下载 SharePoint 分享文件。纯 HTTP 实现,零浏览器依赖。
|
|
174
|
+
|
|
175
|
+
### 功能特性
|
|
176
|
+
|
|
177
|
+
- **无需浏览器** — 纯 HTTP 请求,不依赖 Playwright / Chromium
|
|
178
|
+
- **预扫描报告** — 下载前展示文件总数和总大小
|
|
179
|
+
- **稳定终端界面** — Rich 驱动的 TUI,实时进度不闪烁
|
|
180
|
+
- **断点续传** — 中断后重新运行,通过 `.part` 临时文件 + HTTP `Range` 请求自动续传
|
|
181
|
+
- **自动跳过** — 已下载完成的文件即时跳过
|
|
182
|
+
- **保留目录结构** — 子文件夹按原始层级重建
|
|
183
|
+
- **安全编码处理** — 防止特殊字符/中文路径的双重编码问题
|
|
184
|
+
- **单文件支持** — 兼容 `:w:`(Word)、`:x:`(Excel)、`:p:`(PowerPoint)分享链接
|
|
185
|
+
- **多语言** — 自动检测系统语言,中文环境显示中文,其他显示英文
|
|
186
|
+
|
|
187
|
+
### 支持的分享链接类型
|
|
188
|
+
|
|
189
|
+
| 类型 | URL 特征 | 处理方式 |
|
|
190
|
+
|------|----------|----------|
|
|
191
|
+
| 文件夹 | `:f:` | 通过 REST API 递归枚举文件和子文件夹 |
|
|
192
|
+
| Word 文档 | `:w:` | 解析 `sourcedoc` GUID,通过 `GetFileById` API 获取文件路径 |
|
|
193
|
+
| Excel 表格 | `:x:` | 同上 |
|
|
194
|
+
| PowerPoint | `:p:` | 同上 |
|
|
195
|
+
|
|
196
|
+
### 原理
|
|
197
|
+
|
|
198
|
+
访问 SharePoint 分享链接(`?e=...`)后获取认证 cookie,随后通过 SharePoint REST API 获取文件信息并下载。文件夹分享会递归枚举子目录,单文件分享通过 GUID 定位文件。
|
|
199
|
+
|
|
200
|
+
> **局限**:当前仅支持「任何人可查看」类型的分享链接(匿名访问)。组织内部链接需额外 OAuth2 认证。
|
|
201
|
+
|
|
202
|
+
### 依赖
|
|
203
|
+
|
|
204
|
+
- Python >= 3.9
|
|
205
|
+
- [requests](https://pypi.org/project/requests/)
|
|
206
|
+
- [rich](https://pypi.org/project/rich/)
|
|
207
|
+
|
|
208
|
+
### 安装与使用
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
pip install sharept-dl
|
|
212
|
+
|
|
213
|
+
# 文件夹分享
|
|
214
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:f:/g/personal/...' -o ./downloads
|
|
215
|
+
|
|
216
|
+
# 单文件分享
|
|
217
|
+
sharept-dl -u 'https://xxx.sharepoint.cn/:w:/r/personal/.../Doc.aspx?sourcedoc=...&file=....docx'
|
|
218
|
+
|
|
219
|
+
# 详细日志
|
|
220
|
+
sharept-dl -u '...' -v
|
|
221
|
+
|
|
222
|
+
# 禁用断点续传(强制重新下载)
|
|
223
|
+
sharept-dl -u '...' --no-resume
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
> **⚠️ 重要**: URL 务必使用**单引号** `'...'` 包裹,不要用双引号。双引号会让 shell 解释 `$`、`\` 等特殊字符,导致 URL 被截断。
|
|
227
|
+
|
|
228
|
+
### 多语言
|
|
229
|
+
|
|
230
|
+
工具会根据系统语言自动选择提示语言,中文环境显示中文,其他环境显示英文。也可以通过代码手动设置:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
from sharepoint_dl import set_language
|
|
234
|
+
set_language("en") # 强制英文
|
|
235
|
+
set_language("zh") # 强制中文
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### 中断恢复
|
|
239
|
+
|
|
240
|
+
下载中断后,再次运行相同命令即可自动续传——已完成的文件直接跳过,未完成的从 `.part` 断点继续。
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# 首次运行 —— 在第 42/64 个文件时中断
|
|
244
|
+
sharept-dl -u '...' -o ./downloads
|
|
245
|
+
|
|
246
|
+
# 重新运行 —— 跳过前 41 个,续传第 42 个,继续下载后续文件
|
|
247
|
+
sharept-dl -u '...' -o ./downloads
|
|
248
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sharept-dl"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "SharePoint 文件下载工具 — 纯 HTTP 实现,支持文件夹和单文件分享链接"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Neal"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["sharepoint", "download", "batch", "cli", "rest-api"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Intended Audience :: System Administrators",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Programming Language :: Python :: 3.13",
|
|
29
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
30
|
+
"Topic :: Utilities",
|
|
31
|
+
]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"requests>=2.28",
|
|
34
|
+
"rich>=13.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"pytest>=7.0",
|
|
40
|
+
"pytest-cov>=4.0",
|
|
41
|
+
"pytest-mock>=3.10",
|
|
42
|
+
"requests-mock>=1.11",
|
|
43
|
+
"ruff>=0.3",
|
|
44
|
+
"mypy>=1.8",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
sharept-dl = "sharepoint_dl.cli:main"
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Repository = "https://github.com/user/sharept-dl"
|
|
52
|
+
Issues = "https://github.com/user/sharept-dl/issues"
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.packages.find]
|
|
55
|
+
include = ["sharepoint_dl*"]
|
|
56
|
+
|
|
57
|
+
[tool.ruff]
|
|
58
|
+
line-length = 120
|
|
59
|
+
target-version = "py39"
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint]
|
|
62
|
+
select = ["E", "F", "I", "N", "W"]
|
|
63
|
+
|
|
64
|
+
[tool.ruff.format]
|
|
65
|
+
quote-style = "double"
|
|
66
|
+
|
|
67
|
+
[tool.mypy]
|
|
68
|
+
python_version = "3.9"
|
|
69
|
+
strict = false
|
|
70
|
+
ignore_missing_imports = true
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
testpaths = ["tests"]
|
|
74
|
+
addopts = "-v --tb=short"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""sharept-dl — SharePoint 批量下载工具。
|
|
2
|
+
|
|
3
|
+
纯 HTTP 实现,通过分享链接 token 换取 cookie,利用 SharePoint REST API
|
|
4
|
+
递归枚举文件和下载,无需浏览器、无需登录。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
__all__ = [
|
|
9
|
+
"SharePointSession",
|
|
10
|
+
"format_bytes",
|
|
11
|
+
"shorten_path",
|
|
12
|
+
"safe_unquote",
|
|
13
|
+
"safe_quote",
|
|
14
|
+
"safe_quote_strict",
|
|
15
|
+
"t",
|
|
16
|
+
"set_language",
|
|
17
|
+
"current_language",
|
|
18
|
+
"main",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
from .i18n import current_language, set_language, t # noqa: E402, F401
|
|
22
|
+
from .session import SharePointSession # noqa: E402, F401
|
|
23
|
+
from .utils import ( # noqa: E402, F401
|
|
24
|
+
format_bytes,
|
|
25
|
+
safe_quote,
|
|
26
|
+
safe_quote_strict,
|
|
27
|
+
safe_unquote,
|
|
28
|
+
shorten_path,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main(): # noqa: D401
|
|
33
|
+
"""快捷入口函数,不需要传 sys.argv。"""
|
|
34
|
+
import sys
|
|
35
|
+
|
|
36
|
+
from .cli import main as _main
|
|
37
|
+
|
|
38
|
+
sys.exit(_main())
|