feat(drivers): add GuangYaPan driver with offline download support - #2882
Open
PIKACHUIM wants to merge 1 commit into
Open
feat(drivers): add GuangYaPan driver with offline download support#2882PIKACHUIM wants to merge 1 commit into
PIKACHUIM wants to merge 1 commit into
Conversation
xrgzs
requested changes
Aug 1, 2026
Comment on lines
+224
to
+250
| func (d *GuangYaPan) multipartUploadToOSS(ctx context.Context, bucket *oss.Bucket, objectPath string, file model.FileStreamer, up driver.UpdateProgress) error { | ||
| partSize := calcUploadPartSize(file.GetSize()) | ||
| imur, err := bucket.InitiateMultipartUpload(objectPath, oss.Sequential()) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| total := file.GetSize() | ||
| partCount := int((total + partSize - 1) / partSize) | ||
| parts := make([]oss.UploadPart, 0, partCount) | ||
| var uploaded int64 | ||
| partNumber := 1 | ||
|
|
||
| for uploaded < total { | ||
| if err := ctx.Err(); err != nil { | ||
| return err | ||
| } | ||
| curPartSize := partSize | ||
| left := total - uploaded | ||
| if left < curPartSize { | ||
| curPartSize = left | ||
| } | ||
|
|
||
| reader := io.LimitReader(file, curPartSize) | ||
| part, err := bucket.UploadPart(imur, driver.NewLimitedUploadStream(ctx, reader), curPartSize, partNumber) | ||
| if err != nil { | ||
| return err |
Member
There was a problem hiding this comment.
上传流处理有问题,需要添加一下分片重试。
-
没有 hybrid cache 集成:直接通过
io.LimitReader从原始FileStreamer顺序读取。FileStreamer本质上是单向流(只实现了io.Reader),一旦某一分片上传失败需要重试时,io.LimitReader已经消耗了对应字节,无法回退重读。 -
没有
stream.NewStreamSectionReader:参考驱动(quark_open、aliyundrive_open、115_open、pikpak)都使用stream.NewStreamSectionReader(file, int(partSize), &up)来获得可 Seek 的 SectionReader,确保分片上传失败后可以rd.Seek(0, io.SeekStart)重读。 -
没有 retry 包装:参考驱动在分片上传外层都有
retry.Do+rd.Seek(0, io.SeekStart)重试逻辑,guangyapan 没有。
建议修复 multipartUploadToOSS,参照 quark_open/aliyundrive_open 的模式,改为使用 stream.NewStreamSectionReader 获取可重读的分片 reader,并用 retry.Do 包装分片上传逻辑。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(drivers): add GuangYaPan driver with offline download
Summary / 摘要
This PR adds the GuangYaPan cloud drive driver to OpenList, refactoring
PR #2583. It implements the
full driver (List / Link / MakeDir / Rename / Remove / Move / Copy / Put / GetDetails),
offline download (magnet / torrent / HTTP / FTP), three login methods (access token /
refresh token / SMS), OSS multipart upload, per-endpoint rate limiting, and concurrent
token refresh. All community review comments were addressed, and several issues found
during review were fixed — including a runtime upload failure
(
Get upload token failed: 上传已完成) when the backend reports the file is alreadyuploaded / instant-uploaded.
drivers/guangyapanwith all 12 core interfaces implemented.internal/offline_download/guangyapan.ClientIDis now a required user-supplied field (reverse-engineered defaultclient constant removed per review).
Msg="上传已完成"(already uploaded /instant upload): the token request is now treated as a successful fast-upload and
skips the OSS upload step, waiting for the async task instead.
Review comments addressed (PR #2583)
util.go, 13 helpers)defaultClientClientIDnow required)GetDetails/nd.bizassets.s/v1/get_assets)drivers/guangyapan/ 此 PR 包含破坏性变更。
/ 此 PR 修改了公开 API、配置、存储格式或迁移行为。
/ 此 PR 需要关联仓库同步修改。
Related repository PRs / 关联仓库 PR:
Related Issues / 关联 Issue
Changes / 变更文件清单
New (7 files, 1794 lines)
drivers/guangyapan/driver.godrivers/guangyapan/util.godrivers/guangyapan/types.godrivers/guangyapan/offline.godrivers/guangyapan/meta.godriver.ConfigandAdditiondefinitionsinternal/offline_download/guangyapan/guangyapan.gointernal/offline_download/guangyapan/util.goModified (7 files, +66 / -1)
drivers/all.gointernal/conf/const.goGuangYaPanTempDirinternal/offline_download/all.gointernal/offline_download/tool/add.gocase "GuangYaPan"branchinternal/offline_download/tool/download.goserver/handles/offline_download.goSetGuangYaPanhandlerserver/router.go/set_guangyapanrouteFixes / 修复清单
Critical (compile / runtime failures)
Putsignature mismatch (compile error)(model.Obj, error)to matchdriver.PutResultaccess_tokenempty-check inpostAPId.ensureAccessToken(ctx)refreshTokenconcurrent data racesync.Mutex+ double-check inGuangYaPanresty.Client.SetHeaderconcurrent writeRequest.SetHeaderinstead of mutating client headerMajor
refreshTaskCache boolnot concurrency-safeatomic.BooldeleteResptypetaskRespdeleteFilesparam inDeleteOfflineTasksensureAccessTokencontained SMS login pathInitList/findChildFolderIDpagination unboundedmaxPage = 10000guardtype:"text"type:"text"(hidden by default)setTempStatustimer not cancelled onDropstatusTimer,Stop()inDropX-Device-Signsuffixdevice_signfieldMinor
fileTypes: []int{}IsSuccess()vsisSuccessMsginconsistencyisSuccessMsgdeleteResp/taskRespfully duplicatedtaskRespEqualFold("success")checksisSuccessMsg()model.Object.Ctimefield confirmationObject.Pathstores parentID (ambiguous)Upload bug fixed this round (PR follow-up)
Get upload token failed: 上传已完成on creating/updating a file.Msg="上传已完成"(file already uploaded /instant upload) with a valid
TaskIDbut no OSS credentials. The oldgetUploadTokenrejected this non-successMsg as an error; even if allowed,Putonly skipped OSS upload on
code == 156, so it still failed.uploadTokenDatagains anAlreadyDone boolfield (json:"-").getUploadTokentreatsMsgvalues like上传已完成/秒传成功/upload completed/already uploadedas success and setsAlreadyDone.Putskips the OSS upload and callswaitUploadTaskInfowhencode == 156 || token.AlreadyDone.上传已完成,秒传成功) are intentionally keptbecause they are the exact Msg values returned by the real backend API.
Architecture / 架构设计
Auth flow
flowchart TD Start[Init] --> HasAccess{has AccessToken?} HasAccess -->|Yes| Validate[Validate Token] Validate -->|OK| PrepareRoot[Prepare Root Folder] Validate -->|Fail| ClearAT[Clear AccessToken] ClearAT --> HasRefresh HasAccess -->|No| HasRefresh{has RefreshToken?} HasRefresh -->|Yes| Refresh[Refresh Token] Refresh -->|OK| PrepareRoot HasRefresh -->|No| HasPhone{has PhoneNumber?} HasPhone -->|Yes,VerifyCode| SMSLogin[SMS Login] SMSLogin --> PrepareRoot HasPhone -->|Yes,SendCode| SendSMS[Send SMS Code] HasPhone -->|No| Fail[Fail: no auth method]Concurrency protection
flowchart LR A[Concurrent postAPI] --> B{AccessToken valid?} B -->|401/403| C[refreshToken] C --> D[refreshMu.Lock] D --> E{Already refreshed?} E -->|Yes| F[Return OK] E -->|No| G[Do refresh + SaveStorage] G --> F F --> H[Retry postAPI]Configuration / 配置项说明
client_idphone_number+86 13800000000)captcha_tokensend_codeverify_codeaccess_tokenrefresh_tokendevice_iddevice_signX-Device-Signheaderroot_pathpage_sizeorder_bysort_typeLogin flows
Method A — Access Token (recommended)
Method B — Refresh Token (recommended, long-lived)
Method C — SMS two-step
Compatibility / 兼容性
github.com/OpenListTeam/go-cache,github.com/aliyun/aliyun-oss-go-sdk,github.com/go-resty/resty/v2,golang.org/x/time/rate. No new third-party dependencies.existing storage configuration.
Testing / 测试
go test ./...drivers/guangyapanandinternal/offline_download/guangyapan(0 errors).Msg="上传已完成"with a validTaskIDnow returns success instead of
Get upload token failed.go build ./drivers/guangyapan/...was not run in this environment(no Go toolchain available); please run it before merge.
Checklist / 检查清单
/ 我已阅读 CONTRIBUTING。
/ 我确认此贡献符合仓库许可证、贡献规范和行为准则。
gofmt,go fmt, orprettierwhere applicable./ 我已按适用情况使用
gofmt、go fmt或prettier格式化变更代码。/ 我已在适用情况下请求相关维护者或代码所有者审查。
AI Disclosure / AI 使用声明
/ 此 PR 包含 AI 辅助内容。
Tools used / 使用工具:
Usage scope / 使用范围:
Code generation / 代码生成
Refactoring / 重构
Documentation / 文档
Tests / 测试
Translation / 翻译
Review assistance / 审查辅助
I have reviewed and validated all AI-assisted content included in this PR.
/ 我已审核并验证此 PR 中的所有 AI 辅助内容。
I have ensured that all AI-assisted commits include
Co-Authored-Byattribution./ 我已确保所有 AI 辅助提交都包含
Co-Authored-By归属信息。I can reproduce all AI-assisted content included in this PR without any AI tools.
/ 我可以在没有任何 AI 工具的情况下重现此 PR 中包含的所有 AI 辅助内容。
Acknowledgements / 致谢