Skip to content

Commit 3b8de90

Browse files
author
iqquee
committed
Screenshot method updated
1 parent 04690da commit 3b8de90

File tree

3 files changed

+102
-79
lines changed

3 files changed

+102
-79
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@
1919

2020
# Go workspace file
2121
go.work
22+
23+
default/

screenshot.go

Lines changed: 75 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package urlbox
33
import (
44
"errors"
55
"fmt"
6-
"io"
76
"net/http"
87
)
98

@@ -14,139 +13,158 @@ var (
1413

1514
type (
1615
Request struct {
17-
Url string // url of website to screenshot
18-
Format *string // screenshot file format
16+
Url string `json:"url"` // url of website to screenshot
17+
Format string `json:"fornmat"` // screenshot file format
1918
Options Options // optional params for the request
2019
}
2120
Options struct {
22-
FullPage *bool // for full page screenshot
23-
Width *string
21+
FullPage bool // for full page screenshot
22+
Width int
2423
BlockingOptions Blocking // options for blocking or dismissing certain page elements, such as cookie banners
2524
SelectorOption Selector // selector parameter
2625
ImageOption Image // options relating to the outputted PNG, WebP or JPEG file
27-
Download Download // pass in a filename which sets the content-disposition header on the response. E.g. download=myfilename.png This will make the Urlbox link downloadable, and will prompt the user to save the file as myfilename.png
26+
DownloadOption Download // pass in a filename which sets the content-disposition header on the response. E.g. download=myfilename.png This will make the Urlbox link downloadable, and will prompt the user to save the file as myfilename.png
2827
WaitOption Wait
2928
}
3029
Blocking struct {
31-
BlockAds *bool // remove ads from page
32-
HideCookieBanners *bool // remove cookie banners if any
33-
ClickAccept *bool // click accept buttons to dismiss pop-upsSelector
30+
BlockAds bool `json:"block_ads"` // remove ads from page
31+
HideCookieBanners bool `json:"hide_cookie_banners"` // remove cookie banners if any
32+
ClickAccept bool `json:"click_accept"` // click accept buttons to dismiss pop-upsSelector
3433
}
3534
Selector struct {
36-
Selector *string // for css selectors e.g #playground for id of playground
37-
FailIfSelectorMissing *bool // fail the request when the selector is not found
35+
Selector string `json:"selector"` // for css selectors e.g #playground for id of playground
36+
FailIfSelectorMissing bool `json:"fail_if_selector_missing"` // fail the request when the selector is not found
3837
}
3938

4039
Image struct {
41-
Retina *bool // take a 'retina' or high-definition screenshot, equivalent to setting a device pixel ratio of 2.0 or @2x. Please note that retina screenshots will be double the normal dimensions and will normally take slightly longer to process due to the much bigger image size.
42-
Quality int // the image quality of the resulting screenshot (JPEG/WebP only)
43-
}
44-
45-
Wait struct {
46-
Delay *int // the amount of time to wait before Urlbox takes the screenshot or PDF, in milliseconds.
47-
TimeOut *int // the amount of time to wait for the requested URL to respond, in milliseconds.
40+
Retina bool `json:"retina"` // take a 'retina' or high-definition screenshot, equivalent to setting a device pixel ratio of 2.0 or @2x. Please note that retina screenshots will be double the normal dimensions and will normally take slightly longer to process due to the much bigger image size.
41+
Quality int `json:"quality"` // the image quality of the resulting screenshot (JPEG/WebP only)
4842
}
4943

5044
Download struct {
5145
DownloadFile bool
52-
FileName *string
46+
FileName string `json:"download"`
5347
}
5448

55-
Response struct {
56-
File io.ReadCloser `json:"file"`
49+
Wait struct {
50+
Delay int // the amount of time to wait before Urlbox takes the screenshot or PDF, in milliseconds.
51+
TimeOut int // the amount of time to wait for the requested URL to respond, in milliseconds.
5752
}
5853
)
5954

60-
// parse() sets up default values if the user doesnt pass any params in
55+
// parse() sets up default values if the user doesn't pass any params in
6156
func (r Request) parse() Request {
6257
// if a file format is not provided, set file format as png
63-
if r.Format == nil {
58+
if r.Format == "" {
6459
png := FileFormatPng
65-
r.Format = &png
60+
r.Format = png
6661
}
6762
// if FullPage Options field is not passed set to false
68-
if r.Options.FullPage == nil {
63+
if !r.Options.FullPage {
6964
fullPage := false
70-
r.Options.FullPage = &fullPage
65+
r.Options.FullPage = fullPage
7166
}
7267
// if Width Options field is not passed set to DefaultWidth
73-
if r.Options.Width == nil {
68+
if r.Options.Width == 0 {
7469
width := DefaultWidth
75-
r.Options.Width = &width
70+
r.Options.Width = width
7671
}
7772
// if BlockAds Options field is not passed set to true
78-
if r.Options.BlockingOptions.BlockAds == nil {
73+
if !r.Options.BlockingOptions.BlockAds {
7974
blockAds := true
80-
r.Options.BlockingOptions.BlockAds = &blockAds
75+
r.Options.BlockingOptions.BlockAds = blockAds
8176
}
8277
// if HideCookieBanners Options field is not passed set to true
83-
if r.Options.BlockingOptions.HideCookieBanners == nil {
78+
if !r.Options.BlockingOptions.HideCookieBanners {
8479
cookie := true
85-
r.Options.BlockingOptions.HideCookieBanners = &cookie
80+
r.Options.BlockingOptions.HideCookieBanners = cookie
8681
}
8782
// if ClickAccept Options field is not passed set to true
88-
if r.Options.BlockingOptions.ClickAccept == nil {
83+
if !r.Options.BlockingOptions.ClickAccept {
8984
accept := true
90-
r.Options.BlockingOptions.ClickAccept = &accept
85+
r.Options.BlockingOptions.ClickAccept = accept
9186
}
9287
// by default FailIfSelectorMissing should be false. Even if the selector is not found, it should not return any error
93-
if r.Options.SelectorOption.FailIfSelectorMissing == nil {
88+
if !r.Options.SelectorOption.FailIfSelectorMissing {
9489
failSelector := false
95-
r.Options.SelectorOption.FailIfSelectorMissing = &failSelector
90+
r.Options.SelectorOption.FailIfSelectorMissing = failSelector
9691
}
9792
// by default the Retina is set to false
98-
if r.Options.ImageOption.Retina == nil {
93+
if !r.Options.ImageOption.Retina {
9994
retina := false
100-
r.Options.ImageOption.Retina = &retina
95+
r.Options.ImageOption.Retina = retina
10196
}
10297
// by default the Quality is set to 80
10398
if r.Options.ImageOption.Quality == 0 {
10499
quality := 80
105100
r.Options.ImageOption.Quality = quality
106101
}
107102
// by default the Delay is set to 0
108-
if r.Options.WaitOption.Delay == nil {
103+
if r.Options.WaitOption.Delay == 0 {
109104
delay := 0
110-
r.Options.WaitOption.Delay = &delay
105+
r.Options.WaitOption.Delay = delay
111106
}
112107
// by default the TimeOut is set to 30000 in milliseconds(3 seconds)
113-
if r.Options.WaitOption.TimeOut == nil {
108+
if r.Options.WaitOption.TimeOut == 0 {
114109
timeOut := 30000
115-
r.Options.WaitOption.TimeOut = &timeOut
110+
r.Options.WaitOption.TimeOut = timeOut
116111
}
117112

118113
return r
119114
}
120115

121-
func (c *Client) SynchronousScreenshot(r Request) (*Response, error) {
116+
func (c *Client) Screenshot(rq Request) ([]byte, error) {
117+
// the function shouldnt run if there was no url provided
118+
if rq.Url == "" {
119+
return nil, ErrUrlRequired
120+
}
121+
// check if the Image quality is not above 100
122+
if rq.Options.ImageOption.Quality > 100 {
123+
return nil, ErrImageQualityExceeded
124+
}
125+
126+
r := rq.parse()
127+
128+
// setup the url
129+
url := fmt.Sprintf("%s/%v?url=%s&width=%v&full_page=%v&block_ads=%v&hide_cookie_banners=%v&click_accept=%v&retina=%v&quality=%v&delay=%v&timeout=%v",
130+
c.ApiKey, r.Format, r.Url, r.Options.Width, r.Options.FullPage, r.Options.BlockingOptions.BlockAds,
131+
r.Options.BlockingOptions.HideCookieBanners, r.Options.BlockingOptions.ClickAccept,
132+
r.Options.ImageOption.Retina, r.Options.ImageOption.Quality, r.Options.WaitOption.Delay, r.Options.WaitOption.TimeOut,
133+
)
134+
135+
res, err := c.newRequest(http.MethodGet, url, nil)
136+
if err != nil {
137+
return nil, err
138+
}
139+
140+
return res, nil
141+
}
142+
143+
func (c *Client) ScreenshotAsync(rq Request) ([]byte, error) {
122144
// the function shouldnt run if there was no url provided
123-
if r.Url == "" {
145+
if rq.Url == "" {
124146
return nil, ErrUrlRequired
125147
}
126148
// check if the Image quality is not above 100
127-
if r.Options.ImageOption.Quality > 100 {
149+
if rq.Options.ImageOption.Quality > 100 {
128150
return nil, ErrImageQualityExceeded
129151
}
130152

131-
r.parse()
153+
r := rq.parse()
132154

133155
var downloadFileName string
134-
if r.Options.Download.DownloadFile {
135-
fileName := fmt.Sprintf("%v.%v", r.Options.Download.FileName, r.Format)
156+
if r.Options.DownloadOption.DownloadFile {
157+
fileName := fmt.Sprintf("%v.%v", r.Options.DownloadOption.FileName, r.Format)
136158
downloadFileName = fileName
137159
}
138-
// setup the url
139-
url := fmt.Sprintf("%s/%v?url=%s&width=%v&full_page=%v&block_ads=%v&hide_cookie_banners=%v&click_accept=%v&selector=%v&retina=%v&quality=%v&download=%v&delay=%v&timeout=%v ",
140-
c.ApiKey, &r.Format, r.Url, &r.Options.Width, &r.Options.FullPage, &r.Options.BlockingOptions.BlockAds,
141-
&r.Options.BlockingOptions.HideCookieBanners, &r.Options.BlockingOptions.ClickAccept, &r.Options.SelectorOption.Selector,
142-
&r.Options.ImageOption.Retina, r.Options.ImageOption.Quality, downloadFileName, r.Options.WaitOption.Delay, r.Options.WaitOption.TimeOut,
143-
)
160+
r.Options.DownloadOption.FileName = downloadFileName
144161

145-
var response Response
162+
url := "render/sync"
146163

147-
if err := c.newRequest(http.MethodGet, url, nil, response); err != nil {
164+
res, err := c.newRequest(http.MethodPost, url, r)
165+
if err != nil {
148166
return nil, err
149167
}
150168

151-
return &response, nil
169+
return res, nil
152170
}

urlbox.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package urlbox
33
import (
44
"bytes"
55
"encoding/json"
6-
"fmt"
76
"io"
7+
"io/ioutil"
88
"net/http"
99

1010
"github.com/pkg/errors"
@@ -32,59 +32,62 @@ const (
3232
// FileFormatMp4 for mp4 file format
3333
FileFormatMp4 = "mp4"
3434
// DefaultWidth default width of the screen shots to be taken
35-
DefaultWidth = "1280"
35+
DefaultWidth = 1280
3636
)
3737

3838
// client config
3939
type Client struct {
40-
Http http.Client
41-
BaseUrl string
42-
ApiKey string
43-
BearerToken string
40+
Http http.Client
41+
BaseUrl string
42+
ApiKey string
43+
SecretKey string
4444
}
4545

46-
// NewClient
47-
func NewClient(h http.Client, apiKey, bearerToken string) *Client {
46+
// New is the urlbox config initializer
47+
func New(h http.Client, apiKey, secretKey string) *Client {
4848
return &Client{
49-
BaseUrl: "https://api.urlbox.io/v1/",
50-
Http: h,
51-
ApiKey: apiKey,
52-
BearerToken: bearerToken,
49+
BaseUrl: "https://api.urlbox.io/v1/",
50+
Http: h,
51+
ApiKey: apiKey,
52+
SecretKey: secretKey,
5353
}
5454
}
5555

5656
/*
5757
newRequest makes a http request to the urlbox server and decodes the server response into the reqBody parameter passed into the newRequest method
5858
*/
59-
func (c *Client) newRequest(method, reqURL string, reqBody interface{}, resp interface{}) error {
59+
func (c *Client) newRequest(method, reqURL string, reqBody interface{}) ([]byte, error) {
6060
newURL := c.BaseUrl + reqURL
6161
var body io.Reader
6262

6363
if reqBody != nil {
6464
bb, err := json.Marshal(reqBody)
6565
if err != nil {
66-
return errors.Wrap(err, "http client ::: unable to marshal request struct")
66+
return nil, errors.Wrap(err, "http client ::: unable to marshal request struct")
6767
}
6868
body = bytes.NewReader(bb)
6969
}
7070

71-
bearer := fmt.Sprintf("Bearer %v", c.BearerToken)
71+
// bearer := fmt.Sprintf("Bearer %v", c.SecretKey)
7272
req, err := http.NewRequest(method, newURL, body)
73-
req.Header.Set("Content-Type", "application/json")
74-
req.Header.Set("Authorization", bearer)
73+
// req.Header.Set("Content-Type", "application/json")
74+
// req.Header.Set("Authorization", bearer)
7575

7676
if err != nil {
77-
return errors.Wrap(err, "http client ::: unable to create request body")
77+
return nil, errors.Wrap(err, "http client ::: unable to create request body")
7878
}
7979

8080
res, err := c.Http.Do(req)
8181
if err != nil {
82-
return errors.Wrap(err, "http client ::: client failed to execute request")
82+
return nil, errors.Wrap(err, "http client ::: client failed to execute request")
8383
}
8484

85-
if err := json.NewDecoder(res.Body).Decode(&resp); err != nil {
86-
return errors.Wrap(err, "http client ::: unable to unmarshal response body")
85+
defer res.Body.Close()
86+
87+
b, err := ioutil.ReadAll(res.Body)
88+
if err != nil {
89+
return nil, errors.Wrap(err, "http client ::: client failed to read file")
8790
}
8891

89-
return nil
92+
return b, nil
9093
}

0 commit comments

Comments
 (0)