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