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

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 

10 

11 

12def getsitepackages(): 

13 """ 

14 Overwrites function :epkg:`getsitepackages` 

15 which does not work for a virtual environment. 

16 

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__), ".."))] 

24 

25 

26def locate_image_documentation(image_name): 

27 """ 

28 Tries to local an image in the module for help generation in a folder ``_doc``. 

29 

30 @param image_name path 

31 @return local file 

32 

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) 

61 

62 

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 

77 

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 

94 

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("/") 

113 

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 

118 

119 

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) 

128 

129 

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. 

135 

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>`_ 

146 

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. 

150 

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. 

155 

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) 

164 

165 if len(name) == 0: 

166 raise ValueError( # pragma: no cover 

167 "No image to display.") 

168 

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)) 

183 

184 if width is None: 

185 width = max(img.size[0] for img in images) * 2 

186 width = max(200, width) 

187 

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)