Skip to content

Commit 5f7580c

Browse files
committed
refactored code & corrected readme files
1 parent 375d884 commit 5f7580c

File tree

7 files changed

+83
-105
lines changed

7 files changed

+83
-105
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GetPocket API Golang SDK
22

3-
[![Release](https://img.shields.io/badge/release-v1.0.2-blue)](https://github.com/Lapp-coder/go-pocket-sdk/releases)
3+
[![Release](https://img.shields.io/badge/release-v1.0.3-blue)](https://github.com/Lapp-coder/go-pocket-sdk/releases)
44

55
### The basis of the package was made on code from [this](https://github.com/zhashkevych/go-pocket-sdk) repository.
66

@@ -62,12 +62,12 @@ func main() {
6262
Favorite: "0",
6363
})
6464

65-
for _, v := range items {
65+
for _, item := range items {
6666
// Modifying all found user elements
6767
actions := []pocket.Action{
68-
{Name: pocket.Favorite, ItemId: v.ItemId, Time: time.Now().Unix()},
69-
{Name: pocket.Archive, ItemId: v.ItemId, Time: time.Now().Unix()},
70-
{Name: pocket.TagsAdd, ItemId: v.ItemId, Tags: "github.com, github, system-version-control"},
68+
{Name: pocket.Favorite, ItemId: item.Id, Time: time.Now().Unix()},
69+
{Name: pocket.Archive, ItemId: item.Id, Time: time.Now().Unix()},
70+
{Name: pocket.TagsAdd, ItemId: item.Id, Tags: "github.com, github, system-version-control"},
7171
}
7272

7373
_ = client.Modify(ctx, pocket.ModifyInput{

README_RU.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GetPocket API Golang SDK
22

3-
[![Release](https://img.shields.io/badge/release-v1.0.2-blue)](https://github.com/Lapp-coder/go-pocket-sdk/releases)
3+
[![Release](https://img.shields.io/badge/release-v1.0.3-blue)](https://github.com/Lapp-coder/go-pocket-sdk/releases)
44

55
### Основа пакета была сделана на коде из [этого](https://github.com/zhashkevych/go-pocket-sdk) репозитория.
66

@@ -61,12 +61,12 @@ func main() {
6161
Favorite: "0",
6262
})
6363

64-
for _, v := range items {
64+
for _, item := range items {
6565
// Модифицирование всех найденных элементов пользователя
6666
actions := []pocket.Action{
67-
{Name: pocket.Favorite, ItemId: v.ItemId, Time: time.Now().Unix()},
68-
{Name: pocket.Archive, ItemId: v.ItemId, Time: time.Now().Unix()},
69-
{Name: pocket.TagsAdd, ItemId: v.ItemId, Tags: "github.com, github, system-version-control"},
67+
{Name: pocket.Favorite, ItemId: item.Id, Time: time.Now().Unix()},
68+
{Name: pocket.Archive, ItemId: item.Id, Time: time.Now().Unix()},
69+
{Name: pocket.TagsAdd, ItemId: item.Id, Tags: "github.com, github, system-version-control"},
7070
}
7171

7272
_ = client.Modify(ctx, pocket.ModifyInput{

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ go 1.16
44

55
require (
66
github.com/stretchr/testify v1.7.0
7-
github.com/valyala/fastjson v1.6.3
7+
github.com/tidwall/gjson v1.8.1
88
)

go.sum

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
33
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
44
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5-
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
65
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
76
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
87
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
9-
github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc=
10-
github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
8+
github.com/tidwall/gjson v1.8.1 h1:8j5EE9Hrh3l9Od1OIEDAb7IpezNA20UdRngNAj5N0WU=
9+
github.com/tidwall/gjson v1.8.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
10+
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
11+
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
12+
github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8=
13+
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
14+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
1115
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
1216
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
1317
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

pocket.go

Lines changed: 43 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7-
"errors"
87
"fmt"
8+
"github.com/tidwall/gjson"
99
"io/ioutil"
1010
"net/http"
11-
"strings"
1211
"time"
13-
14-
"github.com/valyala/fastjson"
1512
)
1613

1714
const (
@@ -27,7 +24,7 @@ const (
2724
xErrorHeader = "X-Error"
2825
xErrorCodeHeader = "X-Error-Code"
2926

30-
defaultTimeout = time.Second * 5
27+
defaultTimeout = time.Second * 10
3128
)
3229

3330
// Client is a getpocket API client
@@ -39,7 +36,7 @@ type Client struct {
3936
// NewClient creates a new client with your application key (to generate a key, create your application here: https://getpocket.com/developer/apps)
4037
func NewClient(consumerKey string) (*Client, error) {
4138
if consumerKey == "" {
42-
return nil, errors.New("empty consumer key")
39+
return nil, fmt.Errorf("empty consumer key")
4340
}
4441

4542
return &Client{
@@ -79,56 +76,63 @@ func (c *Client) Retrieving(ctx context.Context, input RetrievingInput) ([]Item,
7976
return nil, err
8077
}
8178

82-
values, err := c.doHTTP(ctx, endpointRetrieving, req)
79+
result, err := c.doHTTP(ctx, endpointRetrieving, req)
8380
if err != nil {
8481
return nil, err
8582
}
8683

87-
if values.GetObject("list") == nil {
88-
return nil, nil
89-
}
84+
return c.getItems(result), nil
85+
}
9086

91-
return c.parseItems(values), nil
87+
func (c *Client) getItems(result gjson.Result) []Item {
88+
var items []Item
89+
for itemId := range result.Get("list").Map() {
90+
item := newItem(itemId)
91+
item.fillFields(result)
92+
items = append(items, item)
93+
}
94+
return items
9295
}
9396

9497
// Authorize returns the Authorization structure with the access token, user name and state obtained from the authorization request
9598
func (c *Client) Authorize(ctx context.Context, requestToken string) (Authorization, error) {
9699
if requestToken == "" {
97-
return Authorization{}, errors.New("empty request token")
100+
return Authorization{}, fmt.Errorf("empty request token")
98101
}
99102

100103
body := requestAuthorization{
101104
ConsumerKey: c.consumerKey,
102105
Code: requestToken,
103106
}
104107

105-
values, err := c.doHTTP(ctx, endpointRequestAuthorize, body)
108+
result, err := c.doHTTP(ctx, endpointRequestAuthorize, body)
106109
if err != nil {
107110
return Authorization{}, err
108111
}
109112

110-
accessToken := values.GetStringBytes("access_token")
111-
username := values.GetStringBytes("username")
112-
state := values.GetStringBytes("state")
113-
if string(accessToken) == "" {
114-
return Authorization{}, errors.New("empty access token in API response")
113+
accessToken := result.Get("access_token").String()
114+
username := result.Get("username").String()
115+
state := result.Get("state").String()
116+
117+
if accessToken == "" {
118+
return Authorization{}, fmt.Errorf("empty access token in API response")
115119
}
116120

117121
return Authorization{
118-
AccessToken: string(accessToken),
119-
Username: string(username),
120-
State: string(state),
122+
AccessToken: accessToken,
123+
Username: username,
124+
State: state,
121125
}, nil
122126
}
123127

124128
// GetAuthorizationURL returns the url string that is used to grant the user access rights to his Pocket account in your application
125129
func (c *Client) GetAuthorizationURL(requestToken, redirectURL string) (string, error) {
126130
if requestToken == "" {
127-
return "", errors.New("empty request token")
131+
return "", fmt.Errorf("empty request token")
128132
}
129133

130134
if redirectURL == "" {
131-
return "", errors.New("empty redirection URL")
135+
return "", fmt.Errorf("empty redirection URL")
132136
}
133137

134138
return fmt.Sprintf(authorizeUrl, requestToken, redirectURL), nil
@@ -139,7 +143,7 @@ func (c *Client) GetAuthorizationURL(requestToken, redirectURL string) (string,
139143
// State - metadata string that will be returned at each subsequent authentication response (if you don't need it, specify an empty string).
140144
func (c *Client) GetRequestToken(ctx context.Context, redirectURL string, state string) (string, error) {
141145
if redirectURL == "" {
142-
return "", errors.New("empty redirect URL")
146+
return "", fmt.Errorf("empty redirect URL")
143147
}
144148

145149
body := requestToken{
@@ -148,84 +152,52 @@ func (c *Client) GetRequestToken(ctx context.Context, redirectURL string, state
148152
State: state,
149153
}
150154

151-
values, err := c.doHTTP(ctx, endpointRequestToken, body)
155+
result, err := c.doHTTP(ctx, endpointRequestToken, body)
152156
if err != nil {
153157
return "", err
154158
}
155159

156-
token := values.GetStringBytes("code")
157-
if string(token) == "" {
158-
return "", errors.New("empty request token in API response")
159-
}
160-
161-
return string(token), nil
162-
}
163-
164-
func (c *Client) parseItems(values *fastjson.Value) []Item {
165-
const indexForItemId int = 13
166-
167-
var (
168-
items []Item
169-
itemId string
170-
index int
171-
)
172-
173-
newJsonStr := values.GetObject("list").String()
174-
for index != -1 {
175-
index = strings.Index(newJsonStr, ":{\"item_id\":\"")
176-
if index != -1 {
177-
for i := index + indexForItemId; string(newJsonStr[i]) != "\""; i++ {
178-
itemId += string(newJsonStr[i])
179-
}
180-
181-
items = append(items, createItem(itemId, values))
182-
183-
itemId = ""
184-
oldJsonStr := newJsonStr
185-
newJsonStr = ``
186-
187-
for i := index + indexForItemId; i != len(oldJsonStr); i++ {
188-
newJsonStr += string(oldJsonStr[i])
189-
}
190-
}
160+
token := result.Get("code").String()
161+
if token == "" {
162+
return "", fmt.Errorf("empty request token in API response")
191163
}
192164

193-
return items
165+
return token, nil
194166
}
195167

196-
func (c *Client) doHTTP(ctx context.Context, endpoint string, body interface{}) (*fastjson.Value, error) {
168+
func (c *Client) doHTTP(ctx context.Context, endpoint string, body interface{}) (gjson.Result, error) {
197169
b, err := json.Marshal(body)
198170
if err != nil {
199-
return nil, fmt.Errorf("an error occurred when marshal the input body: %s", err.Error())
171+
return gjson.Result{}, fmt.Errorf("an error occurred when marshal the input body: %s", err.Error())
200172
}
201173

202174
req, err := http.NewRequestWithContext(ctx, "POST", host+endpoint, bytes.NewBufferString(string(b)))
203175
if err != nil {
204-
return nil, fmt.Errorf("an error occurred when creating the query: %s", err.Error())
176+
return gjson.Result{}, fmt.Errorf("an error occurred when creating the query: %s", err.Error())
205177
}
206178

207179
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
208180
req.Header.Set("X-Accept", "application/json")
209181

210182
resp, err := c.client.Do(req)
211183
if err != nil {
212-
return nil, fmt.Errorf("an error occurred when sending a request to the Pocket server: %s", err.Error())
184+
return gjson.Result{}, fmt.Errorf("an error occurred when sending a request to the Pocket server: %s", err.Error())
213185
}
214186
defer resp.Body.Close()
215187

216188
if resp.StatusCode != http.StatusOK {
217-
return nil, fmt.Errorf("API error %s: %s", resp.Header.Get(xErrorCodeHeader), resp.Header.Get(xErrorHeader))
189+
return gjson.Result{}, fmt.Errorf("API error %s: %s", resp.Header.Get(xErrorCodeHeader), resp.Header.Get(xErrorHeader))
218190
}
219191

220192
respBody, err := ioutil.ReadAll(resp.Body)
221193
if err != nil {
222-
return nil, fmt.Errorf("an error occurred when reading the request body: %s", err.Error())
194+
return gjson.Result{}, fmt.Errorf("an error occurred when reading the request body: %s", err.Error())
223195
}
224196

225-
values, err := fastjson.Parse(string(respBody))
226-
if err != nil {
227-
return nil, fmt.Errorf("an error occurred while parsing the response body: %s", err.Error())
197+
result := gjson.Parse(string(respBody))
198+
if result.String() == "" {
199+
return gjson.Result{}, fmt.Errorf("failed to parse response body")
228200
}
229201

230-
return values, nil
202+
return result, nil
231203
}

pocket_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func TestClient_Add(t *testing.T) {
8080
wantErr: false,
8181
},
8282
{
83-
name: "OK_WithoutTagsAndTweeId",
83+
name: "OK_WithoutTagsAndTweetId",
8484
input: args{
8585
ctx: context.Background(),
8686
addInput: AddInput{
@@ -291,7 +291,7 @@ func TestClient_Retrieving(t *testing.T) {
291291
expectedResponseBody: `{"status":1,"list":{"229279689":{"item_id":"229279689","resolved_id":"229279689","given_url":"http:\/\/www.grantland.com\/blog\/the-triangle\/post\/_\/id\/38347\/ryder-cup-preview","given_title":"The Massive Ryder Cup Preview - The Triangle Blog - Grantland","favorite":"0","status":"0","resolved_title":"The Massive Ryder Cup Preview","resolved_url":"http:\/\/www.grantland.com\/blog\/the-triangle\/post\/_\/id\/38347\/ryder-cup-preview","excerpt":"The list of things I love about the Ryder Cup is so long that it could fill a (tedious) novel, and golf fans can probably guess most of them.","is_article":"1","has_video":"1","has_image":"1","word_count":"3197"}}}`,
292292
expectedItems: []Item{
293293
{
294-
ItemId: "229279689",
294+
Id: "229279689",
295295
ResolvedId: "229279689",
296296
GivenUrl: `http://www.grantland.com/blog/the-triangle/post/_/id/38347/ryder-cup-preview`,
297297
GivenTitle: `The Massive Ryder Cup Preview - The Triangle Blog - Grantland`,

response.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package go_pocket_sdk
22

33
import (
4-
"github.com/valyala/fastjson"
4+
"fmt"
5+
"github.com/tidwall/gjson"
56
)
67

78
type Authorization struct {
@@ -11,7 +12,7 @@ type Authorization struct {
1112
}
1213

1314
type Item struct {
14-
ItemId string
15+
Id string
1516
ResolvedId string
1617
GivenUrl string
1718
ResolvedUrl string
@@ -26,20 +27,21 @@ type Item struct {
2627
WordCount string
2728
}
2829

29-
func createItem(itemId string, values *fastjson.Value) Item {
30-
return Item{
31-
ItemId: itemId,
32-
ResolvedId: string(values.GetStringBytes("list", itemId, "resolved_id")),
33-
GivenUrl: string(values.GetStringBytes("list", itemId, "given_url")),
34-
ResolvedUrl: string(values.GetStringBytes("list", itemId, "resolved_url")),
35-
GivenTitle: string(values.GetStringBytes("list", itemId, "given_title")),
36-
ResolvedTitle: string(values.GetStringBytes("list", itemId, "resolved_title")),
37-
Favorite: string(values.GetStringBytes("list", itemId, "favorite")),
38-
Status: string(values.GetStringBytes("list", itemId, "status")),
39-
Excerpt: string(values.GetStringBytes("list", itemId, "excerpt")),
40-
IsArticle: string(values.GetStringBytes("list", itemId, "is_article")),
41-
HasImage: string(values.GetStringBytes("list", itemId, "has_image")),
42-
HasVideo: string(values.GetStringBytes("list", itemId, "has_video")),
43-
WordCount: string(values.GetStringBytes("list", itemId, "word_count")),
44-
}
30+
func newItem(itemId string) Item {
31+
return Item{Id: itemId}
32+
}
33+
34+
func (i *Item) fillFields(result gjson.Result) {
35+
i.ResolvedId = result.Get(fmt.Sprintf("list.%s.resolved_id", i.Id)).String()
36+
i.GivenUrl = result.Get(fmt.Sprintf("list.%s.given_url", i.Id)).String()
37+
i.ResolvedUrl = result.Get(fmt.Sprintf("list.%s.resolved_url", i.Id)).String()
38+
i.GivenTitle = result.Get(fmt.Sprintf("list.%s.given_title", i.Id)).String()
39+
i.ResolvedTitle = result.Get(fmt.Sprintf("list.%s.resolved_title", i.Id)).String()
40+
i.Favorite = result.Get(fmt.Sprintf("list.%s.favorite", i.Id)).String()
41+
i.Status = result.Get(fmt.Sprintf("list.%s.status", i.Id)).String()
42+
i.Excerpt = result.Get(fmt.Sprintf("list.%s.excerpt", i.Id)).String()
43+
i.IsArticle = result.Get(fmt.Sprintf("list.%s.is_article", i.Id)).String()
44+
i.HasImage = result.Get(fmt.Sprintf("list.%s.has_image", i.Id)).String()
45+
i.HasVideo = result.Get(fmt.Sprintf("list.%s.has_video", i.Id)).String()
46+
i.WordCount = result.Get(fmt.Sprintf("list.%s.word_count", i.Id)).String()
4547
}

0 commit comments

Comments
 (0)