storer/service/service.go

203 lines
4.9 KiB
Go
Raw Normal View History

2024-02-19 18:09:39 +00:00
package service
import (
"errors"
"github.com/gofiber/fiber/v2"
"io"
quizdal "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
"penahub.gitlab.yandexcloud.net/backend/quiz/storer.git/dal"
mw "penahub.gitlab.yandexcloud.net/backend/quiz/storer.git/middleware"
"strconv"
"sync"
"github.com/rs/xid"
)
type Service struct {
store *dal.Storer
dal *quizdal.DAL
}
func New(s *dal.Storer, q *quizdal.DAL) *Service {
return &Service{
store: s,
dal: q,
}
}
func (s *Service) Register(app *fiber.App) {
app.Put("/quiz/customization", s.UploadCustom)
app.Put("/quiz/putImages", s.UploadImages)
}
// MB Size constants
const (
MB = 1 << 20
)
func (s *Service) UploadCustom(c *fiber.Ctx) error {
accountId, ok := mw.GetAccountId(c)
if !ok {
return nil
}
// Check valid file
form, err := c.MultipartForm()
if err != nil || form == nil || form.File == nil {
return c.Status(fiber.StatusBadRequest).SendString("expecting multipart form file")
}
squizIdStr := form.Value["quiz"]
if len(squizIdStr) == 0 {
return c.Status(fiber.StatusFailedDependency).SendString("no quiz id provided")
}
squizId, err := strconv.ParseInt(squizIdStr[0], 10, 64)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("not valid quiz id provided " + err.Error())
}
quiz, err := s.dal.QuizRepo.GetQuizById(c.Context(), accountId, uint64(squizId))
if err != nil {
return c.Status(fiber.StatusNotAcceptable).SendString("not exists quiz id provided " + err.Error())
}
var (
wg sync.WaitGroup
errm sync.Mutex
errs []error
)
if len(form.File["script"]) >= 1 {
wg.Add(1)
go func() {
defer wg.Done()
fileHeader := form.File["script"][0]
file, err := fileHeader.Open()
if err != nil {
errm.Lock()
defer errm.Unlock()
errs = append(errs, errors.New(err.Error()+" => script read"))
return
}
defer file.Close()
if err := s.store.UploadScript(c.Context(), quiz.Qid, file, fileHeader.Size); err != nil {
errm.Lock()
defer errm.Unlock()
errs = append(errs, errors.New(err.Error()+" => script upload"))
}
}()
}
if len(form.File["style"]) >= 1 {
wg.Add(1)
go func() {
defer wg.Done()
fileHeader := form.File["style"][0]
file, err := fileHeader.Open()
if err != nil {
errm.Lock()
defer errm.Unlock()
errs = append(errs, errors.New(err.Error()+" => style read"))
return
}
defer file.Close()
if err := s.store.UploadStyle(c.Context(), quiz.Qid, file, fileHeader.Size); err != nil {
errm.Lock()
defer errm.Unlock()
errs = append(errs, errors.New(err.Error()+" => style upload"))
}
}()
}
if len(form.File["fonts"]) >= 1 {
files, sizes := map[string]io.Reader{}, map[string]int64{}
for _, fileHeader := range form.File["fonts"] {
file, err := fileHeader.Open()
if err != nil {
errm.Lock()
errs = append(errs, errors.New(err.Error()+" => fonts read"))
errm.Unlock()
}
files[fileHeader.Filename] = file
sizes[fileHeader.Filename] = fileHeader.Size
}
wg.Add(1)
go func() {
defer wg.Done()
if errorsFontUploading := s.store.UploadFonts(c.Context(), quiz.Qid, files, sizes); err != nil {
errm.Lock()
defer errm.Unlock()
errs = append(errs, errorsFontUploading...)
}
}()
}
wg.Wait()
if len(errs) > 0 {
return c.Status(fiber.StatusInternalServerError).JSON(errs)
}
return c.SendStatus(fiber.StatusOK)
}
func (s *Service) UploadImages(c *fiber.Ctx) error {
accountId, ok := mw.GetAccountId(c)
if !ok {
return nil
}
// Check valid file
form, err := c.MultipartForm()
if err != nil || form == nil || form.File == nil {
return c.Status(fiber.StatusBadRequest).SendString("expecting multipart form file")
}
squizIdStr := form.Value["quiz"]
if len(squizIdStr) == 0 {
return c.Status(fiber.StatusFailedDependency).SendString("no quiz id provided")
}
squizId, err := strconv.ParseInt(squizIdStr[0], 10, 64)
if err != nil {
return c.Status(fiber.StatusBadRequest).SendString("not valid quiz id provided " + err.Error())
}
quiz, err := s.dal.QuizRepo.GetQuizById(c.Context(), accountId, uint64(squizId))
if err != nil {
return c.Status(fiber.StatusNotAcceptable).SendString("not exists quiz id provided " + err.Error())
}
var errs []error
imgids := make(map[string]string)
if len(form.File["image"]) >= 1 {
files, sizes := make(map[string]io.Reader), make(map[string]int64)
for _, imgFile := range form.File["image"] {
f, err := imgFile.Open()
if err != nil {
errs = append(errs, errors.New(err.Error()+" => imgs read"))
continue
}
fname := xid.New().String()
files[fname] = f
sizes[fname] = imgFile.Size
imgids[imgFile.Filename] = fname
defer f.Close()
}
if err := s.store.UploadImages(c.Context(), quiz.Qid, files, sizes); err != nil {
errs = append(errs, err...)
}
}
if len(errs) > 0 {
return c.Status(fiber.StatusInternalServerError).JSON(errs)
}
return c.Status(fiber.StatusOK).JSON(imgids)
}