236 lines
7.7 KiB
Go
236 lines
7.7 KiB
Go
package qiniu
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"u-desk/internal/oss"
|
|
)
|
|
|
|
// StorageType 存储类型枚举
|
|
type StorageType int
|
|
|
|
const (
|
|
// StorageTypeStandard 标准存储 (0)
|
|
StorageTypeStandard StorageType = 0
|
|
// StorageTypeIA 低频存储 (1) - Infrequent Access
|
|
StorageTypeIA StorageType = 1
|
|
// StorageTypeArchive 归档存储 (2) - Archive
|
|
StorageTypeArchive StorageType = 2
|
|
// StorageTypeDeepArchive 深度归档存储 (3) - Deep Archive
|
|
StorageTypeDeepArchive StorageType = 3
|
|
// StorageTypeIntelligentTiering 智能分层存储 (4)
|
|
StorageTypeIntelligentTiering StorageType = 4
|
|
// StorageTypeArchiveIR 归档直读存储 (5) - Archive Immediate Retrieval
|
|
StorageTypeArchiveIR StorageType = 5
|
|
)
|
|
|
|
// String 返回存储类型的字符串表示
|
|
func (t StorageType) String() string {
|
|
switch t {
|
|
case StorageTypeStandard:
|
|
return "标准存储"
|
|
case StorageTypeIA:
|
|
return "低频存储"
|
|
case StorageTypeArchive:
|
|
return "归档存储"
|
|
case StorageTypeDeepArchive:
|
|
return "深度归档存储"
|
|
case StorageTypeIntelligentTiering:
|
|
return "智能分层存储"
|
|
case StorageTypeArchiveIR:
|
|
return "归档直读存储"
|
|
default:
|
|
return "未知"
|
|
}
|
|
}
|
|
|
|
// LifecycleConfig 文件生命周期配置
|
|
type LifecycleConfig struct {
|
|
// ToIAAfterDays 转换到低频存储的天数,-1 表示取消
|
|
ToIAAfterDays int
|
|
// ToIntelligentTieringAfterDays 转换到智能分层存储的天数,-1 表示取消
|
|
ToIntelligentTieringAfterDays int
|
|
// ToArchiveIRAfterDays 转换到归档直读存储的天数,-1 表示取消
|
|
ToArchiveIRAfterDays int
|
|
// ToArchiveAfterDays 转换到归档存储的天数,-1 表示取消
|
|
ToArchiveAfterDays int
|
|
// ToDeepArchiveAfterDays 转换到深度归档存储的天数,-1 表示取消
|
|
ToDeepArchiveAfterDays int
|
|
// DeleteAfterDays 过期删除的天数,-1 表示取消,0 表示不设置
|
|
DeleteAfterDays int
|
|
}
|
|
|
|
// ChangeStorageType 修改文件存储类型
|
|
// 根据: https://developer.qiniu.com/kodo/api/3710/chtype
|
|
func (c *Client) ChangeStorageType(ctx context.Context, key string, storageType StorageType) error {
|
|
encodedEntry := c.encodeEntry(key)
|
|
path := fmt.Sprintf("/chtype/%s/type/%d", encodedEntry, storageType)
|
|
|
|
resp, err := c.doRequest("POST", path, nil)
|
|
if err != nil {
|
|
return oss.NewError("STYPE_ERROR", "failed to change storage type", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
return nil
|
|
}
|
|
|
|
body, _ := io.ReadAll(resp.Body)
|
|
return oss.NewError("STYPE_ERROR",
|
|
fmt.Sprintf("change storage type failed with status %d: %s", resp.StatusCode, string(body)), nil)
|
|
}
|
|
|
|
// SetDeleteAfterDays 设置文件过期删除时间
|
|
// 根据: https://developer.qiniu.com/kodo/api/update-file-lifecycle
|
|
//
|
|
// 参数:
|
|
// - key: 文件 key
|
|
// - days: 过期天数,0 表示取消过期删除设置
|
|
//
|
|
// 注意:
|
|
// - 文件在设置的天数之后被删除,删除后不可恢复
|
|
// - 设置为 0 表示取消过期删除设置
|
|
func (c *Client) SetDeleteAfterDays(ctx context.Context, key string, days int) error {
|
|
encodedEntry := c.encodeEntry(key)
|
|
path := fmt.Sprintf("/deleteAfterDays/%s/%d", encodedEntry, days)
|
|
|
|
resp, err := c.doRequest("POST", path, nil)
|
|
if err != nil {
|
|
return oss.NewError("LIFECYCLE_ERROR", "failed to set delete after days", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
return nil
|
|
}
|
|
|
|
body, _ := io.ReadAll(resp.Body)
|
|
return oss.NewError("LIFECYCLE_ERROR",
|
|
fmt.Sprintf("set delete after days failed with status %d: %s", resp.StatusCode, string(body)), nil)
|
|
}
|
|
|
|
// SetLifecycle 设置文件生命周期
|
|
// 根据: https://developer.qiniu.com/kodo/api/8062/modify-object-life-cycle
|
|
//
|
|
// 参数说明:
|
|
// - ToIAAfterDays: 转换到低频存储的天数,设置为 -1 表示取消
|
|
// - ToIntelligentTieringAfterDays: 转换到智能分层存储的天数,设置为 -1 表示取消
|
|
// - ToArchiveIRAfterDays: 转换到归档直读存储的天数,设置为 -1 表示取消
|
|
// - ToArchiveAfterDays: 转换到归档存储的天数,设置为 -1 表示取消
|
|
// - ToDeepArchiveAfterDays: 转换到深度归档存储的天数,设置为 -1 表示取消
|
|
// - DeleteAfterDays: 过期删除的天数,设置为 -1 表示取消,0 表示不设置
|
|
//
|
|
// 注意:
|
|
// - 所有参数都是可选的,只设置需要的参数即可
|
|
// - 文件删除后不可恢复
|
|
func (c *Client) SetLifecycle(ctx context.Context, key string, config *LifecycleConfig) error {
|
|
encodedEntry := c.encodeEntry(key)
|
|
path := fmt.Sprintf("/lifecycle/%s", encodedEntry)
|
|
|
|
// 添加各个生命周期参数
|
|
if config.ToIAAfterDays != 0 {
|
|
path += fmt.Sprintf("/toIAAfterDays/%d", config.ToIAAfterDays)
|
|
}
|
|
if config.ToIntelligentTieringAfterDays != 0 {
|
|
path += fmt.Sprintf("/toIntelligentTieringAfterDays/%d", config.ToIntelligentTieringAfterDays)
|
|
}
|
|
if config.ToArchiveIRAfterDays != 0 {
|
|
path += fmt.Sprintf("/toArchiveIRAfterDays/%d", config.ToArchiveIRAfterDays)
|
|
}
|
|
if config.ToArchiveAfterDays != 0 {
|
|
path += fmt.Sprintf("/toArchiveAfterDays/%d", config.ToArchiveAfterDays)
|
|
}
|
|
if config.ToDeepArchiveAfterDays != 0 {
|
|
path += fmt.Sprintf("/toDeepArchiveAfterDays/%d", config.ToDeepArchiveAfterDays)
|
|
}
|
|
if config.DeleteAfterDays != 0 {
|
|
path += fmt.Sprintf("/deleteAfterDays/%d", config.DeleteAfterDays)
|
|
}
|
|
|
|
// 如果没有设置任何参数,返回错误
|
|
if path == fmt.Sprintf("/lifecycle/%s", encodedEntry) {
|
|
return oss.NewError("LIFECYCLE_ERROR", "no lifecycle parameters specified", nil)
|
|
}
|
|
|
|
resp, err := c.doRequest("POST", path, nil)
|
|
if err != nil {
|
|
return oss.NewError("LIFECYCLE_ERROR", "failed to set lifecycle", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode == 200 {
|
|
return nil
|
|
}
|
|
|
|
body, _ := io.ReadAll(resp.Body)
|
|
return oss.NewError("LIFECYCLE_ERROR",
|
|
fmt.Sprintf("set lifecycle failed with status %d: %s", resp.StatusCode, string(body)), nil)
|
|
}
|
|
|
|
// CancelIAConversion 取消转低频存储的生命周期规则
|
|
func (c *Client) CancelIAConversion(ctx context.Context, key string) error {
|
|
config := &LifecycleConfig{
|
|
ToIAAfterDays: -1,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// CancelArchiveConversion 取消转归档存储的生命周期规则
|
|
func (c *Client) CancelArchiveConversion(ctx context.Context, key string) error {
|
|
config := &LifecycleConfig{
|
|
ToArchiveAfterDays: -1,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// CancelDeleteAfterDays 取消过期删除的生命周期规则
|
|
func (c *Client) CancelDeleteAfterDays(ctx context.Context, key string) error {
|
|
config := &LifecycleConfig{
|
|
DeleteAfterDays: -1,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// SetToIAAfterDays 设置文件转低频存储的天数
|
|
func (c *Client) SetToIAAfterDays(ctx context.Context, key string, days int) error {
|
|
config := &LifecycleConfig{
|
|
ToIAAfterDays: days,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// SetToArchiveAfterDays 设置文件转归档存储的天数
|
|
func (c *Client) SetToArchiveAfterDays(ctx context.Context, key string, days int) error {
|
|
config := &LifecycleConfig{
|
|
ToArchiveAfterDays: days,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// SetToDeepArchiveAfterDays 设置文件转深度归档存储的天数
|
|
func (c *Client) SetToDeepArchiveAfterDays(ctx context.Context, key string, days int) error {
|
|
config := &LifecycleConfig{
|
|
ToDeepArchiveAfterDays: days,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// SetToIntelligentTieringAfterDays 设置文件转智能分层存储的天数
|
|
func (c *Client) SetToIntelligentTieringAfterDays(ctx context.Context, key string, days int) error {
|
|
config := &LifecycleConfig{
|
|
ToIntelligentTieringAfterDays: days,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|
|
|
|
// SetToArchiveIRAfterDays 设置文件转归档直读存储的天数
|
|
func (c *Client) SetToArchiveIRAfterDays(ctx context.Context, key string, days int) error {
|
|
config := &LifecycleConfig{
|
|
ToArchiveIRAfterDays: days,
|
|
}
|
|
return c.SetLifecycle(ctx, key, config)
|
|
}
|