203 lines
4.9 KiB
Go
203 lines
4.9 KiB
Go
|
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)
|
||
|
}
|