Metadata-Version: 2.4
Name: sharept-dl
Version: 1.1.0
Summary: Download files from SharePoint shared links — pure HTTP, supports both folder and single file shares
Author: Neal
License: MIT
Project-URL: Repository, https://github.com/Neal-Ding/sharept-dl
Project-URL: Issues, https://github.com/Neal-Ding/sharept-dl/issues
Keywords: sharepoint,download,batch,cli,rest-api
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Requires-Dist: rich>=13.0
Provides-Extra: browser
Requires-Dist: cryptography>=41.0; extra == "browser"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: pytest-mock>=3.10; extra == "dev"
Requires-Dist: requests-mock>=1.11; extra == "dev"
Requires-Dist: ruff>=0.3; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Dynamic: license-file

# sharept-dl

Batch download files from SharePoint shared links — pure HTTP, zero browser dependencies.

[中文说明](#中文说明) below.

## Features

- **Two auth modes** — anonymous "Anyone with the link" sharing works out of the box; organization-internal links use browser cookies automatically
- **Auto cookie extraction** — `--cookies-from-browser chrome|edge|firefox|safari` reads SharePoint auth cookies without manual copying
- **No browser required** — uses plain HTTP, no Playwright, no Chromium
- **Pre-scan report** — shows file count and total size before downloading
- **Stable TUI** — Rich-powered terminal UI with real-time progress, no flickering
- **Resumable downloads** — interrupted transfers pick up where they left off via HTTP `Range` requests
- **Auto-skip** — already-downloaded files are detected and skipped instantly
- **Preserves folder structure** — subdirectories are recreated locally
- **Safe URL handling** — prevents double-encoding of paths with special/Chinese characters
- **Single file support** — handles `:w:` (Word), `:x:` (Excel), `:p:` (PowerPoint), `:b:`, `:t:`, `:s:` share links via GUID lookup
- **Multi-language** — auto-detects system locale; displays Chinese or English based on your environment

## Supported share link types

| Type | URL pattern | How it works |
|------|-------------|--------------|
| Folder | `:f:` | Recursively enumerates files & subfolders via REST API |
| Word | `:w:` | Parses `sourcedoc` GUID, resolves via `GetFileById` API |
| Excel | `:x:` | Same as Word |
| PowerPoint | `:p:` | Same as Word |
| Other file | `:b:`, `:t:`, `:s:` | Same as Word |

## How it works

```
Anonymous share ("Anyone with the link")
  │
  ├─ [1] HTTP GET → 302 redirect → Set-Cookie (auth via ?e= token)
  ├─ [2] REST API: enumerate files & folders
  └─ [3] Download each file (with Range support for resume)

Organization-internal link (requires login)
  │
  ├─ [1] Extract FedAuth / rtFa cookies from browser
  ├─ [2] Inject cookies into HTTP session
  ├─ [3] HTTP GET → 302 redirect → (cookie auth)
  ├─ [4] REST API: enumerate files & folders
  └─ [5] Download each file (with Range support for resume)
```

> **Limitation**: Each folder is limited to **5,000 files and 5,000 subfolders** (SharePoint REST API `$top` limit). Folders exceeding this limit will have truncated results.

## Requirements

- Python >= 3.9
- [requests](https://pypi.org/project/requests/)
- [rich](https://pypi.org/project/rich/)
- Optional: `pip install sharept-dl[browser]` for Chrome/Edge cookie decryption (Firefox and Safari work without extra deps)

## Installation

### Via pip

```bash
pip install sharept-dl
```

### From source

```bash
git clone https://github.com/Neal-Ding/sharept-dl
cd sharept-dl
pip install -e .
```

## Usage

```bash
# Anonymous share (Anyone with the link)
sharept-dl -u 'https://xxx.sharepoint.cn/:f:/g/personal/...'

# Organization-internal link — auto-read cookies from browser
sharept-dl -u 'https://xxx.sharepoint.com/:f:/g/...' --cookies-from-browser chrome

# Manual cookie injection
sharept-dl -u 'https://xxx.sharepoint.com/:f:/g/...' --cookie 'FedAuth=eyJ...; rtFa=...'

# Single file share (Word/Excel/PowerPoint)
sharept-dl -u 'https://xxx.sharepoint.cn/:w:/r/personal/.../Doc.aspx?sourcedoc=...&file=....docx'

# Specify output directory
sharept-dl -u '...' -o ./my_files

# Verbose mode (debugging)
sharept-dl -u '...' -v

# Force re-download everything
sharept-dl -u '...' --no-resume

# Run as a Python module (no pip install needed)
python -m sharept_dl -u '...'
```

> **⚠️ Important**: Always wrap the URL in **single quotes** `'...'`, NOT double quotes.
> Double quotes allow the shell to interpret `$`, `\`, and other special characters,
> which will break the URL.

### Options

| Argument | Short | Required | Default | Description |
|----------|-------|----------|---------|-------------|
| `--url` | `-u` | Yes | — | SharePoint share link (folder `:f:` or file `:w:`/`:x:`/`:p:`/`:b:`/`:t:`/`:s:`) |
| `--output` | `-o` | No | `.` | Output directory |
| `--timeout` | `-t` | No | `60` | HTTP request timeout in seconds |
| `--delay` | `-d` | No | `0.3` | Delay between file downloads (to avoid rate limits) |
| `--no-resume` | | No | `false` | Disable resume — force re-download all files |
| `--cookies-from-browser` | | No | — | Read auth cookies from browser: `chrome`, `edge`, `firefox`, `safari` |
| `--cookie` | | No | — | Manual cookie string: `'FedAuth=...; rtFa=...'` |
| `--verbose` | `-v` | No | `false` | Verbose logging (prints to stderr) |

### How to get cookies for internal links

**Method 1 — Auto-extract (recommended):**

```bash
# Login to SharePoint in your browser first, then run:
sharept-dl -u '...' --cookies-from-browser safari   # macOS
sharept-dl -u '...' --cookies-from-browser chrome   # macOS/Windows/Linux
sharept-dl -u '...' --cookies-from-browser edge     # macOS/Windows
sharept-dl -u '...' --cookies-from-browser firefox  # macOS/Windows/Linux
```

The `--cookies-from-browser` flag automatically reads `FedAuth` and `rtFa` cookies
from your browser's local storage. No manual copying needed.

For Chrome/Edge on macOS, `cryptography` is required for cookie decryption:
```bash
pip install sharept-dl[browser]
```

**Method 2 — Manual injection:**

1. Open SharePoint in your browser and sign in
2. Open DevTools (F12) → Application → Cookies
3. Find your SharePoint domain, copy the values of `FedAuth` and `rtFa`
4. Run:
```bash
sharept-dl -u '...' --cookie 'FedAuth=PASTE_HERE; rtFa=PASTE_HERE'
```

### Exit codes

| Code | Meaning |
|------|---------|
| `0` | All files downloaded successfully, or interrupted by user (partial completion) |
| `1` | Authentication failed, missing site context, login required, or one or more files failed to download |

### Interrupt & resume

If the download is interrupted (Ctrl+C, network failure, etc.), simply run the same command again. The tool will:

1. Skip all fully-downloaded files (instant)
2. Detect `.part` temporary files and resume from where they left off via HTTP `Range` requests

```bash
# First run — interrupted at file 42/64
sharept-dl -u '...' -o ./downloads
# ... Ctrl+C ...

# Second run — skips 41 complete files, resumes file 42, continues from 43
sharept-dl -u '...' -o ./downloads
```

## Development

```bash
pip install -e ".[dev]"
pytest tests/ -v
```

## Project structure

```
sharept-dl/
├── sharept_dl/
│   ├── __init__.py       # Package exports
│   ├── __main__.py       # python -m entry point
│   ├── cli.py            # CLI argument parsing & main loop
│   ├── cookies.py        # Browser cookie extraction (Chrome/Edge/Firefox/Safari)
│   ├── i18n.py           # Multi-language support (zh/en)
│   ├── session.py        # SharePoint authentication & REST API
│   ├── ui.py             # Rich terminal UI rendering
│   └── utils.py          # Utility functions & safe encoding
├── tests/
│   ├── test_utils.py     # Utility function tests
│   ├── test_session.py   # Session & API tests (mocked HTTP)
│   ├── test_cli.py       # CLI argument parsing tests
│   └── test_i18n.py      # i18n language detection tests
├── main.py               # Legacy entry point (backward compatible)
├── pyproject.toml        # Project metadata & build config
├── requirements.txt      # pip dependency list
├── LICENSE               # MIT license
└── README.md             # This file
```

## Internationalization (i18n)

sharept-dl automatically detects your system language:

- **Chinese** (`zh_CN`, `zh_TW`, etc.) → displays Chinese messages
- **Anything else** → displays English messages

You can override the language in code:

```python
from sharept_dl import set_language
set_language("en")  # force English
set_language("zh")  # force Chinese
```

## License

MIT

---

## 中文说明

无需浏览器即可批量下载 SharePoint 分享文件。纯 HTTP 实现，零浏览器依赖。

### 功能特性

- **两种认证模式** — 「任何人可查看」的匿名分享开箱即用；组织内部链接通过浏览器 Cookie 自动认证
- **自动提取 Cookie** — `--cookies-from-browser chrome|edge|firefox|safari` 自动读取浏览器中的 SharePoint 认证信息
- **无需浏览器** — 纯 HTTP 请求，不依赖 Playwright / Chromium
- **预扫描报告** — 下载前展示文件总数和总大小
- **稳定终端界面** — Rich 驱动的 TUI，实时进度不闪烁
- **断点续传** — 中断后重新运行，通过 `.part` 临时文件 + HTTP `Range` 请求自动续传
- **自动跳过** — 已下载完成的文件即时跳过
- **保留目录结构** — 子文件夹按原始层级重建
- **安全编码处理** — 防止特殊字符/中文路径的双重编码问题
- **单文件支持** — 兼容 `:w:`（Word）、`:x:`（Excel）、`:p:`（PowerPoint）、`:b:`、`:t:`、`:s:` 分享链接
- **多语言** — 自动检测系统语言，中文环境显示中文，其他显示英文

### 支持的分享链接类型

| 类型 | URL 特征 | 处理方式 |
|------|----------|----------|
| 文件夹 | `:f:` | 通过 REST API 递归枚举文件和子文件夹 |
| Word 文档 | `:w:` | 解析 `sourcedoc` GUID，通过 `GetFileById` API 获取文件路径 |
| Excel 表格 | `:x:` | 同上 |
| PowerPoint | `:p:` | 同上 |
| 其他文件 | `:b:`、`:t:`、`:s:` | 同上 |

### 原理

**匿名分享**通过访问 `?e=...` 令牌获取认证 cookie，**组织内部链接**通过浏览器 Cookie（FedAuth / rtFa）完成认证，随后通过 SharePoint REST API 获取文件信息并下载。文件夹分享会递归枚举子目录，单文件分享通过 GUID 定位文件。

> **局限**：每个文件夹最多枚举 **5,000 个文件和 5,000 个子文件夹**（SharePoint REST API `$top` 限制）。超出此数量的内容将被截断。

### 依赖

- Python >= 3.9
- [requests](https://pypi.org/project/requests/)
- [rich](https://pypi.org/project/rich/)
- 可选：`pip install sharept-dl[browser]` 用于 Chrome/Edge 的 Cookie 解密（Firefox 和 Safari 无需额外依赖）

### 安装与使用

```bash
pip install sharept-dl

# 匿名分享
sharept-dl -u 'https://xxx.sharepoint.cn/:f:/g/personal/...' -o ./downloads

# 内部链接 — 自动从浏览器读取 Cookie
sharept-dl -u 'https://xxx.sharepoint.com/:f:/g/...' --cookies-from-browser chrome

# 手动注入 Cookie
sharept-dl -u 'https://xxx.sharepoint.com/:f:/g/...' --cookie 'FedAuth=eyJ...; rtFa=...'

# 单文件分享
sharept-dl -u 'https://xxx.sharepoint.cn/:w:/r/personal/.../Doc.aspx?sourcedoc=...&file=....docx'

# 详细日志
sharept-dl -u '...' -v
```

> **⚠️ 重要**: URL 务必使用**单引号** `'...'` 包裹，不要用双引号。

### 参数说明

| 参数 | 短选项 | 必选 | 默认值 | 说明 |
|------|--------|------|--------|------|
| `--url` | `-u` | 是 | — | SharePoint 分享链接（文件夹 `:f:` 或文件 `:w:`/`:x:`/`:p:`/`:b:`/`:t:`/`:s:`） |
| `--output` | `-o` | 否 | `.` | 输出目录 |
| `--timeout` | `-t` | 否 | `60` | HTTP 请求超时秒数 |
| `--delay` | `-d` | 否 | `0.3` | 文件间下载间隔秒数 |
| `--no-resume` | | 否 | `false` | 禁用断点续传 |
| `--cookies-from-browser` | | 否 | — | 从浏览器读取 Cookie：`chrome`、`edge`、`firefox`、`safari` |
| `--cookie` | | 否 | — | 手动传入 Cookie：`'FedAuth=...; rtFa=...'` |
| `--verbose` | `-v` | 否 | `false` | 详细日志 |

### 如何获取内部链接的 Cookie

**方法一 — 自动提取（推荐）：**

```bash
# 先在浏览器中登录 SharePoint，然后运行：
sharept-dl -u '...' --cookies-from-browser safari   # macOS
sharept-dl -u '...' --cookies-from-browser chrome   # macOS/Windows/Linux
sharept-dl -u '...' --cookies-from-browser edge     # macOS/Windows
sharept-dl -u '...' --cookies-from-browser firefox  # macOS/Windows/Linux
```

Chrome/Edge 在 macOS 上需要 `cryptography` 来解密 Cookie：
```bash
pip install sharept-dl[browser]
```

**方法二 — 手动注入：**

1. 在浏览器中打开 SharePoint 并登录
2. 打开开发者工具（F12）→ Application → Cookies
3. 找到你的 SharePoint 域名，复制 `FedAuth` 和 `rtFa` 的值
4. 运行：
```bash
sharept-dl -u '...' --cookie 'FedAuth=PASTE_HERE; rtFa=PASTE_HERE'
```

### 退出码

| 代码 | 含义 |
|------|------|
| `0` | 全部下载成功，或用户主动中断（部分完成） |
| `1` | 认证失败、需要登录、链接无效，或至少一个文件下载失败 |

### 多语言

工具会根据系统语言自动选择提示语言，中文环境显示中文，其他环境显示英文。也可以通过代码手动设置：

```python
from sharept_dl import set_language
set_language("en")  # 强制英文
set_language("zh")  # 强制中文
```

### 中断恢复

下载中断后，再次运行相同命令即可自动续传——已完成的文件直接跳过，未完成的从 `.part` 断点继续。

```bash
# 首次运行 —— 在第 42/64 个文件时中断
sharept-dl -u '...' -o ./downloads

# 重新运行 —— 跳过前 41 个，续传第 42 个，继续下载后续文件
sharept-dl -u '...' -o ./downloads
```
