]> BookStack Code Mirror - api-scripts/blob - ruby-generate-csv-list-of-all-pages/export_pages.rb
Adding a Ruby example, exporting list of all pages for use in CSV/Excel
[api-scripts] / ruby-generate-csv-list-of-all-pages / export_pages.rb
1 require 'csv'
2 require 'httparty'
3 require 'dotenv/load'
4 require 'logger'
5 require 'bundler/setup'
6
7 Bundler.require(:default)
8
9 logger = Logger.new('bookstack.log')
10
11 class BookStackAPI
12   include HTTParty
13   base_uri ENV['BS_URL']
14   headers 'Authorization' => "Token #{ENV['BS_TOKEN_ID']}:#{ENV['BS_TOKEN_SECRET']}"
15   format :json
16
17   def self.get(path, options = {})
18     url = "#{base_uri}#{path}"
19     ::Logger.new(STDOUT).info("Making GET request to: #{url}")
20     ::Logger.new(STDOUT).info("Query parameters: #{options[:query]}")
21     response = super(path, options)
22     ::Logger.new(STDOUT).info("Response status: #{response.code}")
23     response
24   end
25 end
26
27 def get_all_items(path)
28   results = []
29   page_size = 500
30   offset = 0
31   total = 1
32
33   while offset < total
34     sleep(0.5) if offset > 0
35
36     response = BookStackAPI.get(path, query: { count: page_size, offset: offset })
37     total = response['total']
38     offset += page_size
39
40     results.concat(response['data'])
41   end
42
43   ::Logger.new(STDOUT).info("Retrieved #{results.count} items from #{path}")
44   results
45 end
46
47 def generate_csv(pages, books, shelves)
48   book_map = books.map { |book| [book['id'], book] }.to_h
49   shelf_map = shelves.map { |shelf| [shelf['id'], shelf] }.to_h
50
51   CSV.open('bookstack_data.csv', 'w') do |csv|
52     csv << ['Type', 'ID', 'Name', 'URL', 'Book ID', 'Book Name', 'Book URL', 'Shelf Name', 'Date Modified', 'Date Created']
53
54     pages.each do |page|
55       book = book_map[page['book_id']]
56       shelf_name = shelf_map[book['shelf_id']]['name'] if book && shelf_map[book['shelf_id']]
57       csv << [
58         'Page',
59         page['id'],
60         page['name'],
61         "=HYPERLINK(\"#{ENV['BS_URL']}/books/#{page['book_id']}/page/#{page['id']}\")",
62         page['book_id'],
63         book ? book['name'] : '',
64         "=HYPERLINK(\"#{ENV['BS_URL']}/books/#{page['book_id']}\")",
65         shelf_name || '',
66         page['updated_at'],
67         page['created_at']
68       ]
69     end
70
71     books.each do |book|
72       shelf_name = shelf_map[book['shelf_id']]['name'] if shelf_map[book['shelf_id']]
73       csv << [
74         'Book',
75         book['id'],
76         book['name'],
77         "=HYPERLINK(\"#{ENV['BS_URL']}/books/#{book['id']}\")",
78         '',
79         '',
80         '',
81         shelf_name || '',
82         book['updated_at'],
83         page['created_at']
84       ]
85     end
86   end
87 end
88
89 begin
90   logger.info('Started generating BookStack data CSV')
91   logger.info("BookStack URL: #{ENV['BS_URL']}")
92
93   pages = get_all_items('/api/pages')
94   books = get_all_items('/api/books')
95   shelves = get_all_items('/api/shelves')
96
97   generate_csv(pages, books, shelves)
98
99   logger.info('CSV file generated: bookstack_data.csv')
100 rescue StandardError => e
101   logger.error("Error: #{e.message}")
102   logger.error(e.backtrace.join("\n"))
103 end