Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

153 lines
4.9KB

  1. package main
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. )
  9. type crmdFileInfo struct {
  10. Name string `json:"name,omitempty"`
  11. Type string `json:"type,omitempty"`
  12. Role string `json:"role,omitempty"`
  13. Size int64 `json:"size,omitempty"`
  14. }
  15. type crmdAttachmentID struct {
  16. ID string `json:"attachmentId"`
  17. }
  18. type crmdAttachment struct {
  19. ID string `json:"id"` //"id": "591e55398345683ee",
  20. Name string `json:"name"` //"name": "static_qr_code_without_logo.png",
  21. Deleted bool `json:"deleted"` //"deleted": false,
  22. Type string `json:"type"` //"type": "image/png",
  23. Size int `json:"size"` //"size": 509,
  24. SourceID string `json:"sourceId"` //"sourceId": null,
  25. CreateAT string `json:"createAt"` //"createdAt": "2017-05-19 02:15:21",
  26. Role string `json:"role"` //"role": "Attachment",
  27. Storage string `json:"storage"` //"storage": null,
  28. StorageFielPath string `json:"storageFilePath"` //"storageFilePath": null,
  29. Global bool `json:"global"` // "global": false,
  30. ParentID string `json:"parentId"` // "parentId": null,
  31. ParentType string `json:"parentType"` // "parentType": null,
  32. RelatedID string `json:"relatedId"` // "relatedId": null,
  33. RelatedType string `json:"relatedType"` // "relatedType": null,
  34. CreatedByID string `json:"createdById"` // "createdById": "1",
  35. CreatedbyName string `json:"createdByName"` // "createdByName": "Admin"
  36. }
  37. func crmUploadFile(path string) (fileID string, fileInfo crmdFileInfo, err error) {
  38. fileInfo, err = getFileInfo4CRM(path)
  39. headers, err := crmPrepareAttachmentHTTPHeader(fileInfo)
  40. data, err := crmFileDataString(path, fileInfo)
  41. url := crmUploadAttachmentURL()
  42. resp, err := postRAW([]byte(data), url, headers)
  43. fileID, err = crmFileIDFromJSON(resp)
  44. // log.Println(fileID)
  45. // log.Println(err)
  46. return
  47. }
  48. //crmFileIDFromHTTP read attachment id from http response
  49. // as http response cannot be 'rewind', this function is
  50. // specifically used for one purpose only.
  51. // i.e. upload attachment to EspoCRM
  52. func crmFileIDFromJSON(jsonStr string) (fileID string, err error) {
  53. attach := crmdAttachmentID{}
  54. err = json.Unmarshal([]byte(jsonStr), &attach)
  55. return attach.ID, err
  56. }
  57. //crmPrepareAttachmentHTTPHeader when uploading a file, we need its mime, auth header, etc.
  58. func crmPrepareAttachmentHTTPHeader(fileInfo crmdFileInfo) (headers map[string]string, err error) {
  59. headers = map[string]string{}
  60. headers["Authorization"] = crmAuthHeader()
  61. headers["Accept"] = "application/json"
  62. headers["Content-Type"] = fileInfo.Type
  63. return headers, err
  64. }
  65. func crmUploadAttachmentURL() string {
  66. return CRMConfig.apiUploadAttachmentURL()
  67. }
  68. func crmAuthHeader() string {
  69. //return "Basic cGF0cmljazpiNjFmYWRlMTM5OWYwY2ZjNmZjZjcxNTU0OTljNTNkOQ=="
  70. s := CRMConfig.UserName + ":" + CRMConfig.UserPass
  71. r := base64.StdEncoding.EncodeToString([]byte(s))
  72. return "Basic " + r
  73. }
  74. //crmFileDataString, encode a base64 string of the given file
  75. //so that the receiver EspoCRM can correctly understand and decode it.
  76. //"data:image/png;base64,iVB....="
  77. //
  78. //TODO: for big files, this might ave issue cause out of memory
  79. func crmFileDataString(path string, fileInfo crmdFileInfo) (encoded string, err error) {
  80. content, err := ioutil.ReadFile(path)
  81. if err != nil {
  82. return "", err
  83. }
  84. b64content := base64.StdEncoding.EncodeToString(content)
  85. encoded = fmt.Sprintf("data:%s;base64,%s", fileInfo.Type, b64content)
  86. //encode it
  87. return encoded, nil
  88. }
  89. func crmUploadAttachmentMeta(fileID string, fileInfo crmdFileInfo) (resp string, err error) {
  90. headers := map[string]string{}
  91. headers["Authorization"] = crmAuthHeader()
  92. headers["Accept"] = "application/json, text/javascript, */*; q=0.01"
  93. headers["Content-Type"] = "application/json"
  94. fileInfo.Role = "Attachment"
  95. jb, _ := json.Marshal(fileInfo)
  96. //log.Println(string(jb))
  97. URL := crmAttachmentMetaURL(fileID)
  98. resp, err = putRAW(jb, URL, headers)
  99. return
  100. }
  101. func crmAttachmentMetaURL(fileID string) string {
  102. return CRMConfig.apiEntityURL("Attachment", fileID)
  103. }
  104. func crmCreateAttachment(path string) (result crmdAttachment, err error) {
  105. fileID, fileInfo, err := crmUploadFile(path)
  106. aInfo, err := crmUploadAttachmentMeta(fileID, fileInfo)
  107. if err != nil {
  108. return
  109. }
  110. json.Unmarshal([]byte(aInfo), &result)
  111. return
  112. }
  113. func crmDownloadAttachmentAs(fileID, saveAs string) (err error) {
  114. f, err := crmDownloadAttachment(fileID)
  115. if err != nil {
  116. return
  117. }
  118. err = os.Rename(f, saveAs)
  119. return
  120. }
  121. func crmDownloadAttachment(fileID string) (filename string, err error) {
  122. u := crmURL4DownloadAttachmet(fileID)
  123. headers := map[string]string{}
  124. headers["Authorization"] = crmAuthHeader()
  125. f, _, err := saveURLwithHTTPHeader(u, headers)
  126. //log.Println(f)
  127. return f, err
  128. }
  129. func crmURL4DownloadAttachmet(fileID string) string {
  130. return CRMConfig.BaseURL + "?entryPoint=download&id=" + fileID
  131. }