diff --git a/README.md b/README.md index 7a6b0f6..4ab2641 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,9 @@ usage: exporter.py [-h] [-p PATH] [-t TOKEN_FILE] [-H HOST] [--additional-headers ADDITIONAL_HEADERS [ADDITIONAL_HEADERS ...]] [-l {pages,chapters,books} [{pages,chapters,books} ...]] [--force-update-files] [--images] [--markdown-images] - [--images-dir IMAGES_DIR] [--dont-export-attachments] - [--dont-export-external-attachments] [-V {debug,info,warning,error}] + [--images-dir IMAGES_DIR] [--skip-broken-image-links] + [--dont-export-attachments] [--dont-export-external-attachments] + [-V {debug,info,warning,error}] BookStack exporter @@ -93,6 +94,10 @@ options: When exporting images, they will be organized in directory located at the same path as exported document. This parameter defines name of this directory. + --skip-broken-image-links + Don't fail and skip downloading images if their url obtained from + images gallery API seem broken (image cannot be downloaded OR fails to + download). --dont-export-attachments Set this to prevent exporting any attachments. --dont-export-external-attachments diff --git a/exporter.py b/exporter.py index b06893d..9784f91 100644 --- a/exporter.py +++ b/exporter.py @@ -9,6 +9,7 @@ import sys from typing import Dict, List, Union from urllib.request import urlopen, Request +from urllib.error import URLError, HTTPError import urllib.parse import base64 from time import time @@ -129,6 +130,12 @@ help='When exporting images, they will be organized in' ' directory located at the same path as exported document.' ' This parameter defines name of this directory.') +parser.add_argument('--skip-broken-image-links', + default=False, + action='store_true', + help="Don't fail and skip downloading images if their " + "url obtained from images gallery API seem broken " + "(image cannot be downloaded OR fails to download).") parser.add_argument('--dont-export-attachments', default=False, action='store_true', @@ -196,6 +203,7 @@ def removesuffix(text, suffix): HEADERS_NO_TOKEN[values[0]] = values[1] SKIP_TIMESTAMPS: bool = args.force_update_files +SKIP_BROKEN_IMAGE_LINKS: bool = args.skip_broken_image_links class ApiRateLimiter: @@ -533,7 +541,14 @@ def export_images(): if not check_if_update_needed(path, img): continue - data: bytes = api_get_bytes(img.get_url(), raw_url=True) + try: + data: bytes = api_get_bytes(img.get_url(), raw_url=True) + except (URLError, HTTPError) as exc: + error(f"Failed downloading image '{img.get_url()}': {exc}") + if not SKIP_BROKEN_IMAGE_LINKS: + sys.exit(1) + else: + continue with open(path, 'wb') as file: info(f"Saving {path}") file.write(data)