util.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package util
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "mime/multipart"
  8. "net/http"
  9. "strconv"
  10. "strings"
  11. "sync"
  12. "time"
  13. "github.com/aws/aws-sdk-go/aws"
  14. "github.com/aws/aws-sdk-go/aws/credentials"
  15. "github.com/aws/aws-sdk-go/aws/session"
  16. "github.com/aws/aws-sdk-go/service/s3"
  17. "github.com/aws/aws-sdk-go/service/s3/s3manager"
  18. "github.com/happierall/l"
  19. "github.com/metarare/metarare_api/common"
  20. "github.com/metarare/metarare_api/models"
  21. "gorm.io/gorm"
  22. )
  23. type AWSConfs struct {
  24. Region string
  25. BucketName string
  26. Access_key_id string
  27. Access_key string
  28. }
  29. type MetaPack struct {
  30. BoosterID int `json:"booster_id"`
  31. ID int `json:"id"`
  32. TxHash string `json:"tx_hash"`
  33. RandomNumber string `json:"random_number"`
  34. Image string `json:"image"`
  35. ExternalURL string `json:"external_url"`
  36. Description string `json:"description"`
  37. Name string `json:"name"`
  38. Attributes []Trait `json:"attributes"`
  39. AnimationURL string `json:"animation_url,omitempty"`
  40. Signature string `json:"signature"`
  41. }
  42. type Trait struct {
  43. TraitType string `json:"trait_type,omitempty"`
  44. Value string `json:"value,omitempty"`
  45. }
  46. //NOTE x AppendData
  47. func AppendData(prevData interface{}, dataObject interface{}, key string) map[string]interface{} {
  48. prev, _ := json.Marshal(prevData)
  49. convert := map[string]interface{}{}
  50. if prevData != nil {
  51. json.Unmarshal(prev, &convert)
  52. }
  53. datas, err := json.Marshal(dataObject)
  54. if err != nil {
  55. return nil
  56. }
  57. new := map[string]interface{}{}
  58. err = json.Unmarshal(datas, &new)
  59. if err != nil {
  60. var payload interface{}
  61. json.Unmarshal(datas, &payload)
  62. convert[key] = payload
  63. }
  64. for k, v := range new {
  65. convert[k] = v
  66. }
  67. return convert
  68. }
  69. func GetCredentials(awsConf AWSConfs) (*session.Session, error) {
  70. return session.NewSession(&aws.Config{
  71. Region: aws.String(awsConf.Region),
  72. Credentials: credentials.NewStaticCredentials(awsConf.Access_key_id, awsConf.Access_key, ""),
  73. })
  74. }
  75. var mutex sync.Mutex
  76. func UploadToS3(awsConf AWSConfs, path string, header *multipart.FileHeader) (string, error) {
  77. mutex.Lock()
  78. s, err := GetCredentials(awsConf)
  79. if err != nil {
  80. return "", err
  81. }
  82. file, err := header.Open()
  83. if err != nil {
  84. return "", err
  85. }
  86. fileSize := header.Size
  87. buffer := make([]byte, fileSize)
  88. file.Read(buffer)
  89. var obj *s3.PutObjectOutput
  90. now := time.Now()
  91. _split := strings.Split(header.Filename, ".")
  92. _extension := _split[len(_split)-1]
  93. _hex := common.GenerateRandomString(10, "")
  94. time := now.UnixNano() / 1000000
  95. formattedFileName := fmt.Sprintf("%s_%d.%s", _hex, time, _extension)
  96. // runeFileName := []rune(header.Filename)
  97. // index2 := float64(len(runeFileName)) - math.Min(float64(len(runeFileName)), 10)
  98. // str := runeFileName[int(index2):]
  99. // tailOfFile := ""
  100. // for _, r := range str {
  101. // tailOfFile = fmt.Sprintf("%s%s", tailOfFile, string(r))
  102. // }
  103. // formattedFileName := fmt.Sprintf("%s_%s_%s_%s",
  104. // fmt.Sprintf("%04d%02d%02d", now.Year(), now.Month(), now.Day()),
  105. // fmt.Sprintf("%02d%02d%02d", now.Hour(), now.Minute(), now.Second()),
  106. // fmt.Sprintf("%03d", now.Nanosecond()/1000000),
  107. // fmt.Sprintf("%s", tailOfFile),
  108. // )
  109. k := fmt.Sprintf("%s/%s",
  110. path,
  111. formattedFileName,
  112. )
  113. extension := strings.Split(formattedFileName, ".")
  114. if extension[len(extension)-1] != "gif" {
  115. //NOTE x resize image
  116. imgResize := &ContentsCenter{}
  117. if pbImage, err := imgResize.Resize(buffer); err == nil {
  118. buffer = make([]byte, len(pbImage))
  119. workingEleCount := copy(buffer, pbImage)
  120. fmt.Printf("copied ele count : %d", workingEleCount)
  121. }
  122. }
  123. obj, err = s3.New(s).PutObject(&s3.PutObjectInput{
  124. Bucket: aws.String(awsConf.BucketName),
  125. Key: aws.String(k),
  126. ACL: aws.String("public-read"),
  127. Body: bytes.NewReader(buffer),
  128. ContentLength: aws.Int64(int64(len(buffer))),
  129. ContentType: aws.String(http.DetectContentType(buffer)),
  130. ContentDisposition: aws.String("attachment"),
  131. ServerSideEncryption: aws.String("AES256"),
  132. })
  133. if err != nil {
  134. l.Error(err, obj)
  135. return "", err
  136. }
  137. url := "https://s3.%s.amazonaws.com/%s/%s"
  138. url = fmt.Sprintf(url, awsConf.Region, awsConf.BucketName, k)
  139. l.Log("uploaded file link : ", url)
  140. mutex.Unlock()
  141. return url, err
  142. }
  143. func UploadToMetaJson(awsConf AWSConfs, fileName string, serializedData []byte) (string, error) {
  144. s, err := GetCredentials(awsConf)
  145. if err != nil {
  146. return "", err
  147. }
  148. uploader := s3manager.NewUploader(s)
  149. _, err = uploader.Upload(&s3manager.UploadInput{
  150. Bucket: aws.String(awsConf.BucketName),
  151. Key: aws.String(fileName),
  152. ACL: aws.String("public-read"),
  153. Body: bytes.NewReader(serializedData),
  154. })
  155. if err != nil {
  156. return "", fmt.Errorf("Error occurred while s3uploader", err.Error())
  157. }
  158. filePath := "https://nftinfo.meta-rare.net/" + fileName
  159. return filePath, nil
  160. }
  161. func MakeMetaData(awsConf AWSConfs, db *gorm.DB, tokenID uint64, txHash string, name string, description string, assets string) error {
  162. _tokneID := strconv.FormatUint(tokenID, 10)
  163. meta := MetaPack{
  164. BoosterID: 0,
  165. ID: int(tokenID),
  166. TxHash: txHash,
  167. RandomNumber: common.GenerateRandomNumber(32),
  168. Name: name,
  169. Description: description,
  170. ExternalURL: `https://nftinfo.meta-rare.net/` + _tokneID,
  171. }
  172. str := strings.Split(assets, ".")
  173. kind := str[len(str)-1]
  174. if kind == "mp4" {
  175. meta.AnimationURL = assets
  176. meta.Image = assets
  177. } else {
  178. meta.Image = assets
  179. }
  180. _t := []models.Traits{}
  181. err := db.Where("token_id = ?", tokenID).Find(&_t).Error
  182. if errors.Is(err, gorm.ErrRecordNotFound) {
  183. fmt.Printf("%s", err)
  184. }
  185. _trait := make([]Trait, 0)
  186. for _, item := range _t {
  187. _trait = append(_trait, Trait{TraitType: item.Key, Value: item.Value})
  188. }
  189. meta.Attributes = _trait
  190. serializedData, _ := json.Marshal(meta)
  191. path, _err := UploadToMetaJson(awsConf, _tokneID, serializedData)
  192. if _err != nil {
  193. fmt.Print(err.Error())
  194. return _err
  195. } else {
  196. fmt.Println("path :", path)
  197. }
  198. return nil
  199. }