подготовка для cli + api
This commit is contained in:
parent
deb168b2e1
commit
d3397d8e4c
@ -1,24 +1,32 @@
|
|||||||
package handler
|
package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/xuri/excelize/v2"
|
"github.com/sirupsen/logrus"
|
||||||
"gitstore.ru/tolikproh/sirius/internal/model"
|
"gitstore.ru/tolikproh/sirius/internal/model"
|
||||||
|
"gitstore.ru/tolikproh/sirius/internal/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
log *logrus.Logger
|
||||||
|
cfg *model.Config
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
TEXT_TYPES = map[string]interface{}{
|
TEXT_TYPES = map[string]interface{}{
|
||||||
"text/plain; charset=utf-8": nil,
|
"text/plain; charset=utf-8": nil,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func New(cfg *model.Config, log *logrus.Logger) *Handler {
|
||||||
|
// HTTP Server
|
||||||
|
return &Handler{cfg: cfg, log: log}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Handler) GinConvert(c *gin.Context) {
|
func (s *Handler) GinConvert(c *gin.Context) {
|
||||||
sessionId := uuid.New().String()
|
sessionId := uuid.New().String()
|
||||||
|
|
||||||
@ -40,8 +48,6 @@ func (s *Handler) GinConvert(c *gin.Context) {
|
|||||||
buffer := make([]byte, fileHeader.Size)
|
buffer := make([]byte, fileHeader.Size)
|
||||||
file.Read(buffer)
|
file.Read(buffer)
|
||||||
|
|
||||||
buffer = bytes.TrimPrefix(buffer, []byte("\xef\xbb\xbf"))
|
|
||||||
|
|
||||||
fileType := http.DetectContentType(buffer)
|
fileType := http.DetectContentType(buffer)
|
||||||
|
|
||||||
// Validate File Type
|
// Validate File Type
|
||||||
@ -53,55 +59,17 @@ func (s *Handler) GinConvert(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !json.Valid(buffer) {
|
respBuff, err := service.SiriusConv(buffer)
|
||||||
s.log.Errorf("session id: %s. error code: 003. formated data not json", sessionId)
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
|
||||||
"error": errors.New("formated data not json").Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var sirius model.Sirius
|
|
||||||
|
|
||||||
err = json.Unmarshal(buffer, &sirius)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Errorf("session id: %s. error code: 004. %s", sessionId, err.Error())
|
s.log.Errorf("session id: %s. error code: 004. %s", sessionId, err.Error())
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": errors.New("Error unmarshal file").Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
buff, err := SaveToExel(sirius.NewBolid().ZoneInfo())
|
c.Data(200, "application/vnd.ms-excel", respBuff.Bytes())
|
||||||
if err != nil {
|
|
||||||
s.log.Errorf("session id: %s. error code: 005. %s", sessionId, err.Error())
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{
|
|
||||||
"error": errors.New("Error create file").Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Data(200, "application/vnd.ms-excel", buff.Bytes())
|
|
||||||
|
|
||||||
s.log.Printf("session id: %s.converted: ok. filename: %s; file size: %d bytes", sessionId, fileHeader.Filename, fileHeader.Size)
|
s.log.Printf("session id: %s.converted: ok. filename: %s; file size: %d bytes", sessionId, fileHeader.Filename, fileHeader.Size)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveToExel(data []model.ZoneInfo) (*bytes.Buffer, error) {
|
|
||||||
f := excelize.NewFile()
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
// Create a new sheet.
|
|
||||||
f.SetCellValue("Sheet1", "A2", "№ зоны")
|
|
||||||
f.SetCellValue("Sheet1", "B2", "Описание зоны")
|
|
||||||
f.SetCellValue("Sheet1", "C2", "Адреса в зоне")
|
|
||||||
i := 3
|
|
||||||
for _, d := range data {
|
|
||||||
f.SetCellValue("Sheet1", "A"+strconv.Itoa(i), d.ZoneNum)
|
|
||||||
f.SetCellValue("Sheet1", "B"+strconv.Itoa(i), d.ZoneName)
|
|
||||||
f.SetCellValue("Sheet1", "C"+strconv.Itoa(i), d.InputString())
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
return f.WriteToBuffer()
|
|
||||||
}
|
|
@ -1,8 +1,14 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"gitstore.ru/tolikproh/sirius/internal/model"
|
"gitstore.ru/tolikproh/sirius/internal/model"
|
||||||
|
"gitstore.ru/tolikproh/sirius/internal/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
@ -10,7 +16,60 @@ type Handler struct {
|
|||||||
cfg *model.Config
|
cfg *model.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
TEXT_TYPES = map[string]interface{}{
|
||||||
|
"text/plain; charset=utf-8": nil,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func New(cfg *model.Config, log *logrus.Logger) *Handler {
|
func New(cfg *model.Config, log *logrus.Logger) *Handler {
|
||||||
// HTTP Server
|
// HTTP Server
|
||||||
return &Handler{cfg: cfg, log: log}
|
return &Handler{cfg: cfg, log: log}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Handler) GinConvert(c *gin.Context) {
|
||||||
|
sessionId := uuid.New().String()
|
||||||
|
|
||||||
|
s.log.Printf("start convert. session id: %s; user agent: %s; remote addr: %s; file size [byte]: %d",
|
||||||
|
sessionId, c.Request.UserAgent(), c.Request.RemoteAddr, c.Request.ContentLength)
|
||||||
|
|
||||||
|
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, s.cfg.Srv.MaxSizeFile<<20)
|
||||||
|
|
||||||
|
file, fileHeader, err := c.Request.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
s.log.Errorf("session id: %s. error code: 001. %s", sessionId, err.Error())
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
buffer := make([]byte, fileHeader.Size)
|
||||||
|
file.Read(buffer)
|
||||||
|
|
||||||
|
fileType := http.DetectContentType(buffer)
|
||||||
|
|
||||||
|
// Validate File Type
|
||||||
|
if _, ex := TEXT_TYPES[fileType]; !ex {
|
||||||
|
s.log.Errorf("session id: %s. error code: 002. formated data not text/plain", sessionId)
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": errors.New("formated data not text/plain").Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
respBuff, err := service.SiriusConv(buffer)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Errorf("session id: %s. error code: 004. %s", sessionId, err.Error())
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data(200, "application/vnd.ms-excel", respBuff.Bytes())
|
||||||
|
|
||||||
|
s.log.Printf("session id: %s.converted: ok. filename: %s; file size: %d bytes", sessionId, fileHeader.Filename, fileHeader.Size)
|
||||||
|
|
||||||
|
}
|
||||||
|
49
internal/service/convert.go
Normal file
49
internal/service/convert.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/xuri/excelize/v2"
|
||||||
|
"gitstore.ru/tolikproh/sirius/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SiriusConv(data []byte) (*bytes.Buffer, error) {
|
||||||
|
|
||||||
|
data = bytes.TrimPrefix(data, []byte("\xef\xbb\xbf"))
|
||||||
|
|
||||||
|
if !json.Valid(data) {
|
||||||
|
return nil, errors.New("formated data not json")
|
||||||
|
}
|
||||||
|
|
||||||
|
var sirius model.Sirius
|
||||||
|
|
||||||
|
err := json.Unmarshal(data, &sirius)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Error unmarshal file")
|
||||||
|
}
|
||||||
|
|
||||||
|
return SaveToExel(sirius.NewBolid().ZoneInfo())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func SaveToExel(data []model.ZoneInfo) (*bytes.Buffer, error) {
|
||||||
|
f := excelize.NewFile()
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
// Create a new sheet.
|
||||||
|
f.SetCellValue("Sheet1", "A2", "№ зоны")
|
||||||
|
f.SetCellValue("Sheet1", "B2", "Описание зоны")
|
||||||
|
f.SetCellValue("Sheet1", "C2", "Адреса в зоне")
|
||||||
|
i := 3
|
||||||
|
for _, d := range data {
|
||||||
|
f.SetCellValue("Sheet1", "A"+strconv.Itoa(i), d.ZoneNum)
|
||||||
|
f.SetCellValue("Sheet1", "B"+strconv.Itoa(i), d.ZoneName)
|
||||||
|
f.SetCellValue("Sheet1", "C"+strconv.Itoa(i), d.InputString())
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.WriteToBuffer()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user