Skip to content
Snippets Groups Projects
Commit d9f7be8a authored by ale's avatar ale
Browse files

add OpenLibrary metadata lookup (unused for now)

parent a56704d4
Branches
Tags
No related merge requests found
package liber
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"regexp"
"strings"
)
type openLibraryRefiner struct{}
func (r *openLibraryRefiner) Name() string {
return "openlibrary"
}
type olSearchResults struct {
Docs []olSearchResult `json:"docs"`
}
type olSearchResult struct {
Title string `json:"title"`
Author string `json:"author_name"`
Date string `json:"first_publish_year"`
OLKey string `json:"key"`
}
type olAuthor struct {
Name string `json:"name"`
}
type olPublisher olAuthor
type olExcerpt struct {
Text string `json:"text"`
}
type olMetadata struct {
Key string `json:"key"`
Title string `json:"title"`
Identifiers map[string][]string `json:"identifiers"`
Authors []*olAuthor `json:"authors"`
Excerpts []*olExcerpt `json:"excerpts"`
Publishers []*olPublisher `json:"publishers"`
PublishDate string `json:"publish_date"`
Cover map[string]string `json:"cover"`
Language []string
}
var dateRx = regexp.MustCompile(`(\d{4})`)
func (m *olMetadata) toMetadata() *Metadata {
out := &Metadata{
Title: m.Title,
Language: m.Language,
}
for _, a := range m.Authors {
out.Creator = append(out.Creator, a.Name)
}
for _, p := range m.Publishers {
out.Publisher = append(out.Publisher, p.Name)
}
for _, attr := range []string{"isbn_10", "isbn_13"} {
if isbn, ok := m.Identifiers[attr]; ok {
out.ISBN = append(out.ISBN, isbn...)
}
}
if match := dateRx.FindString(m.PublishDate); match != "" {
out.Date = match
}
for _, e := range m.Excerpts {
out.Description = e.Text
break
}
return out
}
var olSemaphore = make(chan bool, 3)
func openlibraryQuery(uri string, out interface{}) error {
olSemaphore <- true
defer func() {
<-olSemaphore
}()
resp, err := http.Get(uri)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("HTTP status %s", resp.Status)
}
if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
return err
}
return nil
}
// Return book information given an ID.
func (r *openLibraryRefiner) queryBibKeys(bibkeys []string) ([]*Metadata, error) {
values := make(url.Values)
values.Set("bibkeys", strings.Join(bibkeys, ","))
values.Set("jscmd", "data")
values.Set("format", "json")
uri := fmt.Sprintf("https://openlibrary.org/api/books?%s", values.Encode())
var result map[string]*olMetadata
if err := openlibraryQuery(uri, &result); err != nil {
return nil, err
}
var out []*Metadata
for _, m := range result {
out = append(out, m.toMetadata())
}
return out, nil
}
// Find a book given one or more ISBN numbers.
func (r *openLibraryRefiner) queryISBN(isbn []string) ([]*Metadata, error) {
var bibkeys []string
for _, i := range isbn {
bibkeys = append(bibkeys, fmt.Sprintf("ISBN:%s", i))
}
return r.queryBibKeys(bibkeys)
}
// Find a book using title/author.
func (r *openLibraryRefiner) queryTitleAuthor(m *Metadata) ([]*Metadata, error) {
values := make(url.Values)
values.Set("title", m.Title)
if len(m.Creator) > 0 {
values.Set("author", m.Creator[0])
}
uri := fmt.Sprintf("https://openlibrary.org/search.json?%s", values.Encode())
var result olSearchResults
if err := openlibraryQuery(uri, &result); err != nil {
return nil, err
}
var bibkeys []string
for _, doc := range result.Docs {
bibkeys = append(bibkeys, fmt.Sprintf("OLID:%s", doc.OLKey))
}
return r.queryBibKeys(bibkeys)
}
func (r *openLibraryRefiner) Lookup(m *Metadata) ([]*Metadata, error) {
if len(m.ISBN) > 0 {
return r.queryISBN(m.ISBN)
}
return r.queryTitleAuthor(m)
}
func (r *openLibraryRefiner) GetBookCover(m *Metadata) ([]byte, error) {
return nil, nil
}
......@@ -306,6 +306,7 @@ func (db *Database) Update(dir string, chooser MetadataChooserFunc) {
// Check Google Books when the metadata is not
// sufficient to fully describe the book.
refiners: []MetadataRefiner{
//&openLibraryRefiner{},
&googleBooksRefiner{},
},
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment