Skip to content
This repository has been archived by the owner on Jul 27, 2024. It is now read-only.

Adding a Ruby example, exporting list of all pages for use in CSV/Excel #20

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ruby-generate-csv-list-of-all-pages/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
BS_URL=<your_bookstack_url>
BS_TOKEN_ID=<your_api_token_id>
BS_TOKEN_SECRET=<your_api_token_secret>
5 changes: 5 additions & 0 deletions ruby-generate-csv-list-of-all-pages/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source 'https://rubygems.org'

gem 'httparty'
gem 'dotenv'
gem 'logger'
78 changes: 78 additions & 0 deletions ruby-generate-csv-list-of-all-pages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# BookStack Data Exporter

This Ruby script allows you to export data from a BookStack instance into a CSV file. The exported data includes information about pages, books, and shelves, along with their respective URLs and modification dates.

## Prerequisites

Before running the script, make sure you have the following:

- Ruby installed on your system
- Access to a BookStack instance with API enabled
- BookStack API token ID and token secret

## Installation

1. Clone this repository or download the script file.
2. Install the required dependencies by running the following command:

```
bundle install
```

3. Create a `.env` file in the same directory as the script and provide the following environment variables:

```
BS_URL=<your_bookstack_url>
BS_TOKEN_ID=<your_api_token_id>
BS_TOKEN_SECRET=<your_api_token_secret>
```

Replace `<your_bookstack_url>`, `<your_api_token_id>`, and `<your_api_token_secret>` with your actual BookStack URL, API token ID, and API token secret, respectively.

## Usage

To run the script and export the data, execute the following command:

```
ruby export_bookstack_data.rb
```

The script will retrieve data from your BookStack instance and generate a CSV file named `bookstack_data.csv` in the same directory.

## CSV Output

The generated CSV file will have the following columns:

- Type: Indicates whether the row represents a page or a book.
- ID: The unique identifier of the page or book.
- Name: The name of the page or book.
- URL: The URL of the page or book, formatted as an Excel hyperlink.
- Book ID: The ID of the book to which the page belongs (applicable only for pages).
- Book Name: The name of the book to which the page belongs (applicable only for pages).
- Book URL: The URL of the book, formatted as an Excel hyperlink (applicable only for pages).
- Shelf Name: The name of the shelf to which the book belongs.
- Date Modified: The last modification date of the page or book.

The URLs in the 'URL' and 'Book URL' columns are wrapped in the `=HYPERLINK()` function, allowing you to easily access the respective pages and books directly from the CSV file when opened in Excel.
HYPERLINK() - is an Excel shortcut to make URL clickable, feel free to remove, if you don't use Excel.

## Logging

Logging to STDOUT, but can be adjusted to a file.

## Example

Here's an example of how the generated CSV file might look.

```
Type,ID,Name,URL,Book ID,Book Name,Book URL,Shelf Name,Date Modified
Page,1,Introduction,=HYPERLINK("https://example.com/books/1/page/1"),1,User Guide,=HYPERLINK("https://example.com/books/1"),Getting Started,2023-05-01T10:00:00.000000Z
Page,2,Installation,=HYPERLINK("https://example.com/books/1/page/2"),1,User Guide,=HYPERLINK("https://example.com/books/1"),Getting Started,2023-05-02T11:30:00.000000Z
Book,1,User Guide,=HYPERLINK("https://example.com/books/1"),,,,Getting Started,2023-05-01T09:00:00.000000Z
```

## License

This script is released under the [MIT License](LICENSE).

Feel free to customize and adapt the script to suit your specific requirements.
103 changes: 103 additions & 0 deletions ruby-generate-csv-list-of-all-pages/export_pages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
require 'csv'
require 'httparty'
require 'dotenv/load'
require 'logger'
require 'bundler/setup'

Bundler.require(:default)

logger = Logger.new('bookstack.log')

class BookStackAPI
include HTTParty
base_uri ENV['BS_URL']
headers 'Authorization' => "Token #{ENV['BS_TOKEN_ID']}:#{ENV['BS_TOKEN_SECRET']}"
format :json

def self.get(path, options = {})
url = "#{base_uri}#{path}"
::Logger.new(STDOUT).info("Making GET request to: #{url}")
::Logger.new(STDOUT).info("Query parameters: #{options[:query]}")
response = super(path, options)
::Logger.new(STDOUT).info("Response status: #{response.code}")
response
end
end

def get_all_items(path)
results = []
page_size = 500
offset = 0
total = 1

while offset < total
sleep(0.5) if offset > 0

response = BookStackAPI.get(path, query: { count: page_size, offset: offset })
total = response['total']
offset += page_size

results.concat(response['data'])
end

::Logger.new(STDOUT).info("Retrieved #{results.count} items from #{path}")
results
end

def generate_csv(pages, books, shelves)
book_map = books.map { |book| [book['id'], book] }.to_h
shelf_map = shelves.map { |shelf| [shelf['id'], shelf] }.to_h

CSV.open('bookstack_data.csv', 'w') do |csv|
csv << ['Type', 'ID', 'Name', 'URL', 'Book ID', 'Book Name', 'Book URL', 'Shelf Name', 'Date Modified', 'Date Created']

pages.each do |page|
book = book_map[page['book_id']]
shelf_name = shelf_map[book['shelf_id']]['name'] if book && shelf_map[book['shelf_id']]
csv << [
'Page',
page['id'],
page['name'],
"=HYPERLINK(\"#{ENV['BS_URL']}/books/#{page['book_id']}/page/#{page['id']}\")",
page['book_id'],
book ? book['name'] : '',
"=HYPERLINK(\"#{ENV['BS_URL']}/books/#{page['book_id']}\")",
shelf_name || '',
page['updated_at'],
page['created_at']
]
end

books.each do |book|
shelf_name = shelf_map[book['shelf_id']]['name'] if shelf_map[book['shelf_id']]
csv << [
'Book',
book['id'],
book['name'],
"=HYPERLINK(\"#{ENV['BS_URL']}/books/#{book['id']}\")",
'',
'',
'',
shelf_name || '',
book['updated_at'],
page['created_at']
]
end
end
end

begin
logger.info('Started generating BookStack data CSV')
logger.info("BookStack URL: #{ENV['BS_URL']}")

pages = get_all_items('/api/pages')
books = get_all_items('/api/books')
shelves = get_all_items('/api/shelves')

generate_csv(pages, books, shelves)

logger.info('CSV file generated: bookstack_data.csv')
rescue StandardError => e
logger.error("Error: #{e.message}")
logger.error(e.backtrace.join("\n"))
end