GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

devto.*ArticlesResource.listMyArticles   B
last analyzed

Complexity

Conditions 8

Size

Total Lines 37
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 8.8638

Importance

Changes 0
Metric Value
cc 8
eloc 26
nop 3
dl 0
loc 37
ccs 16
cts 21
cp 0.7619
crap 8.8638
rs 7.3333
c 0
b 0
f 0
1
package devto
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"fmt"
7
	"net/http"
8
	"strings"
9
10
	"github.com/google/go-querystring/query"
11
)
12
13
// ArticlesResource implements the APIResource interface
14
// for devto articles.
15
type ArticlesResource struct {
16
	API *Client
17
}
18
19
// List will return the articles uploaded to devto, the result
20
// can be narrowed down, filtered or enhanced using query
21
// parameters as specified on the documentation.
22
// See: https://docs.dev.to/api/#tag/articles/paths/~1articles/get
23
func (ar *ArticlesResource) List(ctx context.Context, opt ArticleListOptions) ([]ListedArticle, error) {
24 1
	q, err := query.Values(opt)
25 1
	if err != nil {
26
		return nil, err
27
	}
28 1
	req, err := ar.API.NewRequest(http.MethodGet, fmt.Sprintf("api/articles?%s", q.Encode()), nil)
29 1
	if err != nil {
30
		return nil, err
31
	}
32
33 1
	res, err := ar.API.HTTPClient.Do(req)
34 1
	if err != nil {
35
		return nil, err
36
	}
37 1
	defer res.Body.Close()
38
39 1
	if nonSuccessfulResponse(res) {
40
		return nil, unmarshalErrorResponse(res)
41
	}
42 1
	var articles []ListedArticle
43 1
	if err := json.NewDecoder(res.Body).Decode(&articles); err != nil {
44
		return nil, err
45
	}
46 1
	return articles, nil
47
}
48
49
// ListForTag is a convenience method for retrieving articles
50
// for a particular tag, calling the base List method.
51
func (ar *ArticlesResource) ListForTag(ctx context.Context, tag string, page int) ([]ListedArticle, error) {
52 1
	return ar.List(ctx, ArticleListOptions{Tags: tag, Page: page})
53
}
54
55
// ListForUser is a convenience method for retrieving articles
56
// written by a particular user, calling the base List method.
57
func (ar *ArticlesResource) ListForUser(ctx context.Context, username string, page int) ([]ListedArticle, error) {
58 1
	return ar.List(ctx, ArticleListOptions{Username: username, Page: page})
59
}
60
61
// ListMyPublishedArticles lists all published articles
62
// written by the user authenticated with this client,
63
// erroring if the caller is not authenticated. Articles in
64
// the response will be listed in reverse chronological order
65
// by their publication times.
66
//
67
// If opts is nil, then no query parameters will be sent; the
68
// page number will be 1 and the page size will be 30
69
// articles.
70
func (ar *ArticlesResource) ListMyPublishedArticles(ctx context.Context, opts *MyArticlesOptions) ([]ListedArticle, error) {
71 1
	return ar.listMyArticles(ctx, "api/articles/me/published", opts)
72
}
73
74
// ListMyUnpublishedArticles lists all unpublished articles
75
// written by the user authenticated with this client,
76
// erroring if the caller is not authenticated. Articles in
77
// the response will be listed in reverse chronological order
78
// by their creation times.
79
//
80
// If opts is nil, then no query parameters will be sent; the
81
// page number will be 1 and the page size will be 30
82
// articles.
83
func (ar *ArticlesResource) ListMyUnpublishedArticles(ctx context.Context, opts *MyArticlesOptions) ([]ListedArticle, error) {
84 1
	return ar.listMyArticles(ctx, "api/articles/me/unpublished", opts)
85
}
86
87
// ListAllMyArticles lists all articles written by the user
88
// authenticated with this client, erroring if the caller is
89
// not authenticated. Articles in the response will be listed
90
// in reverse chronological order by their creation times,
91
// with unpublished articles listed before published articles.
92
//
93
// If opts is nil, then no query parameters will be sent; the
94
// page number will be 1 and the page size will be 30
95
// articles.
96
func (ar *ArticlesResource) ListAllMyArticles(ctx context.Context, opts *MyArticlesOptions) ([]ListedArticle, error) {
97 1
	return ar.listMyArticles(ctx, "api/articles/me/all", opts)
98
}
99
100
// listMyArticles serves for handling roundtrips to the
101
// /api/articles/me/* endpoints, requesting articles from the
102
// endpoint passed in, and returning a list of articles.
103
func (ar *ArticlesResource) listMyArticles(
104
	ctx context.Context,
105
	endpoint string,
106
	opts *MyArticlesOptions,
107
) ([]ListedArticle, error) {
108 1
	if ar.API.Config.InsecureOnly {
109 1
		return nil, ErrProtectedEndpoint
110
	}
111
112 1
	req, err := ar.API.NewRequest(http.MethodGet, endpoint, nil)
113 1
	if err != nil {
114
		return nil, err
115
	}
116 1
	req.Header.Add(APIKeyHeader, ar.API.Config.APIKey)
117
118 1
	if opts != nil {
119 1
		q, err := query.Values(opts)
120 1
		if err != nil {
121
			return nil, err
122
		}
123 1
		req.URL.RawQuery = q.Encode()
124
	}
125
126 1
	res, err := ar.API.HTTPClient.Do(req)
127 1
	if err != nil {
128
		return nil, err
129
	}
130 1
	defer res.Body.Close()
131
132 1
	if nonSuccessfulResponse(res) {
133
		return nil, unmarshalErrorResponse(res)
134
	}
135 1
	var articles []ListedArticle
136 1
	if err := json.NewDecoder(res.Body).Decode(&articles); err != nil {
137
		return nil, err
138
	}
139 1
	return articles, nil
140
}
141
142
// Find will retrieve an Article matching the ID passed.
143
func (ar *ArticlesResource) Find(ctx context.Context, id uint32) (Article, error) {
144 1
	req, err := ar.API.NewRequest(http.MethodGet, fmt.Sprintf("api/articles/%d", id), nil)
145 1
	if err != nil {
146
		return Article{}, err
147
	}
148
149 1
	res, err := ar.API.HTTPClient.Do(req)
150 1
	if err != nil {
151
		return Article{}, err
152
	}
153 1
	defer res.Body.Close()
154
155 1
	if nonSuccessfulResponse(res) {
156 1
		return Article{}, unmarshalErrorResponse(res)
157
	}
158 1
	var art Article
159 1
	if err := json.NewDecoder(res.Body).Decode(&art); err != nil {
160
		return Article{}, err
161
	}
162 1
	return art, nil
163
}
164
165
// New will create a new article on dev.to
166
func (ar *ArticlesResource) New(ctx context.Context, u ArticleUpdate) (Article, error) {
167 1
	if ar.API.Config.InsecureOnly {
168 1
		return Article{}, ErrProtectedEndpoint
169
	}
170 1
	cont, err := json.Marshal(&u)
171 1
	if err != nil {
172
		return Article{}, err
173
	}
174 1
	req, err := ar.API.NewRequest(http.MethodPost, "api/articles", strings.NewReader(string(cont)))
175 1
	if err != nil {
176
		return Article{}, err
177
	}
178 1
	req.Header.Add(APIKeyHeader, ar.API.Config.APIKey)
179 1
	res, err := ar.API.HTTPClient.Do(req)
180 1
	if err != nil {
181
		return Article{}, err
182
	}
183 1
	defer res.Body.Close()
184
185 1
	if nonSuccessfulResponse(res) {
186 1
		return Article{}, unmarshalErrorResponse(res)
187
	}
188
189 1
	var a Article
190 1
	if err := json.NewDecoder(res.Body).Decode(&a); err != nil {
191
		return Article{}, err
192
	}
193 1
	return a, nil
194
}
195
196
// Update will mutate the resource by id, and all the changes
197
// performed to the Article will be applied, thus validation
198
// on the API side.
199
func (ar *ArticlesResource) Update(ctx context.Context, u ArticleUpdate, id uint32) (Article, error) {
200 1
	if ar.API.Config.InsecureOnly {
201 1
		return Article{}, ErrProtectedEndpoint
202
	}
203 1
	cont, err := json.Marshal(&u)
204 1
	if err != nil {
205
		return Article{}, err
206
	}
207 1
	req, err := ar.API.NewRequest(http.MethodPut, fmt.Sprintf("api/articles/%d", id), strings.NewReader(string(cont)))
208 1
	if err != nil {
209
		return Article{}, err
210
	}
211 1
	req.Header.Add(APIKeyHeader, ar.API.Config.APIKey)
212 1
	res, err := ar.API.HTTPClient.Do(req)
213 1
	if err != nil {
214
		return Article{}, err
215
	}
216 1
	defer res.Body.Close()
217
218 1
	if nonSuccessfulResponse(res) {
219 1
		return Article{}, unmarshalErrorResponse(res)
220
	}
221
222 1
	var a Article
223 1
	if err := json.NewDecoder(res.Body).Decode(&a); err != nil {
224
		return Article{}, err
225
	}
226 1
	return a, nil
227
}
228