Skip to content

Commit 695c446

Browse files
author
jojoliang
committed
ci 内容审核
1 parent 98eab28 commit 695c446

File tree

7 files changed

+218
-51
lines changed

7 files changed

+218
-51
lines changed

ci.go

Lines changed: 121 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,49 +4,49 @@ import (
44
"context"
55
"encoding/json"
66
"encoding/xml"
7-
"io"
87
"net/http"
98
)
109

10+
type CIService service
11+
1112
type PicOperations struct {
1213
IsPicInfo int `json:"is_pic_info,omitempty"`
1314
Rules []PicOperationsRules `json:"rules,omitemtpy"`
1415
}
15-
1616
type PicOperationsRules struct {
1717
Bucket string `json:"bucket,omitempty"`
1818
FileId string `json:"fileid"`
1919
Rule string `json:"rule"`
2020
}
2121

2222
func EncodePicOperations(pic *PicOperations) string {
23+
if pic == nil {
24+
return ""
25+
}
2326
bs, err := json.Marshal(pic)
2427
if err != nil {
2528
return ""
2629
}
2730
return string(bs)
2831
}
2932

30-
type CloudImageReuslt struct {
33+
type ImageProcessResult struct {
3134
XMLName xml.Name `xml:"UploadResult"`
3235
OriginalInfo *PicOriginalInfo `xml:"OriginalInfo,omitempty"`
3336
ProcessObject *PicProcessObject `xml:"ProcessResults>Object,omitempty"`
3437
}
35-
3638
type PicOriginalInfo struct {
3739
Key string `xml:"Key,omitempty"`
3840
Location string `xml:"Location,omitempty"`
3941
ImageInfo *PicImageInfo `xml:"ImageInfo,omitempty"`
4042
}
41-
4243
type PicImageInfo struct {
4344
Format string `xml:"Format,omitempty"`
4445
Width int `xml:"Width,omitempty"`
4546
Height int `xml:"Height,omitempty"`
4647
Size int `xml:"Size,omitempty"`
4748
Quality int `xml:"Quality,omitempty"`
4849
}
49-
5050
type PicProcessObject struct {
5151
Key string `xml:"Key,omitempty"`
5252
Location string `xml:"Location,omitempty"`
@@ -57,24 +57,42 @@ type PicProcessObject struct {
5757
Quality int `xml:"Quality,omitempty"`
5858
}
5959

60-
type CloudImageOptions struct {
60+
type picOperationsHeader struct {
6161
PicOperations string `header:"Pic-Operations" xml:"-" url:"-"`
6262
}
6363

64-
func (s *ObjectService) PostCI(ctx context.Context, name string, opt *CloudImageOptions) (*CloudImageReuslt, *Response, error) {
65-
var res CloudImageReuslt
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
6672
sendOpt := sendOptions{
6773
baseURL: s.client.BaseURL.BucketURL,
6874
uri: "/" + encodeURIComponent(name) + "?image_process",
6975
method: http.MethodPost,
70-
optHeader: opt,
76+
optHeader: header,
7177
result: &res,
7278
}
7379
resp, err := s.client.send(ctx, &sendOpt)
7480
return &res, resp, err
7581
}
7682

77-
type CloudImageRecognitionInfo struct {
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 {
7896
Code int `xml:"Code,omitempty"`
7997
Msg string `xml:"Msg,omitempty"`
8098
HitFlag int `xml:"HitFlag,omitempty"`
@@ -83,18 +101,99 @@ type CloudImageRecognitionInfo struct {
83101
Count int `xml:"Count,omitempty"`
84102
}
85103

86-
type CloudImageRecognitionResult struct {
87-
PornInfo *CloudImageRecognitionInfo `xml:"PornInfo,omitempty"`
88-
TerroristInfo *CloudImageRecognitionInfo `xml:"TerroristInfo,omitempty"`
89-
PoliticsInfo *CloudImageRecognitionInfo `xml:"PoliticsInfo,omitempty"`
90-
AdsInfo *CloudImageRecognitionInfo `xml:"AdsInfo,omitempty"`
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"`
91187
}
92188

93-
func GetRecognitionResult(body io.ReadCloser) *CloudImageRecognitionResult {
94-
var res CloudImageRecognitionResult
95-
err := xml.NewDecoder(body).Decode(&res)
96-
if err != nil && err != io.EOF {
97-
return nil
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,
98196
}
99-
return &res
197+
resp, err := s.client.send(ctx, &sendOpt)
198+
return &res, resp, err
100199
}

cos.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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_post.go renamed to example/object/ci_image_process.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"context"
5-
"encoding/xml"
65
"fmt"
76
"net/http"
87
"net/url"
@@ -48,7 +47,7 @@ func main() {
4847
},
4948
})
5049

51-
pic := &cos.PicOperations{
50+
opt := &cos.ImageProcessOptions{
5251
IsPicInfo: 1,
5352
Rules: []cos.PicOperationsRules{
5453
{
@@ -57,12 +56,8 @@ func main() {
5756
},
5857
},
5958
}
60-
opt := &cos.CloudImageOptions{
61-
PicOperations: cos.EncodePicOperations(pic),
62-
}
6359
name := "test.jpg"
64-
res, _, err := c.Object.PostCI(context.Background(), name, opt)
65-
data, _ := xml.Marshal(res)
66-
fmt.Printf("%+v\n", string(data))
60+
res, _, err := c.CI.ImageProcess(context.Background(), name, opt)
6761
log_status(err)
62+
fmt.Printf("%+v\n", res)
6863
}

example/object/ci_get.go renamed to example/object/ci_image_recognition.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,12 @@ func main() {
4545
},
4646
},
4747
})
48-
opt := &cos.ObjectGetOptions{
49-
CIProcess: "sensitive-content-recognition",
50-
CIDetectType: "porn,terrorist,politics,ads",
48+
opt := &cos.ImageRecognitionOptions{
49+
DetectType: "porn,terrorist,politics",
5150
}
5251

53-
// Case1 Download object into ReadCloser(). the body needs to be closed
5452
name := "test.jpg"
55-
resp, err := c.Object.Get(context.Background(), name, opt)
53+
res, _, err := c.CI.ImageRecognition(context.Background(), name, opt)
5654
log_status(err)
57-
resp.Body.Close()
58-
res := cos.GetRecognitionResult(resp.Body)
59-
if res != nil {
60-
fmt.Printf("%+v\n", res)
61-
}
55+
fmt.Printf("%+v\n", res)
6256
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
"net/url"
8+
"os"
9+
"time"
10+
11+
"github.com/tencentyun/cos-go-sdk-v5"
12+
"github.com/tencentyun/cos-go-sdk-v5/debug"
13+
)
14+
15+
func log_status(err error) {
16+
if err == nil {
17+
return
18+
}
19+
if cos.IsNotFoundError(err) {
20+
// WARN
21+
fmt.Println("WARN: Resource is not existed")
22+
} else if e, ok := cos.IsCOSError(err); ok {
23+
fmt.Printf("ERROR: Code: %v\n", e.Code)
24+
fmt.Printf("ERROR: Message: %v\n", e.Message)
25+
fmt.Printf("ERROR: Resource: %v\n", e.Resource)
26+
fmt.Printf("ERROR: RequestId: %v\n", e.RequestID)
27+
// ERROR
28+
} else {
29+
fmt.Printf("ERROR: %v\n", err)
30+
// ERROR
31+
}
32+
}
33+
34+
func main() {
35+
bu, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
36+
cu, _ := url.Parse("https://test-1259654469.ci.ap-guangzhou.myqcloud.com")
37+
b := &cos.BaseURL{BucketURL: bu, CIURL: cu}
38+
c := cos.NewClient(b, &http.Client{
39+
Transport: &cos.AuthorizationTransport{
40+
SecretID: os.Getenv("COS_SECRETID"),
41+
SecretKey: os.Getenv("COS_SECRETKEY"),
42+
Transport: &debug.DebugRequestTransport{
43+
RequestHeader: true,
44+
RequestBody: true,
45+
ResponseHeader: true,
46+
ResponseBody: true,
47+
},
48+
},
49+
})
50+
opt := &cos.PutVideoAuditingJobOptions{
51+
InputObject: "demo.mp4",
52+
Conf: &cos.VideoAuditingJobConf{
53+
DetectType: "Porn,Terrorism,Politics,Ads",
54+
Snapshot: &cos.PutVideoAuditingJobSnapshot{
55+
Mode: "Interval",
56+
Start: 0.5,
57+
TimeInterval: 50.5,
58+
Count: 100,
59+
},
60+
},
61+
}
62+
63+
res, _, err := c.CI.PutVideoAuditingJob(context.Background(), opt)
64+
log_status(err)
65+
fmt.Printf("%+v\n", res)
66+
67+
time.Sleep(3 * time.Second)
68+
res2, _, err := c.CI.GetVideoAuditingJob(context.Background(), res.JobsDetail.JobId)
69+
log_status(err)
70+
fmt.Printf("%+v\n", res2)
71+
}

0 commit comments

Comments
 (0)