Coverage for pyquickhelper/helpgen/utils_sphinx_config.py: 62%
98 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-03 02:21 +0200
1"""
2@file
3@brief Check various settings.
4"""
5import sys
6import os
7import site
8from io import BytesIO
9import urllib.request as urllib_request
12def getsitepackages():
13 """
14 Overwrites function :epkg:`getsitepackages`
15 which does not work for a virtual environment.
17 @return site-package somewhere
18 """
19 try:
20 return site.getsitepackages()
21 except AttributeError:
22 import sphinx
23 return [os.path.normpath(os.path.join(os.path.dirname(sphinx.__file__), ".."))]
26def locate_image_documentation(image_name):
27 """
28 Tries to local an image in the module for help generation in a folder ``_doc``.
30 @param image_name path
31 @return local file
33 When a notebook is taken out from the sources, the image using NbImage
34 cannot be displayed because the function cannot guess from which project
35 it was taken. The function was entering an infinite loop.
36 The function can deal with subfolder and not only the folder which contains the notebook.
37 """
38 image_name = os.path.abspath(image_name)
39 if os.path.exists(image_name):
40 return image_name
41 folder, filename = os.path.split(image_name)
42 while (len(folder) > 0 and
43 (not os.path.exists(folder) or "_doc" not in os.listdir(folder))):
44 fold = os.path.split(folder)[0]
45 if fold == folder:
46 break
47 folder = fold
48 doc = os.path.join(folder, "_doc")
49 if not os.path.exists(doc):
50 raise FileNotFoundError(
51 "Unable to find a folder called _doc, "
52 "the function cannot locate an image %r, doc=%r, folder=%r."
53 "" % (image_name, doc, folder))
54 for root, _, files in os.walk(doc):
55 for name in files:
56 t = os.path.join(root, name)
57 fn = os.path.split(t)[-1]
58 if filename == fn:
59 return t
60 raise FileNotFoundError(image_name)
63def _NbImage_path(name, repository=None, force_github=False, branch='master'):
64 if not isinstance(name, str):
65 return name
66 if os.path.exists(name):
67 return os.path.abspath(name).replace("\\", "/")
68 if not name.startswith('http://') and not name.startswith('https://'):
69 # local file
70 local = name
71 local_split = name.split("/")
72 if "notebooks" not in local_split:
73 local = locate_image_documentation(local)
74 return local
75 else:
76 return name
78 # otherwise --> github
79 paths = local.replace("\\", "/").split("/")
80 try:
81 pos = paths.index("notebooks") - 1
82 except IndexError as e:
83 # we are looking for the right path
84 raise IndexError(
85 "The image is not retrieved from a notebook from a folder "
86 "`_docs/notebooks` or you changed the current folder:"
87 "\n{0}".format(local)) from e
88 except ValueError as ee:
89 # we are looking for the right path
90 raise IndexError(
91 "The image is not retrieve from a notebook from a folder "
92 "``_docs/notebooks`` or you changed the current folder:"
93 "\n{0}".format(local)) from ee
95 if repository is None:
96 module = paths[pos - 1]
97 if module not in sys.modules:
98 if "ensae_teaching_cs" in local:
99 # For some specific modules, we add the location.
100 repository = "https://github.com/sdpython/ensae_teaching_cs/"
101 else:
102 raise ImportError(
103 "The module {0} was not imported, cannot guess "
104 "the location of the repository".format(module))
105 else:
106 modobj = sys.modules[module]
107 if not hasattr(modobj, "__github__"):
108 raise AttributeError(
109 "The module has no attribute '__github__'. "
110 "The repository cannot be guessed.")
111 repository = modobj.__github__
112 repository = repository.rstrip("/")
114 loc = "/".join([branch, "_doc", "notebooks"] + paths[pos + 2:])
115 url = repository + "/" + loc
116 url = url.replace("github.com", "raw.githubusercontent.com")
117 return url
120def _NbImage(url, width=None):
121 if isinstance(url, str):
122 if url.startswith('http://') or url.startswith('https://'):
123 with urllib_request.urlopen(url) as u:
124 text = u.read()
125 content = BytesIO(text)
126 return NbImage(content)
127 return NbImage(url, width=width)
130def NbImage(*name, repository=None, force_github=False, width=None,
131 branch='master', row_height=200, background=(255, 255, 255)):
132 """
133 Retrieves a name or a url of the image if it is not found in the local folder
134 or a subfolder.
136 :param name: image name (name.png) (or multiple names)
137 :param force_github: force the system to retrieve the image from GitHub
138 :param repository: repository, see below
139 :param width: to modify the width
140 :param branch: branch
141 :param row_height: row height if there are multiple images
142 :param background: background color (only if there multiple images)
143 :return: an `Image object
144 <http://ipython.org/ipython-doc/2/api/generated/IPython.core.display.html
145 #IPython.core.display.Image>`_
147 We assume the image is retrieved from a notebook.
148 This function will display an image even though the notebook is not run
149 from the sources. IPython must be installed.
151 if *repository* is None, then the function will use the variable
152 ``module.__github__`` to guess the location of the image.
153 The function is able to retrieve an image in a subfolder.
154 Displays a better message if ``__github__`` was not found.
156 See notebook :ref:`examplenbimagerst`.
157 """
158 from IPython.core.display import Image
159 if len(name) == 1:
160 url = _NbImage_path(
161 name[0], repository=repository,
162 force_github=force_github, branch=branch)
163 return Image(url, width=width)
165 if len(name) == 0:
166 raise ValueError( # pragma: no cover
167 "No image to display.")
169 from ..imghelper.img_helper import concat_images
170 from PIL import Image as pil_image
171 images = []
172 for img in name:
173 url = _NbImage_path(
174 img, repository=repository,
175 force_github=force_github, branch=branch)
176 if url.startswith('http://') or url.startswith('https://'):
177 with urllib_request.urlopen(url) as u:
178 text = u.read()
179 content = BytesIO(text)
180 images.append(pil_image.open(content))
181 else:
182 images.append(pil_image.open(url))
184 if width is None:
185 width = max(img.size[0] for img in images) * 2
186 width = max(200, width)
188 new_image = concat_images(images, width=width, height=row_height,
189 background=background)
190 b = BytesIO()
191 new_image.save(b, format='png')
192 data = b.getvalue()
193 return Image(data, width=width)