management server listener (#17)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
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>
This commit is contained in:
13
query/amazon.go
Normal file
13
query/amazon.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.yetaga.in/alazyreader/library/media"
|
||||
)
|
||||
|
||||
type Amazon struct{}
|
||||
|
||||
func (o *Amazon) GetByISBN(isbn string) (*media.Book, error) {
|
||||
return nil, fmt.Errorf("unimplemented")
|
||||
}
|
28
query/funcs.go
Normal file
28
query/funcs.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func tryGetFirst(s []string) string {
|
||||
if len(s) == 0 {
|
||||
return ""
|
||||
}
|
||||
return s[0]
|
||||
}
|
||||
|
||||
func buildTitle(title, subtitle string) string {
|
||||
if subtitle != "" {
|
||||
return fmt.Sprintf("%s: %s", title, subtitle)
|
||||
}
|
||||
return title
|
||||
}
|
||||
|
||||
func getLastName(author string) string {
|
||||
names := strings.Split(author, " ")
|
||||
if len(names) < 2 {
|
||||
return author
|
||||
}
|
||||
return names[len(names)-1]
|
||||
}
|
158
query/googlebooks.go
Normal file
158
query/googlebooks.go
Normal file
@@ -0,0 +1,158 @@
|
||||
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 ""
|
||||
}
|
11
query/null.go
Normal file
11
query/null.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"git.yetaga.in/alazyreader/library/media"
|
||||
)
|
||||
|
||||
type Null struct{}
|
||||
|
||||
func (o *Null) GetByISBN(isbn string) (*media.Book, error) {
|
||||
return nil, nil
|
||||
}
|
46
query/openlibrary.go
Normal file
46
query/openlibrary.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.yetaga.in/alazyreader/go-openlibrary/client"
|
||||
"git.yetaga.in/alazyreader/library/media"
|
||||
)
|
||||
|
||||
type OpenLibrary struct {
|
||||
client client.Client
|
||||
}
|
||||
|
||||
func (o *OpenLibrary) GetByISBN(isbn string) (*media.Book, error) {
|
||||
details, err := o.client.GetByISBN(isbn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return openLibraryToBook(details), nil
|
||||
}
|
||||
|
||||
func openLibraryToBook(details *client.BookDetails) *media.Book {
|
||||
return &media.Book{
|
||||
Title: details.Title,
|
||||
Authors: getAuthors(details.Authors),
|
||||
SortAuthor: strings.ToLower(getLastName(tryGetFirst(getAuthors(details.Authors)))),
|
||||
Publisher: getPublisher(details.Publishers),
|
||||
ISBN10: tryGetFirst(details.Identifiers.ISBN10),
|
||||
ISBN13: tryGetFirst(details.Identifiers.ISBN13),
|
||||
}
|
||||
}
|
||||
|
||||
func getPublisher(publishers []client.Publishers) string {
|
||||
if len(publishers) == 0 {
|
||||
return ""
|
||||
}
|
||||
return publishers[0].Name
|
||||
}
|
||||
|
||||
func getAuthors(authors []client.Authors) []string {
|
||||
ret := make([]string, len(authors))
|
||||
for _, author := range authors {
|
||||
ret = append(ret, author.Name)
|
||||
}
|
||||
return ret
|
||||
}
|
Reference in New Issue
Block a user