13 baseUrlPtr := flag.String("baseurl", "", "The base URL of your BookStack instance")
14 tokenId := flag.String("tokenid", "", "Your BookStack API Token ID")
15 tokenSecret := flag.String("tokensecret", "", "Your BookStack API Token Secret")
16 exportDir := flag.String("exportdir", "./page-export", "The directory to store exported data")
20 if *baseUrlPtr == "" || *tokenId == "" || *tokenSecret == "" {
21 panic("baseurl, tokenid and tokensecret arguments are required")
24 api := NewBookStackApi(*baseUrlPtr, *tokenId, *tokenSecret)
26 // Grab all content from BookStack
27 fmt.Println("Fetching books...")
28 bookIdMap := getBookMap(api)
29 fmt.Printf("Fetched %d books\n", len(bookIdMap))
30 fmt.Println("Fetching chapters...")
31 chapterIdMap := getChapterMap(api)
32 fmt.Printf("Fetched %d chapters\n", len(chapterIdMap))
33 fmt.Println("Fetching pages...")
34 pageIdMap := getPageMap(api)
35 fmt.Printf("Fetched %d pages\n", len(pageIdMap))
37 // Track progress when going through our pages
38 pageCount := len(pageIdMap)
41 // Cycle through each of our fetches pages
42 for _, p := range pageIdMap {
43 fmt.Printf("Exporting page %d/%d [%s]\n", currentCount, pageCount, p.Name)
44 // Get the full page content
45 fullPage := api.GetPage(p.Id)
47 // Work out a book+chapter relative path
48 book := bookIdMap[fullPage.BookId]
50 if chapter, ok := chapterIdMap[fullPage.ChapterId]; ok {
51 path = "/" + chapter.Slug
54 // Get the html, or markdown, content from our page along with the file name
55 // based upon the page slug
56 content := fullPage.Html
57 fName := fullPage.Slug + ".html"
58 if fullPage.Markdown != "" {
59 content = fullPage.Markdown
60 fName = fullPage.Slug + ".md"
63 // Create our directory path
64 absExportPath, err := filepath.Abs(*exportDir)
69 absPath := filepath.Join(absExportPath, path)
70 err = os.MkdirAll(absPath, 0744)
75 // Write the content to the filesystem
76 fPath := filepath.Join(absPath, fName)
77 err = os.WriteFile(fPath, []byte(content), 0644)
82 // Wait to avoid hitting rate limits
83 time.Sleep(time.Second / 4)