mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-26 11:06:23 +00:00
feat: 添加文件驱动和本地驱动实现,支持文件操作功能
This commit is contained in:
38
pkg/filedriver/base_driver.go
Normal file
38
pkg/filedriver/base_driver.go
Normal file
@ -0,0 +1,38 @@
|
||||
package filedriver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/LiteyukiStudio/spage/pkg/constants"
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type FileDriver interface {
|
||||
Save(ctx *app.RequestContext, path string, r io.Reader) error
|
||||
Open(ctx *app.RequestContext, path string) (io.ReadCloser, error)
|
||||
Delete(ctx *app.RequestContext, path string) error
|
||||
Stat(ctx *app.RequestContext, path string) (os.FileInfo, error)
|
||||
Get(ctx *app.RequestContext, path string)
|
||||
ListDir(ctx *app.RequestContext, path string) ([]os.FileInfo, error)
|
||||
}
|
||||
|
||||
type DriverConfig struct {
|
||||
Type string `mapstructure:"file.driver.type"`
|
||||
BasePath string `mapstructure:"file.driver.base_path"`
|
||||
WebDavUrl string `mapstructure:"file.driver.webdav.url"`
|
||||
WebDavUser string `mapstructure:"file.driver.webdav.user"`
|
||||
WebDavPassword string `mapstructure:"file.driver.webdav.password"`
|
||||
WebDavPolicy string `mapstructure:"file.driver.webdav.policy"` // proxy|redirect
|
||||
}
|
||||
|
||||
func GetFileDriver(driverConfig *DriverConfig) (FileDriver, error) {
|
||||
switch driverConfig.Type {
|
||||
case constants.FileDriverLocal:
|
||||
return NewLocalDriver(driverConfig), nil
|
||||
case constants.FileDriverWebdav:
|
||||
return NewWebDAVClientDriver(driverConfig), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported file driver type: %s", driverConfig.Type)
|
||||
}
|
||||
}
|
74
pkg/filedriver/local_driver.go
Normal file
74
pkg/filedriver/local_driver.go
Normal file
@ -0,0 +1,74 @@
|
||||
package filedriver
|
||||
|
||||
import (
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type LocalDriver struct {
|
||||
BasePath string
|
||||
}
|
||||
|
||||
func NewLocalDriver(driverConfig *DriverConfig) *LocalDriver {
|
||||
return &LocalDriver{
|
||||
BasePath: driverConfig.BasePath,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *LocalDriver) fullPath(path string) string {
|
||||
return filepath.Join(d.BasePath, path)
|
||||
}
|
||||
|
||||
func (d *LocalDriver) Save(ctx *app.RequestContext, path string, r io.Reader) error {
|
||||
full := d.fullPath(path)
|
||||
if err := os.MkdirAll(filepath.Dir(full), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(full)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(f *os.File) {
|
||||
err := f.Close()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}(f)
|
||||
_, err = io.Copy(f, r)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *LocalDriver) Open(ctx *app.RequestContext, path string) (io.ReadCloser, error) {
|
||||
return os.Open(d.fullPath(path))
|
||||
}
|
||||
|
||||
func (d *LocalDriver) Get(ctx *app.RequestContext, path string) {
|
||||
ctx.File(d.fullPath(path))
|
||||
ctx.Abort()
|
||||
}
|
||||
|
||||
func (d *LocalDriver) Delete(ctx *app.RequestContext, path string) error {
|
||||
return os.Remove(d.fullPath(path))
|
||||
}
|
||||
|
||||
func (d *LocalDriver) Stat(ctx *app.RequestContext, path string) (os.FileInfo, error) {
|
||||
return os.Stat(d.fullPath(path))
|
||||
}
|
||||
|
||||
func (d *LocalDriver) ListDir(ctx *app.RequestContext, path string) ([]os.FileInfo, error) {
|
||||
entries, err := os.ReadDir(d.fullPath(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos := make([]os.FileInfo, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
info, err := entry.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
infos = append(infos, info)
|
||||
}
|
||||
return infos, nil
|
||||
}
|
76
pkg/filedriver/webdav_driver.go
Normal file
76
pkg/filedriver/webdav_driver.go
Normal file
@ -0,0 +1,76 @@
|
||||
package filedriver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/LiteyukiStudio/spage/pkg/constants"
|
||||
"github.com/LiteyukiStudio/spage/pkg/resps"
|
||||
"github.com/cloudwego/hertz/pkg/app"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/studio-b12/gowebdav"
|
||||
)
|
||||
|
||||
type WebDAVClientDriver struct {
|
||||
client *gowebdav.Client
|
||||
config *DriverConfig
|
||||
BasePath string
|
||||
}
|
||||
|
||||
func NewWebDAVClientDriver(driverConfig *DriverConfig) *WebDAVClientDriver {
|
||||
c := gowebdav.NewClient(driverConfig.WebDavUrl, driverConfig.WebDavUser, driverConfig.WebDavPassword)
|
||||
return &WebDAVClientDriver{client: c, BasePath: driverConfig.BasePath, config: driverConfig}
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) fullPath(p string) string {
|
||||
if d.BasePath == "" {
|
||||
return p
|
||||
}
|
||||
return path.Join(d.BasePath, p)
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) Save(ctx *app.RequestContext, p string, r io.Reader) error {
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.client.Write(d.fullPath(p), data, 0644)
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) Open(ctx *app.RequestContext, p string) (io.ReadCloser, error) {
|
||||
data, err := d.client.Read(d.fullPath(p))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return io.NopCloser(bytes.NewReader(data)), nil
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) Get(ctx *app.RequestContext, p string) {
|
||||
if d.config.WebDavPolicy == constants.WebDavPolicyRedirect {
|
||||
ctx.Redirect(302, []byte(d.config.WebDavUrl+d.fullPath(p)))
|
||||
return
|
||||
} else {
|
||||
data, err := d.client.Read(d.fullPath(p))
|
||||
if err != nil {
|
||||
resps.InternalServerError(ctx, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.SetBodyStream(bytes.NewReader(data), len(data))
|
||||
ctx.Response.Header.Set("Content-Type", "application/octet-stream")
|
||||
ctx.Response.Header.Set("Content-Length", fmt.Sprintf("%d", len(data)))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) Delete(ctx *app.RequestContext, p string) error {
|
||||
return d.client.Remove(d.fullPath(p))
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) Stat(ctx *app.RequestContext, p string) (os.FileInfo, error) {
|
||||
return d.client.Stat(d.fullPath(p))
|
||||
}
|
||||
|
||||
func (d *WebDAVClientDriver) ListDir(ctx *app.RequestContext, p string) ([]os.FileInfo, error) {
|
||||
return d.client.ReadDir(d.fullPath(p))
|
||||
}
|
1
pkg/utils/file.go
Normal file
1
pkg/utils/file.go
Normal file
@ -0,0 +1 @@
|
||||
package utils
|
Reference in New Issue
Block a user