switch to builtin http requests lib, update filetype names for BookStack v22.04.2
This commit is contained in:
parent
0047055c42
commit
3cd62ed06a
3 changed files with 25 additions and 20 deletions
|
@ -9,7 +9,6 @@ Customizable script for exporting notes from BookStack through API
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
- Python at least in version 3.6
|
- Python at least in version 3.6
|
||||||
- requests python library
|
|
||||||
|
|
||||||
Full example on how to use the script:
|
Full example on how to use the script:
|
||||||
1. Clone the repo
|
1. Clone the repo
|
||||||
|
|
43
exporter.py
43
exporter.py
|
@ -4,15 +4,13 @@ import logging
|
||||||
import os
|
import os
|
||||||
from logging import info, error
|
from logging import info, error
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from urllib.request import urlopen, Request
|
||||||
import requests
|
|
||||||
from requests import Response
|
|
||||||
|
|
||||||
logging.basicConfig(format='%(levelname)s :: %(message)s', level=logging.INFO)
|
logging.basicConfig(format='%(levelname)s :: %(message)s', level=logging.INFO)
|
||||||
|
|
||||||
# (formatName, fileExtension)
|
# (formatName, fileExtension)
|
||||||
FORMATS: dict['str', 'str'] = {
|
FORMATS: dict['str', 'str'] = {
|
||||||
'md': 'md',
|
'markdown': 'md',
|
||||||
'plaintext': 'txt',
|
'plaintext': 'txt',
|
||||||
'pdf': 'pdf',
|
'pdf': 'pdf',
|
||||||
'html': 'html'
|
'html': 'html'
|
||||||
|
@ -31,6 +29,10 @@ parser.add_argument('-f', '--formats', type=str, default='md',
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
formats = args.formats.split(',')
|
formats = args.formats.split(',')
|
||||||
|
for frmt in formats:
|
||||||
|
if frmt not in FORMATS.keys():
|
||||||
|
raise Exception("Unknown format name (NOT file extension), "
|
||||||
|
"check api docs for current version of your BookStack")
|
||||||
|
|
||||||
API_PREFIX: str = f"{args.host.removesuffix(os.path.sep)}/api"
|
API_PREFIX: str = f"{args.host.removesuffix(os.path.sep)}/api"
|
||||||
FS_PATH: str = args.path.removesuffix(os.path.sep)
|
FS_PATH: str = args.path.removesuffix(os.path.sep)
|
||||||
|
@ -80,24 +82,29 @@ def make_dir(path: str):
|
||||||
path_obj.mkdir(exist_ok=True, parents=True)
|
path_obj.mkdir(exist_ok=True, parents=True)
|
||||||
|
|
||||||
|
|
||||||
def api_get(path: str) -> dict:
|
def api_get_bytes(path: str) -> bytes:
|
||||||
response: Response = requests.get(f'{API_PREFIX}/{path}', headers=HEADERS)
|
request: Request = Request(f'{API_PREFIX}/{path}', headers=HEADERS)
|
||||||
|
|
||||||
if response.status_code == 403:
|
with urlopen(request) as response:
|
||||||
error("403 Forbidden, check your token!")
|
response = response
|
||||||
exit(response.status_code)
|
if response.status == 403:
|
||||||
|
error("403 Forbidden, check your token!")
|
||||||
|
exit(response.status)
|
||||||
|
|
||||||
data: dict = json.loads(response.text)
|
return response.read()
|
||||||
return data
|
|
||||||
|
|
||||||
|
def api_get_dict(path: str) -> dict:
|
||||||
|
return json.loads(api_get_bytes(path).decode())
|
||||||
|
|
||||||
|
|
||||||
info("Getting info about Shelves and their Books")
|
info("Getting info about Shelves and their Books")
|
||||||
|
|
||||||
for shelf_data in api_get('shelves').get('data'):
|
for shelf_data in api_get_dict('shelves').get('data'):
|
||||||
shelf = Node(shelf_data.get('name'), None, shelf_data.get('id'))
|
shelf = Node(shelf_data.get('name'), None, shelf_data.get('id'))
|
||||||
shelves[shelf.get_id()] = shelf
|
shelves[shelf.get_id()] = shelf
|
||||||
|
|
||||||
shelf_details = json.loads(requests.get(f'{API_PREFIX}/shelves/{shelf.get_id()}', headers=HEADERS).text)
|
shelf_details = api_get_dict(f'shelves/{shelf.get_id()}')
|
||||||
|
|
||||||
if shelf_details.get('books') is None:
|
if shelf_details.get('books') is None:
|
||||||
continue
|
continue
|
||||||
|
@ -107,7 +114,7 @@ for shelf_data in api_get('shelves').get('data'):
|
||||||
|
|
||||||
info("Getting info about Books not belonging to any shelf")
|
info("Getting info about Books not belonging to any shelf")
|
||||||
|
|
||||||
for book_data in api_get('books').get('data'):
|
for book_data in api_get_dict('books').get('data'):
|
||||||
if book_data.get('id') != 0:
|
if book_data.get('id') != 0:
|
||||||
continue
|
continue
|
||||||
book = Node(book_data.get('name'), None, book_data.get('id'))
|
book = Node(book_data.get('name'), None, book_data.get('id'))
|
||||||
|
@ -116,12 +123,12 @@ for book_data in api_get('books').get('data'):
|
||||||
|
|
||||||
info("Getting info about Chapters")
|
info("Getting info about Chapters")
|
||||||
|
|
||||||
for chapter_data in api_get('chapters').get('data'):
|
for chapter_data in api_get_dict('chapters').get('data'):
|
||||||
chapter = Node(chapter_data.get('name'), books.get(chapter_data.get('book_id')), chapter_data.get('id'))
|
chapter = Node(chapter_data.get('name'), books.get(chapter_data.get('book_id')), chapter_data.get('id'))
|
||||||
chapters[chapter.get_id()] = chapter
|
chapters[chapter.get_id()] = chapter
|
||||||
|
|
||||||
info("Getting info about Pages")
|
info("Getting info about Pages")
|
||||||
for page_data in api_get('pages').get('data'):
|
for page_data in api_get_dict('pages').get('data'):
|
||||||
parent_id = page_data.get('chapter_id')
|
parent_id = page_data.get('chapter_id')
|
||||||
if parent_id == 0:
|
if parent_id == 0:
|
||||||
parent_id = page_data.get('book_id')
|
parent_id = page_data.get('book_id')
|
||||||
|
@ -140,10 +147,10 @@ for page in pages.values():
|
||||||
for frmt in formats:
|
for frmt in formats:
|
||||||
path: str = f"{FS_PATH}{os.path.sep}{page.get_path()}{os.path.sep}{page.get_name()}.{FORMATS[frmt]}"
|
path: str = f"{FS_PATH}{os.path.sep}{page.get_path()}{os.path.sep}{page.get_name()}.{FORMATS[frmt]}"
|
||||||
|
|
||||||
result: Response = requests.get(f'{API_PREFIX}/pages/{page.get_id()}/export/{frmt}', headers=HEADERS)
|
data: bytes = api_get_bytes(f'pages/{page.get_id()}/export/{frmt}')
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
info(f"Updating file with page \"{page.get_name()}.{FORMATS[frmt]}\"")
|
info(f"Updating file with page \"{page.get_name()}.{FORMATS[frmt]}\"")
|
||||||
else:
|
else:
|
||||||
info(f"Saving new file with page \"{page.get_name()}.{FORMATS[frmt]}\"")
|
info(f"Saving new file with page \"{page.get_name()}.{FORMATS[frmt]}\"")
|
||||||
with open(path, 'wb') as f:
|
with open(path, 'wb') as f:
|
||||||
f.write(result.content)
|
f.write(data)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
requests
|
|
Loading…
Reference in a new issue