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.

188 line
5.6 KiB

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