Bookstack
Usuario / Pass Admin
admin@admin.com password
Url para Backup
https://dizzytech.de/posts/bookstack_how_to_backup/
Api tokens
Token ID
yYJJmpTpOmq0S2zGQ59AGSDTlB5y4TAZToken Secret
TIzFFAGPfOVWyMdoY13Wr5Pnatuj952JName
tellevo
Codigo Respaldo HTML Python
El siguiente codigo, obtenido los token de Bookstack, es posible generar los respaldos en html de todo el contenido de bookstack.
Esto viene de la Url para Backup de atras.
#!/usr/bin/env python3
import osimport requestsfrom urllib.parse import urljoin, urlencodefrom typing import List, Dict, Any
# API Credentials# You can either provide them as environment variables# or hard-code them in the empty strings belowAPI_URL = os.getenv('API_URL', 'http://bookstack.limachelocales.cl') or '' # http://bookstack.local/CLIENT_ID = os.getenv('API_CLIENT_ID', 'yYJJmpTpOmq0S2zGQ59AGSDTlB5y4TAZ') or ''CLIENT_SECRET = os.getenv('API_CLIENT_SECRET', 'TIzFFAGPfOVWyMdoY13Wr5Pnatuj952J') or ''
# Export Format & Location# Can be provided as arguments when calling the script# or be hard-coded as strings belowEXPORT_FORMAT='html'EXPORT_LOCATION = '/home/goviedo/proyectos/bookstack/htmls' # Destination path for the export
EXTENSION_BY_FORMAT = { 'pdf': 'pdf', 'html': 'html', 'plaintext': 'txt'}
def api_get(endpoint: str) -> str: """Make a simple GET HTTP request to the API.""" url = urljoin(API_URL.rstrip('/') + '/', endpoint.lstrip('/')) headers = {'Authorization': f'Token {CLIENT_ID}:{CLIENT_SECRET}'} response = requests.get(url, headers=headers) response.raise_for_status() return response.text
def api_get_json(endpoint: str) -> Dict[str, Any]: """Make a simple GET HTTP request to the API & decode the JSON response.""" url = urljoin(API_URL.rstrip('/') + '/', endpoint.lstrip('/')) headers = {'Authorization': f'Token {CLIENT_ID}:{CLIENT_SECRET}'} response = requests.get(url, headers=headers) response.raise_for_status() return response.json()
def get_all_books() -> List[Dict[str, Any]]: """Get all books from the system API.""" count = 100 offset = 0 total = 0 all_books = []
while True: endpoint = f'api/books?{urlencode({"count": count, "offset": offset})}' resp = api_get_json(endpoint)
# Only set total on first request, due to API bug: # https://github.com/BookStackApp/BookStack/issues/2043 if offset == 0: total = resp.get('total', 0)
new_books = resp.get('data', []) all_books.extend(new_books) offset += count
if offset >= total: break
return all_books
def dd(*args): """DEBUG: Dump out the given variables and exit.""" for arg in args: print(arg) exit(1)
def main(): """Main script logic.""" books = get_all_books() out_dir = os.path.realpath(EXPORT_LOCATION)
# Create export directory if it doesn't exist os.makedirs(out_dir, exist_ok=True)
for book in books: book_id = book['id'] extension = EXTENSION_BY_FORMAT.get(EXPORT_FORMAT, EXPORT_FORMAT) content = api_get(f"api/books/{book_id}/export/{EXPORT_FORMAT}") out_path = os.path.join(out_dir, f"{book['slug']}.{extension}")
with open(out_path, 'w', encoding='utf-8') as f: f.write(content)
if __name__ == '__main__': main()