github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/backend/imagekit/client/upload.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"net/url"
    10  
    11  	"github.com/rclone/rclone/lib/rest"
    12  )
    13  
    14  // UploadParam defines upload parameters
    15  type UploadParam struct {
    16  	FileName      string `json:"fileName"`
    17  	Folder        string `json:"folder,omitempty"` // default value:  /
    18  	Tags          string `json:"tags,omitempty"`
    19  	IsPrivateFile *bool  `json:"isPrivateFile,omitempty"` // default: false
    20  }
    21  
    22  // UploadResult defines the response structure for the upload API
    23  type UploadResult struct {
    24  	FileID       string            `json:"fileId"`
    25  	Name         string            `json:"name"`
    26  	URL          string            `json:"url"`
    27  	ThumbnailURL string            `json:"thumbnailUrl"`
    28  	Height       int               `json:"height"`
    29  	Width        int               `json:"Width"`
    30  	Size         uint64            `json:"size"`
    31  	FilePath     string            `json:"filePath"`
    32  	AITags       []map[string]any  `json:"AITags"`
    33  	VersionInfo  map[string]string `json:"versionInfo"`
    34  }
    35  
    36  // Upload uploads an asset to a imagekit account.
    37  //
    38  // The asset can be:
    39  //   - the actual data (io.Reader)
    40  //   - the Data URI (Base64 encoded), max ~60 MB (62,910,000 chars)
    41  //   - the remote FTP, HTTP or HTTPS URL address of an existing file
    42  //
    43  // https://docs.imagekit.io/api-reference/upload-file-api/server-side-file-upload
    44  func (ik *ImageKit) Upload(ctx context.Context, file io.Reader, param UploadParam) (*http.Response, *UploadResult, error) {
    45  	var err error
    46  
    47  	if param.FileName == "" {
    48  		return nil, nil, errors.New("Upload: Filename is required")
    49  	}
    50  
    51  	// Initialize URL values
    52  	formParams := url.Values{}
    53  
    54  	formParams.Add("useUniqueFileName", fmt.Sprint(false))
    55  
    56  	// Add individual fields to URL values
    57  	if param.FileName != "" {
    58  		formParams.Add("fileName", param.FileName)
    59  	}
    60  
    61  	if param.Tags != "" {
    62  		formParams.Add("tags", param.Tags)
    63  	}
    64  
    65  	if param.Folder != "" {
    66  		formParams.Add("folder", param.Folder)
    67  	}
    68  
    69  	if param.IsPrivateFile != nil {
    70  		formParams.Add("isPrivateFile", fmt.Sprintf("%v", *param.IsPrivateFile))
    71  	}
    72  
    73  	response := &UploadResult{}
    74  
    75  	formReader, contentType, _, err := rest.MultipartUpload(ctx, file, formParams, "file", param.FileName)
    76  
    77  	if err != nil {
    78  		return nil, nil, fmt.Errorf("failed to make multipart upload: %w", err)
    79  	}
    80  
    81  	opts := rest.Opts{
    82  		Method:      "POST",
    83  		Path:        "/files/upload",
    84  		RootURL:     ik.UploadPrefix,
    85  		Body:        formReader,
    86  		ContentType: contentType,
    87  	}
    88  
    89  	resp, err := ik.HTTPClient.CallJSON(ctx, &opts, nil, response)
    90  
    91  	if err != nil {
    92  		return resp, response, err
    93  	}
    94  
    95  	return resp, response, err
    96  }