From e2bf82118033b3d0317afdde8c7f0da6e767e003 Mon Sep 17 00:00:00 2001 From: jojoliang Date: Tue, 27 Apr 2021 15:12:58 +0800 Subject: [PATCH] add CI QRCode && Update CI --- auth.go | 21 ++- ci.go | 175 +++++++++++++++++++-- ci_doc.go | 7 + example/CI/ci_QRcode.go | 89 +++++++++++ example/CI/ci_get.go | 54 +++++++ .../CI/content_auditing/ci_image_recognition.go | 53 +++++++ example/object/ci_doc_process.go | 132 ---------------- example/object/ci_image_process.go | 63 -------- example/object/ci_image_recognition.go | 56 ------- example/object/ci_put.go | 70 --------- example/object/ci_video_auditing_job.go | 71 --------- object.go | 7 +- object_part.go | 1 + 13 files changed, 388 insertions(+), 411 deletions(-) create mode 100644 example/CI/ci_QRcode.go create mode 100644 example/CI/ci_get.go create mode 100644 example/CI/content_auditing/ci_image_recognition.go delete mode 100644 example/object/ci_doc_process.go delete mode 100644 example/object/ci_image_process.go delete mode 100644 example/object/ci_image_recognition.go delete mode 100644 example/object/ci_put.go delete mode 100644 example/object/ci_video_auditing_job.go diff --git a/auth.go b/auth.go index f591a6d..a95540a 100644 --- a/auth.go +++ b/auth.go @@ -48,6 +48,12 @@ var needSignHeaders = map[string]bool{ "x-cos-object-type": true, } +var ciParameters = map[string]bool{ + "imagemogr2/": true, + "watermark/": true, + "imageview2/": true, +} + func safeURLEncode(s string) string { s = encodeURIComponent(s) s = strings.Replace(s, "!", "%21", -1) @@ -205,8 +211,10 @@ func genFormatParameters(parameters url.Values) (formatParameters string, signed for key, values := range parameters { key = strings.ToLower(key) for _, value := range values { - ps.Add(key, value) - signedParameterList = append(signedParameterList, key) + if !isCIParameter(key) { + ps.Add(key, value) + signedParameterList = append(signedParameterList, key) + } } } //formatParameters = strings.ToLower(ps.Encode()) @@ -246,6 +254,15 @@ func calHMACDigest(key, msg, signMethod string) []byte { return h.Sum(nil) } +func isCIParameter(key string) bool { + for k, v := range ciParameters { + if strings.HasPrefix(key, k) && v { + return true + } + } + return false +} + func isSignHeader(key string) bool { for k, v := range needSignHeaders { if key == k && v { diff --git a/ci.go b/ci.go index 545ddce..738c4c6 100644 --- a/ci.go +++ b/ci.go @@ -1,14 +1,18 @@ package cos import ( + "bytes" "context" + "encoding/base64" "encoding/json" "encoding/xml" + "errors" "fmt" "hash/crc64" "io" "net/http" "os" + "strconv" ) type CIService service @@ -54,15 +58,24 @@ type PicImageInfo struct { Orientation int `xml:"Orientation,omitempty"` } type PicProcessObject struct { - Key string `xml:"Key,omitempty"` - Location string `xml:"Location,omitempty"` - Format string `xml:"Format,omitempty"` - Width int `xml:"Width,omitempty"` - Height int `xml:"Height,omitempty"` - Size int `xml:"Size,omitempty"` - Quality int `xml:"Quality,omitempty"` - ETag string `xml:"ETag,omitempty"` - WatermarkStatus int `xml:"WatermarkStatus,omitempty"` + Key string `xml:"Key,omitempty"` + Location string `xml:"Location,omitempty"` + Format string `xml:"Format,omitempty"` + Width int `xml:"Width,omitempty"` + Height int `xml:"Height,omitempty"` + Size int `xml:"Size,omitempty"` + Quality int `xml:"Quality,omitempty"` + ETag string `xml:"ETag,omitempty"` + WatermarkStatus int `xml:"WatermarkStatus,omitempty"` + CodeStatus int `xml:"CodeStatus,omitempty"` + QRcodeInfo []QRcodeInfo `xml:"QRcodeInfo,omitempty"` +} +type QRcodeInfo struct { + CodeUrl string `xml:"CodeUrl,omitempty"` + CodeLocation *CodeLocation `xml:"CodeLocation,omitempty"` +} +type CodeLocation struct { + Point []string `xml:"Point,omitempty"` } type picOperationsHeader struct { @@ -110,9 +123,10 @@ type RecognitionInfo struct { } // 图片审核 https://cloud.tencent.com/document/product/460/37318 -func (s *CIService) ImageRecognition(ctx context.Context, name string, opt *ImageRecognitionOptions) (*ImageRecognitionResult, *Response, error) { - if opt != nil && opt.CIProcess == "" { - opt.CIProcess = "sensitive-content-recognition" +func (s *CIService) ImageRecognition(ctx context.Context, name string, DetectType string) (*ImageRecognitionResult, *Response, error) { + opt := &ImageRecognitionOptions{ + CIProcess: "sensitive-content-recognition", + DetectType: DetectType, } var res ImageRecognitionResult sendOpt := sendOptions{ @@ -153,6 +167,7 @@ type PutVideoAuditingJobResult struct { } `xml:"JobsDetail,omitempty"` } +// 视频审核-创建任务 https://cloud.tencent.com/document/product/460/46427 func (s *CIService) PutVideoAuditingJob(ctx context.Context, opt *PutVideoAuditingJobOptions) (*PutVideoAuditingJobResult, *Response, error) { var res PutVideoAuditingJobResult sendOpt := sendOptions{ @@ -194,6 +209,7 @@ type GetVideoAuditingJobSnapshot struct { AdsInfo *RecognitionInfo `xml:",omitempty"` } +// 视频审核-查询任务 https://cloud.tencent.com/document/product/460/46926 func (s *CIService) GetVideoAuditingJob(ctx context.Context, jobid string) (*GetVideoAuditingJobResult, *Response, error) { var res GetVideoAuditingJobResult sendOpt := sendOptions{ @@ -206,7 +222,8 @@ func (s *CIService) GetVideoAuditingJob(ctx context.Context, jobid string) (*Get return &res, resp, err } -// ci put https://cloud.tencent.com/document/product/460/18147 +// 图片持久化处理-上传时处理 https://cloud.tencent.com/document/product/460/18147 +// 二维码识别-上传时识别 https://cloud.tencent.com/document/product/460/37513 func (s *CIService) Put(ctx context.Context, name string, r io.Reader, uopt *ObjectPutOptions) (*ImageProcessResult, *Response, error) { if r == nil { return nil, nil, fmt.Errorf("reader is nil") @@ -257,3 +274,135 @@ func (s *CIService) PutFromFile(ctx context.Context, name string, filePath strin return s.Put(ctx, name, fd, opt) } + +// 基本图片处理 https://cloud.tencent.com/document/product/460/36540 +// 盲水印-下载时添加 https://cloud.tencent.com/document/product/460/19017 +func (s *CIService) Get(ctx context.Context, name string, operation string, opt *ObjectGetOptions, id ...string) (*Response, error) { + var u string + if len(id) == 1 { + u = fmt.Sprintf("/%s?versionId=%s&%s", encodeURIComponent(name), id[0], operation) + } else if len(id) == 0 { + u = fmt.Sprintf("/%s?%s", encodeURIComponent(name), operation) + } else { + return nil, errors.New("wrong params") + } + + sendOpt := sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: u, + method: http.MethodGet, + optQuery: opt, + optHeader: opt, + disableCloseBody: true, + } + resp, err := s.client.send(ctx, &sendOpt) + + if opt != nil && opt.Listener != nil { + if err == nil && resp != nil { + if totalBytes, e := strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 64); e == nil { + resp.Body = TeeReader(resp.Body, nil, totalBytes, opt.Listener) + } + } + } + return resp, err +} + +func (s *CIService) GetToFile(ctx context.Context, name, localpath, operation string, opt *ObjectGetOptions, id ...string) (*Response, error) { + resp, err := s.Get(ctx, name, operation, opt, id...) + if err != nil { + return resp, err + } + defer resp.Body.Close() + + // If file exist, overwrite it + fd, err := os.OpenFile(localpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660) + if err != nil { + return resp, err + } + + _, err = io.Copy(fd, resp.Body) + fd.Close() + if err != nil { + return resp, err + } + + return resp, nil +} + +type GetQRcodeResult struct { + XMLName xml.Name `xml:"Response"` + CodeStatus int `xml:"CodeStatus,omitempty"` + QRcodeInfo *QRcodeInfo `xml:"QRcodeInfo,omitempty"` + ResultImage string `xml:"ResultImage,omitempty"` +} + +// 二维码识别-下载时识别 https://cloud.tencent.com/document/product/436/54070 +func (s *CIService) GetQRcode(ctx context.Context, name string, cover int, opt *ObjectGetOptions, id ...string) (*GetQRcodeResult, *Response, error) { + var u string + if len(id) == 1 { + u = fmt.Sprintf("/%s?versionId=%s&ci-process=QRcode&cover=%v", encodeURIComponent(name), id[0], cover) + } else if len(id) == 0 { + u = fmt.Sprintf("/%s?ci-process=QRcode&cover=%v", encodeURIComponent(name), cover) + } else { + return nil, nil, errors.New("wrong params") + } + + var res GetQRcodeResult + sendOpt := sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: u, + method: http.MethodGet, + optQuery: opt, + optHeader: opt, + result: &res, + } + resp, err := s.client.send(ctx, &sendOpt) + return &res, resp, err +} + +type GenerateQRcodeOptions struct { + QRcodeContent string `url:"qrcode-content,omitempty"` + Mode int `url:"mode,omitempty"` + Width int `url:"width,omitempty"` +} +type GenerateQRcodeResult struct { + XMLName xml.Name `xml:"Response"` + ResultImage string `xml:"ResultImage,omitempty"` +} + +// 二维码生成 https://cloud.tencent.com/document/product/436/54071 +func (s *CIService) GenerateQRcode(ctx context.Context, opt *GenerateQRcodeOptions) (*GenerateQRcodeResult, *Response, error) { + var res GenerateQRcodeResult + sendOpt := &sendOptions{ + baseURL: s.client.BaseURL.BucketURL, + uri: "/?ci-process=qrcode-generate", + method: http.MethodGet, + optQuery: opt, + result: &res, + } + resp, err := s.client.send(ctx, sendOpt) + return &res, resp, err +} + +func (s *CIService) GenerateQRcodeToFile(ctx context.Context, filePath string, opt *GenerateQRcodeOptions) (*GenerateQRcodeResult, *Response, error) { + res, resp, err := s.GenerateQRcode(ctx, opt) + if err != nil { + return res, resp, err + } + + // If file exist, overwrite it + fd, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660) + if err != nil { + return res, resp, err + } + defer fd.Close() + + bs, err := base64.StdEncoding.DecodeString(res.ResultImage) + if err != nil { + return res, resp, err + } + fb := bytes.NewReader(bs) + _, err = io.Copy(fd, fb) + + return res, resp, err +} diff --git a/ci_doc.go b/ci_doc.go index 30b3214..74df304 100644 --- a/ci_doc.go +++ b/ci_doc.go @@ -73,6 +73,7 @@ type CreateDocProcessJobsResult struct { JobsDetail DocProcessJobDetail `xml:"JobsDetail,omitempty"` } +// 创建文档预览任务 https://cloud.tencent.com/document/product/436/54056 func (s *CIService) CreateDocProcessJobs(ctx context.Context, opt *CreateDocProcessJobsOptions) (*CreateDocProcessJobsResult, *Response, error) { var res CreateDocProcessJobsResult sendOpt := sendOptions{ @@ -92,6 +93,7 @@ type DescribeDocProcessJobResult struct { NonExistJobIds string `xml:"NonExistJobIds,omitempty"` } +// 查询文档预览任务 https://cloud.tencent.com/document/product/436/54095 func (s *CIService) DescribeDocProcessJob(ctx context.Context, jobid string) (*DescribeDocProcessJobResult, *Response, error) { var res DescribeDocProcessJobResult sendOpt := sendOptions{ @@ -121,6 +123,7 @@ type DescribeDocProcessJobsResult struct { NextToken string `xml:"NextToken,omitempty"` } +// 拉取符合条件的文档预览任务 https://cloud.tencent.com/document/product/436/54096 func (s *CIService) DescribeDocProcessJobs(ctx context.Context, opt *DescribeDocProcessJobsOptions) (*DescribeDocProcessJobsResult, *Response, error) { var res DescribeDocProcessJobsResult sendOpt := sendOptions{ @@ -169,6 +172,7 @@ type DocProcessQueueNotifyConfig struct { Event string `xml:"Event,omitempty"` } +// 查询文档预览队列 https://cloud.tencent.com/document/product/436/54055 func (s *CIService) DescribeDocProcessQueues(ctx context.Context, opt *DescribeDocProcessQueuesOptions) (*DescribeDocProcessQueuesResult, *Response, error) { var res DescribeDocProcessQueuesResult sendOpt := sendOptions{ @@ -196,6 +200,7 @@ type UpdateDocProcessQueueResult struct { Queue *DocProcessQueue `xml:"Queue"` } +// 更新文档预览队列 https://cloud.tencent.com/document/product/436/54094 func (s *CIService) UpdateDocProcessQueue(ctx context.Context, opt *UpdateDocProcessQueueOptions) (*UpdateDocProcessQueueResult, *Response, error) { var res UpdateDocProcessQueueResult sendOpt := sendOptions{ @@ -233,6 +238,7 @@ type DocProcessBucket struct { AliasBucketId string `xml:"AliasBucketId,omitempty"` } +// 查询文档预览开通状态 https://cloud.tencent.com/document/product/436/54057 func (s *CIService) DescribeDocProcessBuckets(ctx context.Context, opt *DescribeDocProcessBucketsOptions) (*DescribeDocProcessBucketsResult, *Response, error) { var res DescribeDocProcessBucketsResult sendOpt := sendOptions{ @@ -259,6 +265,7 @@ type DocPreviewOptions struct { Zoom int `url:"zoom,omitempty"` } +// 同步请求接口 https://cloud.tencent.com/document/product/436/54058 func (s *CIService) DocPreview(ctx context.Context, name string, opt *DocPreviewOptions) (*Response, error) { sendOpt := sendOptions{ baseURL: s.client.BaseURL.BucketURL, diff --git a/example/CI/ci_QRcode.go b/example/CI/ci_QRcode.go new file mode 100644 index 0000000..6edb39f --- /dev/null +++ b/example/CI/ci_QRcode.go @@ -0,0 +1,89 @@ +package main + +import ( + "context" + "fmt" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func log_status(err error) { + if err == nil { + return + } + if cos.IsNotFoundError(err) { + // WARN + fmt.Println("WARN: Resource is not existed") + } else if e, ok := cos.IsCOSError(err); ok { + fmt.Printf("ERROR: Code: %v\n", e.Code) + fmt.Printf("ERROR: Message: %v\n", e.Message) + fmt.Printf("ERROR: Resource: %v\n", e.Resource) + fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) + // ERROR + } else { + fmt.Printf("ERROR: %v\n", err) + // ERROR + } +} + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{BucketURL: u} + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + // Notice when put a large file and set need the request body, might happend out of memory error. + RequestBody: false, + ResponseHeader: true, + ResponseBody: false, + }, + }, + }) + + opt := &cos.ObjectPutOptions{ + nil, + &cos.ObjectPutHeaderOptions{ + XOptionHeader: &http.Header{}, + }, + } + pic := &cos.PicOperations{ + IsPicInfo: 1, + Rules: []cos.PicOperationsRules{ + { + FileId: "format.jpg", + Rule: "QRcode/cover/1", + }, + }, + } + opt.XOptionHeader.Add("Pic-Operations", cos.EncodePicOperations(pic)) + name := "test.jpg" + local_filename := "./QRcode.jpg" + res, _, err := c.CI.PutFromFile(context.Background(), name, local_filename, opt) + log_status(err) + fmt.Printf("%+v\n", res) + fmt.Printf("%+v\n", res.OriginalInfo) + fmt.Printf("%+v\n", res.ProcessResults) + + res2, _, err := c.CI.GetQRcode(context.Background(), name, 0, nil) + log_status(err) + fmt.Printf("%+v\n", res2) + + gopt := &cos.GenerateQRcodeOptions{ + QRcodeContent: fmt.Sprintf("<%v>", res2.QRcodeInfo.CodeUrl), + Mode: 0, + Width: 200, + } + res3, _, err := c.CI.GenerateQRcode(context.Background(), gopt) + log_status(err) + fmt.Printf("%+v\n", res3) + + _, _, err = c.CI.GenerateQRcodeToFile(context.Background(), "./downQRcode.jpg", gopt) + log_status(err) +} diff --git a/example/CI/ci_get.go b/example/CI/ci_get.go new file mode 100644 index 0000000..dab3d89 --- /dev/null +++ b/example/CI/ci_get.go @@ -0,0 +1,54 @@ +package main + +import ( + "context" + "fmt" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func log_status(err error) { + if err == nil { + return + } + if cos.IsNotFoundError(err) { + // WARN + fmt.Println("WARN: Resource is not existed") + } else if e, ok := cos.IsCOSError(err); ok { + fmt.Printf("ERROR: Code: %v\n", e.Code) + fmt.Printf("ERROR: Message: %v\n", e.Message) + fmt.Printf("ERROR: Resource: %v\n", e.Resource) + fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) + // ERROR + } else { + fmt.Printf("ERROR: %v\n", err) + // ERROR + } +} + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{BucketURL: u} + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + // Notice when put a large file and set need the request body, might happend out of memory error. + RequestBody: false, + ResponseHeader: true, + ResponseBody: false, + }, + }, + }) + + name := "test.jpg" + filepath := "test.jpg" + _, err := c.CI.GetToFile(context.Background(), name, filepath, "imageMogr2/thumbnail/!50px", nil) + log_status(err) +} diff --git a/example/CI/content_auditing/ci_image_recognition.go b/example/CI/content_auditing/ci_image_recognition.go new file mode 100644 index 0000000..c907e62 --- /dev/null +++ b/example/CI/content_auditing/ci_image_recognition.go @@ -0,0 +1,53 @@ +package main + +import ( + "context" + "fmt" + "net/http" + "net/url" + "os" + + "github.com/tencentyun/cos-go-sdk-v5" + "github.com/tencentyun/cos-go-sdk-v5/debug" +) + +func log_status(err error) { + if err == nil { + return + } + if cos.IsNotFoundError(err) { + // WARN + fmt.Println("WARN: Resource is not existed") + } else if e, ok := cos.IsCOSError(err); ok { + fmt.Printf("ERROR: Code: %v\n", e.Code) + fmt.Printf("ERROR: Message: %v\n", e.Message) + fmt.Printf("ERROR: Resource: %v\n", e.Resource) + fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) + // ERROR + } else { + fmt.Printf("ERROR: %v\n", err) + // ERROR + } +} + +func main() { + u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") + b := &cos.BaseURL{BucketURL: u} + c := cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: os.Getenv("COS_SECRETID"), + SecretKey: os.Getenv("COS_SECRETKEY"), + Transport: &debug.DebugRequestTransport{ + RequestHeader: true, + RequestBody: true, + ResponseHeader: true, + ResponseBody: true, + }, + }, + }) + DetectType := "porn,terrorist,politics" + name := "test.jpg" + res, _, err := c.CI.ImageRecognition(context.Background(), name, DetectType) + log_status(err) + fmt.Printf("%+v\n", res) +} diff --git a/example/object/ci_doc_process.go b/example/object/ci_doc_process.go deleted file mode 100644 index c743d64..0000000 --- a/example/object/ci_doc_process.go +++ /dev/null @@ -1,132 +0,0 @@ -package main - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" - "os" - - "github.com/tencentyun/cos-go-sdk-v5" - "github.com/tencentyun/cos-go-sdk-v5/debug" -) - -func log_status(err error) { - if err == nil { - return - } - if cos.IsNotFoundError(err) { - // WARN - fmt.Println("WARN: Resource is not existed") - } else if e, ok := cos.IsCOSError(err); ok { - fmt.Printf("ERROR: Code: %v\n", e.Code) - fmt.Printf("ERROR: Message: %v\n", e.Message) - fmt.Printf("ERROR: Resource: %v\n", e.Resource) - fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) - // ERROR - } else { - fmt.Printf("ERROR: %v\n", err) - // ERROR - } -} - -func main() { - u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") - cu, _ := url.Parse("https://test-1259654469.ci.ap-guangzhou.myqcloud.com") - b := &cos.BaseURL{BucketURL: u, CIURL: cu} - c := cos.NewClient(b, &http.Client{ - Transport: &cos.AuthorizationTransport{ - SecretID: os.Getenv("COS_SECRETID"), - SecretKey: os.Getenv("COS_SECRETKEY"), - Transport: &debug.DebugRequestTransport{ - RequestHeader: true, - // Notice when put a large file and set need the request body, might happend out of memory error. - RequestBody: true, - ResponseHeader: true, - ResponseBody: true, - }, - }, - }) - - // 1、UpdateDocProcessQueue - updateQueueOpt := &cos.UpdateDocProcessQueueOptions{ - Name: "queue-doc-process-1", - QueueID: "p111a8dd208104ce3b11c78398f658ca8", - State: "Active", - NotifyConfig: &cos.DocProcessQueueNotifyConfig{ - State: "Off", - }, - } - updateQueueRes, _, err := c.CI.UpdateDocProcessQueue(context.Background(), updateQueueOpt) - log_status(err) - fmt.Printf("%+v\n", updateQueueRes) - - // 2、DescribeDocProcessQueues - DescribeQueueOpt := &cos.DescribeDocProcessQueuesOptions{ - QueueIds: "p111a8dd208104ce3b11c78398f658ca8,p4318f85d2aa14c43b1dba6f9b78be9b3,aacb2bb066e9c4478834d4196e76c49d3", - PageNumber: 1, - PageSize: 2, - } - DescribeQueueRes, _, err := c.CI.DescribeDocProcessQueues(context.Background(), DescribeQueueOpt) - log_status(err) - fmt.Printf("%+v\n", DescribeQueueRes) - - // 3、DescribeDocProcessBuckets - BucketsOpt := &cos.DescribeDocProcessBucketsOptions{ - Regions: "All", - } - BucketsRes, _, err := c.CI.DescribeDocProcessBuckets(context.Background(), BucketsOpt) - log_status(err) - fmt.Printf("%+v\n", BucketsRes) - - // 4、CreateDocProcessJobs - createJobOpt := &cos.CreateDocProcessJobsOptions{ - Tag: "DocProcess", - Input: &cos.DocProcessJobInput{ - Object: "form.pdf", - }, - Operation: &cos.DocProcessJobOperation{ - Output: &cos.DocProcessJobOutput{ - Region: "ap-guangzhou", - Object: "test-doc${Number}", - Bucket: "test-1259654469", - }, - DocProcess: &cos.DocProcessJobDocProcess{ - TgtType: "png", - StartPage: 1, - EndPage: -1, - ImageParams: "watermark/1/image/aHR0cDovL3Rlc3QwMDUtMTI1MTcwNDcwOC5jb3MuYXAtY2hvbmdxaW5nLm15cWNsb3VkLmNvbS8xLmpwZw==/gravity/southeast", - }, - }, - QueueId: "p111a8dd208104ce3b11c78398f658ca8", - } - createJobRes, _, err := c.CI.CreateDocProcessJobs(context.Background(), createJobOpt) - log_status(err) - fmt.Printf("%+v\n", createJobRes.JobsDetail) - - // 5、DescribeDocProcessJob - DescribeJobRes, _, err := c.CI.DescribeDocProcessJob(context.Background(), createJobRes.JobsDetail.JobId) - log_status(err) - fmt.Printf("%+v\n", DescribeJobRes.JobsDetail) - - // 6、DescribeDocProcessJobs - DescribeJobsOpt := &cos.DescribeDocProcessJobsOptions{ - QueueId: "p111a8dd208104ce3b11c78398f658ca8", - Tag: "DocProcess", - } - DescribeJobsRes, _, err := c.CI.DescribeDocProcessJobs(context.Background(), DescribeJobsOpt) - log_status(err) - fmt.Printf("%+v\n", DescribeJobsRes) - - // 7、doc-preview - opt := &cos.DocPreviewOptions{ - Page: 1, - } - resp, err := c.CI.DocPreview(context.Background(), "form.pdf", opt) - log_status(err) - fd, _ := os.OpenFile("form.pdf", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660) - io.Copy(fd, resp.Body) - fd.Close() - -} diff --git a/example/object/ci_image_process.go b/example/object/ci_image_process.go deleted file mode 100644 index 6fc1584..0000000 --- a/example/object/ci_image_process.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net/http" - "net/url" - "os" - - "github.com/tencentyun/cos-go-sdk-v5" - "github.com/tencentyun/cos-go-sdk-v5/debug" -) - -func log_status(err error) { - if err == nil { - return - } - if cos.IsNotFoundError(err) { - // WARN - fmt.Println("WARN: Resource is not existed") - } else if e, ok := cos.IsCOSError(err); ok { - fmt.Printf("ERROR: Code: %v\n", e.Code) - fmt.Printf("ERROR: Message: %v\n", e.Message) - fmt.Printf("ERROR: Resource: %v\n", e.Resource) - fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) - // ERROR - } else { - fmt.Printf("ERROR: %v\n", err) - // ERROR - } -} - -func main() { - u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") - b := &cos.BaseURL{BucketURL: u} - c := cos.NewClient(b, &http.Client{ - Transport: &cos.AuthorizationTransport{ - SecretID: os.Getenv("COS_SECRETID"), - SecretKey: os.Getenv("COS_SECRETKEY"), - Transport: &debug.DebugRequestTransport{ - RequestHeader: true, - // Notice when put a large file and set need the request body, might happend out of memory error. - RequestBody: false, - ResponseHeader: true, - ResponseBody: true, - }, - }, - }) - - opt := &cos.ImageProcessOptions{ - IsPicInfo: 1, - Rules: []cos.PicOperationsRules{ - { - FileId: "format.jpg", - Rule: "imageView2/format/png", - }, - }, - } - name := "test.jpg" - res, _, err := c.CI.ImageProcess(context.Background(), name, opt) - log_status(err) - fmt.Printf("%+v\n", res) -} diff --git a/example/object/ci_image_recognition.go b/example/object/ci_image_recognition.go deleted file mode 100644 index a17fd18..0000000 --- a/example/object/ci_image_recognition.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net/http" - "net/url" - "os" - - "github.com/tencentyun/cos-go-sdk-v5" - "github.com/tencentyun/cos-go-sdk-v5/debug" -) - -func log_status(err error) { - if err == nil { - return - } - if cos.IsNotFoundError(err) { - // WARN - fmt.Println("WARN: Resource is not existed") - } else if e, ok := cos.IsCOSError(err); ok { - fmt.Printf("ERROR: Code: %v\n", e.Code) - fmt.Printf("ERROR: Message: %v\n", e.Message) - fmt.Printf("ERROR: Resource: %v\n", e.Resource) - fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) - // ERROR - } else { - fmt.Printf("ERROR: %v\n", err) - // ERROR - } -} - -func main() { - u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") - b := &cos.BaseURL{BucketURL: u} - c := cos.NewClient(b, &http.Client{ - Transport: &cos.AuthorizationTransport{ - SecretID: os.Getenv("COS_SECRETID"), - SecretKey: os.Getenv("COS_SECRETKEY"), - Transport: &debug.DebugRequestTransport{ - RequestHeader: true, - RequestBody: true, - ResponseHeader: true, - ResponseBody: true, - }, - }, - }) - opt := &cos.ImageRecognitionOptions{ - DetectType: "porn,terrorist,politics", - } - - name := "test.jpg" - res, _, err := c.CI.ImageRecognition(context.Background(), name, opt) - log_status(err) - fmt.Printf("%+v\n", res) -} diff --git a/example/object/ci_put.go b/example/object/ci_put.go deleted file mode 100644 index 5417431..0000000 --- a/example/object/ci_put.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net/http" - "net/url" - "os" - - "github.com/tencentyun/cos-go-sdk-v5" - "github.com/tencentyun/cos-go-sdk-v5/debug" -) - -func log_status(err error) { - if err == nil { - return - } - if cos.IsNotFoundError(err) { - // WARN - fmt.Println("WARN: Resource is not existed") - } else if e, ok := cos.IsCOSError(err); ok { - fmt.Printf("ERROR: Code: %v\n", e.Code) - fmt.Printf("ERROR: Message: %v\n", e.Message) - fmt.Printf("ERROR: Resource: %v\n", e.Resource) - fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) - // ERROR - } else { - fmt.Printf("ERROR: %v\n", err) - // ERROR - } -} - -func main() { - u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") - b := &cos.BaseURL{BucketURL: u} - c := cos.NewClient(b, &http.Client{ - Transport: &cos.AuthorizationTransport{ - SecretID: os.Getenv("COS_SECRETID"), - SecretKey: os.Getenv("COS_SECRETKEY"), - Transport: &debug.DebugRequestTransport{ - RequestHeader: true, - // Notice when put a large file and set need the request body, might happend out of memory error. - RequestBody: false, - ResponseHeader: true, - ResponseBody: true, - }, - }, - }) - - opt := &cos.ObjectPutOptions{ - nil, - &cos.ObjectPutHeaderOptions{ - XOptionHeader: &http.Header{}, - }, - } - pic := &cos.PicOperations{ - IsPicInfo: 1, - Rules: []cos.PicOperationsRules{ - { - FileId: "format.jpg", - Rule: "imageView2/format/png", - }, - }, - } - opt.XOptionHeader.Add("Pic-Operations", cos.EncodePicOperations(pic)) - name := "test.jpg" - local_filename := "./test.jpg" - _, err := c.Object.PutFromFile(context.Background(), name, local_filename, opt) - log_status(err) -} diff --git a/example/object/ci_video_auditing_job.go b/example/object/ci_video_auditing_job.go deleted file mode 100644 index 9a5cbb7..0000000 --- a/example/object/ci_video_auditing_job.go +++ /dev/null @@ -1,71 +0,0 @@ -package main - -import ( - "context" - "fmt" - "net/http" - "net/url" - "os" - "time" - - "github.com/tencentyun/cos-go-sdk-v5" - "github.com/tencentyun/cos-go-sdk-v5/debug" -) - -func log_status(err error) { - if err == nil { - return - } - if cos.IsNotFoundError(err) { - // WARN - fmt.Println("WARN: Resource is not existed") - } else if e, ok := cos.IsCOSError(err); ok { - fmt.Printf("ERROR: Code: %v\n", e.Code) - fmt.Printf("ERROR: Message: %v\n", e.Message) - fmt.Printf("ERROR: Resource: %v\n", e.Resource) - fmt.Printf("ERROR: RequestId: %v\n", e.RequestID) - // ERROR - } else { - fmt.Printf("ERROR: %v\n", err) - // ERROR - } -} - -func main() { - bu, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com") - cu, _ := url.Parse("https://test-1259654469.ci.ap-guangzhou.myqcloud.com") - b := &cos.BaseURL{BucketURL: bu, CIURL: cu} - c := cos.NewClient(b, &http.Client{ - Transport: &cos.AuthorizationTransport{ - SecretID: os.Getenv("COS_SECRETID"), - SecretKey: os.Getenv("COS_SECRETKEY"), - Transport: &debug.DebugRequestTransport{ - RequestHeader: true, - RequestBody: true, - ResponseHeader: true, - ResponseBody: true, - }, - }, - }) - opt := &cos.PutVideoAuditingJobOptions{ - InputObject: "demo.mp4", - Conf: &cos.VideoAuditingJobConf{ - DetectType: "Porn,Terrorism,Politics,Ads", - Snapshot: &cos.PutVideoAuditingJobSnapshot{ - Mode: "Interval", - Start: 0.5, - TimeInterval: 50.5, - Count: 100, - }, - }, - } - - res, _, err := c.CI.PutVideoAuditingJob(context.Background(), opt) - log_status(err) - fmt.Printf("%+v\n", res) - - time.Sleep(3 * time.Second) - res2, _, err := c.CI.GetVideoAuditingJob(context.Background(), res.JobsDetail.JobId) - log_status(err) - fmt.Printf("%+v\n", res2) -} diff --git a/object.go b/object.go index a91bffc..112330f 100644 --- a/object.go +++ b/object.go @@ -825,7 +825,6 @@ func (s *ObjectService) checkUploadedParts(ctx context.Context, name, UploadID, } // MultiUpload/Upload 为高级upload接口,并发分块上传 -// 注意该接口目前只供参考 // // 当 partSize > 0 时,由调用者指定分块大小,否则由 SDK 自动切分,单位为MB // 由调用者指定分块大小时,请确认分块数量不超过10000 @@ -870,8 +869,9 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string return nil, rsp, err } result := &CompleteMultipartUploadResult{ - Key: name, - ETag: rsp.Header.Get("ETag"), + Location: fmt.Sprintf("%s/%s", s.client.BaseURL.BucketURL, name), + Key: name, + ETag: rsp.Header.Get("ETag"), } if rsp != nil && s.client.Conf.EnableCRC { scoscrc := rsp.Header.Get("x-cos-hash-crc64ecma") @@ -1001,7 +1001,6 @@ func (s *ObjectService) Upload(ctx context.Context, name string, filepath string v, resp, err := s.CompleteMultipartUpload(context.Background(), name, uploadID, optcom) if err != nil { - s.AbortMultipartUpload(ctx, name, uploadID) return v, resp, err } diff --git a/object_part.go b/object_part.go index 3e04aed..63e66b9 100644 --- a/object_part.go +++ b/object_part.go @@ -523,6 +523,7 @@ func (s *ObjectService) MultiCopy(ctx context.Context, name string, sourceURL st v, resp, err := s.CompleteMultipartUpload(ctx, name, uploadID, optcom) if err != nil { s.AbortMultipartUpload(ctx, name, uploadID) + return nil, resp, err } cpres := &ObjectCopyResult{ ETag: v.ETag,