14 type BookStackApi struct {
20 func NewBookStackApi(baseUrl string, tokenId string, tokenSecret string) *BookStackApi {
24 TokenSecret: tokenSecret,
30 func (bs BookStackApi) authHeader() string {
31 return fmt.Sprintf("Token %s:%s", bs.TokenID, bs.TokenSecret)
34 func (bs BookStackApi) getRequest(method string, urlPath string, data map[string]string) *http.Request {
35 method = strings.ToUpper(method)
36 completeUrlStr := fmt.Sprintf("%s/api/%s", strings.TrimRight(bs.BaseURL, "/"), strings.TrimLeft(urlPath, "/"))
38 queryValues := url.Values{}
39 for k, v := range data {
42 encodedData := queryValues.Encode()
44 r, err := http.NewRequest(method, completeUrlStr, strings.NewReader(encodedData))
49 r.Header.Add("Authorization", bs.authHeader())
51 if method != "GET" && method != "HEAD" {
52 r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
53 r.Header.Add("Content-Length", strconv.Itoa(len(encodedData)))
55 r.URL.RawQuery = encodedData
61 func (bs BookStackApi) doRequest(method string, urlPath string, data map[string]string) []byte {
62 client := &http.Client{
63 Transport: &http.Transport{
64 TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
67 r := bs.getRequest(method, urlPath, data)
68 res, err := client.Do(r)
73 defer res.Body.Close()
75 body, err := ioutil.ReadAll(res.Body)
83 func (bs BookStackApi) getFromListResponse(responseData []byte, models any) ListResponse {
84 var response ListResponse
86 if err := json.Unmarshal(responseData, &response); err != nil {
90 if err := json.Unmarshal(response.Data, models); err != nil {
97 func (bs BookStackApi) GetBooks(count int, page int) ([]Book, int) {
100 data := bs.doRequest("GET", "/books", getPagingParams(count, page))
101 response := bs.getFromListResponse(data, &books)
103 return books, response.Total
106 func (bs BookStackApi) GetChapters(count int, page int) ([]Chapter, int) {
107 var chapters []Chapter
109 data := bs.doRequest("GET", "/chapters", getPagingParams(count, page))
110 response := bs.getFromListResponse(data, &chapters)
112 return chapters, response.Total
115 func (bs BookStackApi) GetPages(count int, page int) ([]Page, int) {
118 data := bs.doRequest("GET", "/pages", getPagingParams(count, page))
119 response := bs.getFromListResponse(data, &pages)
121 return pages, response.Total
124 func (bs BookStackApi) GetPage(id int) Page {
127 data := bs.doRequest("GET", fmt.Sprintf("/pages/%d", id), nil)
128 if err := json.Unmarshal(data, &page); err != nil {
135 func getPagingParams(count int, page int) map[string]string {
136 return map[string]string{
137 "count": strconv.Itoa(count),
138 "offset": strconv.Itoa(count * (page - 1)),