Skip to content

Commit e32fab2

Browse files
committed
Add examples, housekeeping
1 parent 19bd0c7 commit e32fab2

File tree

10 files changed

+124
-66
lines changed

10 files changed

+124
-66
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ if err != nil {
4040
}
4141
```
4242

43+
## Complete example programs
44+
45+
You can see complete example programs which retrive coordinates and postal codes in the [examples](examples/) folder.
46+
47+
- postal codes lookup example: [examples/postal](examples/postal/main.go)
48+
- coordinates lookup example: [examples/wikipedia](examples/wikipedia/main.go)
4349

4450

4551
## Bugs and feature request

examples/postal/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module example-postal
2+
3+
go 1.19
4+
5+
require github.com/qba73/geonames v0.0.2

examples/postal/go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
2+
github.com/qba73/geonames v0.0.2 h1:MWYZ+YbG5uEdzFyG0ZMo0xLBU0jCQT/P2635Q2S598s=
3+
github.com/qba73/geonames v0.0.2/go.mod h1:2YIjYC03dZXrYz8D2OZCMRwGLKn/6qaSEJ0yPShv6E4=

examples/postal/main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/qba73/geonames"
8+
)
9+
10+
func main() {
11+
// We exported valid "GEONAMES_USER" env var
12+
geo, err := geonames.NewClient()
13+
if err != nil {
14+
panic(err)
15+
}
16+
17+
codes, err := geo.GetPostCode("Fort William", "UK")
18+
if err != nil {
19+
log.Fatal(err)
20+
}
21+
22+
for _, c := range codes {
23+
fmt.Printf("%+v\n", c)
24+
}
25+
}

examples/wikipedia/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module example-wikipedia
2+
3+
go 1.19
4+
5+
require github.com/qba73/geonames v0.0.2

examples/wikipedia/go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
2+
github.com/qba73/geonames v0.0.2 h1:MWYZ+YbG5uEdzFyG0ZMo0xLBU0jCQT/P2635Q2S598s=
3+
github.com/qba73/geonames v0.0.2/go.mod h1:2YIjYC03dZXrYz8D2OZCMRwGLKn/6qaSEJ0yPShv6E4=

examples/wikipedia/main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/qba73/geonames"
8+
)
9+
10+
func main() {
11+
// We exported valid "GEONAMES_USER" env var
12+
geo, err := geonames.NewClient()
13+
if err != nil {
14+
panic(err)
15+
}
16+
17+
codes, err := geo.GetPostCode("Fort William", "UK")
18+
if err != nil {
19+
log.Fatal(err)
20+
}
21+
22+
for _, c := range codes {
23+
fmt.Printf("%+v\n", c)
24+
}
25+
}

geonames.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package geonames
22

33
import (
4+
"context"
5+
"encoding/json"
46
"errors"
57
"fmt"
8+
"io"
69
"net/http"
7-
"net/url"
810
"os"
911
"time"
1012
)
@@ -91,24 +93,33 @@ func NewClient(options ...option) (*Client, error) {
9193
return &c, nil
9294
}
9395

94-
// makeURL knows how to create encoded URL with provided query parameters.
95-
func makeURL(base string, params url.Values) (string, error) {
96-
b, err := url.Parse(base)
96+
func (c Client) get(url string, data interface{}) error {
97+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
98+
defer cancel()
99+
100+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
97101
if err != nil {
98-
return "", fmt.Errorf("parsing base url, %w", err)
102+
return fmt.Errorf("creating request: %w", err)
99103
}
100-
b.RawQuery = params.Encode()
101-
return b.String(), nil
102-
}
104+
res, err := c.httpClient.Do(req)
105+
if err != nil {
106+
return fmt.Errorf("sending GET request: %w", err)
107+
}
108+
defer res.Body.Close()
103109

104-
// prepareGETRequest takes URL string and prepares HTTP Get request.
105-
func (c Client) prepareGETRequest(u string) (*http.Request, error) {
106-
req, err := http.NewRequest(http.MethodGet, u, nil)
110+
if res.StatusCode != http.StatusOK {
111+
return fmt.Errorf("got response code: %v", res.StatusCode)
112+
}
113+
114+
body, err := io.ReadAll(res.Body)
107115
if err != nil {
108-
return nil, err
116+
return fmt.Errorf("reading response body: %w", err)
117+
}
118+
119+
if err := json.Unmarshal(body, data); err != nil {
120+
return fmt.Errorf("unmarshaling response body: %w", err)
109121
}
110-
req.Header = c.headers
111-
return req, nil
122+
return nil
112123
}
113124

114125
type Position struct {

postal.go

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package geonames
22

33
import (
4-
"encoding/json"
54
"fmt"
6-
"io"
75
"net/url"
86
)
97

@@ -31,29 +29,13 @@ type PostalCode struct {
3129

3230
// Get knows how to retrieve postal codes for the given place name and country code.
3331
func (c Client) GetPostCode(place, country string) ([]PostalCode, error) {
34-
u, err := c.makePostalURL(place, country)
32+
url, err := c.buildPostalURL(place, country)
3533
if err != nil {
3634
return nil, err
3735
}
38-
39-
req, err := c.prepareGETRequest(u)
40-
if err != nil {
41-
return nil, err
42-
}
43-
44-
res, err := c.httpClient.Do(req)
45-
if err != nil {
46-
return nil, err
47-
}
48-
defer res.Body.Close()
49-
5036
var pr postalResponse
51-
data, err := io.ReadAll(res.Body)
52-
if err != nil {
53-
return nil, fmt.Errorf("reading response body %w", err)
54-
}
55-
if err := json.Unmarshal(data, &pr); err != nil {
56-
return nil, fmt.Errorf("unmarshalling data, %w", err)
37+
if err := c.get(url, &pr); err != nil {
38+
return nil, err
5739
}
5840

5941
var postalCodes []PostalCode
@@ -74,12 +56,18 @@ func (c Client) GetPostCode(place, country string) ([]PostalCode, error) {
7456
return postalCodes, nil
7557
}
7658

77-
func (c Client) makePostalURL(placeName, countryCode string) (string, error) {
78-
prms := url.Values{
59+
func (c Client) buildPostalURL(placeName, countryCode string) (string, error) {
60+
params := url.Values{
7961
"placename": {placeName},
8062
"country": {countryCode},
8163
"username": {c.userName},
8264
}
83-
basePostal := fmt.Sprintf("%s/%s", c.baseURL, "postalCodeSearchJSON")
84-
return makeURL(basePostal, prms)
65+
basePostal := fmt.Sprintf("%s/postalCodeSearchJSON", c.baseURL)
66+
67+
u, err := url.Parse(basePostal)
68+
if err != nil {
69+
return "", fmt.Errorf("parsing base url for postal, %w", err)
70+
}
71+
u.RawQuery = params.Encode()
72+
return u.String(), nil
8573
}

wikipedia.go

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package geonames
22

33
import (
4-
"encoding/json"
54
"fmt"
6-
"io"
75
"net/url"
86
"strconv"
97
)
@@ -39,33 +37,20 @@ type Geoname struct {
3937

4038
// GetPlace retrives geo coordinates for given place name and country code.
4139
func (c Client) GetPlace(name, country string, maxResults int) ([]Geoname, error) {
42-
u, err := c.makeWikiURL(name, country, maxResults)
43-
if err != nil {
44-
return nil, err
45-
}
46-
req, err := c.prepareGETRequest(u)
47-
if err != nil {
48-
return nil, err
40+
if maxResults < 1 {
41+
return nil, fmt.Errorf("invalid max results: %d", maxResults)
4942
}
50-
51-
res, err := c.httpClient.Do(req)
43+
url, err := c.buildWikiURL(name, country, maxResults)
5244
if err != nil {
5345
return nil, err
5446
}
55-
defer res.Body.Close()
56-
57-
data, err := io.ReadAll(res.Body)
58-
if err != nil {
59-
return nil, fmt.Errorf("reading response body %w", err)
60-
}
6147

6248
var wr wikipediaResponse
63-
if err := json.Unmarshal(data, &wr); err != nil {
64-
return nil, fmt.Errorf("unmarshalling data, %w", err)
49+
if err := c.get(url, &wr); err != nil {
50+
return nil, err
6551
}
6652

6753
var geonames []Geoname
68-
6954
for _, g := range wr.Geonames {
7055
geoname := Geoname{
7156
Summary: g.Summary,
@@ -87,17 +72,19 @@ func (c Client) GetPlace(name, country string, maxResults int) ([]Geoname, error
8772
return geonames, nil
8873
}
8974

90-
func (c Client) makeWikiURL(place, country string, maxResults int) (string, error) {
91-
if maxResults < 1 {
92-
return "", fmt.Errorf("incorrect results limit: %q", maxResults)
93-
}
94-
prms := url.Values{
75+
func (c Client) buildWikiURL(place, country string, maxResults int) (string, error) {
76+
params := url.Values{
9577
"q": []string{place},
9678
"title": []string{place},
9779
"countryCode": []string{country},
9880
"maxRows": []string{strconv.Itoa(maxResults)},
9981
"username": []string{c.userName},
10082
}
101-
base := fmt.Sprintf("%s/%s", c.baseURL, "wikipediaSearchJSON")
102-
return makeURL(base, prms)
83+
baseWiki := fmt.Sprintf("%s/wikipediaSearchJSON", c.baseURL)
84+
u, err := url.Parse(baseWiki)
85+
if err != nil {
86+
return "", fmt.Errorf("parsing wikipedia base url: %w", err)
87+
}
88+
u.RawQuery = params.Encode()
89+
return u.String(), nil
10390
}

0 commit comments

Comments
 (0)