You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

259 lines
8.4 KiB

5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. package cos
  2. import (
  3. "context"
  4. "encoding/json"
  5. "encoding/xml"
  6. "fmt"
  7. "hash/crc64"
  8. "io"
  9. "net/http"
  10. "os"
  11. )
  12. type CIService service
  13. type PicOperations struct {
  14. IsPicInfo int `json:"is_pic_info,omitempty"`
  15. Rules []PicOperationsRules `json:"rules,omitemtpy"`
  16. }
  17. type PicOperationsRules struct {
  18. Bucket string `json:"bucket,omitempty"`
  19. FileId string `json:"fileid"`
  20. Rule string `json:"rule"`
  21. }
  22. func EncodePicOperations(pic *PicOperations) string {
  23. if pic == nil {
  24. return ""
  25. }
  26. bs, err := json.Marshal(pic)
  27. if err != nil {
  28. return ""
  29. }
  30. return string(bs)
  31. }
  32. type ImageProcessResult struct {
  33. XMLName xml.Name `xml:"UploadResult"`
  34. OriginalInfo *PicOriginalInfo `xml:"OriginalInfo,omitempty"`
  35. ProcessResults *PicProcessObject `xml:"ProcessResults>Object,omitempty"`
  36. }
  37. type PicOriginalInfo struct {
  38. Key string `xml:"Key,omitempty"`
  39. Location string `xml:"Location,omitempty"`
  40. ImageInfo *PicImageInfo `xml:"ImageInfo,omitempty"`
  41. ETag string `xml:"ETag,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. Quality int `xml:"Quality,omitempty"`
  48. Ave string `xml:"Ave,omitempty"`
  49. Orientation int `xml:"Orientation,omitempty"`
  50. }
  51. type PicProcessObject struct {
  52. Key string `xml:"Key,omitempty"`
  53. Location string `xml:"Location,omitempty"`
  54. Format string `xml:"Format,omitempty"`
  55. Width int `xml:"Width,omitempty"`
  56. Height int `xml:"Height,omitempty"`
  57. Size int `xml:"Size,omitempty"`
  58. Quality int `xml:"Quality,omitempty"`
  59. ETag string `xml:"ETag,omitempty"`
  60. WatermarkStatus int `xml:"WatermarkStatus,omitempty"`
  61. }
  62. type picOperationsHeader struct {
  63. PicOperations string `header:"Pic-Operations" xml:"-" url:"-"`
  64. }
  65. type ImageProcessOptions = PicOperations
  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. type ImageRecognitionOptions struct {
  83. CIProcess string `url:"ci-process,omitempty"`
  84. DetectType string `url:"detect-type,omitempty"`
  85. }
  86. type ImageRecognitionResult struct {
  87. XMLName xml.Name `xml:"RecognitionResult"`
  88. PornInfo *RecognitionInfo `xml:"PornInfo,omitempty"`
  89. TerroristInfo *RecognitionInfo `xml:"TerroristInfo,omitempty"`
  90. PoliticsInfo *RecognitionInfo `xml:"PoliticsInfo,omitempty"`
  91. AdsInfo *RecognitionInfo `xml:"AdsInfo,omitempty"`
  92. }
  93. type RecognitionInfo struct {
  94. Code int `xml:"Code,omitempty"`
  95. Msg string `xml:"Msg,omitempty"`
  96. HitFlag int `xml:"HitFlag,omitempty"`
  97. Score int `xml:"Score,omitempty"`
  98. Label string `xml:"Label,omitempty"`
  99. Count int `xml:"Count,omitempty"`
  100. }
  101. // 图片审核 https://cloud.tencent.com/document/product/460/37318
  102. func (s *CIService) ImageRecognition(ctx context.Context, name string, opt *ImageRecognitionOptions) (*ImageRecognitionResult, *Response, error) {
  103. if opt != nil && opt.CIProcess == "" {
  104. opt.CIProcess = "sensitive-content-recognition"
  105. }
  106. var res ImageRecognitionResult
  107. sendOpt := sendOptions{
  108. baseURL: s.client.BaseURL.BucketURL,
  109. uri: "/" + encodeURIComponent(name),
  110. method: http.MethodGet,
  111. optQuery: opt,
  112. result: &res,
  113. }
  114. resp, err := s.client.send(ctx, &sendOpt)
  115. return &res, resp, err
  116. }
  117. type PutVideoAuditingJobOptions struct {
  118. XMLName xml.Name `xml:"Request"`
  119. InputObject string `xml:"Input>Object"`
  120. Conf *VideoAuditingJobConf `xml:"Conf"`
  121. }
  122. type VideoAuditingJobConf struct {
  123. DetectType string `xml:",omitempty"`
  124. Snapshot *PutVideoAuditingJobSnapshot `xml:",omitempty"`
  125. Callback string `xml:",omitempty"`
  126. }
  127. type PutVideoAuditingJobSnapshot struct {
  128. Mode string `xml:",omitempty"`
  129. Count int `xml:",omitempty"`
  130. TimeInterval float32 `xml:",omitempty"`
  131. Start float32 `xml:",omitempty"`
  132. }
  133. type PutVideoAuditingJobResult struct {
  134. XMLName xml.Name `xml:"Response"`
  135. JobsDetail struct {
  136. JobId string `xml:"JobId,omitempty"`
  137. State string `xml:"State,omitempty"`
  138. CreationTime string `xml:"CreationTime,omitempty"`
  139. Object string `xml:"Object,omitempty"`
  140. } `xml:"JobsDetail,omitempty"`
  141. }
  142. func (s *CIService) PutVideoAuditingJob(ctx context.Context, opt *PutVideoAuditingJobOptions) (*PutVideoAuditingJobResult, *Response, error) {
  143. var res PutVideoAuditingJobResult
  144. sendOpt := sendOptions{
  145. baseURL: s.client.BaseURL.CIURL,
  146. uri: "/video/auditing",
  147. method: http.MethodPost,
  148. body: opt,
  149. result: &res,
  150. }
  151. resp, err := s.client.send(ctx, &sendOpt)
  152. return &res, resp, err
  153. }
  154. type GetVideoAuditingJobResult struct {
  155. XMLName xml.Name `xml:"Response"`
  156. JobsDetail *VideoAuditingJobDetail `xml:",omitempty"`
  157. NonExistJobIds string `xml:",omitempty"`
  158. }
  159. type VideoAuditingJobDetail struct {
  160. Code string `xml:",omitempty"`
  161. Message string `xml:",omitempty"`
  162. JobId string `xml:",omitempty"`
  163. State string `xml:",omitempty"`
  164. CreationTime string `xml:",omitempty"`
  165. Object string `xml:",omitempty"`
  166. SnapshotCount string `xml:",omitempty"`
  167. Result int `xml:",omitempty"`
  168. PornInfo *RecognitionInfo `xml:",omitempty"`
  169. TerrorismInfo *RecognitionInfo `xml:",omitempty"`
  170. PoliticsInfo *RecognitionInfo `xml:",omitempty"`
  171. AdsInfo *RecognitionInfo `xml:",omitempty"`
  172. Snapshot *GetVideoAuditingJobSnapshot `xml:",omitempty"`
  173. }
  174. type GetVideoAuditingJobSnapshot struct {
  175. Url string `xml:",omitempty"`
  176. PornInfo *RecognitionInfo `xml:",omitempty"`
  177. TerrorismInfo *RecognitionInfo `xml:",omitempty"`
  178. PoliticsInfo *RecognitionInfo `xml:",omitempty"`
  179. AdsInfo *RecognitionInfo `xml:",omitempty"`
  180. }
  181. func (s *CIService) GetVideoAuditingJob(ctx context.Context, jobid string) (*GetVideoAuditingJobResult, *Response, error) {
  182. var res GetVideoAuditingJobResult
  183. sendOpt := sendOptions{
  184. baseURL: s.client.BaseURL.CIURL,
  185. uri: "/video/auditing/" + jobid,
  186. method: http.MethodGet,
  187. result: &res,
  188. }
  189. resp, err := s.client.send(ctx, &sendOpt)
  190. return &res, resp, err
  191. }
  192. // ci put https://cloud.tencent.com/document/product/460/18147
  193. func (s *CIService) Put(ctx context.Context, name string, r io.Reader, uopt *ObjectPutOptions) (*ImageProcessResult, *Response, error) {
  194. if r == nil {
  195. return nil, nil, fmt.Errorf("reader is nil")
  196. }
  197. if err := CheckReaderLen(r); err != nil {
  198. return nil, nil, err
  199. }
  200. opt := cloneObjectPutOptions(uopt)
  201. totalBytes, err := GetReaderLen(r)
  202. if err != nil && opt != nil && opt.Listener != nil {
  203. return nil, nil, err
  204. }
  205. if err == nil {
  206. // 与 go http 保持一致, 非bytes.Buffer/bytes.Reader/strings.Reader由用户指定ContentLength, 或使用 Chunk 上传
  207. if opt != nil && opt.ContentLength == 0 && IsLenReader(r) {
  208. opt.ContentLength = totalBytes
  209. }
  210. }
  211. reader := TeeReader(r, nil, totalBytes, nil)
  212. if s.client.Conf.EnableCRC {
  213. reader.writer = crc64.New(crc64.MakeTable(crc64.ECMA))
  214. }
  215. if opt != nil && opt.Listener != nil {
  216. reader.listener = opt.Listener
  217. }
  218. var res ImageProcessResult
  219. sendOpt := sendOptions{
  220. baseURL: s.client.BaseURL.BucketURL,
  221. uri: "/" + encodeURIComponent(name),
  222. method: http.MethodPut,
  223. body: reader,
  224. optHeader: opt,
  225. result: &res,
  226. }
  227. resp, err := s.client.send(ctx, &sendOpt)
  228. return &res, resp, err
  229. }
  230. // ci put object from local file
  231. func (s *CIService) PutFromFile(ctx context.Context, name string, filePath string, opt *ObjectPutOptions) (*ImageProcessResult, *Response, error) {
  232. fd, err := os.Open(filePath)
  233. if err != nil {
  234. return nil, nil, err
  235. }
  236. defer fd.Close()
  237. return s.Put(ctx, name, fd, opt)
  238. }