diff --git a/.gitignore b/.gitignore index 167dc6d..23e1760 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ go.work cover.html cover.rpt coverage.out +deploy diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..80c991e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +# build the webapp including dependencies from / and /cmd + +FROM golang:1.22 AS deps + +# setup module environment +WORKDIR /build +ADD *mod ./ +ADD *sum ./ +RUN go mod download +ADD cmd/web/*mod ./cmd/web/ +ADD cmd/web/*sum ./cmd/web/ +RUN cd /build/cmd/web && go mod download + +# build +FROM deps as dev +ADD *go ./ +ADD cmd/*go ./cmd/ +ADD cmd/web/ ./cmd/web/ +RUN cd cmd/web && \ + CGO_ENABLED=0 GOOS=linux \ + go build -ldflags "-w -X main.docker=true" -o /build/webserver . + +# install into minimal image +FROM gcr.io/distroless/base AS base +WORKDIR / +EXPOSE 8000 +COPY --from=dev /build/webserver / +CMD ["/webserver", "--address", "0.0.0.0", "--port", "8000"] diff --git a/README.md b/README.md index 1c9b5bb..fa23161 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # cexfind A Go module with console, cli and web app clients for rapid and -effective searches for equipment on Cex/Webuy using the unofficial -`webuy.io` json search endpoint. +effective searches for second hand equipment for sale at Cex/Webuy using +the unofficial `webuy.io` json search endpoint. Note that these programs only work for queries made in the UK (or via a -proxy terminating in the UK). +proxy terminating in the UK). This is intended to be a fun project and +is not intended for commercial use. -This is intended to be a fun project and is not intended for commercial -use. +The web client is presently deployed on Google Cloud Run. [Try it +out!](https://cexfind-min-poyflf5akq-nw.a.run.app/). ## Usage diff --git a/cex.go b/cex.go index 2289b0e..2cf355c 100644 --- a/cex.go +++ b/cex.go @@ -127,7 +127,11 @@ func Search(queries []string, strict bool) ([]Box, error) { results := makeQueries(queries, strict) for br := range results { if br.err != nil { - err = fmt.Errorf("\"%s\": %w", br.query, br.err) + if err != nil { + err = fmt.Errorf("\"%s\": %w\n%w", br.query, br.err, err) + } else { + err = fmt.Errorf("\"%s\": %w", br.query, br.err) + } continue } if _, ok := idMap[br.box.ID]; ok { // don't add duplicates @@ -138,7 +142,12 @@ func Search(queries []string, strict bool) ([]Box, error) { } allBoxes.sort() if len(allBoxes) == 0 { - return allBoxes, errors.New("no results") + if err != nil { + err = fmt.Errorf("%w", err) + } else { + err = errors.New("no results") + } + return allBoxes, err } return allBoxes, err } diff --git a/cmd/web/main.go b/cmd/web/main.go index e300b4e..e3f411c 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -14,7 +14,7 @@ var Server func(address, port string) = Serve var usage = ` run a webserver to search Cex/Webuy for second hand equipment -eg [-a 127.0.0.1] [-p 8001] +eg -address 192.168.4.5 -port 8001 ` // indirect Exit for testing diff --git a/query.go b/query.go index 03365b8..cb8585b 100644 --- a/query.go +++ b/query.go @@ -28,6 +28,8 @@ var ( urlDetail = "https://uk.webuy.com/product-detail?id=" // save web output to temp file if DEBUG true debug = false + // + NoResultsFoundError error = errors.New("no results found") ) // jsonResults encompasses the interesting fields in a Cex web search result @@ -127,7 +129,7 @@ func postQuery(queryBytes []byte) (jsonResults, error) { if errors.As(err, &ju) { // no results tend to provide data that cannot be parsed, // used for a general "home" type page - return r, errors.New("no results found") + return r, NoResultsFoundError } // assume html page; try and extract heading reason := headingExtract(responseBytes) @@ -137,7 +139,7 @@ func postQuery(queryBytes []byte) (jsonResults, error) { return r, errors.New(reason) } if len(r.Results) < 1 || len(r.Results[0].Hits) < 1 { - return r, errors.New("no results") + return r, NoResultsFoundError } return r, nil }