From 8f8f0fb868b0935c43d2ea4158877529d948ccc9 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 25 Jun 2017 18:11:28 +0900 Subject: [PATCH 1/4] Fix #3860: Don't download images when builders not supported images --- CHANGES | 1 + sphinx/transforms/post_transforms/images.py | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 9ad92038d..4522b15c7 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,7 @@ Bugs fixed * #3873: Failure of deprecation warning mechanism of ``sphinx.util.compat.Directive`` * #3874: Bogus warnings for "citation not referenced" for cross-file citations +* #3860: Don't download images when builders not supported images Testing -------- diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index e1cc9f78b..196b6dd5e 100644 --- a/sphinx/transforms/post_transforms/images.py +++ b/sphinx/transforms/post_transforms/images.py @@ -57,7 +57,9 @@ class ImageDownloader(BaseImageConverter): def match(self, node): # type: (nodes.Node) -> bool - if self.app.builder.supported_remote_images: + if self.app.builder.supported_image_types == []: + return False + elif self.app.builder.supported_remote_images: return False else: return '://' in node['uri'] @@ -108,7 +110,9 @@ class DataURIExtractor(BaseImageConverter): def match(self, node): # type: (nodes.Node) -> bool - if self.app.builder.supported_data_uri_images: + if self.app.builder.supported_remote_images == []: + return False + elif self.app.builder.supported_data_uri_images is True: return False else: return 'data:' in node['uri'] From ea87cfba4fccdc86cacc3ebc54c96f6bf861d310 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 25 Jun 2017 18:49:13 +0900 Subject: [PATCH 2/4] Fix #3860: Remote image URIs without filename break builders not supported remote images --- CHANGES | 2 ++ sphinx/transforms/post_transforms/images.py | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4522b15c7..1bfbed055 100644 --- a/CHANGES +++ b/CHANGES @@ -39,6 +39,8 @@ Bugs fixed ``sphinx.util.compat.Directive`` * #3874: Bogus warnings for "citation not referenced" for cross-file citations * #3860: Don't download images when builders not supported images +* #3860: Remote image URIs without filename break builders not supported remote + images Testing -------- diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index 196b6dd5e..c57355774 100644 --- a/sphinx/transforms/post_transforms/images.py +++ b/sphinx/transforms/post_transforms/images.py @@ -20,7 +20,7 @@ from sphinx.transforms import SphinxTransform from sphinx.util import logging, requests from sphinx.util import epoch_to_rfc1123, rfc1123_to_epoch from sphinx.util.images import guess_mimetype, get_image_extension, parse_data_uri -from sphinx.util.osutil import ensuredir +from sphinx.util.osutil import ensuredir, movefile if False: # For type annotation @@ -69,6 +69,8 @@ class ImageDownloader(BaseImageConverter): basename = os.path.basename(node['uri']) if '?' in basename: basename = basename.split('?')[0] + if basename == '': + basename = sha1(node['uri']).hexdigest() dirname = node['uri'].replace('://', '/').translate({ord("?"): u"/", ord("&"): u"/"}) ensuredir(os.path.join(self.imagedir, dirname)) @@ -96,6 +98,14 @@ class ImageDownloader(BaseImageConverter): os.utime(path, (timestamp, timestamp)) mimetype = guess_mimetype(path, default='*') + if mimetype != '*' and os.path.splitext(basename)[1] == '': + # append a suffix if URI does not contain suffix + ext = get_image_extension(mimetype) + newpath = os.path.join(self.imagedir, dirname, basename + ext) + movefile(path, newpath) + self.app.env.original_image_uri.pop(path) + self.app.env.original_image_uri[newpath] = node['uri'] + path = newpath node['candidates'].pop('?') node['candidates'][mimetype] = path node['uri'] = path From 372e8f2c64c7e8aa530d79a57f9626ad542e1357 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 25 Jun 2017 18:51:49 +0900 Subject: [PATCH 3/4] Add simple svg tester for imghdr --- sphinx/util/images.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sphinx/util/images.py b/sphinx/util/images.py index 2d228e66d..eba295a3c 100644 --- a/sphinx/util/images.py +++ b/sphinx/util/images.py @@ -120,3 +120,17 @@ def parse_data_uri(uri): image_data = base64.b64decode(data) return DataURI(mimetype, charset, image_data) + + +def test_svg(h, f): + """An additional imghdr library helper; test the header is SVG's or not.""" + try: + if ' Date: Sun, 25 Jun 2017 18:52:12 +0900 Subject: [PATCH 4/4] Show correct URI if image candidate not found --- sphinx/builders/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index fdf524bf6..007964e82 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -22,6 +22,7 @@ from six import itervalues from docutils import nodes from sphinx.deprecation import RemovedInSphinx20Warning +from sphinx.environment.adapters.asset import ImageAdapter from sphinx.util import i18n, path_stabilize, logging, status_iterator from sphinx.util.osutil import SEP, relative_uri from sphinx.util.i18n import find_catalog @@ -200,6 +201,7 @@ class Builder(object): def post_process_images(self, doctree): # type: (nodes.Node) -> None """Pick the best candidate for all image URIs.""" + images = ImageAdapter(self.env) for node in doctree.traverse(nodes.image): if '?' in node['candidates']: # don't rewrite nonlocal image URIs @@ -210,7 +212,8 @@ class Builder(object): if candidate: break else: - logger.warning('no matching candidate for image URI %r', node['uri'], + logger.warning('no matching candidate for image URI %r', + images.get_original_image_uri(node['uri']), location=node) continue node['uri'] = candidate