Go client for the Write.as API https://developers.write.as
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.5 KiB

  1. package writeas
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. )
  7. type (
  8. // Post represents a published Write.as post, whether anonymous, owned by a
  9. // user, or part of a collection.
  10. Post struct {
  11. ID string `json:"id"`
  12. Slug string `json:"slug"`
  13. Token string `json:"token"`
  14. Font string `json:"appearance"`
  15. Language *string `json:"language"`
  16. RTL *bool `json:"rtl"`
  17. Listed bool `json:"listed"`
  18. Created time.Time `json:"created"`
  19. Title string `json:"title"`
  20. Content string `json:"body"`
  21. Views int64 `json:"views"`
  22. Tags []string `json:"tags"`
  23. Images []string `json:"images"`
  24. OwnerName string `json:"owner,omitempty"`
  25. Collection *Collection `json:"collection,omitempty"`
  26. }
  27. // OwnedPostParams are, together, fields only the original post author knows.
  28. OwnedPostParams struct {
  29. ID string `json:"-"`
  30. Token string `json:"token,omitempty"`
  31. }
  32. // PostParams holds values for creating or updating a post.
  33. PostParams struct {
  34. // Parameters only for updating
  35. OwnedPostParams
  36. // Parameters for creating or updating
  37. Title string `json:"title,omitempty"`
  38. Content string `json:"body,omitempty"`
  39. Font string `json:"font,omitempty"`
  40. IsRTL *bool `json:"rtl,omitempty"`
  41. Language *string `json:"lang,omitempty"`
  42. // Parameters only for creating
  43. Crosspost []map[string]string `json:"crosspost,omitempty"`
  44. // Parameters for collection posts
  45. Collection string `json:"-"`
  46. }
  47. // ClaimPostResult contains the post-specific result for a request to
  48. // associate a post to an account.
  49. ClaimPostResult struct {
  50. ID string `json:"id,omitempty"`
  51. Code int `json:"code,omitempty"`
  52. ErrorMessage string `json:"error_msg,omitempty"`
  53. Post *Post `json:"post,omitempty"`
  54. }
  55. )
  56. // GetPost retrieves a published post, returning the Post and any error (in
  57. // user-friendly form) that occurs. See
  58. // https://developer.write.as/docs/api/#retrieve-a-post.
  59. func (c *Client) GetPost(id string) (*Post, error) {
  60. p := &Post{}
  61. env, err := c.get(fmt.Sprintf("/posts/%s", id), p)
  62. if err != nil {
  63. return nil, err
  64. }
  65. var ok bool
  66. if p, ok = env.Data.(*Post); !ok {
  67. return nil, fmt.Errorf("Wrong data returned from API.")
  68. }
  69. status := env.Code
  70. if status == http.StatusOK {
  71. return p, nil
  72. } else if status == http.StatusNotFound {
  73. return nil, fmt.Errorf("Post not found.")
  74. } else if status == http.StatusGone {
  75. return nil, fmt.Errorf("Post unpublished.")
  76. }
  77. return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
  78. }
  79. // CreatePost publishes a new post, returning a user-friendly error if one comes
  80. // up. See https://developer.write.as/docs/api/#publish-a-post.
  81. func (c *Client) CreatePost(sp *PostParams) (*Post, error) {
  82. p := &Post{}
  83. endPre := ""
  84. if sp.Collection != "" {
  85. endPre = "/collections/" + sp.Collection
  86. }
  87. env, err := c.post(endPre+"/posts", sp, p)
  88. if err != nil {
  89. return nil, err
  90. }
  91. var ok bool
  92. if p, ok = env.Data.(*Post); !ok {
  93. return nil, fmt.Errorf("Wrong data returned from API.")
  94. }
  95. status := env.Code
  96. if status == http.StatusCreated {
  97. return p, nil
  98. } else if status == http.StatusBadRequest {
  99. return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
  100. } else {
  101. return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
  102. }
  103. return p, nil
  104. }
  105. // UpdatePost updates a published post with the given PostParams. See
  106. // https://developer.write.as/docs/api/#update-a-post.
  107. func (c *Client) UpdatePost(sp *PostParams) (*Post, error) {
  108. p := &Post{}
  109. env, err := c.put(fmt.Sprintf("/posts/%s", sp.ID), sp, p)
  110. if err != nil {
  111. return nil, err
  112. }
  113. var ok bool
  114. if p, ok = env.Data.(*Post); !ok {
  115. return nil, fmt.Errorf("Wrong data returned from API.")
  116. }
  117. status := env.Code
  118. if status == http.StatusOK {
  119. return p, nil
  120. } else if c.isNotLoggedIn(status) {
  121. return nil, fmt.Errorf("Not authenticated.")
  122. } else if status == http.StatusBadRequest {
  123. return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
  124. }
  125. return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
  126. }
  127. // DeletePost permanently deletes a published post. See
  128. // https://developer.write.as/docs/api/#delete-a-post.
  129. func (c *Client) DeletePost(sp *PostParams) error {
  130. env, err := c.delete(fmt.Sprintf("/posts/%s", sp.ID), map[string]string{
  131. "token": sp.Token,
  132. })
  133. if err != nil {
  134. return err
  135. }
  136. status := env.Code
  137. if status == http.StatusNoContent {
  138. return nil
  139. } else if c.isNotLoggedIn(status) {
  140. return fmt.Errorf("Not authenticated.")
  141. } else if status == http.StatusBadRequest {
  142. return fmt.Errorf("Bad request: %s", env.ErrorMessage)
  143. }
  144. return fmt.Errorf("Problem getting post: %d. %v\n", status, err)
  145. }
  146. // ClaimPosts associates anonymous posts with a user / account.
  147. // https://developer.write.as/docs/api/#claim-posts.
  148. func (c *Client) ClaimPosts(sp *[]OwnedPostParams) (*[]ClaimPostResult, error) {
  149. p := &[]ClaimPostResult{}
  150. env, err := c.put("/posts/claim", sp, p)
  151. if err != nil {
  152. return nil, err
  153. }
  154. var ok bool
  155. if p, ok = env.Data.(*[]ClaimPostResult); !ok {
  156. return nil, fmt.Errorf("Wrong data returned from API.")
  157. }
  158. status := env.Code
  159. if status == http.StatusOK {
  160. return p, nil
  161. } else if c.isNotLoggedIn(status) {
  162. return nil, fmt.Errorf("Not authenticated.")
  163. } else if status == http.StatusBadRequest {
  164. return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
  165. } else {
  166. return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
  167. }
  168. // TODO: does this also happen with moving posts?
  169. return p, nil
  170. }