46 lines
1.1 KiB
Go
46 lines
1.1 KiB
Go
package files
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Service struct {
|
|
root string
|
|
}
|
|
|
|
type StoredFile struct {
|
|
OriginalName string
|
|
RelativePath string
|
|
AbsolutePath string
|
|
}
|
|
|
|
func NewService(root string) *Service {
|
|
return &Service{root: root}
|
|
}
|
|
|
|
func (s *Service) Save(projectID uint, originalName string, content io.Reader) (StoredFile, error) {
|
|
cleanName := filepath.Base(strings.ReplaceAll(strings.TrimSpace(originalName), "\\", "/"))
|
|
if cleanName == "." || cleanName == "" {
|
|
cleanName = "upload.bin"
|
|
}
|
|
relative := filepath.ToSlash(filepath.Join("projects", fmt.Sprint(projectID), fmt.Sprintf("%d-%s", time.Now().UnixNano(), cleanName)))
|
|
absolute := filepath.Join(s.root, filepath.FromSlash(relative))
|
|
if err := os.MkdirAll(filepath.Dir(absolute), 0o755); err != nil {
|
|
return StoredFile{}, err
|
|
}
|
|
file, err := os.Create(absolute)
|
|
if err != nil {
|
|
return StoredFile{}, err
|
|
}
|
|
defer file.Close()
|
|
if _, err := io.Copy(file, content); err != nil {
|
|
return StoredFile{}, err
|
|
}
|
|
return StoredFile{OriginalName: cleanName, RelativePath: relative, AbsolutePath: absolute}, nil
|
|
}
|