diff --git a/collection.go b/collection.go new file mode 100644 index 0000000..42e2202 --- /dev/null +++ b/collection.go @@ -0,0 +1,16 @@ +package writeas + +// Collection represents a collection of posts. Blogs are a type of collection +// on Write.as. +type Collection struct { + Alias string `json:"alias"` + Title string `json:"title"` + Description string `json:"description"` + StyleSheet string `json:"style_sheet"` + Private bool `json:"private"` + Views int64 `json:"views"` + Domain string `json:"domain,omitempty"` + Email string `json:"email,omitempty"` + + TotalPosts int `json:"total_posts"` +} diff --git a/post.go b/post.go new file mode 100644 index 0000000..22b8630 --- /dev/null +++ b/post.go @@ -0,0 +1,66 @@ +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"` + ModifyToken string `json:"token"` + Font string `json:"appearance"` + Language *string `json:"language"` + RTL *bool `json:"rtl"` + Listed bool `json:"listed"` + Created time.Time `json:"created"` + 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"` + } + + // SubmittedPost represents a new post for publishing or updating. + SubmittedPost struct { + Title string `json:"title"` + Content string `json:"body"` + Font string `json:"font"` + IsRTL *bool `json:"rtl"` + Language *string `json:"lang"` + + Crosspost []map[string]string `json:"crosspost"` + } +) + +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.") + } else { + return nil, fmt.Errorf("Problem getting post: %s. %v\n", status, err) + } + return p, nil +} diff --git a/post/post.go b/post/post.go deleted file mode 100644 index f2e669c..0000000 --- a/post/post.go +++ /dev/null @@ -1,25 +0,0 @@ -package post - -import ( - "fmt" - writeas "github.com/writeas/writeas-go" - "net/http" -) - -func Get(id string) string { - status, body, err := getAPI().Call("GET", fmt.Sprintf("/%s", id)) - - if status == http.StatusOK { - return body - } else if status == http.StatusNotFound { - return "Post not found." - } else if status == http.StatusGone { - return "Post unpublished." - } else { - return fmt.Sprintf("Problem getting post: %s. %v\n", status, err) - } -} - -func getAPI() *writeas.API { - return writeas.GetAPI() -} diff --git a/post/post_test.go b/post/post_test.go deleted file mode 100644 index da2efd5..0000000 --- a/post/post_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package post - -import ( - "testing" - - "strings" -) - -func TestGet(t *testing.T) { - res := Get("3psnxyhqxy3hq") - if !strings.HasPrefix(res, " Write.as Blog") { - t.Errorf("Unexpected fetch results: %s\n", res) - } -} diff --git a/post_test.go b/post_test.go new file mode 100644 index 0000000..65ceee2 --- /dev/null +++ b/post_test.go @@ -0,0 +1,30 @@ +package writeas + +import ( + "testing" + + "strings" +) + +func TestGet(t *testing.T) { + wac := NewClient("") + + res, err := wac.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) + } + } + + 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) + } + } +} diff --git a/writeas.go b/writeas.go index 7255067..6da8793 100644 --- a/writeas.go +++ b/writeas.go @@ -1,48 +1,85 @@ package writeas import ( + "encoding/json" "errors" "fmt" - "io/ioutil" + "github.com/writeas/impart" + "io" "net/http" "time" ) const ( apiURL = "https://write.as/api" ) -type API struct { - BaseURL string +type Client struct { + baseURL string + + // Access token for the user making requests. + token string + // Client making requests to the API + client *http.Client } // defaultHTTPTimeout is the default http.Client timeout. const defaultHTTPTimeout = 10 * time.Second -var httpClient = &http.Client{Timeout: defaultHTTPTimeout} - -func GetAPI() *API { - return &API{apiURL} +func NewClient(token string) *Client { + return &Client{ + token: token, + client: &http.Client{Timeout: defaultHTTPTimeout}, + baseURL: apiURL, + } } -func (a API) Call(method, path string) (int, string, error) { +func (c *Client) get(path string, r interface{}) (*impart.Envelope, error) { + method := "GET" if method != "GET" && method != "HEAD" { - return 0, "", errors.New(fmt.Sprintf("Method %s not currently supported by library (only HEAD and GET).\n", method)) + return nil, errors.New(fmt.Sprintf("Method %s not currently supported by library (only HEAD and GET).\n", method)) } - r, _ := http.NewRequest(method, fmt.Sprintf("%s%s", a.BaseURL, path), nil) - r.Header.Add("User-Agent", "writeas-go v1") + return c.request(method, path, nil, r) +} + +func (c *Client) post(path string, data io.Reader, r interface{}) (*impart.Envelope, error) { + return c.request("POST", path, data, r) +} - resp, err := httpClient.Do(r) +func (c *Client) request(method, path string, data io.Reader, result interface{}) (*impart.Envelope, error) { + url := fmt.Sprintf("%s%s", c.baseURL, path) + r, err := http.NewRequest(method, url, data) if err != nil { - return 0, "", err + return nil, fmt.Errorf("Create request: %v", err) + } + + c.prepareRequest(r) + resp, err := c.client.Do(r) + if err != nil { + return nil, fmt.Errorf("Request: %v", err) } defer resp.Body.Close() - content, err := ioutil.ReadAll(resp.Body) + env := &impart.Envelope{ + Code: resp.StatusCode, + } + if result != nil { + env.Data = result + } + + err = json.NewDecoder(resp.Body).Decode(&env) if err != nil { - return resp.StatusCode, "", err + return nil, err } - return resp.StatusCode, string(content), nil + return env, nil +} + +func (c *Client) prepareRequest(r *http.Request) { + r.Header.Add("User-Agent", "go-writeas v1") + r.Header.Add("Content-Type", "application/json") + if c.token != "" { + r.Header.Add("Authorization", "Token "+c.token) + } }