Page MenuHomeMusing Studio

No OneTemporary

diff --git a/post.go b/post.go
index 300c57e..225bda7 100644
--- a/post.go
+++ b/post.go
@@ -1,217 +1,266 @@
package writeas
import (
"fmt"
"net/http"
"time"
)
type (
// Post represents a published Write.as post, whether anonymous, owned by a
// user, or part of a collection.
Post struct {
ID string `json:"id"`
Slug string `json:"slug"`
Token string `json:"token"`
Font string `json:"appearance"`
Language *string `json:"language"`
RTL *bool `json:"rtl"`
Listed bool `json:"listed"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
Title string `json:"title"`
Content string `json:"body"`
Views int64 `json:"views"`
Tags []string `json:"tags"`
Images []string `json:"images"`
OwnerName string `json:"owner,omitempty"`
Collection *Collection `json:"collection,omitempty"`
}
// OwnedPostParams are, together, fields only the original post author knows.
OwnedPostParams struct {
ID string `json:"-"`
Token string `json:"token,omitempty"`
}
// PostParams holds values for creating or updating a post.
PostParams struct {
// Parameters only for updating
ID string `json:"-"`
Token string `json:"token,omitempty"`
// Parameters for creating or updating
Title string `json:"title,omitempty"`
Content string `json:"body,omitempty"`
Font string `json:"font,omitempty"`
IsRTL *bool `json:"rtl,omitempty"`
Language *string `json:"lang,omitempty"`
// Parameters only for creating
Crosspost []map[string]string `json:"crosspost,omitempty"`
// Parameters for collection posts
Collection string `json:"-"`
}
+ // PinnedPostParams holds values for pinning a post
+ PinnedPostParams struct {
+ ID string `json:"id"`
+ Position int `json:"position"`
+ }
+
+ // BatchPostResult contains the post-specific result as part of a larger
+ // batch operation.
+ BatchPostResult struct {
+ ID string `json:"id,omitempty"`
+ Code int `json:"code,omitempty"`
+ ErrorMessage string `json:"error_msg,omitempty"`
+ }
+
// ClaimPostResult contains the post-specific result for a request to
// associate a post to an account.
ClaimPostResult struct {
ID string `json:"id,omitempty"`
Code int `json:"code,omitempty"`
ErrorMessage string `json:"error_msg,omitempty"`
Post *Post `json:"post,omitempty"`
}
)
// GetPost retrieves a published post, returning the Post and any error (in
// user-friendly form) that occurs. See
// https://developer.write.as/docs/api/#retrieve-a-post.
func (c *Client) GetPost(id string) (*Post, error) {
p := &Post{}
env, err := c.get(fmt.Sprintf("/posts/%s", id), p)
if err != nil {
return nil, err
}
var ok bool
if p, ok = env.Data.(*Post); !ok {
return nil, fmt.Errorf("Wrong data returned from API.")
}
status := env.Code
if status == http.StatusOK {
return p, nil
} else if status == http.StatusNotFound {
return nil, fmt.Errorf("Post not found.")
} else if status == http.StatusGone {
return nil, fmt.Errorf("Post unpublished.")
}
return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
}
// CreatePost publishes a new post, returning a user-friendly error if one comes
// up. See https://developer.write.as/docs/api/#publish-a-post.
func (c *Client) CreatePost(sp *PostParams) (*Post, error) {
p := &Post{}
endPre := ""
if sp.Collection != "" {
endPre = "/collections/" + sp.Collection
}
env, err := c.post(endPre+"/posts", sp, p)
if err != nil {
return nil, err
}
var ok bool
if p, ok = env.Data.(*Post); !ok {
return nil, fmt.Errorf("Wrong data returned from API.")
}
status := env.Code
if status == http.StatusCreated {
return p, nil
} else if status == http.StatusBadRequest {
return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
} else {
return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
}
}
// UpdatePost updates a published post with the given PostParams. See
// https://developer.write.as/docs/api/#update-a-post.
func (c *Client) UpdatePost(sp *PostParams) (*Post, error) {
p := &Post{}
env, err := c.put(fmt.Sprintf("/posts/%s", sp.ID), sp, p)
if err != nil {
return nil, err
}
var ok bool
if p, ok = env.Data.(*Post); !ok {
return nil, fmt.Errorf("Wrong data returned from API.")
}
status := env.Code
if status == http.StatusOK {
return p, nil
} else if c.isNotLoggedIn(status) {
return nil, fmt.Errorf("Not authenticated.")
} else if status == http.StatusBadRequest {
return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
}
return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
}
// DeletePost permanently deletes a published post. See
// https://developer.write.as/docs/api/#delete-a-post.
func (c *Client) DeletePost(sp *PostParams) error {
env, err := c.delete(fmt.Sprintf("/posts/%s", sp.ID), map[string]string{
"token": sp.Token,
})
if err != nil {
return err
}
status := env.Code
if status == http.StatusNoContent {
return nil
} else if c.isNotLoggedIn(status) {
return fmt.Errorf("Not authenticated.")
} else if status == http.StatusBadRequest {
return fmt.Errorf("Bad request: %s", env.ErrorMessage)
}
return fmt.Errorf("Problem getting post: %d. %v\n", status, err)
}
// ClaimPosts associates anonymous posts with a user / account.
// https://developer.write.as/docs/api/#claim-posts.
func (c *Client) ClaimPosts(sp *[]OwnedPostParams) (*[]ClaimPostResult, error) {
p := &[]ClaimPostResult{}
env, err := c.put("/posts/claim", sp, p)
if err != nil {
return nil, err
}
var ok bool
if p, ok = env.Data.(*[]ClaimPostResult); !ok {
return nil, fmt.Errorf("Wrong data returned from API.")
}
status := env.Code
if status == http.StatusOK {
return p, nil
} else if c.isNotLoggedIn(status) {
return nil, fmt.Errorf("Not authenticated.")
} else if status == http.StatusBadRequest {
return nil, fmt.Errorf("Bad request: %s", env.ErrorMessage)
} else {
return nil, fmt.Errorf("Problem getting post: %d. %v\n", status, err)
}
// TODO: does this also happen with moving posts?
}
// GetUserPosts retrieves the authenticated user's posts.
// See https://developers.write.as/docs/api/#retrieve-user-39-s-posts
func (c *Client) GetUserPosts() (*[]Post, error) {
p := &[]Post{}
env, err := c.get("/me/posts", p)
if err != nil {
return nil, err
}
var ok bool
if p, ok = env.Data.(*[]Post); !ok {
return nil, fmt.Errorf("Wrong data returned from API.")
}
status := env.Code
if status != http.StatusOK {
if c.isNotLoggedIn(status) {
return nil, fmt.Errorf("Not authenticated.")
}
return nil, fmt.Errorf("Problem getting posts: %d. %v\n", status, err)
}
return p, nil
}
+
+// PinPost pins a post in the given collection.
+// See https://developers.write.as/docs/api/#pin-a-post-to-a-collection
+func (c *Client) PinPost(alias string, pp *PinnedPostParams) error {
+ res := &[]BatchPostResult{}
+ env, err := c.post(fmt.Sprintf("/collections/%s/pin", alias), []*PinnedPostParams{pp}, res)
+ if err != nil {
+ return err
+ }
+
+ var ok bool
+ if res, ok = env.Data.(*[]BatchPostResult); !ok {
+ return fmt.Errorf("Wrong data returned from API.")
+ }
+
+ // Check for basic request errors on top level response
+ status := env.Code
+ if status != http.StatusOK {
+ if c.isNotLoggedIn(status) {
+ return fmt.Errorf("Not authenticated.")
+ }
+ return fmt.Errorf("Problem pinning post: %d. %v\n", status, err)
+ }
+
+ // Check the individual post result
+ if len(*res) == 0 || len(*res) > 1 {
+ return fmt.Errorf("Wrong data returned from API.")
+ }
+ if (*res)[0].Code != http.StatusOK {
+ return fmt.Errorf("Problem pinning post: %d", (*res)[0].Code)
+ // TODO: return ErrorMessage (right now it'll be empty)
+ // return fmt.Errorf("Problem pinning post: %v", res[0].ErrorMessage)
+ }
+ return nil
+}
diff --git a/post_test.go b/post_test.go
index 830a506..11562d6 100644
--- a/post_test.go
+++ b/post_test.go
@@ -1,92 +1,106 @@
package writeas
import (
"testing"
"fmt"
"strings"
)
func TestCreatePost(t *testing.T) {
wac := NewClient()
p, err := wac.CreatePost(&PostParams{
Title: "Title!",
Content: "This is a post.",
Font: "sans",
})
if err != nil {
t.Errorf("Post create failed: %v", err)
return
}
t.Logf("Post created: %+v", p)
token := p.Token
// Update post
p, err = wac.UpdatePost(&PostParams{
OwnedPostParams: OwnedPostParams{
ID: p.ID,
Token: token,
},
Content: "Now it's been updated!",
})
if err != nil {
t.Errorf("Post update failed: %v", err)
return
}
t.Logf("Post updated: %+v", p)
// Delete post
err = wac.DeletePost(&PostParams{
OwnedPostParams: OwnedPostParams{
ID: p.ID,
Token: token,
},
})
if err != nil {
t.Errorf("Post delete failed: %v", err)
return
}
t.Logf("Post deleted!")
}
func TestGetPost(t *testing.T) {
dwac := NewDevClient()
res, err := dwac.GetPost("zekk5r9apum6p")
if err != nil {
t.Errorf("Unexpected fetch results: %+v, err: %v\n", res, err)
} else {
t.Logf("Post: %+v", res)
if res.Content != "This is a post." {
t.Errorf("Unexpected fetch results: %+v\n", res)
}
}
wac := NewClient()
res, err = wac.GetPost("3psnxyhqxy3hq")
if err != nil {
t.Errorf("Unexpected fetch results: %+v, err: %v\n", res, err)
} else {
if !strings.HasPrefix(res.Content, " Write.as Blog") {
t.Errorf("Unexpected fetch results: %+v\n", res)
}
}
}
+func TestPinPost(t *testing.T) {
+ dwac := NewDevClient()
+ _, err := dwac.LogIn("demo", "demo")
+ if err != nil {
+ t.Fatalf("Unable to log in: %v", err)
+ }
+ defer dwac.LogOut()
+
+ err = dwac.PinPost("tester", &PinnedPostParams{ID: "olx6uk7064heqltf"})
+ if err != nil {
+ t.Fatalf("Pin failed: %v", err)
+ }
+}
+
func ExampleClient_CreatePost() {
c := NewClient()
// Publish a post
p, err := c.CreatePost(&PostParams{
Title: "Title!",
Content: "This is a post.",
Font: "sans",
})
if err != nil {
fmt.Printf("Unable to create: %v", err)
return
}
fmt.Printf("%s", p.Content)
// Output: This is a post.
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, May 16, 6:44 PM (11 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3240374

Event Timeline