You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sonic/service/storage/impl/file_descriptor.go

142 lines
2.9 KiB
Go

package filestorageimpl
import (
"path/filepath"
"strconv"
"time"
)
type fileDescriptor interface {
getFullDirPath() string
getFullPath() string
getRelativePath() string
getFileName() string
setFileName(string)
getExtensionName() string
getShouldRename() shouldRename
}
type shouldRename = func(relativePath string) (bool, error)
type localFileDescriptor struct {
OriginalName string
Name string
Extension string
BasePath string
SubPath string
AutomaticRename bool
ShouldRename shouldRename
Suffix string
}
func newLocalFileDescriptor(opts ...fdOption) (fileDescriptor, error) {
fd := &localFileDescriptor{}
for _, opt := range opts {
opt(fd)
}
fd.BasePath = filepath.Clean(fd.BasePath)
fd.SubPath = filepath.Clean(fd.SubPath)
fd.OriginalName = filepath.Clean(fd.OriginalName)
ext := filepath.Ext(fd.OriginalName)
if ext != "" {
// remove dot
fd.Extension = ext[1:]
}
originalName := filepath.Base(fd.OriginalName)
for i := len(originalName) - 1; i >= 0; i-- {
if originalName[i] == '.' {
fd.Name = originalName[0:i]
break
}
}
err := rename(fd)
if err != nil {
return fd, err
}
return fd, nil
}
func rename(f fileDescriptor) error {
if f.getShouldRename() == nil {
return nil
}
should, err := f.getShouldRename()(f.getRelativePath())
if err != nil {
return err
}
if !should {
return nil
}
timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
f.setFileName(f.getFileName() + "-" + timestamp)
return nil
}
func (f *localFileDescriptor) getFullName() string {
if f.Extension == "" {
return f.Name + f.Suffix
}
return f.Name + f.Suffix + "." + f.Extension
}
func (f *localFileDescriptor) setFileName(name string) {
f.Name = name
}
func (f *localFileDescriptor) getFullDirPath() string {
return filepath.Join(f.BasePath, f.SubPath)
}
func (f *localFileDescriptor) getFullPath() string {
return filepath.Join(f.BasePath, f.SubPath, f.getFullName())
}
func (f *localFileDescriptor) getRelativePath() string {
return filepath.Join(f.SubPath, f.getFullName())
}
func (f *localFileDescriptor) getExtensionName() string {
return f.Extension
}
func (f *localFileDescriptor) getFileName() string {
return f.Name
}
func (f *localFileDescriptor) getShouldRename() shouldRename {
return f.ShouldRename
}
type fdOption func(f *localFileDescriptor)
func withOriginalName(originalName string) fdOption {
return func(f *localFileDescriptor) {
f.OriginalName = originalName
}
}
func withBasePath(basePath string) fdOption {
return func(f *localFileDescriptor) {
f.BasePath = basePath
}
}
func withSubPath(subPath string) fdOption {
return func(f *localFileDescriptor) {
f.SubPath = subPath
}
}
func withShouldRename(fn func(relativePath string) (bool, error)) fdOption {
return func(f *localFileDescriptor) {
f.ShouldRename = fn
}
}
func withSuffix(suffix string) fdOption {
return func(f *localFileDescriptor) {
f.Suffix = suffix
}
}