initial wrapper
This commit is contained in:
		@@ -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>.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								client/client.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								client/client.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								client/response.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								client/response.go
									
									
									
									
									
										Normal file
									
								
							@@ -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"`
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user