mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-23 01:23:35 +00:00
feat(sora): add GDrive full-cycle test endpoint (upload/download/delete)
This commit is contained in:
@@ -177,7 +177,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
soraGenerationService := service.NewSoraGenerationService(soraGenerationRepository, soraStorageRouter, soraQuotaService)
|
||||
settingHandler := admin.NewSettingHandler(settingService, emailService, turnstileService, opsService, soraS3Storage)
|
||||
soraGDriveOAuthService := service.NewSoraGDriveOAuthService(settingService)
|
||||
gdriveOAuthHandler := admin.NewGDriveOAuthHandler(settingService, soraGDriveOAuthService)
|
||||
gdriveOAuthHandler := admin.NewGDriveOAuthHandler(settingService, soraGDriveOAuthService, soraGDriveStorage)
|
||||
opsHandler := admin.NewOpsHandler(opsService)
|
||||
updateCache := repository.NewUpdateCache(redisClient)
|
||||
gitHubReleaseClient := repository.ProvideGitHubReleaseClient(configConfig)
|
||||
|
||||
@@ -13,13 +13,15 @@ import (
|
||||
type GDriveOAuthHandler struct {
|
||||
settingService *service.SettingService
|
||||
gdriveOAuth *service.SoraGDriveOAuthService
|
||||
gdriveStorage *service.SoraGDriveStorage
|
||||
}
|
||||
|
||||
// NewGDriveOAuthHandler 创建 GDrive OAuth Handler。
|
||||
func NewGDriveOAuthHandler(settingService *service.SettingService, gdriveOAuth *service.SoraGDriveOAuthService) *GDriveOAuthHandler {
|
||||
func NewGDriveOAuthHandler(settingService *service.SettingService, gdriveOAuth *service.SoraGDriveOAuthService, gdriveStorage *service.SoraGDriveStorage) *GDriveOAuthHandler {
|
||||
return &GDriveOAuthHandler{
|
||||
settingService: settingService,
|
||||
gdriveOAuth: gdriveOAuth,
|
||||
gdriveStorage: gdriveStorage,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,3 +129,20 @@ func (h *GDriveOAuthHandler) OAuthCallback(c *gin.Context) {
|
||||
"message": "OAuth 授权成功",
|
||||
})
|
||||
}
|
||||
|
||||
// TestGDriveStorage 测试 GDrive 存储的完整上传→下载→删除流程。
|
||||
// POST /api/v1/admin/settings/sora-storage/gdrive-test
|
||||
func (h *GDriveOAuthHandler) TestGDriveStorage(c *gin.Context) {
|
||||
if h.gdriveStorage == nil {
|
||||
response.Error(c, http.StatusInternalServerError, "GDrive storage not initialized")
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.gdriveStorage.TestFullCycle(c.Request.Context())
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "GDrive 测试失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, result)
|
||||
}
|
||||
|
||||
@@ -413,6 +413,7 @@ func registerSettingsRoutes(admin *gin.RouterGroup, h *handler.Handlers) {
|
||||
// Google Drive OAuth
|
||||
adminSettings.POST("/sora-storage/gdrive-oauth/start", h.Admin.GDriveOAuth.StartOAuth)
|
||||
adminSettings.POST("/sora-storage/gdrive-oauth/callback", h.Admin.GDriveOAuth.OAuthCallback)
|
||||
adminSettings.POST("/sora-storage/gdrive-test", h.Admin.GDriveOAuth.TestGDriveStorage)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,6 +188,66 @@ func (s *SoraGDriveStorage) TestConnection(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestFullCycle 执行完整的上传→获取链接→删除测试。
|
||||
func (s *SoraGDriveStorage) TestFullCycle(ctx context.Context) (map[string]any, error) {
|
||||
srv, cfg, err := s.getService(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("init client: %w", err)
|
||||
}
|
||||
|
||||
result := map[string]any{}
|
||||
|
||||
// 1. 测试 API 连接
|
||||
about, err := srv.About.Get().Fields("storageQuota").Context(ctx).Do()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("API connection failed: %w", err)
|
||||
}
|
||||
if about.StorageQuota != nil {
|
||||
result["quota_limit_bytes"] = about.StorageQuota.Limit
|
||||
result["quota_used_bytes"] = about.StorageQuota.Usage
|
||||
}
|
||||
|
||||
// 2. 上传测试文件
|
||||
testContent := "sub2api GDrive test file - " + time.Now().Format(time.RFC3339)
|
||||
fileMeta := &drive.File{
|
||||
Name: "sub2api_test_" + uuid.NewString()[:8] + ".txt",
|
||||
MimeType: "text/plain",
|
||||
}
|
||||
if cfg.FolderID != "" {
|
||||
fileMeta.Parents = []string{cfg.FolderID}
|
||||
}
|
||||
uploaded, err := srv.Files.Create(fileMeta).
|
||||
Media(strings.NewReader(testContent)).
|
||||
Fields("id,name,size,webViewLink").
|
||||
Context(ctx).Do()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("upload test file failed: %w", err)
|
||||
}
|
||||
result["uploaded_file_id"] = uploaded.Id
|
||||
result["uploaded_file_name"] = uploaded.Name
|
||||
result["uploaded_file_size"] = uploaded.Size
|
||||
result["web_view_link"] = uploaded.WebViewLink
|
||||
|
||||
// 3. 获取访问链接
|
||||
accessURL, err := s.GetAccessURL(ctx, uploaded.Id)
|
||||
if err != nil {
|
||||
// 即使获取链接失败,仍尝试清理
|
||||
_ = srv.Files.Delete(uploaded.Id).Context(ctx).Do()
|
||||
return nil, fmt.Errorf("get access URL failed: %w", err)
|
||||
}
|
||||
result["access_url"] = accessURL
|
||||
|
||||
// 4. 删除测试文件
|
||||
if err := srv.Files.Delete(uploaded.Id).Context(ctx).Do(); err != nil {
|
||||
result["delete_warning"] = fmt.Sprintf("delete failed (manual cleanup needed): %v", err)
|
||||
} else {
|
||||
result["deleted"] = true
|
||||
}
|
||||
|
||||
result["status"] = "ok"
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// IsHealthy 返回 Google Drive 健康状态(带短缓存)。
|
||||
func (s *SoraGDriveStorage) IsHealthy(ctx context.Context) bool {
|
||||
if s == nil {
|
||||
|
||||
Reference in New Issue
Block a user