2022-05-26 16:53:13 +02:00

269 lines
6.8 KiB
Go

package photosapi
import (
"errors"
)
// Error
var (
// Store
ErrStoreBadChecksum = errors.New("checksum should be sha256 in hex format")
ErrStoreBadChunkSize = errors.New("part file size should be 1MB max")
ErrStoreMissingChunks = errors.New("part checksum missing")
ErrStoreWrongChecksum = errors.New("wrong checksum")
ErrStoreMismatchChecksum = errors.New("part files doesn't match the original checksum")
ErrStoreAlreadyExists = errors.New("original file already exists")
ErrStoreChunkAlreadyExists = errors.New("chunk file already exists")
ErrStoreMissingName = errors.New("name required")
)
// // Service
// var CHUNK_SIZE int64 = 4 << 20
// type FileRequest struct {
// Name string `json:"name"`
// Checksum string `json:"checksum"`
// Chunks []string `json:"chunks"`
// }
// func (s *Service) FileCreate(c *gin.Context) {
// file := &FileRequest{}
// if c.BindJSON(file) != nil {
// return
// }
// if len(file.Name) < 1 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreMissingName)
// return
// }
// if len(file.Checksum) != 40 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChecksum)
// return
// }
// if len(file.Chunks) == 0 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreMissingChunks)
// return
// }
// for _, chunk := range file.Chunks {
// if len(chunk) != 40 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChecksum)
// return
// }
// }
// r, rs, err := s.Store.Combine(file.Chunks)
// if err != nil {
// if strings.HasPrefix(err.Error(), "chunk") && strings.HasSuffix(err.Error(), "doesn't exists") {
// c.AbortWithError(http.StatusBadRequest, err)
// } else {
// c.AbortWithError(http.StatusInternalServerError, err)
// }
// return
// }
// if r != file.Checksum {
// c.AbortWithError(http.StatusExpectationFailed, ErrStoreMismatchChecksum)
// return
// }
// sess := s.CurrentSession(c)
// f := &File{
// Name: file.Name,
// Checksum: file.Checksum,
// Size: rs,
// AuthorId: &sess.AccountId,
// }
// err = s.DB.Transaction(func(tx *gorm.DB) error {
// if err := tx.Create(f).Error; err != nil {
// return err
// }
// for i, chunk := range file.Chunks {
// fc := &FileChunk{
// FileId: f.ID,
// Part: uint32(i + 1),
// Checksum: chunk,
// }
// if err := tx.Create(fc).Error; err != nil {
// return err
// }
// }
// return nil
// })
// if nerr, ok := err.(*pgconn.PgError); ok {
// if nerr.Code == "23505" && nerr.Detail == fmt.Sprintf("Key (checksum)=(%s) already exists.", file.Checksum) {
// err = nil
// }
// }
// if err != nil {
// c.AbortWithError(http.StatusInternalServerError, err)
// return
// }
// c.JSON(http.StatusOK, gin.H{
// "sum": file.Checksum,
// "nbChunks": len(file.Chunks),
// "size": rs,
// })
// }
// func (s *Service) FileCreateChunk(c *gin.Context) {
// if c.Request.ContentLength > CHUNK_SIZE {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChunkSize)
// return
// }
// b := bytes.NewBuffer([]byte{})
// io.Copy(b, c.Request.Body)
// sess := s.CurrentSession(c)
// chunk := s.Store.NewChunk(b.Bytes())
// if err := chunk.Save(sess.Account.Login); err != nil {
// if errors.Is(err, ErrStoreChunkAlreadyExists) {
// c.JSON(http.StatusOK, gin.H{
// "checksum": chunk.Sum,
// })
// } else {
// c.AbortWithError(http.StatusBadRequest, err)
// }
// return
// }
// c.JSON(http.StatusOK, gin.H{
// "checksum": chunk.Sum,
// })
// }
// func (s *Service) FileChunkExists(c *gin.Context) {
// checksum := c.Param("checksum")
// if len(checksum) != 40 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChecksum)
// return
// }
// if s.Store.Chunk(checksum).FileExists() {
// c.Status(http.StatusOK)
// } else {
// c.Status(http.StatusNotFound)
// }
// }
// func (s *Service) FileExists(c *gin.Context) {
// checksum := c.Param("checksum")
// if len(checksum) != 40 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChecksum)
// return
// }
// var fileExists int64
// if err := s.DB.Model(&File{}).Where("checksum = ?", checksum).Count(&fileExists).Error; err != nil {
// c.AbortWithError(http.StatusInternalServerError, err)
// return
// }
// if fileExists > 0 {
// c.Status(http.StatusOK)
// } else {
// c.Status(http.StatusNotFound)
// }
// }
// func (s *Service) FileGet(c *gin.Context) {
// checksum := c.Param("checksum")
// if len(checksum) != 40 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChecksum)
// return
// }
// if checksum == c.GetHeader("If-None-Match") {
// c.Status(http.StatusNotModified)
// return
// }
// f := &File{}
// if err := s.DB.Debug().Preload("Chunks").Where("checksum = ?", checksum).First(&f).Error; err != nil {
// c.AbortWithError(http.StatusBadRequest, err)
// return
// }
// chunks := make([]string, len(f.Chunks))
// for _, fc := range f.Chunks {
// chunks[fc.Part-1] = fc.Checksum
// }
// reader, err := s.Store.NewStoreReader(chunks)
// if err != nil {
// c.AbortWithError(http.StatusInternalServerError, err)
// return
// }
// defer reader.Close()
// c.DataFromReader(
// http.StatusOK,
// reader.Size,
// mime.TypeByExtension(filepath.Ext(f.Name)),
// reader,
// map[string]string{
// "Content-Disposition": fmt.Sprintf("inline; filename=\"%s\"", f.Name),
// "ETag": f.Checksum,
// },
// )
// }
// func (s *Service) FileAnalyze(c *gin.Context) {
// checksum := c.Param("checksum")
// if len(checksum) != 40 {
// c.AbortWithError(http.StatusBadRequest, ErrStoreBadChecksum)
// return
// }
// f := &File{}
// if err := s.DB.Debug().Preload("Chunks").Where("checksum = ?", checksum).First(&f).Error; err != nil {
// c.AbortWithError(http.StatusBadRequest, err)
// return
// }
// chunks := make([]string, len(f.Chunks))
// for _, fc := range f.Chunks {
// chunks[fc.Part-1] = fc.Checksum
// }
// reader, err := s.Store.NewStoreReader(chunks)
// if err != nil {
// c.AbortWithError(http.StatusInternalServerError, err)
// return
// }
// defer reader.Close()
// rawExif, err := exif.SearchAndExtractExifWithReader(reader)
// if err != nil {
// c.AbortWithError(http.StatusInternalServerError, err)
// return
// }
// entries, _, err := exif.GetFlatExifDataUniversalSearch(rawExif, nil, true)
// if err != nil {
// c.AbortWithError(http.StatusInternalServerError, err)
// return
// }
// c.JSON(http.StatusOK, gin.H{
// "exif": entries,
// })
// }
func (s *Service) FileInit() {
file := s.Gin.Group("/file")
file.Use(s.RequireSession)
// file.POST("", s.FileCreate)
// file.HEAD("/:checksum", s.FileExists)
// file.GET("/:checksum", s.FileGet)
// file.POST("/chunk", s.FileCreateChunk)
// file.HEAD("/chunk/:checksum", s.FileChunkExists)
// file.GET("/analyze/:checksum", s.FileAnalyze)
}