initial wrapper

master
David Ashby 1 year ago
parent e2ab98b5f8
commit f35a56507a
  1. 2
      README.md
  2. 101
      client/client.go
  3. 71
      client/response.go
  4. 3
      go.mod

@ -1,3 +1,3 @@
# go-openlibrary
A Go wrapper around the OpenLibrary.org API: https://openlibrary.org/dev/docs/api/books
A simple Go wrapper around the OpenLibrary.org API: <https://openlibrary.org/dev/docs/api/books>.

@ -0,0 +1,101 @@
package client
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
var (
defaultAPI = "https://openlibrary.org/api/books"
)
// Client
type Client struct {
httpClient http.Client
apipath string
}
// NewClient returns a new Client struct using http.DefaultClient and default api path.
func NewClient() (*Client, error) {
return &Client{
apipath: defaultAPI,
}, nil
}
// SetHTTPClient updates the httpClient on the client with a manually-configured one.
// If unset, the client will fall back to using http.DefaultClient.
func (c *Client) SetHTTPClient(h http.Client) {
c.httpClient = h
}
// SetAPIPath updates the hostname and path to the API; the default is "https://openlibrary.org/api/books".
// If APIPath is set to an empty string, the client will fall back to the default option.
func (c *Client) SetAPIPath(p string) {
c.apipath = p
}
// GetByISBN fetches details for a book based on its ISBN10 or ISBN13.
func (c *Client) GetByISBN(k string) (*BookDetails, error) {
key := "ISBN:" + k
return c.fetch(key)
}
// GetByOCLC fetches details for a book based on its WorldCat OCLC number.
func (c *Client) GetByOCLC(k string) (*BookDetails, error) {
key := "OCLC:" + k
return c.fetch(key)
}
// GetByLCCN fetches details for a book based on its Library of Congress Control Number.
func (c *Client) GetByLCCN(k string) (*BookDetails, error) {
key := "LCCN:" + k
return c.fetch(key)
}
// GetByOLID fetches details for a book based on its OpenLibrary ID number.
func (c *Client) GetByOLID(k string) (*BookDetails, error) {
key := "OLID:" + k
return c.fetch(key)
}
// GetByRawKey fetches details for a book based on an arbitrary key; this method is provided
// as a future-proof fallback in case the OpenLibrary API adds more "bibkey" request types in the future.
// Most users should use one of the other lookup functions.
func (c *Client) GetByRawKey(k string) (*BookDetails, error) {
return c.fetch(k)
}
func (c *Client) fetch(key string) (*BookDetails, error) {
path := c.apipath
if path == "" {
path = defaultAPI
}
resp, err := c.httpClient.Get(path + "?bibkeys=%s&jscmd=data&format=json")
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("received non-200 status code: %d", resp.StatusCode)
}
var result response
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if err = json.Unmarshal(b, &result); err != nil {
return nil, err
}
details, ok := result[key]
if !ok {
return nil, fmt.Errorf("book not found")
}
return &details, nil
}

@ -0,0 +1,71 @@
package client
type response map[string]BookDetails
type BookDetails struct {
Authors []Authors `json:"authors"`
Classifications Classifications `json:"classifications"`
Cover Cover `json:"cover"`
Excerpts []Excerpts `json:"excerpts"`
Identifiers Identifiers `json:"identifiers"`
Links []Links `json:"links"`
NumberOfPages int `json:"number_of_pages"`
PublishDate string `json:"publish_date"`
Publishers []Publishers `json:"publishers"`
PublishPlaces []PublishPlaces `json:"publish_places"`
Subjects []Subjects `json:"subjects"`
Title string `json:"title"`
URL string `json:"url"`
Weight string `json:"weight"`
}
type Authors struct {
Name string `json:"name"`
URL string `json:"url"`
}
type Classifications struct {
DeweyDecimalClass []string `json:"dewey_decimal_class"`
LcClassifications []string `json:"lc_classifications"`
}
type Cover struct {
Small string `json:"small"`
Medium string `json:"medium"`
Large string `json:"large"`
}
type Excerpts struct {
Text string `json:"text"`
Comment string `json:"comment"`
}
type Identifiers struct {
Amazon []string `json:"amazon"`
Goodreads []string `json:"goodreads"`
Google []string `json:"google"`
Isbn10 []string `json:"isbn_10"`
Isbn13 []string `json:"isbn_13"`
Lccn []string `json:"lccn"`
Librarything []string `json:"librarything"`
Oclc []string `json:"oclc"`
ProjectGutenberg []string `json:"project_gutenberg"`
}
type Links struct {
Title string `json:"title"`
URL string `json:"url"`
}
type Publishers struct {
Name string `json:"name"`
}
type PublishPlaces struct {
Name string `json:"name"`
}
type Subjects struct {
Name string `json:"name"`
URL string `json:"url"`
}

@ -0,0 +1,3 @@
module git.yetaga.in/alazyreader/go-openlibrary
go 1.16
Loading…
Cancel
Save