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)
|
||
}
|