package routes import ( "net/http" "regexp" "strings" "git.artlef.fr/PersonalLibraryManager/internal/appcontext" "git.artlef.fr/PersonalLibraryManager/internal/dto" "git.artlef.fr/PersonalLibraryManager/internal/inventaire" "git.artlef.fr/PersonalLibraryManager/internal/myvalidator" "git.artlef.fr/PersonalLibraryManager/internal/query" ) func GetSearchBooksHandler(ac appcontext.AppContext) { searchterm := ac.C.Param("searchterm") var params dto.BookSearchGetParam err := ac.C.ShouldBind(¶ms) if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } user, fetchUserErr := ac.GetAuthenticatedUser() if fetchUserErr != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, fetchUserErr) return } limit, err := ac.GetQueryLimit() if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } offset, err := ac.GetQueryOffset() if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } var returnedBooks dto.BookSearchGet if !params.Inventaire { books, err := query.FetchBookSearchGet(ac.Db, user.ID, searchterm, limit, offset) if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } count, err := query.FetchBookSearchGetCount(ac.Db, user.ID, searchterm) if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } returnedBooks = dto.BookSearchGet{Count: count, Inventaire: false, Books: books} } if params.Inventaire || len(returnedBooks.Books) == 0 { returnedBooksPtr, err := searchInInventaireAPI(ac.Config.InventaireUrl, searchterm, limit, offset, params) if err != nil { myvalidator.ReturnErrorsAsJsonResponse(&ac, err) return } returnedBooks = *returnedBooksPtr } ac.C.JSON(http.StatusOK, returnedBooks) } func searchInInventaireAPI(inventaireUrl string, searchterm string, limit int, offset int, params dto.BookSearchGetParam) (*dto.BookSearchGet, error) { isIsbn, err := regexp.Match(`\d{10,13}`, []byte(searchterm)) if err != nil { return nil, err } if isIsbn { queryResult, err := inventaire.CallInventaireFromISBN(inventaireUrl, searchterm, params.Lang) if err != nil { return nil, err } var bookSearchGet dto.BookSearchGet if queryResult != nil { bookSearchGet = inventaireEditionToBookSearchGet(*queryResult) } else { bookSearchGet = dto.BookSearchGet{Count: 0, Inventaire: true} } return &bookSearchGet, err } else { queryResult, err := inventaire.CallInventaireSearch(inventaireUrl, searchterm, params.Lang, limit, offset) if err != nil { return nil, err } bookSearchGet := inventaireBooksToBookSearchGet(inventaireUrl, queryResult) return &bookSearchGet, err } } func inventaireEditionToBookSearchGet(result inventaire.InventaireEditionDetailedSingleResult) dto.BookSearchGet { var books []dto.BookSearchGetBook bookSearchGetBook := dto.BookSearchGetBook{ ID: 0, Title: result.Title, Author: result.Author.Name, Description: result.Description, InventaireID: result.Id, IsInventaireEdition: true, Rating: 0, Read: false, WantRead: false, CoverPath: result.Image, } books = append(books, bookSearchGetBook) return dto.BookSearchGet{Count: 1, Inventaire: true, Books: books} } func inventaireBooksToBookSearchGet(inventaireUrl string, results inventaire.InventaireSearchResult) dto.BookSearchGet { var books []dto.BookSearchGetBook for _, b := range results.Results { coverPath := "" if b.Image != "" && strings.HasPrefix(b.Image, "/") { coverPath = inventaireUrl + b.Image } bookSearchGetBook := dto.BookSearchGetBook{ ID: 0, Title: b.Label, Author: "", Description: b.Description, InventaireID: b.ID, Rating: 0, Read: false, WantRead: false, CoverPath: coverPath, } books = append(books, bookSearchGetBook) } return dto.BookSearchGet{Count: results.Total, Inventaire: true, Books: books} }