| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- package three_party
- import (
- "errors"
- "fmt"
- uuid "github.com/iris-contrib/go.uuid"
- "github.com/kataras/iris/v12"
- "github.com/minio/minio-go/v7"
- "github.com/minio/minio-go/v7/pkg/credentials"
- "io"
- "log"
- "mime/multipart"
- "os"
- "path/filepath"
- "strings"
- "sync"
- "time"
- )
- var defaultFileBucket = "file"
- var defaultIconBucket = "icon"
- var defaultLocation = "us-east-1"
- var minioServerPool *sync.Pool
- // client version and secret, it should be from client side
- const (
- UploadDir string = "./public/upload/"
- UrlBase string = "/upload/"
- )
- // DstFile 文件
- type DstFile struct {
- Name string `json:"name"`
- Src string `json:"src"`
- }
- func init() {
- minioServerPool = &sync.Pool{
- New: func() interface{}{
- return &MinioServe{}
- },
- }
- }
- type MinioFileObject struct {
- BucketName string
- ObjectName string
- FilePath string
- ContentType string
- Config MinioConfig
- }
- type MinioConfig struct {
- MinioHost string `json:"minioHost"`
- MinioPort int64 `json:"minioPort"`
- AccessKey string `json:"accessKey"`
- SecretKey string `json:"secretKey"`
- UseSSL bool `json:"useSSL"`
- }
- func (c *MinioConfig) Validate() error {
- if c.MinioHost == "" {
- return errors.New("minio host not specified")
- }
-
- if c.MinioPort <= 0 {
- return errors.New("minio port not specified")
- }
-
- if c.AccessKey == "" {
- return errors.New("minio access key is not specified")
- }
-
- if c.SecretKey == "" {
- return errors.New("minio secret key is not specified")
- }
- return nil
- }
- func (c *MinioConfig) GetClient()(*minio.Client, error) {
- if err := c.Validate(); err != nil {
- return nil, err
- }
-
- endPoint := fmt.Sprintf("%s:%d", c.MinioHost, c.MinioPort)
- minioClient, err := minio.New(
- endPoint,
- &minio.Options{
- Creds: credentials.NewStaticV4(c.AccessKey, c.SecretKey, ""),
- Secure: c.UseSSL,
- })
-
- if err != nil {
- log.Fatalf("connect minio server fail %s url %s", err.Error(), endPoint)
- }
- return minioClient, nil
- }
- type MinioServerOption func(*MinioServe)
- type MinioServe struct {
- Client *minio.Client
- }
- func NewMinioServer(opts ...MinioServerOption)(*MinioServe, error){
- m := &MinioServe{}
- for _, opt := range opts {
- opt(m)
- }
-
- return m, nil
- }
- func (m *MinioServe) Reset() {
- m.Client = nil
- }
- func (m *MinioServe) checkBucket(ctx iris.Context, bucketName string) bool {
- isExist, err1 := m.Client.BucketExists(ctx, bucketName)
- if err1 != nil {
- log.Fatalf("checkBucket error " + err1.Error())
- return false
- }
-
- if !isExist {
- err2 := m.Client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: defaultLocation})
- if err2 != nil {
- log.Fatalf("checkBucket error " + err2.Error())
- return false
- }
- }
- return true
- }
- func (m *MinioServe) CheckBuckets(ctx iris.Context) bool {
- b1 := m.checkBucket(ctx, defaultFileBucket)
- b2 := m.checkBucket(ctx, defaultIconBucket)
- return b1&&b2
- }
- func (m *MinioServe) UploadFile(ctx iris.Context, obj *MinioFileObject)(*minio.UploadInfo, error) {
- bBucketExist := m.CheckBuckets(ctx)
- if !bBucketExist {
- return nil, nil
- }
-
- info, err := m.Client.FPutObject(ctx, obj.BucketName, obj.ObjectName, obj.FilePath, minio.PutObjectOptions{
- ContentType: obj.ContentType,
- })
-
- if err != nil {
- return &info, err
- }
-
- return &info, nil
- }
- func acquireMinioServer() *MinioServe {
- return minioServerPool.Get().(*MinioServe)
- }
- func releaseMinioServer(m *MinioServe) {
- m.Reset()
- minioServerPool.Put(m)
- }
- func UploadFile(ctx iris.Context) (*DstFile,error){
- file ,info ,err := ctx.FormFile("uploadfile")
- if err != nil {
- return nil ,err
- }
- defer file.Close()
-
- oldFileName := info.Filename
- destFile, url := GenerateNewFileName(oldFileName)
-
- out, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE, 0666)
- if err != nil{
- return nil, err
- }
-
- defer out.Close()
- _ ,err = io.Copy(out, file)
- if err != nil {
- return nil, err
- }
-
- outfile := &DstFile{Name: oldFileName ,Src:url }
-
- return outfile, nil
- }
- // UploadMultiFiles Upload Multi Files
- func UploadMultiFiles(ctx iris.Context)(int, []DstFile, error){
-
- maxSize := ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()
-
- err := ctx.Request().ParseMultipartForm(maxSize)
- if err != nil {
- return 0 , nil, err
- }
-
- form := ctx.Request().MultipartForm
- files := form.File["files[]"]
- count := len(files)
-
- failures := 0
- dstIndex := 1
-
- outFiles := []DstFile{}
- for _, file := range files {
- url, err := SaveUploadFile(file)
- if err != nil {
- failures++
- }else{
- out := DstFile{Name: file.Filename ,Src:url}
- outFiles = append(outFiles, out)
- dstIndex++
- }
- }
-
- num := count - failures
-
- return num ,outFiles ,nil
- }
- func SaveUploadFile(fh *multipart.FileHeader)(string, error){
- src ,err := fh.Open()
- if err != nil {
- return "" ,err
- }
- defer src.Close()
-
- oldFileName := fh.Filename
- srcFile, urlFile := GenerateNewFileName(oldFileName)
-
- out, err := os.OpenFile(srcFile ,os.O_WRONLY|os.O_CREATE ,os.FileMode(0666))
- if err != nil {
- return "" ,err
- }
-
- defer out.Close()
-
- _, err = io.Copy(out, src)
-
- return urlFile, err
- }
- // CreateDateDir Create date directory
- func CreateDateDir() (srcPath, urlPath string) {
- folderName := time.Now().Format("20060102")
- src := filepath.Join(UploadDir, folderName)
- url := filepath.Join(UrlBase, folderName)
- _, err := os.Stat(srcPath)
- if os.IsNotExist(err ){
- _ = os.Mkdir(src, os.ModePerm)
- _ = os.Chmod(src, os.ModePerm)
- }
-
- return src ,url
- }
- // GenerateNewFileName Generate new file name
- func GenerateNewFileName(oldFileName string) (srcPath, urlPath string) {
- u1, _ := uuid.NewV4()
- newFileName := u1.String()
- src , url := CreateDateDir()
-
- dotIndex := strings.LastIndex(oldFileName, ".")
- if dotIndex != -1 && dotIndex != 0 {
- newFileName += oldFileName[dotIndex:]
- }
-
- src = filepath.Join(src, newFileName)
- url = filepath.Join(url, newFileName)
-
- return src, url
- }
|