92 lines
1.7 KiB
Go
92 lines
1.7 KiB
Go
package uploadfiles
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"lmika.dev/lmika/weiro/models"
|
|
)
|
|
|
|
type Provider struct {
|
|
baseDir string
|
|
}
|
|
|
|
func New(baseDir string) *Provider {
|
|
return &Provider{
|
|
baseDir: baseDir,
|
|
}
|
|
}
|
|
|
|
func (p *Provider) AdoptFile(site models.Site, up models.Upload, filename string) error {
|
|
fullPath := p.uploadFileName(site, up)
|
|
baseDir := filepath.Dir(fullPath)
|
|
|
|
if err := os.MkdirAll(baseDir, 0755); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.Rename(filename, fullPath); err == nil {
|
|
return nil
|
|
}
|
|
|
|
// Can't rename, possibly because of a cross-link device issue. So copy instead
|
|
if err := moveFile(filename, fullPath); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func moveFile(src, dst string) error {
|
|
if err := copyFile(src, dst); err != nil {
|
|
_ = os.Remove(dst)
|
|
return err
|
|
}
|
|
_ = os.Remove(src)
|
|
return nil
|
|
}
|
|
|
|
func copyFile(src, dst string) error {
|
|
in, err := os.Open(src)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
|
|
out, err := os.Create(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer out.Close()
|
|
|
|
if _, err = io.Copy(out, in); err != nil {
|
|
return err
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (p *Provider) OpenUpload(site models.Site, up models.Upload) (io.ReadCloser, error) {
|
|
fullPath := p.uploadFileName(site, up)
|
|
return os.Open(fullPath)
|
|
}
|
|
|
|
func (p *Provider) DeleteUpload(site models.Site, up models.Upload) error {
|
|
fullPath := p.uploadFileName(site, up)
|
|
if err := os.Remove(fullPath); err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (p *Provider) UploadDir(site models.Site) string {
|
|
return filepath.Join(p.baseDir, site.GUID)
|
|
}
|
|
|
|
func (p *Provider) uploadFileName(site models.Site, up models.Upload) string {
|
|
return filepath.Join(p.baseDir, site.GUID, up.Slug)
|
|
}
|