Skip to content

Commit deaefed

Browse files
authored
Merge pull request #90 from agin719/cos-v4-dev
Cos v4 dev
2 parents c88b738 + 695c446 commit deaefed

File tree

13 files changed

+1231
-15
lines changed

13 files changed

+1231
-15
lines changed

ci.go

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,199 @@
11
package cos
22

33
import (
4+
"context"
45
"encoding/json"
6+
"encoding/xml"
7+
"net/http"
58
)
69

10+
type CIService service
11+
712
type PicOperations struct {
813
IsPicInfo int `json:"is_pic_info,omitempty"`
914
Rules []PicOperationsRules `json:"rules,omitemtpy"`
1015
}
11-
1216
type PicOperationsRules struct {
1317
Bucket string `json:"bucket,omitempty"`
1418
FileId string `json:"fileid"`
1519
Rule string `json:"rule"`
1620
}
1721

1822
func EncodePicOperations(pic *PicOperations) string {
23+
if pic == nil {
24+
return ""
25+
}
1926
bs, err := json.Marshal(pic)
2027
if err != nil {
2128
return ""
2229
}
2330
return string(bs)
2431
}
32+
33+
type ImageProcessResult struct {
34+
XMLName xml.Name `xml:"UploadResult"`
35+
OriginalInfo *PicOriginalInfo `xml:"OriginalInfo,omitempty"`
36+
ProcessObject *PicProcessObject `xml:"ProcessResults>Object,omitempty"`
37+
}
38+
type PicOriginalInfo struct {
39+
Key string `xml:"Key,omitempty"`
40+
Location string `xml:"Location,omitempty"`
41+
ImageInfo *PicImageInfo `xml:"ImageInfo,omitempty"`
42+
}
43+
type PicImageInfo struct {
44+
Format string `xml:"Format,omitempty"`
45+
Width int `xml:"Width,omitempty"`
46+
Height int `xml:"Height,omitempty"`
47+
Size int `xml:"Size,omitempty"`
48+
Quality int `xml:"Quality,omitempty"`
49+
}
50+
type PicProcessObject struct {
51+
Key string `xml:"Key,omitempty"`
52+
Location string `xml:"Location,omitempty"`
53+
Format string `xml:"Format,omitempty"`
54+
Width int `xml:"Width,omitempty"`
55+
Height int `xml:"Height,omitempty"`
56+
Size int `xml:"Size,omitempty"`
57+
Quality int `xml:"Quality,omitempty"`
58+
}
59+
60+
type picOperationsHeader struct {
61+
PicOperations string `header:"Pic-Operations" xml:"-" url:"-"`
62+
}
63+
64+
type ImageProcessOptions = PicOperations
65+
66+
// 云上数据处理 https://cloud.tencent.com/document/product/460/18147
67+
func (s *CIService) ImageProcess(ctx context.Context, name string, opt *ImageProcessOptions) (*ImageProcessResult, *Response, error) {
68+
header := &picOperationsHeader{
69+
PicOperations: EncodePicOperations(opt),
70+
}
71+
var res ImageProcessResult
72+
sendOpt := sendOptions{
73+
baseURL: s.client.BaseURL.BucketURL,
74+
uri: "/" + encodeURIComponent(name) + "?image_process",
75+
method: http.MethodPost,
76+
optHeader: header,
77+
result: &res,
78+
}
79+
resp, err := s.client.send(ctx, &sendOpt)
80+
return &res, resp, err
81+
}
82+
83+
type ImageRecognitionOptions struct {
84+
CIProcess string `url:"ci-process,omitempty"`
85+
DetectType string `url:"detect-type,omitempty"`
86+
}
87+
88+
type ImageRecognitionResult struct {
89+
XMLName xml.Name `xml:"RecognitionResult"`
90+
PornInfo *RecognitionInfo `xml:"PornInfo,omitempty"`
91+
TerroristInfo *RecognitionInfo `xml:"TerroristInfo,omitempty"`
92+
PoliticsInfo *RecognitionInfo `xml:"PoliticsInfo,omitempty"`
93+
AdsInfo *RecognitionInfo `xml:"AdsInfo,omitempty"`
94+
}
95+
type RecognitionInfo struct {
96+
Code int `xml:"Code,omitempty"`
97+
Msg string `xml:"Msg,omitempty"`
98+
HitFlag int `xml:"HitFlag,omitempty"`
99+
Score int `xml:"Score,omitempty"`
100+
Label string `xml:"Label,omitempty"`
101+
Count int `xml:"Count,omitempty"`
102+
}
103+
104+
// 图片审核 https://cloud.tencent.com/document/product/460/37318
105+
func (s *CIService) ImageRecognition(ctx context.Context, name string, opt *ImageRecognitionOptions) (*ImageRecognitionResult, *Response, error) {
106+
if opt != nil && opt.CIProcess == "" {
107+
opt.CIProcess = "sensitive-content-recognition"
108+
}
109+
var res ImageRecognitionResult
110+
sendOpt := sendOptions{
111+
baseURL: s.client.BaseURL.BucketURL,
112+
uri: "/" + encodeURIComponent(name),
113+
method: http.MethodGet,
114+
optQuery: opt,
115+
result: &res,
116+
}
117+
resp, err := s.client.send(ctx, &sendOpt)
118+
return &res, resp, err
119+
}
120+
121+
type PutVideoAuditingJobOptions struct {
122+
XMLName xml.Name `xml:"Request"`
123+
InputObject string `xml:"Input>Object"`
124+
Conf *VideoAuditingJobConf `xml:"Conf"`
125+
}
126+
type VideoAuditingJobConf struct {
127+
DetectType string `xml:",omitempty"`
128+
Snapshot *PutVideoAuditingJobSnapshot `xml:",omitempty"`
129+
Callback string `xml:",omitempty"`
130+
}
131+
type PutVideoAuditingJobSnapshot struct {
132+
Mode string `xml:",omitempty"`
133+
Count int `xml:",omitempty"`
134+
TimeInterval float32 `xml:",omitempty"`
135+
Start float32 `xml:",omitempty"`
136+
}
137+
138+
type PutVideoAuditingJobResult struct {
139+
XMLName xml.Name `xml:"Response"`
140+
JobsDetail struct {
141+
JobId string `xml:"JobId,omitempty"`
142+
State string `xml:"State,omitempty"`
143+
CreationTime string `xml:"CreationTime,omitempty"`
144+
Object string `xml:"Object,omitempty"`
145+
} `xml:"JobsDetail,omitempty"`
146+
}
147+
148+
func (s *CIService) PutVideoAuditingJob(ctx context.Context, opt *PutVideoAuditingJobOptions) (*PutVideoAuditingJobResult, *Response, error) {
149+
var res PutVideoAuditingJobResult
150+
sendOpt := sendOptions{
151+
baseURL: s.client.BaseURL.CIURL,
152+
uri: "/video/auditing",
153+
method: http.MethodPost,
154+
body: opt,
155+
result: &res,
156+
}
157+
resp, err := s.client.send(ctx, &sendOpt)
158+
return &res, resp, err
159+
}
160+
161+
type GetVideoAuditingJobResult struct {
162+
XMLName xml.Name `xml:"Response"`
163+
JobsDetail *VideoAuditingJobDetail `xml:",omitempty"`
164+
NonExistJobIds string `xml:",omitempty"`
165+
}
166+
type VideoAuditingJobDetail struct {
167+
Code string `xml:",omitempty"`
168+
Message string `xml:",omitempty"`
169+
JobId string `xml:",omitempty"`
170+
State string `xml:",omitempty"`
171+
CreationTime string `xml:",omitempty"`
172+
Object string `xml:",omitempty"`
173+
SnapshotCount string `xml:",omitempty"`
174+
result int `xml:",omitempty"`
175+
PornInfo *RecognitionInfo `xml:",omitempty"`
176+
TerrorismInfo *RecognitionInfo `xml:",omitempty"`
177+
PoliticsInfo *RecognitionInfo `xml:",omitempty"`
178+
AdsInfo *RecognitionInfo `xml:",omitempty"`
179+
Snapshot *GetVideoAuditingJobSnapshot `xml:",omitempty"`
180+
}
181+
type GetVideoAuditingJobSnapshot struct {
182+
Url string `xml:",omitempty"`
183+
PornInfo *RecognitionInfo `xml:",omitempty"`
184+
TerrorismInfo *RecognitionInfo `xml:",omitempty"`
185+
PoliticsInfo *RecognitionInfo `xml:",omitempty"`
186+
AdsInfo *RecognitionInfo `xml:",omitempty"`
187+
}
188+
189+
func (s *CIService) GetVideoAuditingJob(ctx context.Context, jobid string) (*GetVideoAuditingJobResult, *Response, error) {
190+
var res GetVideoAuditingJobResult
191+
sendOpt := sendOptions{
192+
baseURL: s.client.BaseURL.CIURL,
193+
uri: "/video/auditing/" + jobid,
194+
method: http.MethodGet,
195+
result: &res,
196+
}
197+
resp, err := s.client.send(ctx, &sendOpt)
198+
return &res, resp, err
199+
}

cos.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222

2323
const (
2424
// Version current go sdk version
25-
Version = "0.7.10"
25+
Version = "0.7.11"
2626
userAgent = "cos-go-sdk-v5/" + Version
2727
contentTypeXML = "application/xml"
2828
defaultServiceBaseURL = "http://service.cos.myqcloud.com"
@@ -42,6 +42,8 @@ type BaseURL struct {
4242
ServiceURL *url.URL
4343
// 访问 job API 的基础 URL (不包含 path 部分): http://example.com
4444
BatchURL *url.URL
45+
// 访问 CI 的基础 URL
46+
CIURL *url.URL
4547
}
4648

4749
// NewBucketURL 生成 BaseURL 所需的 BucketURL
@@ -82,6 +84,7 @@ type Client struct {
8284
Bucket *BucketService
8385
Object *ObjectService
8486
Batch *BatchService
87+
CI *CIService
8588
}
8689

8790
type service struct {
@@ -99,6 +102,7 @@ func NewClient(uri *BaseURL, httpClient *http.Client) *Client {
99102
baseURL.BucketURL = uri.BucketURL
100103
baseURL.ServiceURL = uri.ServiceURL
101104
baseURL.BatchURL = uri.BatchURL
105+
baseURL.CIURL = uri.CIURL
102106
}
103107
if baseURL.ServiceURL == nil {
104108
baseURL.ServiceURL, _ = url.Parse(defaultServiceBaseURL)
@@ -114,6 +118,7 @@ func NewClient(uri *BaseURL, httpClient *http.Client) *Client {
114118
c.Bucket = (*BucketService)(&c.common)
115119
c.Object = (*ObjectService)(&c.common)
116120
c.Batch = (*BatchService)(&c.common)
121+
c.CI = (*CIService)(&c.common)
117122
return c
118123
}
119124

@@ -244,9 +249,6 @@ func (c *Client) send(ctx context.Context, opt *sendOptions) (resp *Response, er
244249
}
245250

246251
resp, err = c.doAPI(ctx, req, opt.result, !opt.disableCloseBody)
247-
if err != nil {
248-
return
249-
}
250252
return
251253
}
252254

cos_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func setup() {
3232
server = httptest.NewServer(mux)
3333

3434
u, _ := url.Parse(server.URL)
35-
client = NewClient(&BaseURL{u, u, u}, nil)
35+
client = NewClient(&BaseURL{u, u, u, u}, nil)
3636
}
3737

3838
// teardown closes the test HTTP server.

example/object/ci_image_process.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
"os"
9+
10+
"github.com/tencentyun/cos-go-sdk-v5"
11+
"github.com/tencentyun/cos-go-sdk-v5/debug"
12+
)
13+
14+
func log_status(err error) {
15+
if err == nil {
16+
return
17+
}
18+
if cos.IsNotFoundError(err) {
19+
// WARN
20+
fmt.Println("WARN: Resource is not existed")
21+
} else if e, ok := cos.IsCOSError(err); ok {
22+
fmt.Printf("ERROR: Code: %v\n", e.Code)
23+
fmt.Printf("ERROR: Message: %v\n", e.Message)
24+
fmt.Printf("ERROR: Resource: %v\n", e.Resource)
25+
fmt.Printf("ERROR: RequestId: %v\n", e.RequestID)
26+
// ERROR
27+
} else {
28+
fmt.Printf("ERROR: %v\n", err)
29+
// ERROR
30+
}
31+
}
32+
33+
func main() {
34+
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
35+
b := &cos.BaseURL{BucketURL: u}
36+
c := cos.NewClient(b, &http.Client{
37+
Transport: &cos.AuthorizationTransport{
38+
SecretID: os.Getenv("COS_SECRETID"),
39+
SecretKey: os.Getenv("COS_SECRETKEY"),
40+
Transport: &debug.DebugRequestTransport{
41+
RequestHeader: true,
42+
// Notice when put a large file and set need the request body, might happend out of memory error.
43+
RequestBody: false,
44+
ResponseHeader: true,
45+
ResponseBody: true,
46+
},
47+
},
48+
})
49+
50+
opt := &cos.ImageProcessOptions{
51+
IsPicInfo: 1,
52+
Rules: []cos.PicOperationsRules{
53+
{
54+
FileId: "format.jpg",
55+
Rule: "imageView2/format/png",
56+
},
57+
},
58+
}
59+
name := "test.jpg"
60+
res, _, err := c.CI.ImageProcess(context.Background(), name, opt)
61+
log_status(err)
62+
fmt.Printf("%+v\n", res)
63+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
"os"
9+
10+
"github.com/tencentyun/cos-go-sdk-v5"
11+
"github.com/tencentyun/cos-go-sdk-v5/debug"
12+
)
13+
14+
func log_status(err error) {
15+
if err == nil {
16+
return
17+
}
18+
if cos.IsNotFoundError(err) {
19+
// WARN
20+
fmt.Println("WARN: Resource is not existed")
21+
} else if e, ok := cos.IsCOSError(err); ok {
22+
fmt.Printf("ERROR: Code: %v\n", e.Code)
23+
fmt.Printf("ERROR: Message: %v\n", e.Message)
24+
fmt.Printf("ERROR: Resource: %v\n", e.Resource)
25+
fmt.Printf("ERROR: RequestId: %v\n", e.RequestID)
26+
// ERROR
27+
} else {
28+
fmt.Printf("ERROR: %v\n", err)
29+
// ERROR
30+
}
31+
}
32+
33+
func main() {
34+
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
35+
b := &cos.BaseURL{BucketURL: u}
36+
c := cos.NewClient(b, &http.Client{
37+
Transport: &cos.AuthorizationTransport{
38+
SecretID: os.Getenv("COS_SECRETID"),
39+
SecretKey: os.Getenv("COS_SECRETKEY"),
40+
Transport: &debug.DebugRequestTransport{
41+
RequestHeader: true,
42+
RequestBody: true,
43+
ResponseHeader: true,
44+
ResponseBody: true,
45+
},
46+
},
47+
})
48+
opt := &cos.ImageRecognitionOptions{
49+
DetectType: "porn,terrorist,politics",
50+
}
51+
52+
name := "test.jpg"
53+
res, _, err := c.CI.ImageRecognition(context.Background(), name, opt)
54+
log_status(err)
55+
fmt.Printf("%+v\n", res)
56+
}

0 commit comments

Comments
 (0)