优化,添加115接口文档

This commit is contained in:
truewhile
2026-09-05 14:32:58 +08:00
parent d00b14df55
commit 0e9fb2c937
57 changed files with 5682 additions and 76 deletions
+12
View File
@@ -45,6 +45,9 @@ type FileEntry struct {
MTime int64 `json:"mtime,omitempty"`
// PickCode is 115-specific; other providers use ID directly.
PickCode string `json:"pick_code,omitempty"`
// Sha1 is 115-specific content hash(大写 hex,目录/未完成文件可能为空或占位符)。
// 其他网盘不提供,留空时调用方退回大小比对。用于元数据"是否同一文件"的精确判定。
Sha1 string `json:"sha1,omitempty"`
}
// DirectLink is a resolved playback target.
@@ -72,6 +75,15 @@ type Provider interface {
Resolve(ctx context.Context, fileRef string) (*DirectLink, error)
}
// BatchResolver is implemented by providers that can resolve several file
// references in fewer API calls(115 的 downurl 接口支持逗号分隔多个 pick_code,
// 批量换取可显著降低下载队列的换链请求量)。返回以原始引用为键的直链 map;
// 解析失败的引用不在结果中,err 汇报批量机制本身的失败,调用方应据此对缺失
// 项回退到逐个 Resolve。
type BatchResolver interface {
ResolveBatch(ctx context.Context, fileRefs []string) (map[string]*DirectLink, error)
}
// MutableProvider is implemented by cloud bridges that support safe folder
// management through their official API or standard WebDAV methods.
type MutableProvider interface {
+11 -5
View File
@@ -81,7 +81,12 @@ func Test115OpenAPIListPaginates(t *testing.T) {
t.Fatalf("unexpected path %s", r.URL.Path)
}
offset, _ := strconv.Atoi(r.URL.Query().Get("offset"))
count := 100
limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
if limit <= 0 {
limit = 100
}
// 首页返回满页,之后返回 1 条:驱动按 offset/limit 翻页直到短页
count := limit
if offset > 0 {
count = 1
}
@@ -97,11 +102,12 @@ func Test115OpenAPIListPaginates(t *testing.T) {
if err != nil {
t.Fatalf("list: %v", err)
}
if len(entries) != 101 {
t.Fatalf("entries = %d, want 101", len(entries))
// List 使用文档上限 limit=1150:首页 1150 条 + 短页 1 条
if len(entries) != 1151 {
t.Fatalf("entries = %d, want 1151", len(entries))
}
if entries[100].ID != "100" || entries[100].PickCode != "pick100" {
t.Fatalf("last entry wrong: %#v", entries[100])
if entries[1150].ID != "1150" || entries[1150].PickCode != "pick1150" {
t.Fatalf("last entry wrong: %#v", entries[1150])
}
}
+17 -2
View File
@@ -56,8 +56,9 @@ func (p *openAPI115Provider) Ping(ctx context.Context) error {
}
func (p *openAPI115Provider) List(ctx context.Context, dirID string) ([]FileEntry, error) {
// 115 开放平台列表接口按 offset/limit 分页,这里循环取完整个目录
const pageSize = 100
// 115 开放平台列表接口按 offset/limit 分页,这里循环取完整个目录;
// limit 上限 1150(官方文档《获取文件列表》),取上限减少大目录翻页次数
const pageSize = 1150
var out []FileEntry
for offset := 0; ; offset += pageSize {
files, _, err := p.c.GetFsList(ctx, dirID, offset, pageSize)
@@ -72,6 +73,7 @@ func (p *openAPI115Provider) List(ctx context.Context, dirID string) ([]FileEntr
Size: f.FileSize,
MTime: f.ModifiedAt(),
PickCode: f.PickCode,
Sha1: f.Sha1,
})
}
if len(files) < pageSize {
@@ -105,6 +107,19 @@ func (p *openAPI115Provider) ResolveWithUA(ctx context.Context, fileRef, ua stri
return &DirectLink{URL: url, Proxy: false, Headers: map[string]string{"User-Agent": bound}}, nil
}
// ResolveBatch 批量换取直链(downurl 支持逗号分隔多 pick_code,一次请求覆盖
// 整批下载任务的换链)。返回 pickcode → 直链,未解析成功的引用不在结果中;
// err 非 nil 表示批量过程部分/全部失败,调用方对缺失项回退到逐个 Resolve。
// 下载队列统一使用默认 UA,与单个换取的防盗链绑定语义一致。
func (p *openAPI115Provider) ResolveBatch(ctx context.Context, fileRefs []string) (map[string]*DirectLink, error) {
urls, err := p.c.GetDownloadURLsBatch(ctx, fileRefs, "")
out := make(map[string]*DirectLink, len(urls))
for pc, u := range urls {
out[pc] = &DirectLink{URL: u, Proxy: false, Headers: map[string]string{"User-Agent": cloud115.DefaultUA}}
}
return out, err
}
// OpenClient 暴露底层客户端(token 刷新用)。
func (p *openAPI115Provider) OpenClient() *cloud115.OpenClient { return p.c }