From 4370a8133c8e9c870d7d2c659f27ac655896eec0 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Thu, 21 May 2026 14:40:50 -0400 Subject: shorten client method names; implement order cancelation --- lulu.go | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 9 deletions(-) (limited to 'lulu.go') diff --git a/lulu.go b/lulu.go index 212a895..53ce2fd 100644 --- a/lulu.go +++ b/lulu.go @@ -217,11 +217,11 @@ func (c *Client) GetCoverValidation(id uint) (CoverValidation, error) { return rec, nil } -// PrintJobCost calculates the cost of a hypothetical print order without +// Cost calculates the cost of a hypothetical print order without // actually creating a print job. // // https://api.lulu.com/docs/#tag/Print-Job-Cost-Calculations/operation/Print-Job-cost-calculations_create -func (c *Client) PrintJobCost(items []PrintJobCostLineItem, addr ShippingAddress, shipOpt ShippingLevel) (PrintJobCost, ShippingAddressValidation, error) { +func (c *Client) Cost(items []PrintJobCostLineItem, addr ShippingAddress, shipOpt ShippingLevel) (PrintJobCost, ShippingAddressValidation, error) { reqAddr := printJobCostReqShipAddr{ City: addr.City, Country: addr.Country, @@ -240,17 +240,17 @@ func (c *Client) PrintJobCost(items []PrintJobCostLineItem, addr ShippingAddress return resp.cost(), resp.AddressValidation, nil } -// GetPrintJobs retrieves a list of all print jobs that have been -// created, filtered by a set of optional query parameters. +// Jobs retrieves a list of all print jobs that have been created, +// filtered by a set of optional query parameters. // // https://api.lulu.com/docs/#tag/Print-Jobs/operation/Print-Jobs_list -func (c *Client) GetPrintJobs(queries ...PrintJobQuery) ([]PrintJob, error) { +func (c *Client) Jobs(queries ...PrintJobQuery) ([]PrintJob, error) { var q printJobQueries q.apply(queries...) qvals := q.vals() verify := func(v any) error { - resp := v.(*getPrintJobsResp) + resp := v.(*jobsResp) if int(resp.Count) != len(resp.Results) { return fmt.Errorf("count (%d) != len(results) (%d)", resp.Count, len(resp.Results)) } else if len(resp.Results) == 0 && resp.Next != "" { @@ -262,7 +262,7 @@ func (c *Client) GetPrintJobs(queries ...PrintJobQuery) ([]PrintJob, error) { var jobs []PrintJob for page := 1; ; page++ { qvals.Set("page", fmt.Sprint(page)) - var resp getPrintJobsResp + var resp jobsResp if err := c.getQueryDecodeVerify(printJobsPath, qvals, &resp, verify); err != nil { return jobs, pkgErr(err) } @@ -275,10 +275,10 @@ func (c *Client) GetPrintJobs(queries ...PrintJobQuery) ([]PrintJob, error) { } } -// GetPrintJob retrieves the print job with the given ID. +// Job retrieves the print job with the given ID. // // https://api.lulu.com/docs/#tag/Print-Jobs/operation/Print-Jobs_read -func (c *Client) GetPrintJob(id uint64) (PrintJob, error) { +func (c *Client) Job(id uint64) (PrintJob, error) { var job PrintJob path, err := url.JoinPath(printJobsPath, fmt.Sprint(id)) if err != nil { @@ -361,6 +361,25 @@ func verifyProductionDelay(delay time.Duration) error { return nil } +// Cancel cancels the print job with the given ID. +// +// https://api.lulu.com/docs/#tag/Print-Jobs/operation/Print-Jobs_status_cancel +func (c *Client) Cancel(id uint64) error { + path, err := url.JoinPath(printJobsPath, fmt.Sprint(id), "status") + if err != nil { + return pkgErr(err) + } + req := map[string]OrderStatus{"name": OrderCanceled} + var status PrintJobStatus + if err := c.putDecode(path, req, &status); err != nil { + return pkgErr(err) + } + if status.Status != OrderCanceled { + return pkgErr(fmt.Errorf("cancel job %d: expected %s, got %s", id, OrderCanceled, status.Status)) + } + return nil +} + // getDecode sends a GET request and unmarshals the response. func (c *Client) getDecode(path string, v any) error { verify := func(v any) error { return nil } @@ -421,6 +440,35 @@ func (c *Client) post(path string, payload any) (*http.Response, error) { return c.c.Post(url, "application/json", bytes.NewBuffer(body)) } +// putDecode sends a PUT request and unmarshals the response. +func (c *Client) putDecode(path string, payload any, v any) error { + body, err := json.Marshal(payload) + if err != nil { + return errEncReq{payload, path, err} + } + url, err := url.JoinPath(ApiUrl, path) + if err != nil { + return err + } + + debugf("PUT %s request: `%s`\n", url, body) + + req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(body)) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + resp, err := c.c.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return errRespStatus{resp} + } + return decodeResponse(resp, v) +} + func decodeResponse(resp *http.Response, v any) error { body, err := io.ReadAll(resp.Body) if err != nil { -- cgit v1.2.3