Metadata-Version: 2.4
Name: xes-assets
Version: 1.2.4
Summary: Zero-dependency downloader for the XES Python course asset files (RAR + ZIP), plus two on-demand Minecraft assets: importing the library fetches the course files, the MC archives are fetched by name.
Author: xes-assets
License: MIT
Project-URL: Homepage, https://pypi.org/project/xes-assets/
Project-URL: Source, https://livefile.xesimg.com/programme/python_assets/
Project-URL: Lesson files (RAR + ZIP), https://livefile.xesimg.com/programme/python_assets/3f51c62b04d3aacc27b0d53f294ecc3b.rar
Project-URL: Minecraft save (1.16.4), https://livefile.xesimg.com/programme/python_assets/3d613c7ffd23634cf78feeb85cecc8ca.zip
Project-URL: MC Win7 32-bit offline pack, https://livefile.xesimg.com/programme/python_assets/6e4f8416e073755dd7b7aa52111537ef.zip
Keywords: xes,xesimg,assets,downloader,python-assets,no-dependencies,zero-dependency,sha256,minecraft,launcher
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: Chinese (Simplified)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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 :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Archiving
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# xes-assets

零依赖下载器 / Zero-dependency downloader for the XES Python course asset files:

- `https://livefile.xesimg.com/programme/python_assets/3f51c62b04d3aacc27b0d53f294ecc3b.rar`
- `https://livefile.xesimg.com/programme/python_assets/a3635617bd88675041ba69f8398df5a0.zip`

只用 Python 标准库（`urllib`、`hashlib`、`zipfile`），**没有任何第三方依赖**。
Uses nothing but the Python standard library — **no third-party dependency at all**.

## 安装 + 导库即下载 / Install & import-to-download

```bash
pip install xes-assets
```

```python
import xes_assets          # 导入即自动下载两个文件到当前工作目录
print(xes_assets.AUTODOWNLOADED)   # [Path(...rar), Path(...zip)]
```

`import xes_assets` 会立刻把两个文件下载到**当前工作目录**（含断点续传、大小 + SHA-256 校验）；
已存在且校验通过的文件直接跳过。

| 环境变量 | 作用 |
| --- | --- |
| `XES_ASSETS_DEST` | 下载目录（默认当前工作目录） |
| `XES_ASSETS_AUTODOWNLOAD=0` | 导入时**不**下载（退回手动调用 API） |
| `XES_ASSETS_QUIET=1` | 不显示进度条 |

```python
# 指定目录导入
import os; os.environ["XES_ASSETS_DEST"] = r"D:\xes"
import xes_assets
```

导入失败（断网等）会抛 `XesAssetError` 并提示设置 `XES_ASSETS_AUTODOWNLOAD=0`。

## 命令行 / CLI

CLI **不会**触发导入时下载，只做你指定的动作：

```bash
xes-assets --list                        # 查看两个文件的信息
xes-assets zip -d D:\xes                 # 下载 ZIP
xes-assets all -d D:\xes -x              # 下载两个并解压
xes-assets rar --verify-only -d D:\xes   # 只校验已下载文件
python -m xes_assets all -d D:\xes       # 等价写法
```

| 参数 | 说明 |
| --- | --- |
| `ASSET`（位置参数） | `rar`、`zip`、`all`、文件名或 URL；省略时等于 `all` |
| `-d, --dest DIR` | 输出目录（默认当前目录） |
| `-x, --extract` | 下载后解压（RAR 需要外部解压工具，见下） |
| `-f, --overwrite` | 覆盖已存在文件 |
| `--no-verify` | 跳过 SHA-256 校验 |
| `-q, --quiet` | 不显示进度 |
| `--verify-only` | 只校验不下载 |
| `--list` | 列出已知文件 |

## Minecraft 文件（按需下载，导入时**不会**下载）

同一个桶里还有两个 MC 文件。它们体积大，**没有**放进 `ASSET_ORDER`，所以 `import xes_assets`
和 `xes-assets all` 都不会碰它们，必须点名下载：

```bash
xes-assets mc-save -d D:\xes      # 9.2 MB  存档：金州高中主档（Minecraft 1.16.4）
xes-assets mc-win7 -d D:\xes      # 378 MB  32 位 Win7 / 2GB 内存的老电脑用的全离线启动包
```

直接下载也可以（和上面是同一批字节，校验值见文末表格）：

- `https://livefile.xesimg.com/programme/python_assets/3d613c7ffd23634cf78feeb85cecc8ca.zip` — 存档 `saves\金州高中主档\`
- `https://livefile.xesimg.com/programme/python_assets/6e4f8416e073755dd7b7aa52111537ef.zip` — 离线启动包 `MC-Win7-1.16.5\`

```python
from xes_assets import download
download("mc-save", r"D:\xes")    # 解压后是 saves\金州高中主档\
download("mc-win7", r"D:\xes")    # 解压后是 MC-Win7-1.16.5\，双击 Start-Game.bat 进游戏
```

`mc-win7` 里有：HMCL 3.6.20（官方"旧版"线，要求 Java 8+、支持 Windows 7）、Minecraft 1.16.5 的
version json + client.jar + 42 个 Windows 库 + `natives\`（含 32 位 dll）、1.16 资源索引和全部
2596 个资源文件（318.5 MiB，全程不用联网），外加一份 32 位 Java 8（Azul Zulu 8u181 win32）和两个
`.bat`。选 1.16.5 是因为存档本身是 1.16.4 建的，而原压缩包那套 Minecraft 26.1 要求 Java 25
（没有 32 位 Windows 版），老机器装不上。
`Start-Game.bat` 是主路径（离线单人，堆大小按物理内存自动选）；HMCL 那份 jar 在 32 位 Windows 上
**跑不起来**——它要 JavaFX，而只有 Oracle Java 8 自带 JavaFX，包内这份 OpenJDK 没有、OpenJFX 也从
没有 32 位 Windows 版，脚本会自己把这件事说清楚并指向 PCL2。细节见包内 `README.txt`。

## Python API

```python
from xes_assets import ASSETS, download, download_all, download_on_import, extract, verify

download("zip", r"D:\xes")            # -> Path，含大小 + SHA-256 校验
download_all(r"D:\xes")               # 两个都下
download_on_import(r"D:\xes")         # 同导入行为，可指定目录
verify("rar", r"D:\xes")              # -> True/False
extract("zip", r"D:\xes")             # 标准库解压，返回目录
extract("rar", r"D:\xes")             # 需外部 7z / UnRAR（见下）
```

单个函数的行为：

- `download(key, dest=".", *, overwrite=False, verify_checksum=True, progress=None, timeout=60, retries=3)`
  先写 `<文件名>.part`，校验大小与 SHA-256 通过后才原子改名为正式文件；断点续传用 HTTP `Range`
  （服务器返回 206 时继续，否则从头开始），网络中断自动重试。
- `download_all(dest=".", *, keys=None, **kwargs)` → `List[Path]`
- `extract(key, dest=None, *, archive=None, overwrite=False)` → 解压目录 `Path`
- `verify(key, path=None, dest=".")` → `bool`
- `asset_path(key, dest=".")` → 预期的本地路径
- `AUTODOWNLOADED` 为本次导入已下载/已确认的路径列表
- `ASSETS` / `ASSET_ORDER` 为元数据常量；`XesAssetError` 为统一异常

## 文件与校验值 / Files

| key | 文件名 | 大小 | SHA-256 |
| --- | --- | --- | --- |
| `rar` | `3f51c62b04d3aacc27b0d53f294ecc3b.rar` | 568,456,521 B | `ea41b34bd193cf0039386c0cfe22f93c2225bb43ef01d69740106a35e05d7c85` |
| `zip` | `a3635617bd88675041ba69f8398df5a0.zip` | 39,463,900 B | `63fdddb6c37849606ae32d08e522bbd2a627be90971005946b6c332a7715ff93` |
| `mc-save` | `3d613c7ffd23634cf78feeb85cecc8ca.zip` | 9,624,157 B | `8d18d4c12ad8708b749233fa94065dce41188f44b522272d4e64e4a85132d624` |
| `mc-win7` | `6e4f8416e073755dd7b7aa52111537ef.zip` | 396,796,793 B | `6cc67c08af1518387210ee976e79aabda576d4d50b39ce9c18e04f9be36ff3a3` |

后两个是 MC 文件，只在点名下载时取（见上节）。

校验值在主文件被上游替换前一直有效；上游变更时下载会明确报 `checksum mismatch`
（不会静默留下坏文件）。

## 关于 RAR 解压 / About RAR extraction

**下载**永远只需要标准库。**解压 `.rar`** 时本包会依次查找
`7z` / `7zz` / `7za` / `unrar` / `unar` / `bsdtar`（PATH 中或常见安装路径
`C:\Program Files\7-Zip\7z.exe`、`C:\Program Files\WinRAR\UnRAR.exe`），
找不到就抛 `XesAssetError` 并提示手工解压。ZIP 解压完全由标准库完成。

## Changelog

- **1.2.4**（仅元数据）— 修正 PyPI 左侧 Project links：`Project-URL` 的标签上限是 **32 字符**，`Minecraft offline pack for 32-bit Win7 (1.16.5)`（46 字符）会让整次上传被仓库拒成光秃秃的 `400 Bad Request`（twine 7.0 默认不打印原因，得自己拦包才看得到），改成 `MC Win7 32-bit offline pack`。1.2.3 那两个文件已经上传，页面元数据是空的，需要的话在 PyPI 网页端删掉该版本。

- **1.2.3**（仅元数据）— PyPI 左侧 Project links 补上三条直链（课程 RAR、MC 存档、Win7 离线包），之前只有 Homepage 和桶目录；下载逻辑与校验值未变。

- **1.2.2**（仅文档）— 在 Minecraft 一节里补上两个文件的完整直链，之前只有 md5 文件名，页面外的人还得自己拼 `BASE_URL`。下载逻辑、校验值、包内容都没变。

- **1.2.1** — `mc-win7` 换成修订版（新链接、新校验值）：内存不再写死 `-Xmx1G`，改为启动脚本按物理内存自动选堆（<1600MB→384M，<2600MB→640M，其余 1G）并改用 Serial GC / 单档 JIT / 128M metaspace / 64M code cache；预置低配 `.minecraft\options.txt`；异常退出时自动把最新崩溃报告复制成 `CRASH-MC.txt`、JVM 错误复制成 `CRASH-JVM.txt`；README 里写清 **HMCL 3.6.x 需要 JavaFX，而 32 位 Windows 上没有任何自带 JavaFX 的可 redistribut Java**（OpenJFX 无 32 位 Windows 版，Java 11+ 也没有），所以图形化管理改用 PCL2。`mc-save` 未变。
- **1.2.0** — 新增两个按需下载的 MC 文件 `mc-save`（1.16.4 存档）与 `mc-win7`（32 位 Win7 / 2GB 内存的全离线 1.16.5 启动包，含 HMCL 3.6.20 + 全部资源 + 32 位 Java 8）；`--list` 现在用 `[auto]` / `[only]` 标出哪些是导入时下载、哪些要点名；`ON_DEMAND_ORDER` 常量。导入时自动下载的文件集合没有变化（仍是 `rar` + `zip`）。
- **1.1.0** — `import xes_assets` 直接下载（`XES_ASSETS_DEST` / `XES_ASSETS_AUTODOWNLOAD` / `XES_ASSETS_QUIET`），新增 `download_on_import()` 与 `AUTODOWNLOADED`；CLI 不再触发导入下载。
- **1.0.0** — 首个版本：手动下载 API + CLI，断点续传、大小/SHA-256 校验。

## License

MIT
