docs/imports.md
Rama main · réplica de lectura del repositorio original.
# 单张图片与历史路径导入
## 保留原目录结构
如果旧图床文件已经按 URL 路径组织,可以将整个目录树只读挂载到 `/data/migrations`。ImageSilo 会把该目录下的相对路径直接作为公网路径,不写入数据库,也不要求创建历史路径映射:
```text
/data/migrations/i/2022/04/example.jpg -> /i/2022/04/example.jpg
```
只会公开 JPEG、PNG、WebP 和 GIF 普通文件;路径穿越、越界软链接和保留的系统路由都会被拒绝。数据库中的历史路径映射优先于迁移目录中的同名文件。
这种方式适合冷迁移或长期只读兼容。需要在后台管理、搜索、设置可见性或转换 WebP 的图片,仍应使用下方的单张导入接口。
后台“迁移管理”会递归扫描该目录并平铺展示所有可公开交付的图片,支持搜索、格式/大小筛选和复制链接。列表使用 30 分钟惰性快照:缓存过期后的首次访问才重新扫描,不会后台定时扫盘;目录有外部变动时可点击“刷新”立即重建快照。图片直链不依赖该列表快照,文件变动仍按实时文件状态交付。默认只读;若要允许永久删除专用迁移副本,挂载必须可写、容器用户 `10001:10001` 必须拥有删除权限,并显式设置 `IMAGESILO_MIGRATION_MUTATIONS=true`。删除图片后只会向上递归移除真正为空的父目录(包括空的顶层 `i` 或 `images` 目录),不会删除迁移根目录,也不会清理仍含非图片文件的目录。原始迁移快照应继续独立保留。
ImageSilo 的核心导入契约始终只有“一张合法图片 + 一个旧 URL path”。服务端不识别第三方图床格式,也不提供批量任务队列;任意来源都由外部脚本顺序枚举并调用同一个接口。
## 单张 curl
API Token 必须同时具备 `images:upload` 与 `aliases:write`;如果导入为私密并需要脚本自动下载校验,还必须具备 `images:read_private`:
```bash
curl --fail --show-error \
--header "Authorization: Bearer $IMAGESILO_TOKEN" \
--form 'file=@/absolute/path/example.jpg' \
--form 'alias=/old/path/example.jpg' \
--form 'visibility=public' \
"$IMAGESILO_BASE_URL/api/v1/imports"
```
导入只验证格式、大小和像素并保存原始字节,不执行压缩或 WebP 转换。成功响应包含新 Image ID、标准 URL、SHA-256 和已创建的别名。
别名冲突返回 `409 Conflict`。图片记录与一个别名在同一个 SQLite 事务中提交;冲突或数据库失败不会留下新图片记录、正式文件或缩略图。
## 清单脚本
[import-manifest.sh](../scripts/import-manifest.sh) 使用 TSV 清单严格串行导入,并在每项成功后访问旧 URL、重新计算 SHA-256。它需要 `curl`、`jq`,以及 `sha256sum` 或 `shasum`。
清单格式:
```text
# 旧 URL path<TAB>本地图片路径
/i/2022/05/a.jpg /absolute/source/a.jpg
/legacy/b.webp /absolute/source/b.webp
```
执行:
```bash
IMAGESILO_BASE_URL=https://img.example.com \
IMAGESILO_TOKEN=ist_xxx \
scripts/import-manifest.sh \
--manifest ./imports.tsv \
--output ./imports-result.jsonl \
--visibility public
```
结果文件已存在时脚本拒绝覆盖。出现冲突、HTTP 错误、响应 SHA 不一致或旧 URL 字节不一致时,脚本以非零状态退出,并保留逐项 JSONL 结果供筛选和重试。
## 迁移验收
- 清单输入数、成功数、冲突数和错误数可对账。
- 每个成功项的源文件、API 返回 SHA-256 和旧 URL 下载字节一致。
- 重复路径不会创建额外图片记录或正式文件。
- 迁移结束后手动执行系统巡检,并确认缺失文件、孤儿文件和清理失败均为零。
- 使用停止写入后的最终清单再执行一次正式迁移;不要把来源系统解析逻辑加入 ImageSilo 核心服务。