// Package point imlements simple Point API wrapper for getting different info package point import ( "bitbucket.org/skobkin/dumb-http-go" "encoding/json" "errors" "log" "net/http" "net/url" "strconv" ) // Package errors var ( ErrHttpRequest = errors.New("point-api: HTTP request error") ErrJsonDeserialization = errors.New("point-api: JSON deserialization error") ErrNotAuthorized = errors.New("point-api: Not authorized") ErrAuthNeeded = errors.New("point-api: Authentication needed") ErrNoNextPage = errors.New("point-api: Page has next_page: false") ErrAuthorPrivacy = errors.New("point-api: Post author privacy error") ErrWebSocketPing = errors.New("point-api: WebSocket ping received instead of message") ) type PointClient struct { client simple_http.Client apiUrl string token Token } // New creates new Point.im API client instance and initialize it with provided URL func New(apiUrl string) PointClient { return PointClient{ simple_http.Client{http.Client{}}, apiUrl, Token{}, } } // Login tries to log in to Point.im API and store authentication token on success. Token will be used automatically on next API calls. func (c *PointClient) Login(login, password string) (Token, error) { var token Token data := url.Values{} data.Set("login", login) data.Set("password", password) body, reqErr := c.client.MakePostRequest(c.apiUrl+"login", data, nil) if reqErr != nil { return token, reqErr } jsonErr := json.Unmarshal(body, &token) if jsonErr != nil { log.Println(jsonErr) return token, ErrJsonDeserialization } if token.Error != "" { return token, errors.New(token.Error) } c.token = token return token, nil } // GetPostWithComments gets post with provided id and comments in it func (c *PointClient) GetPostWithComments(id string) (PostShowResponse, error) { var response PostShowResponse headers := map[string]string{} if 0 != len(c.token.AuthToken) { headers["Authorization"] = c.token.AuthToken } body, reqErr := c.client.MakeGetRequest(c.apiUrl+"post/"+id, nil, &headers) if reqErr != nil { return response, ErrHttpRequest } jsonErr := json.Unmarshal(body, &response) if jsonErr != nil { log.Println(jsonErr) return response, ErrJsonDeserialization } switch response.Error { case "NotAuthorized": log.Println("Please use correct login and password to fetch this post") return response, ErrNotAuthorized case "PostAuthorError": log.Println("Post author profile is private") return response, ErrAuthorPrivacy } return response, nil } // GetRecentAllPostsPage gets most recent /all posts page func (c *PointClient) GetRecentAllPostsPage() (Page, error) { var page Page if 0 != len(c.token.AuthToken) { log.Println("Can not get recent posts. Login first.") return page, ErrAuthNeeded } headers := map[string]string{ "Authorization": c.token.AuthToken, } body, reqErr := c.client.MakeGetRequest(c.apiUrl+"all", nil, &headers) if reqErr != nil { return page, ErrHttpRequest } jsonErr := json.Unmarshal(body, &page) if jsonErr != nil { log.Println(jsonErr) return page, ErrJsonDeserialization } // Move page.Error to response object if page.Error == "NotAuthorized" { log.Println("Please use correct login and password to fetch recent posts") return page, ErrNotAuthorized } return page, nil } // GetNextAllPostsPageBeforeUid gets next /all page after provided post uid func (c *PointClient) GetNextAllPostsPageBeforeUid(uid int) (Page, error) { var nextPage Page if len(c.token.AuthToken) == 0 { log.Println("Can not get recent posts. Login first.") return nextPage, ErrAuthNeeded } data := url.Values{} data.Set("before", strconv.Itoa(uid)) headers := map[string]string{ "Authorization": c.token.AuthToken, } body, req_err := c.client.MakeGetRequest(c.apiUrl+"all", &data, &headers) if req_err != nil { return nextPage, ErrHttpRequest } json_err := json.Unmarshal(body, &nextPage) if json_err != nil { log.Println(json_err) return nextPage, ErrJsonDeserialization } // Move page.Error to response object if nextPage.Error == "NotAuthorized" { log.Println("Please use correct login and password to fetch recent posts") return nextPage, ErrNotAuthorized } return nextPage, nil } // GetNextAllPostsPage gets next /all page after provided page func (c *PointClient) GetNextAllPostsPage(page Page) (Page, error) { var nextPage Page if len(page.Posts) == 0 { return nextPage, ErrNoNextPage } if len(c.token.AuthToken) == 0 { log.Println("Can not get recent posts. Login first.") return nextPage, ErrAuthNeeded } nextPage, err := c.GetNextAllPostsPageBeforeUid(page.Posts[len(page.Posts)-1].Uid) return nextPage, err }