forked from TrueCloudLab/rclone
vendor: resync with dep ensure
This commit is contained in:
parent
6f2a6dfbc5
commit
6390bb2b09
15 changed files with 899 additions and 37 deletions
8
Gopkg.lock
generated
8
Gopkg.lock
generated
|
@ -212,10 +212,10 @@
|
||||||
revision = "2df9a531813370438a4d79bfc33e21f58063ed87"
|
revision = "2df9a531813370438a4d79bfc33e21f58063ed87"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
name = "github.com/spf13/pflag"
|
name = "github.com/spf13/pflag"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
revision = "7aff26db30c1be810f9de5038ec5ef96ac41fd7c"
|
||||||
version = "v1.0.0"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -279,7 +279,7 @@
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "google.golang.org/appengine"
|
name = "google.golang.org/appengine"
|
||||||
packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","urlfetch"]
|
packages = [".","internal","internal/app_identity","internal/base","internal/datastore","internal/log","internal/modules","internal/remote_api","internal/urlfetch","log","urlfetch"]
|
||||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
|
@ -292,6 +292,6 @@
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "e660aa956f1e580bda1ce240cdb673bcbc00bb8f2ef2e77e85d3d941528836f1"
|
inputs-digest = "119fcfb60b243cc6c75c9ebd02ddc913a1492a128cb7bdecb7ef180a0fc5be44"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|
4
vendor/github.com/spf13/pflag/flag.go
generated
vendored
4
vendor/github.com/spf13/pflag/flag.go
generated
vendored
|
@ -556,6 +556,10 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
|
||||||
name = "int"
|
name = "int"
|
||||||
case "uint64":
|
case "uint64":
|
||||||
name = "uint"
|
name = "uint"
|
||||||
|
case "stringSlice":
|
||||||
|
name = "strings"
|
||||||
|
case "intSlice":
|
||||||
|
name = "ints"
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
4
vendor/github.com/spf13/pflag/flag_test.go
generated
vendored
4
vendor/github.com/spf13/pflag/flag_test.go
generated
vendored
|
@ -978,12 +978,12 @@ const defaultOutput = ` --A for bootstrapping, allo
|
||||||
--IP ip IP address with no default
|
--IP ip IP address with no default
|
||||||
--IPMask ipMask Netmask address with no default
|
--IPMask ipMask Netmask address with no default
|
||||||
--IPNet ipNet IP network with no default
|
--IPNet ipNet IP network with no default
|
||||||
--Ints intSlice int slice with zero default
|
--Ints ints int slice with zero default
|
||||||
--N int a non-zero int (default 27)
|
--N int a non-zero int (default 27)
|
||||||
--ND1 string[="bar"] a string with NoOptDefVal (default "foo")
|
--ND1 string[="bar"] a string with NoOptDefVal (default "foo")
|
||||||
--ND2 num[=4321] a num with NoOptDefVal (default 1234)
|
--ND2 num[=4321] a num with NoOptDefVal (default 1234)
|
||||||
--StringArray stringArray string array with zero default
|
--StringArray stringArray string array with zero default
|
||||||
--StringSlice stringSlice string slice with zero default
|
--StringSlice strings string slice with zero default
|
||||||
--Z int an int that defaults to zero
|
--Z int an int that defaults to zero
|
||||||
--custom custom custom Value implementation
|
--custom custom custom Value implementation
|
||||||
--customP custom a VarP with default (default 10)
|
--customP custom a VarP with default (default 10)
|
||||||
|
|
259
vendor/github.com/yunify/qingstor-sdk-go/client/image/image.go
generated
vendored
Normal file
259
vendor/github.com/yunify/qingstor-sdk-go/client/image/image.go
generated
vendored
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/yunify/qingstor-sdk-go/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ActionSep is separator of action.
|
||||||
|
ActionSep = ":"
|
||||||
|
|
||||||
|
// OPSep is separator of operation.
|
||||||
|
OPSep = "|"
|
||||||
|
|
||||||
|
// KVSep is separator of Key-Value.
|
||||||
|
KVSep = "_"
|
||||||
|
|
||||||
|
//KVPairSep is separator of args.
|
||||||
|
KVPairSep = ","
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// InfoOperation is string of info operation.
|
||||||
|
InfoOperation string = "info"
|
||||||
|
|
||||||
|
// CropOperation is string of crop operation.
|
||||||
|
CropOperation string = "crop"
|
||||||
|
|
||||||
|
// FormatOperation is string of format operation.
|
||||||
|
FormatOperation string = "format"
|
||||||
|
|
||||||
|
// ResizeOperation is string of resize operation.
|
||||||
|
ResizeOperation string = "resize"
|
||||||
|
|
||||||
|
// RotateOperation is string of rotate operation.
|
||||||
|
RotateOperation string = "rotate"
|
||||||
|
|
||||||
|
// WaterMarkOperation is string of watermark operation.
|
||||||
|
WaterMarkOperation string = "watermark"
|
||||||
|
|
||||||
|
// WaterMarkImageOperation is string of watermark image operation.
|
||||||
|
WaterMarkImageOperation string = "watermark_image"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResizeMode is the type of resize mode.
|
||||||
|
type ResizeMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ResizeFixed resizes image to fix width and height.
|
||||||
|
ResizeFixed ResizeMode = iota
|
||||||
|
|
||||||
|
// ResizeForce resizes image to force witdth and height.
|
||||||
|
ResizeForce
|
||||||
|
|
||||||
|
// ResizeThumbnail resizes image to thumbnail width and height.
|
||||||
|
ResizeThumbnail
|
||||||
|
)
|
||||||
|
|
||||||
|
// CropGravity is the type of crop gravity.
|
||||||
|
type CropGravity int
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// CropCenter crops image to center width and height.
|
||||||
|
CropCenter CropGravity = iota
|
||||||
|
|
||||||
|
// CropNorth crops image to north width and height.
|
||||||
|
CropNorth
|
||||||
|
|
||||||
|
// CropEast crops image to east width and height.
|
||||||
|
CropEast
|
||||||
|
|
||||||
|
// CropSouth crops image to south width and height.
|
||||||
|
CropSouth
|
||||||
|
|
||||||
|
// CropWest crops image to west width and height.
|
||||||
|
CropWest
|
||||||
|
|
||||||
|
// CropNorthWest crops image to north west width and height.
|
||||||
|
CropNorthWest
|
||||||
|
|
||||||
|
// CropNorthEast crops image to north east width and height.
|
||||||
|
CropNorthEast
|
||||||
|
|
||||||
|
// CropSouthWest crops image to south west width and height.
|
||||||
|
CropSouthWest
|
||||||
|
|
||||||
|
// CropSouthEast crops image to south east width and height.
|
||||||
|
CropSouthEast
|
||||||
|
|
||||||
|
// CropAuto crops image to auto width and height.
|
||||||
|
CropAuto
|
||||||
|
)
|
||||||
|
|
||||||
|
// Image is struct of Image process.
|
||||||
|
type Image struct {
|
||||||
|
key *string
|
||||||
|
bucket *service.Bucket
|
||||||
|
input *service.ImageProcessInput
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes an image to process.
|
||||||
|
func Init(bucket *service.Bucket, objectKey string) *Image {
|
||||||
|
return &Image{
|
||||||
|
key: &objectKey,
|
||||||
|
bucket: bucket,
|
||||||
|
input: &service.ImageProcessInput{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info gets the information of the image.
|
||||||
|
func (image *Image) Info() *Image {
|
||||||
|
return image.setActionParam(InfoOperation, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RotateParam is param of the rotate operation.
|
||||||
|
type RotateParam struct {
|
||||||
|
Angle int `schema:"a"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate image.
|
||||||
|
func (image *Image) Rotate(param *RotateParam) *Image {
|
||||||
|
return image.setActionParam(RotateOperation, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResizeParam is param of the resize operation.
|
||||||
|
type ResizeParam struct {
|
||||||
|
Width int `schema:"w,omitempty"`
|
||||||
|
Height int `schema:"h,omitempty"`
|
||||||
|
Mode ResizeMode `schema:"m"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resize image.
|
||||||
|
func (image *Image) Resize(param *ResizeParam) *Image {
|
||||||
|
return image.setActionParam(ResizeOperation, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CropParam is param of the crop operation.
|
||||||
|
type CropParam struct {
|
||||||
|
Width int `schema:"w,omitempty"`
|
||||||
|
Height int `schema:"h,omitempty"`
|
||||||
|
Gravity CropGravity `schema:"g"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crop image.
|
||||||
|
func (image *Image) Crop(param *CropParam) *Image {
|
||||||
|
return image.setActionParam(CropOperation, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatParam is param of the format operation.
|
||||||
|
type FormatParam struct {
|
||||||
|
Type string `schema:"t"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format image.
|
||||||
|
func (image *Image) Format(param *FormatParam) *Image {
|
||||||
|
return image.setActionParam(FormatOperation, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaterMarkParam is param of the wartermark operation.
|
||||||
|
type WaterMarkParam struct {
|
||||||
|
Dpi int `schema:"d,omitempty"`
|
||||||
|
Opacity float64 `schema:"p,omitempty"`
|
||||||
|
Text string `schema:"t"`
|
||||||
|
Color string `schema:"c"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaterMark is operation of watermark text content.
|
||||||
|
func (image *Image) WaterMark(param *WaterMarkParam) *Image {
|
||||||
|
return image.setActionParam(WaterMarkOperation, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaterMarkImageParam is param of the waterMark image operation
|
||||||
|
type WaterMarkImageParam struct {
|
||||||
|
Left int `schema:"l"`
|
||||||
|
Top int `schema:"t"`
|
||||||
|
Opacity float64 `schema:"p,omitempty"`
|
||||||
|
URL string `schema:"u"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaterMarkImage is operation of watermark image.
|
||||||
|
func (image *Image) WaterMarkImage(param *WaterMarkImageParam) *Image {
|
||||||
|
return image.setActionParam(WaterMarkImageOperation, param)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process does Image process.
|
||||||
|
func (image *Image) Process() (*service.ImageProcessOutput, error) {
|
||||||
|
defer func(input *service.ImageProcessInput) {
|
||||||
|
input.Action = nil
|
||||||
|
}(image.input)
|
||||||
|
return image.bucket.ImageProcess(*image.key, image.input)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (image *Image) setActionParam(operation string, param interface{}) *Image {
|
||||||
|
uri := operation
|
||||||
|
if param != nil {
|
||||||
|
uri = fmt.Sprintf("%s%s%s", uri, ActionSep, buildOptParamStr(param))
|
||||||
|
}
|
||||||
|
if image.input.Action != nil {
|
||||||
|
uri = fmt.Sprintf("%s%s%s", *image.input.Action, OPSep, uri)
|
||||||
|
}
|
||||||
|
image.input.Action = &uri
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildOptParamStr(param interface{}) string {
|
||||||
|
v := reflect.ValueOf(param).Elem()
|
||||||
|
var kvPairs []string
|
||||||
|
|
||||||
|
for i := 0; i < v.NumField(); i++ {
|
||||||
|
vf := v.Field(i)
|
||||||
|
tf := v.Type().Field(i)
|
||||||
|
key := tf.Tag.Get("schema")
|
||||||
|
value := vf.Interface()
|
||||||
|
tagValues := strings.Split(key, ",")
|
||||||
|
if isEmptyValue(vf) &&
|
||||||
|
len(tagValues) == 2 &&
|
||||||
|
tagValues[1] == "omitempty" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key = tagValues[0]
|
||||||
|
kvPairs = append(kvPairs, fmt.Sprintf("%v%s%v", key, KVSep, value))
|
||||||
|
}
|
||||||
|
return strings.Join(kvPairs, KVPairSep)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmptyValue(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array,
|
||||||
|
reflect.Map,
|
||||||
|
reflect.Slice,
|
||||||
|
reflect.String:
|
||||||
|
return v.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !v.Bool()
|
||||||
|
case reflect.Int,
|
||||||
|
reflect.Int8,
|
||||||
|
reflect.Int16,
|
||||||
|
reflect.Int32,
|
||||||
|
reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint,
|
||||||
|
reflect.Uint8,
|
||||||
|
reflect.Uint16,
|
||||||
|
reflect.Uint32,
|
||||||
|
reflect.Uint64,
|
||||||
|
reflect.Uintptr:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32,
|
||||||
|
reflect.Float64:
|
||||||
|
return v.Float() == 0
|
||||||
|
case reflect.Ptr:
|
||||||
|
return v.IsNil()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
63
vendor/github.com/yunify/qingstor-sdk-go/client/image/image_test.go
generated
vendored
Normal file
63
vendor/github.com/yunify/qingstor-sdk-go/client/image/image_test.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package image
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
qs "github.com/yunify/qingstor-sdk-go/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
var image *Image
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
bucket := &qs.Bucket{}
|
||||||
|
|
||||||
|
// test.jpg is only a string
|
||||||
|
image = Init(bucket, "test.jpg")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQueryString(t *testing.T) {
|
||||||
|
var param interface{}
|
||||||
|
param = &RotateParam{
|
||||||
|
Angle: 90,
|
||||||
|
}
|
||||||
|
image.setActionParam(RotateOperation, param)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90")
|
||||||
|
|
||||||
|
param = &CropParam{
|
||||||
|
Width: 300,
|
||||||
|
Height: 400,
|
||||||
|
Gravity: 0,
|
||||||
|
}
|
||||||
|
image.setActionParam(CropOperation, param)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90|crop:w_300,h_400,g_0")
|
||||||
|
|
||||||
|
param = &ResizeParam{
|
||||||
|
Width: 500,
|
||||||
|
Height: 500,
|
||||||
|
Mode: ResizeForce,
|
||||||
|
}
|
||||||
|
image.setActionParam(ResizeOperation, param)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90|crop:w_300,h_400,g_0|resize:w_500,h_500,m_1")
|
||||||
|
|
||||||
|
param = &FormatParam{
|
||||||
|
Type: "png",
|
||||||
|
}
|
||||||
|
image.setActionParam(FormatOperation, param)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90|crop:w_300,h_400,g_0|resize:w_500,h_500,m_1|format:t_png")
|
||||||
|
|
||||||
|
param = &WaterMarkParam{
|
||||||
|
Text: "5rC05Y2w5paH5a2X",
|
||||||
|
}
|
||||||
|
image.setActionParam(WaterMarkOperation, param)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90|crop:w_300,h_400,g_0|resize:w_500,h_500,m_1|format:t_png|watermark:t_5rC05Y2w5paH5a2X,c_")
|
||||||
|
|
||||||
|
param = &WaterMarkImageParam{
|
||||||
|
URL: "aHR0cHM6Ly9wZWszYS5xaW5nc3Rvci5jb20vaW1nLWRvYy1lZy9xaW5jbG91ZC5wbmc",
|
||||||
|
}
|
||||||
|
image.setActionParam(WaterMarkImageOperation, param)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90|crop:w_300,h_400,g_0|resize:w_500,h_500,m_1|format:t_png|watermark:t_5rC05Y2w5paH5a2X,c_|watermark_image:l_0,t_0,u_aHR0cHM6Ly9wZWszYS5xaW5nc3Rvci5jb20vaW1nLWRvYy1lZy9xaW5jbG91ZC5wbmc")
|
||||||
|
|
||||||
|
image.setActionParam(InfoOperation, nil)
|
||||||
|
assert.Equal(t, *image.input.Action, "rotate:a_90|crop:w_300,h_400,g_0|resize:w_500,h_500,m_1|format:t_png|watermark:t_5rC05Y2w5paH5a2X,c_|watermark_image:l_0,t_0,u_aHR0cHM6Ly9wZWszYS5xaW5nc3Rvci5jb20vaW1nLWRvYy1lZy9xaW5jbG91ZC5wbmc|info")
|
||||||
|
}
|
272
vendor/github.com/yunify/qingstor-sdk-go/docs/image_process_usage.md
generated
vendored
Normal file
272
vendor/github.com/yunify/qingstor-sdk-go/docs/image_process_usage.md
generated
vendored
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
# QingStor Image Processing Usage Guide
|
||||||
|
|
||||||
|
For processing the image stored in QingStor by a variety of basic operations, such as format, crop, watermark and so on.
|
||||||
|
Please see [QingStor Image API](https://docs.qingcloud.com/qingstor/data_process/image_process/index.html).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
Before using the image service, you need to initialize the [Configuration](https://github.com/yunify/qingstor-sdk-go/blob/master/docs/configuration.md) and [QingStor Service](https://github.com/yunify/qingstor-sdk-go/blob/master/docs/qingstor_service_usage.md).
|
||||||
|
|
||||||
|
``` go
|
||||||
|
//Import the latest version API
|
||||||
|
import (
|
||||||
|
"github.com/yunify/qingstor-sdk-go/config"
|
||||||
|
"github.com/yunify/qingstor-sdk-go/client/image"
|
||||||
|
qs "github.com/yunify/qingstor-sdk-go/service"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Snippet
|
||||||
|
|
||||||
|
Create configuration from Access Key and Initialize the QingStor service with a configuration.
|
||||||
|
``` go
|
||||||
|
// Initialize the QingStor service with a configuration
|
||||||
|
config, _ := config.New("ACCESS_KEY_ID", "SECRET_ACCESS_KEY")
|
||||||
|
service, _ := qs.Init(config)
|
||||||
|
```
|
||||||
|
Initialize a QingStor bucket.
|
||||||
|
``` go
|
||||||
|
bucket, _ := service.Bucket("bucketName", "zoneID")
|
||||||
|
```
|
||||||
|
Initialize a image.
|
||||||
|
``` go
|
||||||
|
img := image.Init(bucket, "imageName")
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can use the the high level APIs or basic image process API to do the image operation.
|
||||||
|
|
||||||
|
Get the information of the image
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ := img.Info().Process()
|
||||||
|
```
|
||||||
|
|
||||||
|
Crop the image.
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ := img.Crop(&image.CropParam{
|
||||||
|
...operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
|
||||||
|
Rotate the image.
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ := img.Rotate(&image.RotateParam{
|
||||||
|
...operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
Resize the image.
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ := img.Resize(&image.ResizeParam{
|
||||||
|
...operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
Watermark the image.
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ := img.WaterMark(&image.WaterMarkParam{
|
||||||
|
...operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
WaterMarkImage the image.
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ : = img.WaterMarkImage(&image.WaterMarkImageParam{
|
||||||
|
...operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
Format the image.
|
||||||
|
``` go
|
||||||
|
imageProcessOutput, _ := img.Format(&image.Format{
|
||||||
|
...operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
Operation pipline, the image will be processed by order. The maximum number of operations in the pipeline is 10.
|
||||||
|
``` go
|
||||||
|
// Rotate and then resize the image
|
||||||
|
imageProcessOutput, _ := img.Rotate(&image.RotateParam{
|
||||||
|
... operation_param...
|
||||||
|
}).Resize(&image.ResizeParam{
|
||||||
|
... operation_param...
|
||||||
|
}).Process()
|
||||||
|
```
|
||||||
|
Use the original basic API to rotate the image 90 angles.
|
||||||
|
``` go
|
||||||
|
operation := "rotate:a_90"
|
||||||
|
imageProcessOutput, err := bucket.ImageProcess("imageName", &qs.ImageProcessInput{
|
||||||
|
Action: &operation})
|
||||||
|
```
|
||||||
|
|
||||||
|
`operation_param` is the image operation param, which definined in `qingstor-sdk-go/client/image/image.go`.
|
||||||
|
``` go
|
||||||
|
import "github.com/yunify/qingstor-sdk-go/service"
|
||||||
|
// client/image/image.go
|
||||||
|
type Image struct {
|
||||||
|
key *string
|
||||||
|
bucket *service.Bucket
|
||||||
|
input *service.ImageProcessInput
|
||||||
|
}
|
||||||
|
|
||||||
|
// About cropping image definition
|
||||||
|
type CropGravity int
|
||||||
|
const (
|
||||||
|
CropCenter CropGravity = iota
|
||||||
|
CropNorth
|
||||||
|
CropEast
|
||||||
|
CropSouth
|
||||||
|
CropWest
|
||||||
|
CropNorthWest
|
||||||
|
CropNorthEast
|
||||||
|
CropSouthWest
|
||||||
|
CropSouthEast
|
||||||
|
CropAuto
|
||||||
|
)
|
||||||
|
type CropParam struct {
|
||||||
|
Width int `schema:"w,omitempty"`
|
||||||
|
Height int `schema:"h,omitempty"`
|
||||||
|
Gravity CropGravity `schema:"g"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// About rotating image definitions
|
||||||
|
type RotateParam struct {
|
||||||
|
Angle int `schema:"a"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// About resizing image definitions
|
||||||
|
type ResizeMode int
|
||||||
|
type ResizeParam struct {
|
||||||
|
Width int `schema:"w,omitempty"`
|
||||||
|
Height int `schema:"h,omitempty"`
|
||||||
|
Mode ResizeMode `schema:"m"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// On the definition of text watermarking
|
||||||
|
type WaterMarkParam struct {
|
||||||
|
Dpi int `schema:"d,omitempty"`
|
||||||
|
Opacity float64 `schema:"p,omitempty"`
|
||||||
|
Text string `schema:"t"`
|
||||||
|
Color string `schema:"c"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// On the definition of image watermarking
|
||||||
|
type WaterMarkImageParam struct {
|
||||||
|
Left int `schema:"l"`
|
||||||
|
Top int `schema:"t"`
|
||||||
|
Opacity float64 `schema:"p,omitempty"`
|
||||||
|
URL string `schema:"u"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// About image format conversion definitions
|
||||||
|
type FormatParam struct {
|
||||||
|
Type string `schema:"t"`
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
__Quick Start Code Example:__
|
||||||
|
|
||||||
|
Include a complete example, but the code needs to fill in your own information
|
||||||
|
|
||||||
|
``` go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/yunify/qingstor-sdk-go/client/image"
|
||||||
|
"github.com/yunify/qingstor-sdk-go/config"
|
||||||
|
qs "github.com/yunify/qingstor-sdk-go/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Load your configuration
|
||||||
|
// Replace here with your key pair
|
||||||
|
config, err := config.New("ACCESS_KEY_ID", "SECRET_ACCESS_KEY")
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
// Initialize QingStror Service
|
||||||
|
service, err := qs.Init(config)
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
// Initialize Bucket
|
||||||
|
// Replace here with your bucketName and zoneID
|
||||||
|
bucket, err := service.Bucket("bucketName", "zoneID")
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
// Initialize Image
|
||||||
|
// Replace here with your your ImageName
|
||||||
|
img := image.Init(bucket, "imageName")
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
// Because 0 is an invalid parameter, default not modify
|
||||||
|
imageProcessOutput, err := img.Crop(&image.CropParam{Width: 0}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Rotate the image 90 angles
|
||||||
|
imageProcessOutput, err = img.Rotate(&image.RotateParam{Angle: 90}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Text watermark, Watermark text content, encoded by base64.
|
||||||
|
imageProcessOutput, err = img.WaterMark(&image.WaterMarkParam{
|
||||||
|
Text: "5rC05Y2w5paH5a2X",
|
||||||
|
}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Image watermark, Watermark image url encoded by base64.
|
||||||
|
imageProcessOutput, err = img.WaterMarkImage(&image.WaterMarkImageParam{
|
||||||
|
URL: "aHR0cHM6Ly9wZWszYS5xaW5nc3Rvci5jb20vaW1nLWRvYy1lZy9xaW5jbG91ZC5wbmc",
|
||||||
|
}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Reszie the image with width 300px and height 400 px
|
||||||
|
imageProcessOutput, err = img.Resize(&image.ResizeParam{
|
||||||
|
Width: 300,
|
||||||
|
Height: 400,
|
||||||
|
}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Swap format to jpeg
|
||||||
|
imageProcessOutput, err = img.Format(&image.FormatParam{
|
||||||
|
Type: "jpeg",
|
||||||
|
}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Pipline model
|
||||||
|
// The maximum number of operations in the pipeline is 10
|
||||||
|
imageProcessOutput, err = img.Rotate(&image.RotateParam{
|
||||||
|
Angle: 270,
|
||||||
|
}).Resize(&image.ResizeParam{
|
||||||
|
Width: 300,
|
||||||
|
Height: 300,
|
||||||
|
}).Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Get the information of the image
|
||||||
|
imageProcessOutput, err = img.Info().Process()
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
|
||||||
|
// Use the original api to rotate the image 90 angles
|
||||||
|
operation := "rotate:a_90"
|
||||||
|
imageProcessOutput, err = bucket.ImageProcess("imageName", &qs.ImageProcessInput{
|
||||||
|
Action: &operation})
|
||||||
|
checkErr(err)
|
||||||
|
testOutput(imageProcessOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
// *qs.ImageProcessOutput: github.com/yunify/qingstor-sdk-go/service/object.go
|
||||||
|
func testOutput(out *qs.ImageProcessOutput) {
|
||||||
|
log.Println(*out.StatusCode)
|
||||||
|
log.Println(*out.RequestID)
|
||||||
|
log.Println(out.Body)
|
||||||
|
log.Println(*out.ContentLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkErr(err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
66
vendor/github.com/yunify/qingstor-sdk-go/request/request.go
generated
vendored
66
vendor/github.com/yunify/qingstor-sdk-go/request/request.go
generated
vendored
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pengsrc/go-shared/convert"
|
"github.com/pengsrc/go-shared/convert"
|
||||||
|
@ -64,6 +65,27 @@ func New(o *data.Operation, i data.Input, x interface{}) (*Request, error) {
|
||||||
// Send sends API request.
|
// Send sends API request.
|
||||||
// It returns error if error occurred.
|
// It returns error if error occurred.
|
||||||
func (r *Request) Send() error {
|
func (r *Request) Send() error {
|
||||||
|
err := r.Build()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.Sign()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.Do()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build checks and builds the API request.
|
||||||
|
// It returns error if error occurred.
|
||||||
|
func (r *Request) Build() error {
|
||||||
err := r.check()
|
err := r.check()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -74,12 +96,13 @@ func (r *Request) Send() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.sign()
|
return nil
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.send()
|
// Do sends and unpacks the API request.
|
||||||
|
// It returns error if error occurred.
|
||||||
|
func (r *Request) Do() error {
|
||||||
|
err := r.send()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -95,17 +118,7 @@ func (r *Request) Send() error {
|
||||||
// Sign sign the API request by setting the authorization header.
|
// Sign sign the API request by setting the authorization header.
|
||||||
// It returns error if error occurred.
|
// It returns error if error occurred.
|
||||||
func (r *Request) Sign() error {
|
func (r *Request) Sign() error {
|
||||||
err := r.check()
|
err := r.sign()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = r.build()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = r.sign()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -116,21 +129,30 @@ func (r *Request) Sign() error {
|
||||||
// SignQuery sign the API request by appending query string.
|
// SignQuery sign the API request by appending query string.
|
||||||
// It returns error if error occurred.
|
// It returns error if error occurred.
|
||||||
func (r *Request) SignQuery(timeoutSeconds int) error {
|
func (r *Request) SignQuery(timeoutSeconds int) error {
|
||||||
err := r.check()
|
err := r.signQuery(int(time.Now().Unix()) + timeoutSeconds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.build()
|
return nil
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.signQuery(int(time.Now().Unix()) + timeoutSeconds)
|
// ApplySignature applies the Authorization header.
|
||||||
if err != nil {
|
// It returns error if error occurred.
|
||||||
return err
|
func (r *Request) ApplySignature(authorization string) error {
|
||||||
|
r.HTTPRequest.Header.Set("Authorization", authorization)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyQuerySignature applies the query signature.
|
||||||
|
// It returns error if error occurred.
|
||||||
|
func (r *Request) ApplyQuerySignature(accessKeyID string, expires int, signature string) error {
|
||||||
|
queryValue := r.HTTPRequest.URL.Query()
|
||||||
|
queryValue.Set("access_key_id", accessKeyID)
|
||||||
|
queryValue.Set("expires", strconv.Itoa(expires))
|
||||||
|
queryValue.Set("signature", signature)
|
||||||
|
|
||||||
|
r.HTTPRequest.URL.RawQuery = queryValue.Encode()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
vendor/github.com/yunify/qingstor-sdk-go/request/request_test.go
generated
vendored
2
vendor/github.com/yunify/qingstor-sdk-go/request/request_test.go
generated
vendored
|
@ -67,7 +67,7 @@ func Time(v time.Time) *time.Time {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequest_Send(t *testing.T) {
|
func TestRequestSend(t *testing.T) {
|
||||||
conf, err := config.New("ACCESS_KEY_ID", "SECRET_ACCESS_KEY")
|
conf, err := config.New("ACCESS_KEY_ID", "SECRET_ACCESS_KEY")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
logger.SetLevel("warn")
|
logger.SetLevel("warn")
|
||||||
|
|
7
vendor/github.com/yunify/qingstor-sdk-go/request/signer/qingstor.go
generated
vendored
7
vendor/github.com/yunify/qingstor-sdk-go/request/signer/qingstor.go
generated
vendored
|
@ -122,12 +122,16 @@ func (qss *QingStorSigner) BuildQuerySignature(request *http.Request, expires in
|
||||||
|
|
||||||
// BuildStringToSign build the string to sign.
|
// BuildStringToSign build the string to sign.
|
||||||
func (qss *QingStorSigner) BuildStringToSign(request *http.Request) (string, error) {
|
func (qss *QingStorSigner) BuildStringToSign(request *http.Request) (string, error) {
|
||||||
|
date := request.Header.Get("Date")
|
||||||
|
if request.Header.Get("X-QS-Date") != "" {
|
||||||
|
date = ""
|
||||||
|
}
|
||||||
stringToSign := fmt.Sprintf(
|
stringToSign := fmt.Sprintf(
|
||||||
"%s\n%s\n%s\n%s\n",
|
"%s\n%s\n%s\n%s\n",
|
||||||
request.Method,
|
request.Method,
|
||||||
request.Header.Get("Content-MD5"),
|
request.Header.Get("Content-MD5"),
|
||||||
request.Header.Get("Content-Type"),
|
request.Header.Get("Content-Type"),
|
||||||
request.Header.Get("Date"),
|
date,
|
||||||
)
|
)
|
||||||
|
|
||||||
stringToSign += qss.buildCanonicalizedHeaders(request)
|
stringToSign += qss.buildCanonicalizedHeaders(request)
|
||||||
|
@ -247,6 +251,7 @@ func (qss *QingStorSigner) paramsToSign(key string) bool {
|
||||||
"stats": true,
|
"stats": true,
|
||||||
"upload_id": true,
|
"upload_id": true,
|
||||||
"uploads": true,
|
"uploads": true,
|
||||||
|
"image": true,
|
||||||
"response-expires": true,
|
"response-expires": true,
|
||||||
"response-cache-control": true,
|
"response-cache-control": true,
|
||||||
"response-content-type": true,
|
"response-content-type": true,
|
||||||
|
|
42
vendor/github.com/yunify/qingstor-sdk-go/request/signer/qingstor_test.go
generated
vendored
42
vendor/github.com/yunify/qingstor-sdk-go/request/signer/qingstor_test.go
generated
vendored
|
@ -46,6 +46,27 @@ func TestQingStorSignerWriteSignature(t *testing.T) {
|
||||||
assert.Equal(t, signature, httpRequest.Header.Get("Authorization"))
|
assert.Equal(t, signature, httpRequest.Header.Get("Authorization"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQingStorSignerWriteSignatureWithXQSDate(t *testing.T) {
|
||||||
|
url := "https://qingstor.com/?acl&upload_id=fde133b5f6d932cd9c79bac3c7318da1&part_number=0&other=abc"
|
||||||
|
httpRequest, err := http.NewRequest("GET", url, nil)
|
||||||
|
httpRequest.Header.Set("Date", convert.TimeToString(time.Time{}, convert.RFC822))
|
||||||
|
httpRequest.Header.Set("X-QS-Date", convert.TimeToString(time.Time{}, convert.RFC822))
|
||||||
|
httpRequest.Header.Set("X-QS-Test-2", "Test 2")
|
||||||
|
httpRequest.Header.Set("X-QS-Test-1", "Test 1")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
s := QingStorSigner{
|
||||||
|
AccessKeyID: "ENV_ACCESS_KEY_ID",
|
||||||
|
SecretAccessKey: "ENV_SECRET_ACCESS_KEY",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.WriteSignature(httpRequest)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
signature := "QS ENV_ACCESS_KEY_ID:qkY+tOMdqfDAVv+ZBtlWeEBxlbyIKaQmj5lQlylENzo="
|
||||||
|
assert.Equal(t, signature, httpRequest.Header.Get("Authorization"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestQingStorSignerWriteSignatureChinese(t *testing.T) {
|
func TestQingStorSignerWriteSignatureChinese(t *testing.T) {
|
||||||
url := "https://zone.qingstor.com/bucket-name/中文"
|
url := "https://zone.qingstor.com/bucket-name/中文"
|
||||||
httpRequest, err := http.NewRequest("GET", url, nil)
|
httpRequest, err := http.NewRequest("GET", url, nil)
|
||||||
|
@ -83,3 +104,24 @@ func TestQingStorSignerWriteQuerySignature(t *testing.T) {
|
||||||
targetURL := "https://qingstor.com/?acl&upload_id=fde133b5f6d932cd9c79bac3c7318da1&part_number=0&access_key_id=ENV_ACCESS_KEY_ID&expires=3600&signature=GRL3p3NOgHR9CQygASvyo344vdnO1hFke6ZvQ5mDVHM="
|
targetURL := "https://qingstor.com/?acl&upload_id=fde133b5f6d932cd9c79bac3c7318da1&part_number=0&access_key_id=ENV_ACCESS_KEY_ID&expires=3600&signature=GRL3p3NOgHR9CQygASvyo344vdnO1hFke6ZvQ5mDVHM="
|
||||||
assert.Equal(t, httpRequest.URL.String(), targetURL)
|
assert.Equal(t, httpRequest.URL.String(), targetURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQingStorSignerWriteQuerySignatureWithXQSDate(t *testing.T) {
|
||||||
|
url := "https://qingstor.com/?acl&upload_id=fde133b5f6d932cd9c79bac3c7318da1&part_number=0"
|
||||||
|
httpRequest, err := http.NewRequest("GET", url, nil)
|
||||||
|
httpRequest.Header.Set("Date", convert.TimeToString(time.Time{}, convert.RFC822))
|
||||||
|
httpRequest.Header.Set("X-QS-Date", convert.TimeToString(time.Time{}, convert.RFC822))
|
||||||
|
httpRequest.Header.Set("X-QS-Test-2", "Test 2")
|
||||||
|
httpRequest.Header.Set("X-QS-Test-1", "Test 1")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
s := QingStorSigner{
|
||||||
|
AccessKeyID: "ENV_ACCESS_KEY_ID",
|
||||||
|
SecretAccessKey: "ENV_SECRET_ACCESS_KEY",
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.WriteQuerySignature(httpRequest, 3600)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
targetURL := "https://qingstor.com/?acl&upload_id=fde133b5f6d932cd9c79bac3c7318da1&part_number=0&access_key_id=ENV_ACCESS_KEY_ID&expires=3600&signature=plFxMFP1EzKVtdF%2BbApT8rhW9AUAIWfmZcOGH3m27t0="
|
||||||
|
assert.Equal(t, httpRequest.URL.String(), targetURL)
|
||||||
|
}
|
||||||
|
|
12
vendor/github.com/yunify/qingstor-sdk-go/service/bucket.go
generated
vendored
12
vendor/github.com/yunify/qingstor-sdk-go/service/bucket.go
generated
vendored
|
@ -744,12 +744,14 @@ func (s *Bucket) ListMultipartUploadsRequest(input *ListMultipartUploadsInput) (
|
||||||
type ListMultipartUploadsInput struct {
|
type ListMultipartUploadsInput struct {
|
||||||
// Put all keys that share a common prefix into a list
|
// Put all keys that share a common prefix into a list
|
||||||
Delimiter *string `json:"delimiter,omitempty" name:"delimiter" location:"params"`
|
Delimiter *string `json:"delimiter,omitempty" name:"delimiter" location:"params"`
|
||||||
|
// Limit results returned from the first key after key_marker sorted by alphabetical order
|
||||||
|
KeyMarker *string `json:"key_marker,omitempty" name:"key_marker" location:"params"`
|
||||||
// Results count limit
|
// Results count limit
|
||||||
Limit *int `json:"limit,omitempty" name:"limit" location:"params"`
|
Limit *int `json:"limit,omitempty" name:"limit" location:"params"`
|
||||||
// Limit results to keys that start at this marker
|
|
||||||
Marker *string `json:"marker,omitempty" name:"marker" location:"params"`
|
|
||||||
// Limits results to keys that begin with the prefix
|
// Limits results to keys that begin with the prefix
|
||||||
Prefix *string `json:"prefix,omitempty" name:"prefix" location:"params"`
|
Prefix *string `json:"prefix,omitempty" name:"prefix" location:"params"`
|
||||||
|
// Limit results returned from the first uploading segment after upload_id_marker sorted by the time of upload_id
|
||||||
|
UploadIDMarker *string `json:"upload_id_marker,omitempty" name:"upload_id_marker" location:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates the input for ListMultipartUploads.
|
// Validate validates the input for ListMultipartUploads.
|
||||||
|
@ -774,8 +776,10 @@ type ListMultipartUploadsOutput struct {
|
||||||
Marker *string `json:"marker,omitempty" name:"marker" location:"elements"`
|
Marker *string `json:"marker,omitempty" name:"marker" location:"elements"`
|
||||||
// Bucket name
|
// Bucket name
|
||||||
Name *string `json:"name,omitempty" name:"name" location:"elements"`
|
Name *string `json:"name,omitempty" name:"name" location:"elements"`
|
||||||
// The last key in keys list
|
// The last key in uploads list
|
||||||
NextMarker *string `json:"next_marker,omitempty" name:"next_marker" location:"elements"`
|
NextKeyMarker *string `json:"next_key_marker,omitempty" name:"next_key_marker" location:"elements"`
|
||||||
|
// The last upload_id in uploads list
|
||||||
|
NextUploadIDMarker *string `json:"next_upload_id_marker,omitempty" name:"next_upload_id_marker" location:"elements"`
|
||||||
// Prefix that specified in request parameters
|
// Prefix that specified in request parameters
|
||||||
Prefix *string `json:"prefix,omitempty" name:"prefix" location:"elements"`
|
Prefix *string `json:"prefix,omitempty" name:"prefix" location:"elements"`
|
||||||
// Multipart uploads
|
// Multipart uploads
|
||||||
|
|
117
vendor/github.com/yunify/qingstor-sdk-go/service/object.go
generated
vendored
117
vendor/github.com/yunify/qingstor-sdk-go/service/object.go
generated
vendored
|
@ -467,6 +467,105 @@ type HeadObjectOutput struct {
|
||||||
XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"`
|
XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImageProcess does Image process with the action on the object
|
||||||
|
// Documentation URL: https://docs.qingcloud.com/qingstor/data_process/image_process/index.html
|
||||||
|
func (s *Bucket) ImageProcess(objectKey string, input *ImageProcessInput) (*ImageProcessOutput, error) {
|
||||||
|
r, x, err := s.ImageProcessRequest(objectKey, input)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return x, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = r.Send()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
requestID := r.HTTPResponse.Header.Get(http.CanonicalHeaderKey("X-QS-Request-ID"))
|
||||||
|
x.RequestID = &requestID
|
||||||
|
|
||||||
|
return x, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageProcessRequest creates request and output object of ImageProcess.
|
||||||
|
func (s *Bucket) ImageProcessRequest(objectKey string, input *ImageProcessInput) (*request.Request, *ImageProcessOutput, error) {
|
||||||
|
|
||||||
|
if input == nil {
|
||||||
|
input = &ImageProcessInput{}
|
||||||
|
}
|
||||||
|
|
||||||
|
properties := *s.Properties
|
||||||
|
|
||||||
|
properties.ObjectKey = &objectKey
|
||||||
|
|
||||||
|
o := &data.Operation{
|
||||||
|
Config: s.Config,
|
||||||
|
Properties: &properties,
|
||||||
|
APIName: "Image Process",
|
||||||
|
RequestMethod: "GET",
|
||||||
|
RequestURI: "/<bucket-name>/<object-key>?image",
|
||||||
|
StatusCodes: []int{
|
||||||
|
200, // OK
|
||||||
|
304, // Not modified
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
x := &ImageProcessOutput{}
|
||||||
|
r, err := request.New(o, input, x)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, x, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageProcessInput presents input for ImageProcess.
|
||||||
|
type ImageProcessInput struct {
|
||||||
|
// Image process action
|
||||||
|
Action *string `json:"action" name:"action" location:"params"` // Required
|
||||||
|
// Specified the Cache-Control response header
|
||||||
|
ResponseCacheControl *string `json:"response-cache-control,omitempty" name:"response-cache-control" location:"params"`
|
||||||
|
// Specified the Content-Disposition response header
|
||||||
|
ResponseContentDisposition *string `json:"response-content-disposition,omitempty" name:"response-content-disposition" location:"params"`
|
||||||
|
// Specified the Content-Encoding response header
|
||||||
|
ResponseContentEncoding *string `json:"response-content-encoding,omitempty" name:"response-content-encoding" location:"params"`
|
||||||
|
// Specified the Content-Language response header
|
||||||
|
ResponseContentLanguage *string `json:"response-content-language,omitempty" name:"response-content-language" location:"params"`
|
||||||
|
// Specified the Content-Type response header
|
||||||
|
ResponseContentType *string `json:"response-content-type,omitempty" name:"response-content-type" location:"params"`
|
||||||
|
// Specified the Expires response header
|
||||||
|
ResponseExpires *string `json:"response-expires,omitempty" name:"response-expires" location:"params"`
|
||||||
|
|
||||||
|
// Check whether the object has been modified
|
||||||
|
IfModifiedSince *time.Time `json:"If-Modified-Since,omitempty" name:"If-Modified-Since" format:"RFC 822" location:"headers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates the input for ImageProcess.
|
||||||
|
func (v *ImageProcessInput) Validate() error {
|
||||||
|
|
||||||
|
if v.Action == nil {
|
||||||
|
return errors.ParameterRequiredError{
|
||||||
|
ParameterName: "Action",
|
||||||
|
ParentName: "ImageProcessInput",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageProcessOutput presents output for ImageProcess.
|
||||||
|
type ImageProcessOutput struct {
|
||||||
|
StatusCode *int `location:"statusCode"`
|
||||||
|
|
||||||
|
RequestID *string `location:"requestID"`
|
||||||
|
|
||||||
|
// The response body
|
||||||
|
Body io.ReadCloser `location:"body"`
|
||||||
|
|
||||||
|
// Object content length
|
||||||
|
ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"`
|
||||||
|
}
|
||||||
|
|
||||||
// InitiateMultipartUpload does Initial multipart upload on the object.
|
// InitiateMultipartUpload does Initial multipart upload on the object.
|
||||||
// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/initiate_multipart_upload.html
|
// Documentation URL: https://docs.qingcloud.com/qingstor/api/object/initiate_multipart_upload.html
|
||||||
func (s *Bucket) InitiateMultipartUpload(objectKey string, input *InitiateMultipartUploadInput) (*InitiateMultipartUploadOutput, error) {
|
func (s *Bucket) InitiateMultipartUpload(objectKey string, input *InitiateMultipartUploadInput) (*InitiateMultipartUploadOutput, error) {
|
||||||
|
@ -909,6 +1008,24 @@ type UploadMultipartInput struct {
|
||||||
ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"`
|
ContentLength *int64 `json:"Content-Length,omitempty" name:"Content-Length" location:"headers"`
|
||||||
// Object multipart content MD5sum
|
// Object multipart content MD5sum
|
||||||
ContentMD5 *string `json:"Content-MD5,omitempty" name:"Content-MD5" location:"headers"`
|
ContentMD5 *string `json:"Content-MD5,omitempty" name:"Content-MD5" location:"headers"`
|
||||||
|
// Specify range of the source object
|
||||||
|
XQSCopyRange *string `json:"X-QS-Copy-Range,omitempty" name:"X-QS-Copy-Range" location:"headers"`
|
||||||
|
// Copy source, format (/<bucket-name>/<object-key>)
|
||||||
|
XQSCopySource *string `json:"X-QS-Copy-Source,omitempty" name:"X-QS-Copy-Source" location:"headers"`
|
||||||
|
// Encryption algorithm of the object
|
||||||
|
XQSCopySourceEncryptionCustomerAlgorithm *string `json:"X-QS-Copy-Source-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Algorithm" location:"headers"`
|
||||||
|
// Encryption key of the object
|
||||||
|
XQSCopySourceEncryptionCustomerKey *string `json:"X-QS-Copy-Source-Encryption-Customer-Key,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Key" location:"headers"`
|
||||||
|
// MD5sum of encryption key
|
||||||
|
XQSCopySourceEncryptionCustomerKeyMD5 *string `json:"X-QS-Copy-Source-Encryption-Customer-Key-MD5,omitempty" name:"X-QS-Copy-Source-Encryption-Customer-Key-MD5" location:"headers"`
|
||||||
|
// Check whether the Etag of copy source matches the specified value
|
||||||
|
XQSCopySourceIfMatch *string `json:"X-QS-Copy-Source-If-Match,omitempty" name:"X-QS-Copy-Source-If-Match" location:"headers"`
|
||||||
|
// Check whether the copy source has been modified since the specified date
|
||||||
|
XQSCopySourceIfModifiedSince *time.Time `json:"X-QS-Copy-Source-If-Modified-Since,omitempty" name:"X-QS-Copy-Source-If-Modified-Since" format:"RFC 822" location:"headers"`
|
||||||
|
// Check whether the Etag of copy source does not matches the specified value
|
||||||
|
XQSCopySourceIfNoneMatch *string `json:"X-QS-Copy-Source-If-None-Match,omitempty" name:"X-QS-Copy-Source-If-None-Match" location:"headers"`
|
||||||
|
// Check whether the copy source has not been unmodified since the specified date
|
||||||
|
XQSCopySourceIfUnmodifiedSince *time.Time `json:"X-QS-Copy-Source-If-Unmodified-Since,omitempty" name:"X-QS-Copy-Source-If-Unmodified-Since" format:"RFC 822" location:"headers"`
|
||||||
// Encryption algorithm of the object
|
// Encryption algorithm of the object
|
||||||
XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"`
|
XQSEncryptionCustomerAlgorithm *string `json:"X-QS-Encryption-Customer-Algorithm,omitempty" name:"X-QS-Encryption-Customer-Algorithm" location:"headers"`
|
||||||
// Encryption key of the object
|
// Encryption key of the object
|
||||||
|
|
68
vendor/github.com/yunify/qingstor-sdk-go/test/image.go
generated
vendored
Normal file
68
vendor/github.com/yunify/qingstor-sdk-go/test/image.go
generated
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/DATA-DOG/godog"
|
||||||
|
|
||||||
|
qs "github.com/yunify/qingstor-sdk-go/service"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ImageFeatureContext provides feature context for image.
|
||||||
|
func ImageFeatureContext(s *godog.Suite) {
|
||||||
|
s.Step(`^image process with key "([^"]*)" and query "([^"]*)"$`, imageProcessWithKeyAndQuery)
|
||||||
|
s.Step(`^image process status code is (\d+)$`, imageProcessStatusCodeIs)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageName string
|
||||||
|
|
||||||
|
func imageProcessWithKeyAndQuery(objectKey, query string) error {
|
||||||
|
if bucket == nil {
|
||||||
|
return errors.New("The bucket is not exist")
|
||||||
|
}
|
||||||
|
file, err := os.Open(path.Join("features", "fixtures", objectKey))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
imageName = objectKey
|
||||||
|
|
||||||
|
_, err = bucket.PutObject(imageName, &qs.PutObjectInput{Body: file})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := bucket.ImageProcess(objectKey, &qs.ImageProcessInput{
|
||||||
|
Action: &query})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
imageProcessOutput = output
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageProcessOutput *qs.ImageProcessOutput
|
||||||
|
|
||||||
|
func imageProcessStatusCodeIs(statusCode int) error {
|
||||||
|
defer deleteImage(imageName)
|
||||||
|
return checkEqual(qs.IntValue(imageProcessOutput.StatusCode), statusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var oOutput *qs.DeleteObjectOutput
|
||||||
|
|
||||||
|
func deleteImage(imageName string) error {
|
||||||
|
|
||||||
|
if bucket == nil {
|
||||||
|
return errors.New("The bucket is not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
oOutput, err = bucket.DeleteObject(imageName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return checkEqual(qs.IntValue(oOutput.StatusCode), 204)
|
||||||
|
}
|
1
vendor/github.com/yunify/qingstor-sdk-go/test/main.go
generated
vendored
1
vendor/github.com/yunify/qingstor-sdk-go/test/main.go
generated
vendored
|
@ -41,6 +41,7 @@ func main() {
|
||||||
BucketExternalMirrorFeatureContext(s)
|
BucketExternalMirrorFeatureContext(s)
|
||||||
ObjectFeatureContext(s)
|
ObjectFeatureContext(s)
|
||||||
ObjectMultipartFeatureContext(s)
|
ObjectMultipartFeatureContext(s)
|
||||||
|
ImageFeatureContext(s)
|
||||||
}
|
}
|
||||||
options := godog.Options{
|
options := godog.Options{
|
||||||
Format: "pretty",
|
Format: "pretty",
|
||||||
|
|
5
vendor/github.com/yunify/qingstor-sdk-go/test/object.go
generated
vendored
5
vendor/github.com/yunify/qingstor-sdk-go/test/object.go
generated
vendored
|
@ -396,6 +396,11 @@ func getObjectWithQuerySignature(objectKey string) error {
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
err = r.Build()
|
||||||
|
if err != nil {
|
||||||
|
errChan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
err = r.SignQuery(10)
|
err = r.SignQuery(10)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
errChan <- err
|
||||||
|
|
Loading…
Reference in a new issue