Open Library search API

If nothing is found on the server, returns results from open library
API. Clicking on a book imports it.
This commit is contained in:
2025-12-30 18:13:11 +01:00
parent 4d901ccc02
commit 1bb841332c
18 changed files with 478 additions and 57 deletions

View File

@@ -2,61 +2,44 @@ package openlibrary
import (
"encoding/json"
"io"
"net/http"
"net/url"
"strconv"
"strings"
)
type OpenLibraryQueryResult struct {
Books []OpenLibraryBook `json:"docs"`
NumFound int `json:"numFound"`
}
type OpenLibraryBook struct {
Title string `json:"title"`
Authors []string `json:"author_name"`
OpenLibraryId string `json:"cover_edition_key"`
}
func CallOpenLibrary(searchterm string, limit int, offset int) (OpenLibraryQueryResult, error) {
var queryResult OpenLibraryQueryResult
func computeOpenLibraryUrl(paths ...string) (*url.URL, error) {
baseUrl := "https://openlibrary.org"
booksApiUrl := "search.json"
u, err := url.Parse(baseUrl)
if err != nil {
return queryResult, err
return nil, err
}
u = u.JoinPath(booksApiUrl)
if limit != 0 {
addQueryParamInt(u, "limit", limit)
for _, p := range paths {
u = u.JoinPath(p)
}
if offset != 0 {
addQueryParamInt(u, "offset", offset)
}
addQueryParam(u, "q", searchterm)
client := &http.Client{}
req, err := http.NewRequest("GET", u.String(), nil)
return u, nil
}
func fetchAndParseResult[T any](u *url.URL, queryResult *T) error {
resp, err := doOpenLibraryQuery(u)
if err != nil {
return queryResult, err
}
req.Header.Add("Accept", "application/json")
req.Header.Add("User-Agent", "PersonalLibraryManager/0.1 (artlef@protonmail.com)")
resp, err := client.Do(req)
if err != nil {
return queryResult, err
return err
}
defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
decoder := json.NewDecoder(resp.Body)
err = decoder.Decode(queryResult)
return err
}
func doOpenLibraryQuery(u *url.URL) (*http.Response, error) {
client := &http.Client{}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return queryResult, err
return nil, err
}
bodyString := string(bodyBytes)
decoder := json.NewDecoder(strings.NewReader(bodyString))
err = decoder.Decode(&queryResult)
return queryResult, err
req.Header.Add("Accept", "application/json")
req.Header.Add("User-Agent", "PersonalLibraryManager/0.1 (artlef@protonmail.com)")
return client.Do(req)
}
func addQueryParamInt(u *url.URL, paramName string, paramValue int) {