aboutsummaryrefslogtreecommitdiffstats
path: root/lulu.go
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2026-05-07 12:44:21 -0400
committerSam Anthony <sam@samanthony.xyz>2026-05-07 12:44:21 -0400
commitb57f03381e4bccba2963cebabe51a9cf32bd96dd (patch)
treed19815ddb5c6d495b3123bf888060dd88866a182 /lulu.go
parentf2ee817ba1423b10b382f6b759a19184db8eeacc (diff)
downloadlulu-b57f03381e4bccba2963cebabe51a9cf32bd96dd.zip
implement POST /validate-cover
Diffstat (limited to 'lulu.go')
-rw-r--r--lulu.go91
1 files changed, 61 insertions, 30 deletions
diff --git a/lulu.go b/lulu.go
index 1fdf7a3..621cfc1 100644
--- a/lulu.go
+++ b/lulu.go
@@ -37,7 +37,7 @@ type Client struct {
func NewClient(ctx context.Context, key, secret string) (*Client, error) {
tokenUrl, err := url.JoinPath(ApiUrl, tokenPath)
if err != nil {
- return nil, err
+ return nil, pkgErrf(err, "error creating client")
}
cfg := &clientcredentials.Config{
@@ -55,7 +55,11 @@ func NewClient(ctx context.Context, key, secret string) (*Client, error) {
//
// https://api.lulu.com/docs/#tag/Files-validation/operation/Validate-Interior_create
func (c *Client) ValidateInterior(srcUrl string, mfg PkgId) (uint, error) {
- return c.validateInterior(validateInteriorReq{srcUrl, mfg})
+ id, err := c.validateInterior(validateInteriorReq{srcUrl, mfg})
+ if err != nil {
+ return 0, pkgErr(err)
+ }
+ return id, nil
}
// ValidateInteriorBasic is like ValidateInterior but without the
@@ -63,22 +67,17 @@ func (c *Client) ValidateInterior(srcUrl string, mfg PkgId) (uint, error) {
//
// https://api.lulu.com/docs/#tag/Files-validation/operation/Validate-Interior_create
func (c *Client) ValidateInteriorBasic(srcUrl string) (uint, error) {
- return c.validateInterior(validateInteriorBasicReq{srcUrl})
-}
-
-func (c *Client) validateInterior(payload any) (uint, error) {
- body, err := json.Marshal(payload)
+ id, err := c.validateInterior(validateInteriorBasicReq{srcUrl})
if err != nil {
- return 0, fmt.Errorf("lulu: error encoding request body %v for %s: %w", payload, validateInteriorPath, err)
+ return 0, pkgErr(err)
}
+ return id, nil
+}
- url, err := url.JoinPath(ApiUrl, validateInteriorPath)
- if err != nil {
- return 0, fmt.Errorf("lulu: %w", err)
- }
- resp, err := c.c.Post(url, "application/json", bytes.NewBuffer(body))
+func (c *Client) validateInterior(payload any) (uint, error) {
+ resp, err := c.post(validateInteriorPath, payload)
if err != nil {
- return 0, fmt.Errorf("lulu: %w", err)
+ return 0, err
}
defer resp.Body.Close()
@@ -98,21 +97,23 @@ func (c *Client) validateInterior(payload any) (uint, error) {
func (c *Client) GetInteriorValidation(id uint) (InteriorValidationRecord, error) {
url, err := url.JoinPath(ApiUrl, validateInteriorPath, fmt.Sprint(id))
if err != nil {
- return InteriorValidationRecord{}, fmt.Errorf("lulu: %w", err)
+ return InteriorValidationRecord{}, pkgErr(err)
}
resp, err := c.c.Get(url)
if err != nil {
- return InteriorValidationRecord{}, fmt.Errorf("lulu: %w", err)
+ return InteriorValidationRecord{}, pkgErr(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
- return InteriorValidationRecord{}, errResp{resp}
+ return InteriorValidationRecord{}, pkgErr(errResp{resp})
}
var rec InteriorValidationRecord
- err = decodeResponse(resp, &rec)
- return rec, err
+ if err := decodeResponse(resp, &rec); err != nil {
+ return InteriorValidationRecord{}, pkgErr(err)
+ }
+ return rec, nil
}
// CoverDimensions calculates the required dimensions of the cover for a
@@ -122,28 +123,58 @@ func (c *Client) GetInteriorValidation(id uint) (InteriorValidationRecord, error
// https://api.lulu.com/docs/#tag/Files-validation/operation/Cover-Dimensions_create
func (c *Client) CoverDimensions(mfg PkgId, npages uint, unit Unit) (CoverDimensions, error) {
payload := coverDimensionsReq{mfg, npages, unit}
- body, err := json.Marshal(payload)
+ resp, err := c.post(coverDimensionsPath, payload)
if err != nil {
- return CoverDimensions{}, fmt.Errorf("lulu: error encoding request body %v for %s: %w", payload, coverDimensionsPath, err)
+ return CoverDimensions{}, pkgErr(err)
}
+ defer resp.Body.Close()
- url, err := url.JoinPath(ApiUrl, coverDimensionsPath)
- if err != nil {
- return CoverDimensions{}, fmt.Errorf("lulu: %w", err)
+ if resp.StatusCode != http.StatusCreated {
+ return CoverDimensions{}, errResp{resp}
}
- resp, err := c.c.Post(url, "application/json", bytes.NewBuffer(body))
+
+ var dims CoverDimensions
+ if err := decodeResponse(resp, &dims); err != nil {
+ return CoverDimensions{}, pkgErr(err)
+ }
+ return dims, nil
+}
+
+// ValidateCover starts a server-side validation job for the cover file
+// located at srcUrl, returning the job ID. mfg is the manufacturing
+// settings of the book, and npages is the number of interior pages. Use
+// GetCoverValidation() to poll the status of the job.
+//
+// https://api.lulu.com/docs/#tag/Files-validation/operation/Validate-Cover_create
+func (c *Client) ValidateCover(srcUrl string, mfg PkgId, npages uint) (uint, error) {
+ payload := validateCoverReq{srcUrl, mfg, npages}
+ resp, err := c.post(validateCoverPath, payload)
if err != nil {
- return CoverDimensions{}, fmt.Errorf("lulu: %w", err)
+ return 0, pkgErr(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
- return CoverDimensions{}, errResp{resp}
+ return 0, errResp{resp}
}
- var dims CoverDimensions
- err = decodeResponse(resp, &dims)
- return dims, err
+ var rec CoverValidationRecord
+ if err := decodeResponse(resp, &rec); err != nil {
+ return 0, pkgErr(err)
+ }
+ return rec.Id, nil
+}
+
+func (c *Client) post(path string, payload any) (*http.Response, error) {
+ body, err := json.Marshal(payload)
+ if err != nil {
+ return nil, errEncReq{payload, path, err}
+ }
+ url, err := url.JoinPath(ApiUrl, path)
+ if err != nil {
+ return nil, err
+ }
+ return c.c.Post(url, "application/json", bytes.NewBuffer(body))
}
func decodeResponse(resp *http.Response, v any) error {