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.

222 lines
6.3 KiB

  1. package writeas
  2. import (
  3. "fmt"
  4. "net/http"
  5. )
  6. type (
  7. // Collection represents a collection of posts. Blogs are a type of collection
  8. // on Write.as.
  9. Collection struct {
  10. Alias string `json:"alias"`
  11. Title string `json:"title"`
  12. Description string `json:"description"`
  13. StyleSheet string `json:"style_sheet"`
  14. Private bool `json:"private"`
  15. Views int64 `json:"views"`
  16. Domain string `json:"domain,omitempty"`
  17. Email string `json:"email,omitempty"`
  18. URL string `json:"url,omitempty"`
  19. TotalPosts int `json:"total_posts"`
  20. Posts *[]Post `json:"posts,omitempty"`
  21. }
  22. // CollectionParams holds values for creating a collection.
  23. CollectionParams struct {
  24. Alias string `json:"alias"`
  25. Title string `json:"title"`
  26. }
  27. // DeleteCollectionParams holds the parameters required to delete a
  28. // collection.
  29. DeleteCollectionParams struct {
  30. Alias string `json:"-"`
  31. }
  32. // CollectPostParams holds the parameters for moving posts to a collection.
  33. CollectPostParams struct {
  34. // Alias of the collection.
  35. Alias string `json:"-"`
  36. // Posts to move to this collection.
  37. Posts []*CollectPost
  38. }
  39. // CollectPost is a post being moved to a collection.
  40. CollectPost struct {
  41. // ID of the post.
  42. ID string `json:"id,omitempty"`
  43. // The post's modify token.
  44. //
  45. // This is required if the post does not belong to the user making
  46. // this request.
  47. Token string `json:"token,omitempty"`
  48. }
  49. // CollectPostResult holds the result of moving a single post to a
  50. // collection.
  51. CollectPostResult struct {
  52. Code int `json:"code,omitempty"`
  53. ErrorMessage string `json:"error_msg,omitempty"`
  54. Post *Post `json:"post,omitempty"`
  55. }
  56. )
  57. // CreateCollection creates a new collection, returning a user-friendly error
  58. // if one comes up. Requires a Write.as subscription. See
  59. // https://developer.write.as/docs/api/#create-a-collection
  60. func (c *Client) CreateCollection(sp *CollectionParams) (*Collection, error) {
  61. p := &Collection{}
  62. env, err := c.post("/collections", sp, p)
  63. if err != nil {
  64. return nil, err
  65. }
  66. var ok bool
  67. if p, ok = env.Data.(*Collection); !ok {
  68. return nil, fmt.Errorf("Wrong data returned from API.")
  69. }
  70. status := env.Code
  71. if status != http.StatusCreated {
  72. if status == http.StatusBadRequest {
  73. return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
  74. } else if status == http.StatusForbidden {
  75. return nil, fmt.Errorf("Casual or Pro user required.")
  76. } else if status == http.StatusConflict {
  77. return nil, fmt.Errorf("Collection name is already taken.")
  78. } else if status == http.StatusPreconditionFailed {
  79. return nil, fmt.Errorf("Reached max collection quota.")
  80. }
  81. return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
  82. }
  83. return p, nil
  84. }
  85. // GetCollection retrieves a collection, returning the Collection and any error
  86. // (in user-friendly form) that occurs. See
  87. // https://developer.write.as/docs/api/#retrieve-a-collection
  88. func (c *Client) GetCollection(alias string) (*Collection, error) {
  89. coll := &Collection{}
  90. env, err := c.get(fmt.Sprintf("/collections/%s", alias), coll)
  91. if err != nil {
  92. return nil, err
  93. }
  94. var ok bool
  95. if coll, ok = env.Data.(*Collection); !ok {
  96. return nil, fmt.Errorf("Wrong data returned from API.")
  97. }
  98. status := env.Code
  99. if status == http.StatusOK {
  100. return coll, nil
  101. } else if status == http.StatusNotFound {
  102. return nil, fmt.Errorf("Collection not found.")
  103. } else {
  104. return nil, fmt.Errorf("Problem getting collection: %d. %v\n", status, err)
  105. }
  106. }
  107. // GetCollectionPosts retrieves a collection's posts, returning the Posts
  108. // and any error (in user-friendly form) that occurs. See
  109. // https://developer.write.as/docs/api/#retrieve-collection-posts
  110. func (c *Client) GetCollectionPosts(alias string) (*[]Post, error) {
  111. coll := &Collection{}
  112. env, err := c.get(fmt.Sprintf("/collections/%s/posts", alias), coll)
  113. if err != nil {
  114. return nil, err
  115. }
  116. var ok bool
  117. if coll, ok = env.Data.(*Collection); !ok {
  118. return nil, fmt.Errorf("Wrong data returned from API.")
  119. }
  120. status := env.Code
  121. if status == http.StatusOK {
  122. return coll.Posts, nil
  123. } else if status == http.StatusNotFound {
  124. return nil, fmt.Errorf("Collection not found.")
  125. } else {
  126. return nil, fmt.Errorf("Problem getting collection: %d. %v\n", status, err)
  127. }
  128. }
  129. // GetUserCollections retrieves the authenticated user's collections.
  130. // See https://developers.write.as/docs/api/#retrieve-user-39-s-collections
  131. func (c *Client) GetUserCollections() (*[]Collection, error) {
  132. colls := &[]Collection{}
  133. env, err := c.get("/me/collections", colls)
  134. if err != nil {
  135. return nil, err
  136. }
  137. var ok bool
  138. if colls, ok = env.Data.(*[]Collection); !ok {
  139. return nil, fmt.Errorf("Wrong data returned from API.")
  140. }
  141. status := env.Code
  142. if status != http.StatusOK {
  143. if c.isNotLoggedIn(status) {
  144. return nil, fmt.Errorf("Not authenticated.")
  145. }
  146. return nil, fmt.Errorf("Problem getting collections: %d. %v\n", status, err)
  147. }
  148. return colls, nil
  149. }
  150. // DeleteCollection permanently deletes a collection and makes any posts on it
  151. // anonymous.
  152. //
  153. // See https://developers.write.as/docs/api/#delete-a-collection.
  154. func (c *Client) DeleteCollection(p *DeleteCollectionParams) error {
  155. endpoint := "/collections/" + p.Alias
  156. env, err := c.delete(endpoint, nil /* data */)
  157. if err != nil {
  158. return err
  159. }
  160. status := env.Code
  161. switch status {
  162. case http.StatusNoContent:
  163. return nil
  164. case http.StatusUnauthorized:
  165. return fmt.Errorf("Not authenticated.")
  166. case http.StatusBadRequest:
  167. return fmt.Errorf("Bad request: %s", env.ErrorMessage)
  168. default:
  169. return fmt.Errorf("Problem deleting collection: %d. %s\n", status, env.ErrorMessage)
  170. }
  171. }
  172. // CollectPosts adds a group of posts to a collection.
  173. //
  174. // See https://developers.write.as/docs/api/#move-a-post-to-a-collection.
  175. func (c *Client) CollectPosts(sp *CollectPostParams) ([]*CollectPostResult, error) {
  176. endpoint := "/collections/" + sp.Alias + "/collect"
  177. var p []*CollectPostResult
  178. env, err := c.post(endpoint, sp.Posts, &p)
  179. if err != nil {
  180. return nil, err
  181. }
  182. status := env.Code
  183. switch {
  184. case status == http.StatusOK:
  185. return p, nil
  186. case c.isNotLoggedIn(status):
  187. return nil, fmt.Errorf("Not authenticated.")
  188. case status == http.StatusBadRequest:
  189. return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
  190. default:
  191. return nil, fmt.Errorf("Problem claiming post: %d. %s\n", status, env.ErrorMessage)
  192. }
  193. }