diff --git a/CHANGES b/CHANGES index 5c1650c28..f0d4e8db5 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,9 @@ 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 +* #3860: Remote image URIs without filename break builders not supported remote + images * #3833: command line messages are translated unintentionally with ``language`` setting. * #3840: make checking ``epub_uid`` strict 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 diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index e1cc9f78b..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 @@ -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'] @@ -67,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)) @@ -94,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 @@ -108,7 +120,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'] 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 '