weiro/services/uploads/manage.go

136 lines
3.1 KiB
Go
Raw Normal View History

package uploads
import (
"context"
"fmt"
"html/template"
"io"
"log"
"strings"
"lmika.dev/lmika/weiro/models"
)
var (
uploadCopyTemplate = template.Must(template.New("upload-copy").Parse(`<img src="/uploads/{{.Slug}}" alt="{{.Alt}}">`))
)
type UploadWithURL struct {
Upload models.Upload
CopyTemplate string
URL string
}
func (s *Service) FetchUpload(ctx context.Context, uploadID int64) (res UploadWithURL, _ error) {
site, _, err := s.fetchSiteAndUser(ctx)
if err != nil {
return UploadWithURL{}, err
}
upload, err := s.db.SelectUploadByID(ctx, uploadID)
if err != nil {
return UploadWithURL{}, err
}
return UploadWithURL{
Upload: upload,
CopyTemplate: s.renderCopyTemplate(upload),
URL: fmt.Sprintf("/sites/%v/uploads/%v/raw", site.ID, upload.ID),
}, nil
}
func (s *Service) DeleteUpload(ctx context.Context, uploadID int64) error {
site, _, err := s.fetchSiteAndUser(ctx)
if err != nil {
return err
}
upload, err := s.db.SelectUploadByID(ctx, uploadID)
if err != nil {
return err
}
if err := s.up.DeleteUpload(site, upload); err != nil {
return err
}
return s.db.DeleteUpload(ctx, uploadID)
}
func (s *Service) renderCopyTemplate(upload models.Upload) string {
var sb strings.Builder
if err := uploadCopyTemplate.Execute(&sb, upload); err != nil {
log.Printf("error rendering upload copy template: %v", err)
return ""
}
return sb.String()
}
func (s *Service) ListUploads(ctx context.Context) (res []UploadWithURL, _ error) {
site, _, err := s.fetchSiteAndUser(ctx)
if err != nil {
return nil, err
}
uploads, err := s.db.SelectUploadsOfSite(ctx, site.ID)
if err != nil {
return nil, err
}
res = make([]UploadWithURL, len(uploads))
for i, upload := range uploads {
res[i] = UploadWithURL{
Upload: upload,
CopyTemplate: s.renderCopyTemplate(upload),
URL: fmt.Sprintf("/sites/%v/uploads/%v/raw", site.ID, upload.ID),
}
}
return res, nil
}
func (s *Service) OpenUpload(ctx context.Context, id int64) (models.Upload, func() (io.ReadCloser, error), error) {
site, _, err := s.fetchSiteAndUser(ctx)
if err != nil {
return models.Upload{}, nil, err
}
upload, err := s.db.SelectUploadByID(ctx, id)
if err != nil {
return models.Upload{}, nil, err
} else if upload.SiteID != site.ID {
return models.Upload{}, nil, models.NotFoundError
}
return upload, func() (io.ReadCloser, error) {
rw, err := s.up.OpenUpload(site, upload)
if err != nil {
return nil, err
}
return rw, nil
}, nil
}
func (s *Service) OpenUploadFromSlug(ctx context.Context, slug string) (models.Upload, func() (io.ReadCloser, error), error) {
site, _, err := s.fetchSiteAndUser(ctx)
if err != nil {
return models.Upload{}, nil, err
}
upload, err := s.db.SelectUploadBySiteIDAndSlug(ctx, site.ID, slug)
if err != nil {
return models.Upload{}, nil, err
} else if upload.SiteID != site.ID {
return models.Upload{}, nil, models.NotFoundError
}
return upload, func() (io.ReadCloser, error) {
rw, err := s.up.OpenUpload(site, upload)
if err != nil {
return nil, err
}
return rw, nil
}, nil
}