feat(bookstack-api-02m): create example code in examples/ directory
Add three example programs: basic (list books, get page), search (full-text search with CLI args), and export (markdown/PDF export).
This commit is contained in:
parent
e633fc2764
commit
5185222577
5 changed files with 170 additions and 5 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"worktree_root": "/home/oli/Dev/bookstack-api",
|
"worktree_root": "/home/oli/Dev/bookstack-api",
|
||||||
"last_export_commit": "256361e90b5bed7dd1fcb415a900582db3c02df6",
|
"last_export_commit": "0a1cd5ef389b9ad9a65d5c74028e32cc9e089d4d",
|
||||||
"last_export_time": "2026-01-30T09:55:44.638879084+01:00",
|
"last_export_time": "2026-01-30T09:56:19.739310088+01:00",
|
||||||
"jsonl_hash": "fd9a95897298a7ed8a7abac709e497cb45eaeed644a668cd0f34aa7492667d12"
|
"jsonl_hash": "5773bc4e6df7de102c508785a92ae417f9455bcf3e5f43215dc9255548cf1ea2"
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{"id":"bookstack-api-02m","title":"Create example code in examples/ directory","description":"Create example programs demonstrating library usage.\n\n## Requirements\nFrom PRD Section 8 (Definition of Done):\n- Beispiel-Code in examples/\n\nFrom PRD Section 9 (Go-Projektstruktur):\n```\nexamples/\n└── basic/\n └── main.go\n```\n\n## Examples to Create\n\n### examples/basic/main.go\nBasic usage: client setup, list books, get page\n\n### examples/search/main.go\nSearch workflow: search -\u003e select result -\u003e display page\n\n### examples/export/main.go\nExport page to markdown or PDF file\n\n### examples/iterator/main.go\nUsing ListAll() to iterate all pages\n\n## Technical Details\n- Each example should be runnable standalone\n- Use environment variables for credentials\n- Include error handling\n- Add comments explaining the code\n\n## Acceptance Criteria\n- [ ] examples/basic/main.go exists and runs\n- [ ] At least 2-3 different examples\n- [ ] All examples compile and work\n- [ ] Examples demonstrate key features","status":"open","priority":1,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:40:24.46706112+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-28T09:40:24.46706112+01:00"}
|
{"id":"bookstack-api-02m","title":"Create example code in examples/ directory","description":"Create example programs demonstrating library usage.\n\n## Requirements\nFrom PRD Section 8 (Definition of Done):\n- Beispiel-Code in examples/\n\nFrom PRD Section 9 (Go-Projektstruktur):\n```\nexamples/\n└── basic/\n └── main.go\n```\n\n## Examples to Create\n\n### examples/basic/main.go\nBasic usage: client setup, list books, get page\n\n### examples/search/main.go\nSearch workflow: search -\u003e select result -\u003e display page\n\n### examples/export/main.go\nExport page to markdown or PDF file\n\n### examples/iterator/main.go\nUsing ListAll() to iterate all pages\n\n## Technical Details\n- Each example should be runnable standalone\n- Use environment variables for credentials\n- Include error handling\n- Add comments explaining the code\n\n## Acceptance Criteria\n- [ ] examples/basic/main.go exists and runs\n- [ ] At least 2-3 different examples\n- [ ] All examples compile and work\n- [ ] Examples demonstrate key features","status":"in_progress","priority":1,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:40:24.46706112+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:56:24.058896862+01:00"}
|
||||||
{"id":"bookstack-api-1us","title":"Write README with Quick-Start guide","description":"Create comprehensive README.md with usage documentation.\n\n## Requirements\nFrom PRD Section 8 (Definition of Done):\n- README mit Quick-Start\n\n## Content\n1. **Overview** - What the library does\n2. **Installation** - go get command\n3. **Quick Start** - Basic usage example\n4. **Authentication** - How to get and use API tokens\n5. **Usage Examples**\n - List books\n - Search documentation\n - Get page content\n - Export page\n6. **API Reference** - Link to GoDoc\n7. **License**\n\n## Example Code\n```go\nclient := bookstack.NewClient(bookstack.Config{\n BaseURL: \"https://docs.example.com\",\n TokenID: os.Getenv(\"BOOKSTACK_TOKEN_ID\"),\n TokenSecret: os.Getenv(\"BOOKSTACK_TOKEN_SECRET\"),\n})\n\n// Search documentation\nresults, err := client.Search.Search(ctx, \"deployment\", nil)\n\n// Get a page\npage, err := client.Pages.Get(ctx, 123)\n```\n\n## Acceptance Criteria\n- [ ] Clear installation instructions\n- [ ] Working quick-start example\n- [ ] All main features documented\n- [ ] Links to full documentation","status":"in_progress","priority":1,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:40:24.187495378+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:55:49.379496813+01:00"}
|
{"id":"bookstack-api-1us","title":"Write README with Quick-Start guide","description":"Create comprehensive README.md with usage documentation.\n\n## Requirements\nFrom PRD Section 8 (Definition of Done):\n- README mit Quick-Start\n\n## Content\n1. **Overview** - What the library does\n2. **Installation** - go get command\n3. **Quick Start** - Basic usage example\n4. **Authentication** - How to get and use API tokens\n5. **Usage Examples**\n - List books\n - Search documentation\n - Get page content\n - Export page\n6. **API Reference** - Link to GoDoc\n7. **License**\n\n## Example Code\n```go\nclient := bookstack.NewClient(bookstack.Config{\n BaseURL: \"https://docs.example.com\",\n TokenID: os.Getenv(\"BOOKSTACK_TOKEN_ID\"),\n TokenSecret: os.Getenv(\"BOOKSTACK_TOKEN_SECRET\"),\n})\n\n// Search documentation\nresults, err := client.Search.Search(ctx, \"deployment\", nil)\n\n// Get a page\npage, err := client.Pages.Get(ctx, 123)\n```\n\n## Acceptance Criteria\n- [ ] Clear installation instructions\n- [ ] Working quick-start example\n- [ ] All main features documented\n- [ ] Links to full documentation","status":"closed","priority":1,"issue_type":"task","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:40:24.187495378+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:56:19.808734922+01:00","closed_at":"2026-01-30T09:56:19.808734922+01:00","close_reason":"Closed"}
|
||||||
{"id":"bookstack-api-2x5","title":"Implement SearchService","description":"Implement the SearchService for full-text search across Bookstack content.\n\n## Requirements\nFrom PRD Section 5:\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| All | GET /api/search?query=... | Full-text search |\n\n## API Methods\n```go\ntype SearchService struct {\n client *Client\n}\n\ntype SearchOptions struct {\n Query string\n // Pagination options\n Count int\n Offset int\n}\n\nfunc (s *SearchService) Search(ctx context.Context, query string, opts *SearchOptions) ([]*SearchResult, error)\n```\n\n## SearchResult\nReturns results across all types:\n- page\n- chapter\n- book\n- bookshelf\n\nEach result includes ID, Name, Slug, Type, URL, Preview.\n\n## User Story\nUS1: Als AI-Agent möchte ich die Bookstack-Dokumentation durchsuchen können, um relevante Seiten für Benutzeranfragen zu finden.\n\n## Acceptance Criteria\n- [ ] SearchService struct created\n- [ ] Search() accepts query string and options\n- [ ] Results include all content types\n- [ ] Proper error handling\n- [ ] Unit tests with mock server","status":"closed","priority":0,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:39:31.430412917+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:50:44.683680188+01:00","closed_at":"2026-01-30T09:50:44.683680188+01:00","close_reason":"Closed"}
|
{"id":"bookstack-api-2x5","title":"Implement SearchService","description":"Implement the SearchService for full-text search across Bookstack content.\n\n## Requirements\nFrom PRD Section 5:\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| All | GET /api/search?query=... | Full-text search |\n\n## API Methods\n```go\ntype SearchService struct {\n client *Client\n}\n\ntype SearchOptions struct {\n Query string\n // Pagination options\n Count int\n Offset int\n}\n\nfunc (s *SearchService) Search(ctx context.Context, query string, opts *SearchOptions) ([]*SearchResult, error)\n```\n\n## SearchResult\nReturns results across all types:\n- page\n- chapter\n- book\n- bookshelf\n\nEach result includes ID, Name, Slug, Type, URL, Preview.\n\n## User Story\nUS1: Als AI-Agent möchte ich die Bookstack-Dokumentation durchsuchen können, um relevante Seiten für Benutzeranfragen zu finden.\n\n## Acceptance Criteria\n- [ ] SearchService struct created\n- [ ] Search() accepts query string and options\n- [ ] Results include all content types\n- [ ] Proper error handling\n- [ ] Unit tests with mock server","status":"closed","priority":0,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:39:31.430412917+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:50:44.683680188+01:00","closed_at":"2026-01-30T09:50:44.683680188+01:00","close_reason":"Closed"}
|
||||||
{"id":"bookstack-api-42g","title":"Implement ShelvesService (List, Get)","description":"Implement the ShelvesService with List and Get operations.\n\n## Requirements\nFrom PRD Section 5:\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| List | GET /api/shelves | All shelves |\n| Get | GET /api/shelves/{id} | Single shelf |\n\n## API Methods\n```go\ntype ShelvesService struct {\n client *Client\n}\n\nfunc (s *ShelvesService) List(ctx context.Context, opts *ListOptions) ([]*Shelf, error)\nfunc (s *ShelvesService) Get(ctx context.Context, id int) (*Shelf, error)\nfunc (s *ShelvesService) ListAll(ctx context.Context) iter.Seq2[*Shelf, error]\n```\n\n## Shelf Fields\n- ID, Name, Slug, Description, CreatedAt, UpdatedAt\n\n## Bookstack Hierarchy\nShelf is the top-level container: Shelf -\u003e Book -\u003e Chapter -\u003e Page\n\n## Acceptance Criteria\n- [ ] ShelvesService struct created\n- [ ] List() returns paginated shelves\n- [ ] Get() returns single shelf by ID\n- [ ] ListAll() iterator implemented\n- [ ] Proper error handling\n- [ ] Unit tests with mock server","status":"closed","priority":1,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:39:53.490673653+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:53:07.163294684+01:00","closed_at":"2026-01-30T09:53:07.163294684+01:00","close_reason":"Closed"}
|
{"id":"bookstack-api-42g","title":"Implement ShelvesService (List, Get)","description":"Implement the ShelvesService with List and Get operations.\n\n## Requirements\nFrom PRD Section 5:\n\n| Method | Endpoint | Description |\n|--------|----------|-------------|\n| List | GET /api/shelves | All shelves |\n| Get | GET /api/shelves/{id} | Single shelf |\n\n## API Methods\n```go\ntype ShelvesService struct {\n client *Client\n}\n\nfunc (s *ShelvesService) List(ctx context.Context, opts *ListOptions) ([]*Shelf, error)\nfunc (s *ShelvesService) Get(ctx context.Context, id int) (*Shelf, error)\nfunc (s *ShelvesService) ListAll(ctx context.Context) iter.Seq2[*Shelf, error]\n```\n\n## Shelf Fields\n- ID, Name, Slug, Description, CreatedAt, UpdatedAt\n\n## Bookstack Hierarchy\nShelf is the top-level container: Shelf -\u003e Book -\u003e Chapter -\u003e Page\n\n## Acceptance Criteria\n- [ ] ShelvesService struct created\n- [ ] List() returns paginated shelves\n- [ ] Get() returns single shelf by ID\n- [ ] ListAll() iterator implemented\n- [ ] Proper error handling\n- [ ] Unit tests with mock server","status":"closed","priority":1,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:39:53.490673653+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:53:07.163294684+01:00","closed_at":"2026-01-30T09:53:07.163294684+01:00","close_reason":"Closed"}
|
||||||
{"id":"bookstack-api-5gi","title":"Implement Attachments CRUD","description":"Implement CRUD operations for Attachments.\n\n## Requirements\nFrom PRD feature table: Attachments: CRUD (P2, v0.4)\n\n## API Endpoints (typical Bookstack pattern)\n- GET /api/attachments - List attachments\n- GET /api/attachments/{id} - Get attachment\n- POST /api/attachments - Create attachment\n- PUT /api/attachments/{id} - Update attachment\n- DELETE /api/attachments/{id} - Delete attachment\n\n## API Methods\n```go\ntype AttachmentsService struct {\n client *Client\n}\n\ntype Attachment struct {\n ID int `json:\"id\"`\n Name string `json:\"name\"`\n Extension string `json:\"extension\"`\n PageID int `json:\"uploaded_to\"`\n CreatedAt time.Time `json:\"created_at\"`\n UpdatedAt time.Time `json:\"updated_at\"`\n}\n\nfunc (s *AttachmentsService) List(ctx context.Context, opts *ListOptions) ([]*Attachment, error)\nfunc (s *AttachmentsService) Get(ctx context.Context, id int) (*Attachment, error)\nfunc (s *AttachmentsService) Create(ctx context.Context, req *AttachmentCreateRequest) (*Attachment, error)\nfunc (s *AttachmentsService) Update(ctx context.Context, id int, req *AttachmentUpdateRequest) (*Attachment, error)\nfunc (s *AttachmentsService) Delete(ctx context.Context, id int) error\n```\n\n## Technical Details\n- May need multipart/form-data for file uploads\n- Consider file size limits\n\n## Acceptance Criteria\n- [ ] Attachment type defined\n- [ ] AttachmentsService with all CRUD methods\n- [ ] File upload handling\n- [ ] Unit tests with mock server","status":"closed","priority":2,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:39:54.242422591+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:55:03.114941395+01:00","closed_at":"2026-01-30T09:55:03.114941395+01:00","close_reason":"Closed","comments":[{"id":5,"issue_id":"bookstack-api-5gi","author":"Oliver Jakoubek","text":"Plan: (1) Add Attachment type to types.go, (2) Create attachments.go with AttachmentsService, (3) For Create - Bookstack supports both file upload (multipart) and link attachments (JSON). Will implement link attachments via JSON for now since file upload requires multipart which is more complex. (4) List/Get/Update/Delete follow standard pattern. (5) Register service in bookstack.go Client struct.","created_at":"2026-01-30T08:54:20Z"}]}
|
{"id":"bookstack-api-5gi","title":"Implement Attachments CRUD","description":"Implement CRUD operations for Attachments.\n\n## Requirements\nFrom PRD feature table: Attachments: CRUD (P2, v0.4)\n\n## API Endpoints (typical Bookstack pattern)\n- GET /api/attachments - List attachments\n- GET /api/attachments/{id} - Get attachment\n- POST /api/attachments - Create attachment\n- PUT /api/attachments/{id} - Update attachment\n- DELETE /api/attachments/{id} - Delete attachment\n\n## API Methods\n```go\ntype AttachmentsService struct {\n client *Client\n}\n\ntype Attachment struct {\n ID int `json:\"id\"`\n Name string `json:\"name\"`\n Extension string `json:\"extension\"`\n PageID int `json:\"uploaded_to\"`\n CreatedAt time.Time `json:\"created_at\"`\n UpdatedAt time.Time `json:\"updated_at\"`\n}\n\nfunc (s *AttachmentsService) List(ctx context.Context, opts *ListOptions) ([]*Attachment, error)\nfunc (s *AttachmentsService) Get(ctx context.Context, id int) (*Attachment, error)\nfunc (s *AttachmentsService) Create(ctx context.Context, req *AttachmentCreateRequest) (*Attachment, error)\nfunc (s *AttachmentsService) Update(ctx context.Context, id int, req *AttachmentUpdateRequest) (*Attachment, error)\nfunc (s *AttachmentsService) Delete(ctx context.Context, id int) error\n```\n\n## Technical Details\n- May need multipart/form-data for file uploads\n- Consider file size limits\n\n## Acceptance Criteria\n- [ ] Attachment type defined\n- [ ] AttachmentsService with all CRUD methods\n- [ ] File upload handling\n- [ ] Unit tests with mock server","status":"closed","priority":2,"issue_type":"feature","owner":"mail@oliverjakoubek.de","created_at":"2026-01-28T09:39:54.242422591+01:00","created_by":"Oliver Jakoubek","updated_at":"2026-01-30T09:55:03.114941395+01:00","closed_at":"2026-01-30T09:55:03.114941395+01:00","close_reason":"Closed","comments":[{"id":5,"issue_id":"bookstack-api-5gi","author":"Oliver Jakoubek","text":"Plan: (1) Add Attachment type to types.go, (2) Create attachments.go with AttachmentsService, (3) For Create - Bookstack supports both file upload (multipart) and link attachments (JSON). Will implement link attachments via JSON for now since file upload requires multipart which is more complex. (4) List/Get/Update/Delete follow standard pattern. (5) Register service in bookstack.go Client struct.","created_at":"2026-01-30T08:54:20Z"}]}
|
||||||
|
|
|
||||||
59
examples/basic/main.go
Normal file
59
examples/basic/main.go
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Basic example: set up client, list books, get a page.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
bookstack "code.beautifulmachines.dev/jakoubek/bookstack-api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client, err := bookstack.NewClient(bookstack.Config{
|
||||||
|
BaseURL: os.Getenv("BOOKSTACK_URL"),
|
||||||
|
TokenID: os.Getenv("BOOKSTACK_TOKEN_ID"),
|
||||||
|
TokenSecret: os.Getenv("BOOKSTACK_TOKEN_SECRET"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// List first 5 books
|
||||||
|
books, err := client.Books.List(ctx, &bookstack.ListOptions{Count: 5})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, book := range books {
|
||||||
|
fmt.Printf("Book %d: %s\n", book.ID, book.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the first page if any books exist
|
||||||
|
if len(books) > 0 {
|
||||||
|
pages, err := client.Pages.List(ctx, &bookstack.ListOptions{
|
||||||
|
Count: 1,
|
||||||
|
Filter: map[string]string{"book_id": fmt.Sprintf("%d", books[0].ID)},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(pages) > 0 {
|
||||||
|
page, err := client.Pages.Get(ctx, pages[0].ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("\nPage: %s\n%s\n", page.Name, page.HTML[:min(200, len(page.HTML))])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func min(a, b int) int {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
59
examples/export/main.go
Normal file
59
examples/export/main.go
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Export example: export a page to markdown or PDF.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
bookstack "code.beautifulmachines.dev/jakoubek/bookstack-api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 3 {
|
||||||
|
fmt.Fprintf(os.Stderr, "Usage: %s <page-id> <markdown|pdf>\n", os.Args[0])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pageID, err := strconv.Atoi(os.Args[1])
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Invalid page ID: %s", os.Args[1])
|
||||||
|
}
|
||||||
|
format := os.Args[2]
|
||||||
|
|
||||||
|
client, err := bookstack.NewClient(bookstack.Config{
|
||||||
|
BaseURL: os.Getenv("BOOKSTACK_URL"),
|
||||||
|
TokenID: os.Getenv("BOOKSTACK_TOKEN_ID"),
|
||||||
|
TokenSecret: os.Getenv("BOOKSTACK_TOKEN_SECRET"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
switch format {
|
||||||
|
case "markdown":
|
||||||
|
data, err := client.Pages.ExportMarkdown(ctx, pageID)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Print(string(data))
|
||||||
|
|
||||||
|
case "pdf":
|
||||||
|
data, err := client.Pages.ExportPDF(ctx, pageID)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
filename := fmt.Sprintf("page-%d.pdf", pageID)
|
||||||
|
if err := os.WriteFile(filename, data, 0644); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Saved to %s (%d bytes)\n", filename, len(data))
|
||||||
|
|
||||||
|
default:
|
||||||
|
log.Fatalf("Unknown format: %s (use markdown or pdf)", format)
|
||||||
|
}
|
||||||
|
}
|
||||||
47
examples/search/main.go
Normal file
47
examples/search/main.go
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Search example: search for content and display results.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
bookstack "code.beautifulmachines.dev/jakoubek/bookstack-api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Fprintf(os.Stderr, "Usage: %s <search query>\n", os.Args[0])
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := bookstack.NewClient(bookstack.Config{
|
||||||
|
BaseURL: os.Getenv("BOOKSTACK_URL"),
|
||||||
|
TokenID: os.Getenv("BOOKSTACK_TOKEN_ID"),
|
||||||
|
TokenSecret: os.Getenv("BOOKSTACK_TOKEN_SECRET"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
query := os.Args[1]
|
||||||
|
|
||||||
|
results, err := client.Search.Search(ctx, query, &bookstack.ListOptions{Count: 10})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Search results for %q:\n\n", query)
|
||||||
|
for i, r := range results {
|
||||||
|
fmt.Printf("%d. [%s] %s (score: %.1f)\n", i+1, r.Type, r.Name, r.Score)
|
||||||
|
if r.Preview != "" {
|
||||||
|
fmt.Printf(" %s\n", r.Preview)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) == 0 {
|
||||||
|
fmt.Println("No results found.")
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue