mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #3890 from tk0miya/3860_errors_caused_by_remote_images
3860 errors caused by remote images
This commit is contained in:
commit
04f5af982d
3
CHANGES
3
CHANGES
@ -38,6 +38,9 @@ Bugs fixed
|
|||||||
* #3873: Failure of deprecation warning mechanism of
|
* #3873: Failure of deprecation warning mechanism of
|
||||||
``sphinx.util.compat.Directive``
|
``sphinx.util.compat.Directive``
|
||||||
* #3874: Bogus warnings for "citation not referenced" for cross-file citations
|
* #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``
|
* #3833: command line messages are translated unintentionally with ``language``
|
||||||
setting.
|
setting.
|
||||||
* #3840: make checking ``epub_uid`` strict
|
* #3840: make checking ``epub_uid`` strict
|
||||||
|
@ -22,6 +22,7 @@ from six import itervalues
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx.deprecation import RemovedInSphinx20Warning
|
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 import i18n, path_stabilize, logging, status_iterator
|
||||||
from sphinx.util.osutil import SEP, relative_uri
|
from sphinx.util.osutil import SEP, relative_uri
|
||||||
from sphinx.util.i18n import find_catalog
|
from sphinx.util.i18n import find_catalog
|
||||||
@ -200,6 +201,7 @@ class Builder(object):
|
|||||||
def post_process_images(self, doctree):
|
def post_process_images(self, doctree):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
"""Pick the best candidate for all image URIs."""
|
"""Pick the best candidate for all image URIs."""
|
||||||
|
images = ImageAdapter(self.env)
|
||||||
for node in doctree.traverse(nodes.image):
|
for node in doctree.traverse(nodes.image):
|
||||||
if '?' in node['candidates']:
|
if '?' in node['candidates']:
|
||||||
# don't rewrite nonlocal image URIs
|
# don't rewrite nonlocal image URIs
|
||||||
@ -210,7 +212,8 @@ class Builder(object):
|
|||||||
if candidate:
|
if candidate:
|
||||||
break
|
break
|
||||||
else:
|
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)
|
location=node)
|
||||||
continue
|
continue
|
||||||
node['uri'] = candidate
|
node['uri'] = candidate
|
||||||
|
@ -20,7 +20,7 @@ from sphinx.transforms import SphinxTransform
|
|||||||
from sphinx.util import logging, requests
|
from sphinx.util import logging, requests
|
||||||
from sphinx.util import epoch_to_rfc1123, rfc1123_to_epoch
|
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.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:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
@ -57,7 +57,9 @@ class ImageDownloader(BaseImageConverter):
|
|||||||
|
|
||||||
def match(self, node):
|
def match(self, node):
|
||||||
# type: (nodes.Node) -> bool
|
# 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
|
return False
|
||||||
else:
|
else:
|
||||||
return '://' in node['uri']
|
return '://' in node['uri']
|
||||||
@ -67,6 +69,8 @@ class ImageDownloader(BaseImageConverter):
|
|||||||
basename = os.path.basename(node['uri'])
|
basename = os.path.basename(node['uri'])
|
||||||
if '?' in basename:
|
if '?' in basename:
|
||||||
basename = basename.split('?')[0]
|
basename = basename.split('?')[0]
|
||||||
|
if basename == '':
|
||||||
|
basename = sha1(node['uri']).hexdigest()
|
||||||
dirname = node['uri'].replace('://', '/').translate({ord("?"): u"/",
|
dirname = node['uri'].replace('://', '/').translate({ord("?"): u"/",
|
||||||
ord("&"): u"/"})
|
ord("&"): u"/"})
|
||||||
ensuredir(os.path.join(self.imagedir, dirname))
|
ensuredir(os.path.join(self.imagedir, dirname))
|
||||||
@ -94,6 +98,14 @@ class ImageDownloader(BaseImageConverter):
|
|||||||
os.utime(path, (timestamp, timestamp))
|
os.utime(path, (timestamp, timestamp))
|
||||||
|
|
||||||
mimetype = guess_mimetype(path, default='*')
|
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'].pop('?')
|
||||||
node['candidates'][mimetype] = path
|
node['candidates'][mimetype] = path
|
||||||
node['uri'] = path
|
node['uri'] = path
|
||||||
@ -108,7 +120,9 @@ class DataURIExtractor(BaseImageConverter):
|
|||||||
|
|
||||||
def match(self, node):
|
def match(self, node):
|
||||||
# type: (nodes.Node) -> bool
|
# 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
|
return False
|
||||||
else:
|
else:
|
||||||
return 'data:' in node['uri']
|
return 'data:' in node['uri']
|
||||||
|
@ -120,3 +120,17 @@ def parse_data_uri(uri):
|
|||||||
|
|
||||||
image_data = base64.b64decode(data)
|
image_data = base64.b64decode(data)
|
||||||
return DataURI(mimetype, charset, image_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 '<svg' in h.decode('utf-8').lower():
|
||||||
|
return 'svg+xml'
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# install test_svg() to imghdr
|
||||||
|
# refs: https://docs.python.org/3.6/library/imghdr.html#imghdr.tests
|
||||||
|
imghdr.tests.append(test_svg)
|
||||||
|
Loading…
Reference in New Issue
Block a user