All checks were successful
		
		
	
	ci/woodpecker/push/woodpecker Pipeline was successful
				
			Reviewed-on: #17 Co-authored-by: David Ashby <delta.mu.alpha@gmail.com> Co-committed-by: David Ashby <delta.mu.alpha@gmail.com>
		
			
				
	
	
		
			159 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package query
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| 
 | |
| 	"git.yetaga.in/alazyreader/library/media"
 | |
| )
 | |
| 
 | |
| type GoogleBooks struct{}
 | |
| 
 | |
| type googleBookResult struct {
 | |
| 	Kind       string `json:"kind"`
 | |
| 	TotalItems int    `json:"totalItems"`
 | |
| 	Items      []item `json:"items"`
 | |
| }
 | |
| 
 | |
| type industryIdentifier struct {
 | |
| 	Type       string `json:"type"`
 | |
| 	Identifier string `json:"identifier"`
 | |
| }
 | |
| 
 | |
| type readingMode struct {
 | |
| 	Text  bool `json:"text"`
 | |
| 	Image bool `json:"image"`
 | |
| }
 | |
| 
 | |
| type panelizationSummary struct {
 | |
| 	ContainsEpubBubbles  bool `json:"containsEpubBubbles"`
 | |
| 	ContainsImageBubbles bool `json:"containsImageBubbles"`
 | |
| }
 | |
| 
 | |
| type imageLink struct {
 | |
| 	SmallThumbnail string `json:"smallThumbnail"`
 | |
| 	Thumbnail      string `json:"thumbnail"`
 | |
| }
 | |
| 
 | |
| type volumeInfo struct {
 | |
| 	Title               string               `json:"title"`
 | |
| 	Subtitle            string               `json:"subtitle"`
 | |
| 	Authors             []string             `json:"authors"`
 | |
| 	Publisher           string               `json:"publisher"`
 | |
| 	PublishedDate       string               `json:"publishedDate"`
 | |
| 	Description         string               `json:"description"`
 | |
| 	IndustryIdentifiers []industryIdentifier `json:"industryIdentifiers"`
 | |
| 	ReadingModes        readingMode          `json:"readingModes"`
 | |
| 	PageCount           int                  `json:"pageCount"`
 | |
| 	PrintType           string               `json:"printType"`
 | |
| 	Categories          []string             `json:"categories"`
 | |
| 	AverageRating       float64              `json:"averageRating"`
 | |
| 	RatingsCount        int                  `json:"ratingsCount"`
 | |
| 	MaturityRating      string               `json:"maturityRating"`
 | |
| 	AllowAnonLogging    bool                 `json:"allowAnonLogging"`
 | |
| 	ContentVersion      string               `json:"contentVersion"`
 | |
| 	PanelizationSummary panelizationSummary  `json:"panelizationSummary"`
 | |
| 	ImageLinks          imageLink            `json:"imageLinks"`
 | |
| 	Language            string               `json:"language"`
 | |
| 	PreviewLink         string               `json:"previewLink"`
 | |
| 	InfoLink            string               `json:"infoLink"`
 | |
| 	CanonicalVolumeLink string               `json:"canonicalVolumeLink"`
 | |
| }
 | |
| 
 | |
| type saleInfo struct {
 | |
| 	Country     string `json:"country"`
 | |
| 	Saleability string `json:"saleability"`
 | |
| 	IsEbook     bool   `json:"isEbook"`
 | |
| }
 | |
| 
 | |
| type epub struct {
 | |
| 	IsAvailable bool `json:"isAvailable"`
 | |
| }
 | |
| 
 | |
| type pdf struct {
 | |
| 	IsAvailable bool `json:"isAvailable"`
 | |
| }
 | |
| 
 | |
| type accessInfo struct {
 | |
| 	Country                string `json:"country"`
 | |
| 	Viewability            string `json:"viewability"`
 | |
| 	Embeddable             bool   `json:"embeddable"`
 | |
| 	PublicDomain           bool   `json:"publicDomain"`
 | |
| 	TextToSpeechPermission string `json:"textToSpeechPermission"`
 | |
| 	Epub                   epub   `json:"epub"`
 | |
| 	Pdf                    pdf    `json:"pdf"`
 | |
| 	WebReaderLink          string `json:"webReaderLink"`
 | |
| 	AccessViewStatus       string `json:"accessViewStatus"`
 | |
| 	QuoteSharingAllowed    bool   `json:"quoteSharingAllowed"`
 | |
| }
 | |
| 
 | |
| type searchInfo struct {
 | |
| 	TextSnippet string `json:"textSnippet"`
 | |
| }
 | |
| 
 | |
| type item struct {
 | |
| 	Kind       string     `json:"kind"`
 | |
| 	ID         string     `json:"id"`
 | |
| 	Etag       string     `json:"etag"`
 | |
| 	SelfLink   string     `json:"selfLink"`
 | |
| 	VolumeInfo volumeInfo `json:"volumeInfo"`
 | |
| 	SaleInfo   saleInfo   `json:"saleInfo"`
 | |
| 	AccessInfo accessInfo `json:"accessInfo"`
 | |
| 	SearchInfo searchInfo `json:"searchInfo"`
 | |
| }
 | |
| 
 | |
| func (g *GoogleBooks) GetByISBN(isbn string) (*media.Book, error) {
 | |
| 	client := &http.Client{}
 | |
| 	resp, err := client.Get(fmt.Sprintf("https://www.googleapis.com/books/v1/volumes?q=isbn:%s", isbn))
 | |
| 
 | |
| 	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 googleBookResult
 | |
| 	b, err := io.ReadAll(resp.Body)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	if err = json.Unmarshal(b, &result); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if len(result.Items) == 0 {
 | |
| 		return nil, fmt.Errorf("no book found")
 | |
| 	}
 | |
| 
 | |
| 	return googleToBook(result.Items[0]), nil
 | |
| }
 | |
| 
 | |
| func googleToBook(i item) *media.Book {
 | |
| 	return &media.Book{
 | |
| 		Title:       buildTitle(i.VolumeInfo.Title, i.VolumeInfo.Subtitle),
 | |
| 		Authors:     i.VolumeInfo.Authors,
 | |
| 		SortAuthor:  strings.ToLower(getLastName(tryGetFirst(i.VolumeInfo.Authors))),
 | |
| 		ISBN10:      getIdentifierType(i.VolumeInfo.IndustryIdentifiers, "ISBN_10"),
 | |
| 		ISBN13:      getIdentifierType(i.VolumeInfo.IndustryIdentifiers, "ISBN_13"),
 | |
| 		Publisher:   i.VolumeInfo.Publisher,
 | |
| 		Year:        strings.Split(i.VolumeInfo.PublishedDate, "-")[0],
 | |
| 		Description: i.VolumeInfo.Description,
 | |
| 		Genre:       tryGetFirst(i.VolumeInfo.Categories),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getIdentifierType(iis []industryIdentifier, typename string) string {
 | |
| 	for _, ident := range iis {
 | |
| 		if ident.Type == typename {
 | |
| 			return ident.Identifier
 | |
| 		}
 | |
| 	}
 | |
| 	return ""
 | |
| }
 |