Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring newsapi v2 #4

Merged
merged 6 commits into from
Oct 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import (
func main() {
c := newsapi.NewClient("<API KEY>", newsapi.WithHTTPClient(http.DefaultClient))

sources, _, err := c.GetSources(context.Background(), &newsapi.SourceParameters{
sources, err := c.GetSources(context.Background(), &newsapi.SourceParameters{
Country: "gb",
})

Expand Down Expand Up @@ -95,7 +95,7 @@ import (
func main() {
c := newsapi.NewClient("<API KEY>", newsapi.WithHTTPClient(http.DefaultClient))

articles, _, err := c.GetTopHeadlines(context.Background(), &newsapi.ArticleParameters{
articles, err := c.GetTopHeadlines(context.Background(), &newsapi.TopHeadlineParameters{
Sources: []string{ "cnn", "time" },
})

Expand Down Expand Up @@ -125,7 +125,7 @@ import (
func main() {
c := newsapi.NewClient("<API KEY>", newsapi.WithHTTPClient(http.DefaultClient))

articles, _, err := c.GetEverything(context.Background(), &newsapi.ArticleParameters{
articles, err := c.GetEverything(context.Background(), &newsapi.EverythingParameters{
Sources: []string{ "cnn", "time" },
})

Expand Down
75 changes: 44 additions & 31 deletions article.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@ package newsapi
import (
"context"
"errors"
"fmt"
"net/http"
"time"
)

// ArticleParameters are the parameters used for the newsapi article endpoint
// Source must always contain a value
// See http://beta.newsapi.org/docs for more information on the required parameters
type ArticleParameters struct {
Sources []string `url:"sources,omitempty,comma"`
Domains []string `url:"domains,omitempty,comma"`
// TopHeadlineParameters are the parameters which can be used to tweak to request for the top headlines.
type TopHeadlineParameters struct {
Country string `url:"country,omitempty"`
Category string `url:"category,omitempty"`
Sources []string `url:"sources,omitempty,comma"`
Keywords string `url:"q,omitempty"`
Page int `url:"page,omitempty"`
PageSize int `url:"pageSize,omitempty"`
}

// EverythingParameters are the parameters used for the newsapi everything endpoint.
type EverythingParameters struct {
Keywords string `url:"q,omitempty"`
Sources []string `url:"sources,omitempty,comma"`
Domains []string `url:"domains,omitempty,comma"`
ExcludeDomains []string `url:"excludeDomains,omitempty"`

From time.Time `url:"from,omitempty"`
To time.Time `url:"to,omitempty"`

Keywords string `url:"q,omitempty"`
Category string `url:"category,omitempty"`
Language string `url:"language,omitempty"`
SortBy string `url:"sortBy,omitempty"`
Page int `url:"page,omitempty"`

Page int `url:"page,omitempty"`
PageSize int `url:"pageSize,omitempty"`
}

// Article is a single article from the newsapi article response
Expand All @@ -32,66 +43,68 @@ type Article struct {
URL string `json:"url"`
URLToImage string `json:"urlToImage"`
PublishedAt time.Time `json:"publishedAt"`
Content string `json:"content"`
}

// ArticleResponse is the response from the newsapi article endpoint
// Code and Message property will be filled when an error happened
// See http://beta.newsapi.org/docs for more details on the property's
// ArticleResponse is the response from the newsapi article endpoint.
// Code and Message property will be filled when an error happened.
// See http://beta.newsapi.org/docs for more details on the property's.
type ArticleResponse struct {
Status string `json:"status"`
TotalResults int `json:"totalResults"`
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
Articles []Article `json:"articles"`
}

// GetTopHeadlines returns the articles from newsapi
// See http://beta.newsapi.org/docs for more information
// See http://newsapi.org/docs for more information
// It will return the error from newsapi if there is an error
func (c *Client) GetTopHeadlines(ctx context.Context, params *ArticleParameters) (*ArticleResponse, *http.Response, error) {
func (c *Client) GetTopHeadlines(ctx context.Context, params *TopHeadlineParameters) (*ArticleResponse, error) {
return c.getArticles(ctx, "top-headlines", params)
}

// GetEverything returns the articles from newsapi
// See http://beta.newsapi.org/docs for more information
// See http://newsapi.org/docs for more information
// It will return the error from newsapi if there is an error
func (c *Client) GetEverything(ctx context.Context, params *ArticleParameters) (*ArticleResponse, *http.Response, error) {
func (c *Client) GetEverything(ctx context.Context, params *EverythingParameters) (*ArticleResponse, error) {
return c.getArticles(ctx, "everything", params)
}

// GetArticles returns the articles from newsapi
// See http://beta.newsapi.org/docs for more information
// See http://newsapi.org/docs for more information
// It will return the error from newsapi if there is an error
func (c *Client) getArticles(ctx context.Context, u string, params *ArticleParameters) (*ArticleResponse, *http.Response, error) {
func (c *Client) getArticles(ctx context.Context, u string, params interface{}) (*ArticleResponse, error) {
if params == nil {
return nil, nil, errors.New("empty parameters not possible when asking for articles")
return nil, errors.New("empty parameters not possible when asking for articles")
}

if params != nil {
var err error
u, err = setOptions(u, params)

if err != nil {
return nil, nil, err
return nil, err
}
}

req, err := c.newGetRequest(u)
if err != nil {
return nil, nil, err
return nil, err
}

var response *ArticleResponse
var response = struct {
*Error
*ArticleResponse
}{}

resp, err := c.do(ctx, req, &response)
_, err = c.do(ctx, req, &response)

if err != nil {
return nil, nil, err
return nil, err
}

if response.Code != "" {
return nil, nil, fmt.Errorf("[%s] %s", response.Code, response.Message)
if response.Error != nil {
return nil, response.Error
}

return response, resp, nil
return response.ArticleResponse, nil
}
19 changes: 19 additions & 0 deletions error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package newsapi

import "fmt"

// Error defines an API error from newsapi.
type Error struct {
Code string `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}

func (e Error) Error() string {
return fmt.Sprintf("[%s] %s", e.Code, e.Message)
}

// APIError returns if the given err is of type `newsapi.Error`.
func APIError(err error) bool {
_, ok := err.(*Error)
return ok
}
23 changes: 14 additions & 9 deletions sources.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package newsapi

import (
"context"
"net/http"
)

// SourceParameters are the parameters which can be used in the source request to newsapi
Expand Down Expand Up @@ -35,30 +34,36 @@ type SourceResponse struct {
}

// GetSources returns the sources from newsapi see http://beta.newsapi.org/docs for more information on the parameters
func (c *Client) GetSources(ctx context.Context, params *SourceParameters) (*SourceResponse, *http.Response, error) {
func (c *Client) GetSources(ctx context.Context, params *SourceParameters) (*SourceResponse, error) {
u := "sources"

if params != nil {
var err error
u, err = setOptions(u, params)

if err != nil {
return nil, nil, err
return nil, err
}
}

req, err := c.newGetRequest(u)
if err != nil {
return nil, nil, err
return nil, err
}

var response *SourceResponse

resp, err := c.do(ctx, req, &response)
var response = struct {
*Error
*SourceResponse
}{}

_, err = c.do(ctx, req, &response)
if err != nil {
return nil, nil, err
return nil, err
}

if response.Error != nil {
return nil, response.Error
}

return response, resp, nil
return response.SourceResponse, nil
}