github.com/cloudreve/Cloudreve/v3@v3.0.0-20240224133659-3edb00a6484c/pkg/filesystem/driver/cos/scf.go (about)

     1  package cos
     2  
     3  import (
     4  	"archive/zip"
     5  	"bytes"
     6  	"encoding/base64"
     7  	"io"
     8  	"io/ioutil"
     9  	"net/url"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  
    14  	model "github.com/cloudreve/Cloudreve/v3/models"
    15  	"github.com/cloudreve/Cloudreve/v3/pkg/hashid"
    16  	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
    17  	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
    18  	scf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf/v20180416"
    19  )
    20  
    21  const scfFunc = `# -*- coding: utf8 -*-
    22  # SCF配置COS触发,向 Cloudreve 发送回调
    23  from qcloud_cos_v5 import CosConfig
    24  from qcloud_cos_v5 import CosS3Client
    25  from qcloud_cos_v5 import CosServiceError
    26  from qcloud_cos_v5 import CosClientError
    27  import sys
    28  import logging
    29  import requests
    30  
    31  logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    32  logger = logging.getLogger()
    33  
    34  
    35  def main_handler(event, context):
    36      logger.info("start main handler")
    37      for record in event['Records']:
    38          try:
    39              if "x-cos-meta-callback" not in record['cos']['cosObject']['meta']:
    40                  logger.info("Cannot find callback URL, skiped.")
    41                  return 'Success'
    42              callback = record['cos']['cosObject']['meta']['x-cos-meta-callback']
    43              key = record['cos']['cosObject']['key']
    44              logger.info("Callback URL is " + callback)
    45  
    46              r = requests.get(callback)
    47              print(r.text)
    48  
    49              
    50  
    51          except Exception as e:
    52              print(e)
    53              print('Error getting object {} callback url. '.format(key))
    54              raise e
    55              return "Fail"
    56  
    57      return "Success"
    58  `
    59  
    60  // CreateSCF 创建回调云函数
    61  func CreateSCF(policy *model.Policy, region string) error {
    62  	// 初始化客户端
    63  	credential := common.NewCredential(
    64  		policy.AccessKey,
    65  		policy.SecretKey,
    66  	)
    67  	cpf := profile.NewClientProfile()
    68  	client, err := scf.NewClient(credential, region, cpf)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	// 创建回调代码数据
    74  	buff := &bytes.Buffer{}
    75  	bs64 := base64.NewEncoder(base64.StdEncoding, buff)
    76  	zipWriter := zip.NewWriter(bs64)
    77  	header := zip.FileHeader{
    78  		Name:   "callback.py",
    79  		Method: zip.Deflate,
    80  	}
    81  	writer, err := zipWriter.CreateHeader(&header)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	_, err = io.Copy(writer, strings.NewReader(scfFunc))
    86  	zipWriter.Close()
    87  
    88  	// 创建云函数
    89  	req := scf.NewCreateFunctionRequest()
    90  	funcName := "cloudreve_" + hashid.HashID(policy.ID, hashid.PolicyID) + strconv.FormatInt(time.Now().Unix(), 10)
    91  	zipFileBytes, _ := ioutil.ReadAll(buff)
    92  	zipFileStr := string(zipFileBytes)
    93  	codeSource := "ZipFile"
    94  	handler := "callback.main_handler"
    95  	desc := "Cloudreve 用回调函数"
    96  	timeout := int64(60)
    97  	runtime := "Python3.6"
    98  	req.FunctionName = &funcName
    99  	req.Code = &scf.Code{
   100  		ZipFile: &zipFileStr,
   101  	}
   102  	req.Handler = &handler
   103  	req.Description = &desc
   104  	req.Timeout = &timeout
   105  	req.Runtime = &runtime
   106  	req.CodeSource = &codeSource
   107  
   108  	_, err = client.CreateFunction(req)
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	time.Sleep(time.Duration(5) * time.Second)
   114  
   115  	// 创建触发器
   116  	server, _ := url.Parse(policy.Server)
   117  	triggerType := "cos"
   118  	triggerDesc := `{"event":"cos:ObjectCreated:Post","filter":{"Prefix":"","Suffix":""}}`
   119  	enable := "OPEN"
   120  
   121  	trigger := scf.NewCreateTriggerRequest()
   122  	trigger.FunctionName = &funcName
   123  	trigger.TriggerName = &server.Host
   124  	trigger.Type = &triggerType
   125  	trigger.TriggerDesc = &triggerDesc
   126  	trigger.Enable = &enable
   127  
   128  	_, err = client.CreateTrigger(trigger)
   129  	if err != nil {
   130  		return err
   131  	}
   132  
   133  	return nil
   134  }