##// END OF EJS Templates
fix testing all subpath where to install mathjax
Bussonnier Matthias -
Show More
@@ -1,304 +1,316 b''
1 1 #!/usr/bin/python
2 2 """Utility function for installing MathJax javascript library into
3 3 the notebook's 'static' directory, for offline use.
4 4
5 5 Authors:
6 6
7 7 * Min RK
8 8 * Mark Sienkiewicz
9 9 * Matthias Bussonnier
10 10
11 11 To download and install MathJax:
12 12
13 13 From Python:
14 14
15 15 >>> from IPython.external.mathjax import install_mathjax
16 16 >>> install_mathjax()
17 17
18 18 From the command line:
19 19
20 20 $ python -m IPython.external.mathjax
21 21
22 22 To install MathJax from a file you have already downloaded:
23 23
24 24 $ python -m IPython.external.mathjax mathjax-xxx.tar.gz
25 25 $ python -m IPython.external.mathjax mathjax-xxx.zip
26 26
27 27 It will not install MathJax if it is already there. Use -r to
28 28 replace the existing copy of MathJax.
29 29
30 30 To find the directory where IPython would like MathJax installed:
31 31
32 32 $ python -m IPython.external.mathjax -d
33 33
34 34 """
35 35
36 36
37 37 #-----------------------------------------------------------------------------
38 38 # Copyright (C) 2008-2011 The IPython Development Team
39 39 #
40 40 # Distributed under the terms of the BSD License. The full license is in
41 41 # the file COPYING, distributed as part of this software.
42 42 #-----------------------------------------------------------------------------
43 43
44 44
45 45 #-----------------------------------------------------------------------------
46 46 # Imports
47 47 #-----------------------------------------------------------------------------
48 48
49 49 import os
50 50 import shutil
51 51 import sys
52 52 import tarfile
53 53 import urllib2
54 54 import zipfile
55 55
56 56
57 57 from IPython.utils.path import locate_profile
58 58 from IPython.external import argparse
59 59 #-----------------------------------------------------------------------------
60 60 #
61 61 #-----------------------------------------------------------------------------
62 62
63 63 # Where mathjax will be installed.
64 64
65 65 static = os.path.join(locate_profile('default'), 'static')
66 66 default_dest = os.path.join(static, 'mathjax')
67 67
68 68 ##
69 69
70 70 # Test for access to install mathjax.
71 71
72 72 def check_perms(dest, replace=False):
73 73 parent = os.path.abspath(os.path.join(dest, os.path.pardir))
74 if not os.access(parent, os.W_OK):
74 components = dest.split(os.path.sep)
75 subpaths = [ os.path.sep+os.path.sep.join(components[1:i]) for i in range(1,len(components))]
76
77 existing_path = filter(os.path.exists, subpaths)
78 last_writable = existing_path[-1]
79 if not os.access(last_writable, os.W_OK):
75 80 raise IOError("Need have write access to %s" % parent)
81 not_existing = [ path for path in subpaths if path not in existing_path]
82 # subfolder we will create, will obviously be writable
83 # should we still considere checking separately that
84 # ipython profiles have been created ?
85 for folder in not_existing:
86 os.mkdir(folder)
87
76 88 if os.path.exists(dest):
77 89 if replace:
78 90 if not os.access(dest, os.W_OK):
79 91 raise IOError("Need have write access to %s" % dest)
80 92 print "removing previous MathJax install"
81 93 shutil.rmtree(dest)
82 94 return True
83 95 else:
84 96 print "offline MathJax apparently already installed"
85 97 return False
86 98 else :
87 99 return True
88 100
89 101 ##
90 102
91 103 def extract_tar( fd, dest ) :
92 104 # use 'r|gz' stream mode, because socket file-like objects can't seek:
93 105 tar = tarfile.open(fileobj=fd, mode='r|gz')
94 106
95 107 # we just happen to know that the first entry in the mathjax
96 108 # archive is the directory that the remaining members are in.
97 109 topdir = tar.firstmember.path
98 110
99 111 # extract the archive (contains a single directory) to the static/ directory
100 112 parent = os.path.abspath(os.path.join(dest, os.path.pardir))
101 113 tar.extractall(parent)
102 114
103 115 # it will be mathjax-MathJax-<sha>, rename to just mathjax
104 116 os.rename(os.path.join(parent, topdir), dest)
105 117
106 118 ##
107 119
108 120 def extract_zip( fd, dest ) :
109 121 z = zipfile.ZipFile( fd, 'r' )
110 122
111 123 # we just happen to know that the first entry in the mathjax
112 124 # archive is the directory that the remaining members are in.
113 125 topdir = z.namelist()[0]
114 126
115 127 # extract the archive (contains a single directory) to the static/ directory
116 128 parent = os.path.abspath(os.path.join(dest, os.path.pardir))
117 129 z.extractall( parent )
118 130
119 131 # it will be mathjax-MathJax-<sha>, rename to just mathjax
120 132 d = os.path.join(parent, topdir)
121 133 print d
122 134 os.rename(os.path.join(parent, topdir), dest)
123 135
124 136 ##
125 137
126 138 def install_mathjax(tag='v2.0', dest=default_dest, replace=False, file=None, extractor=extract_tar ):
127 139 """Download and/or install MathJax for offline use.
128 140
129 141 This will install mathjax to the 'static' dir in the IPython notebook
130 142 package, so it will fail if the caller does not have write access
131 143 to that location.
132 144
133 145 MathJax is a ~15MB download, and ~150MB installed.
134 146
135 147 Parameters
136 148 ----------
137 149
138 150 replace : bool [False]
139 151 Whether to remove and replace an existing install.
140 152 dest : str [path to default profile]
141 153 Where to locally install mathjax
142 154 tag : str ['v2.0']
143 155 Which tag to download. Default is 'v2.0', the current stable release,
144 156 but alternatives include 'v1.1a' and 'master'.
145 157 file : file like object [ defualt to content of https://github.com/mathjax/MathJax/tarball/#{tag}]
146 158 File handle from which to untar/unzip/... mathjax
147 159 extractor : function
148 160 Method tu use to untar/unzip/... `file`
149 161 """
150 162 if not check_perms(dest, replace) :
151 163 return
152 164
153 165 if file is None :
154 166 # download mathjax
155 167 mathjax_url = "https://github.com/mathjax/MathJax/tarball/%s" % tag
156 168 print "Downloading mathjax source from %s" % mathjax_url
157 169 response = urllib2.urlopen(mathjax_url)
158 170 file = response.fp
159 171
160 172 print "Extracting to %s" % dest
161 173 extractor( file, dest )
162 174
163 175 ##
164 176
165 177 def test_func( remove, dest) :
166 178 """See if mathjax appears to be installed correctly"""
167 179 status = 0
168 180 if not os.path.isdir( dest ) :
169 181 print "%s directory not found" % dest
170 182 status = 1
171 183 if not os.path.exists( dest + "/MathJax.js" ) :
172 184 print "MathJax.js not present in %s" % dest
173 185 status = 1
174 186 print "ok"
175 187 if remove and os.path.exists(dest):
176 188 shutil.rmtree( dest )
177 189 return status
178 190
179 191 ##
180 192
181 193 def main() :
182 194 # This main is just simple enough that it is not worth the
183 195 # complexity of argparse
184 196
185 197 # What directory is mathjax in?
186 198 parser = argparse.ArgumentParser(
187 199 description="""Install mathjax from internet or local archive""",
188 200 )
189 201
190 202 parser.add_argument(
191 203 '-i',
192 204 '--install-dir',
193 205 default=default_dest,
194 206 help='installation directory (by default : %s)' % (default_dest))
195 207 parser.add_argument(
196 208 '-d',
197 209 '--dest',
198 210 action='store_true',
199 211 help='print where is current mathjax would be installed and exit')
200 212 parser.add_argument(
201 213 '-r',
202 214 '--replace',
203 215 action='store_true',
204 216 help='Wether to replace current mathjax if already exist')
205 217 parser.add_argument(
206 218 '-t',
207 219 '--test',
208 220 action='store_true')
209 221 parser.add_argument('tarball',
210 222 type=int,
211 223 help="the local tar/zip-ball containing mathjax",
212 224 nargs='?',
213 225 metavar='tarball')
214 226
215 227 pargs = parser.parse_args()
216 228
217 229 dest = pargs.install_dir
218 230 if pargs.dest :
219 231 print dest
220 232 return
221 233
222 234 # remove/replace existing mathjax?
223 235 if pargs.replace :
224 236 replace = True
225 237 else :
226 238 replace = False
227 239
228 240 # undocumented test interface
229 241 if pargs.test :
230 242 return test_func( replace, dest)
231 243
232 244 # do it
233 245 if pargs.tarball :
234 246 fname = pargs.tarball
235 247
236 248 # automatically detect zip/tar - could do something based
237 249 # on file content, but really not cost-effective here.
238 250 if fname.endswith('.zip') :
239 251 extractor = extract_zip
240 252 else :
241 253 extractor = extract_tar
242 254 # do it
243 255 install_mathjax(file=open(fname, "r"), replace=replace, extractor=extractor, dest=dest )
244 256 else:
245 257 install_mathjax(replace=replace, dest=dest)
246 258
247 259
248 260 if __name__ == '__main__' :
249 261 sys.exit(main())
250 262
251 263 __all__ = ['install_mathjax', 'main', 'dest']
252 264
253 265 """
254 266 Test notes:
255 267
256 268 IPython uses IPython.testing.iptest as a custom test controller
257 269 (though it is based on nose). It might be possible to fit automatic
258 270 tests of installation into that framework, but it looks awkward to me.
259 271 So, here is a manual procedure for testing this automatic installer.
260 272
261 273 Mark Sienkiewicz, 2012-08-06
262 274 first 8 letters of my last name @ stsci.edu
263 275
264 276 # remove mathjax from the installed ipython instance
265 277 # IOError ok if mathjax was never installed yet.
266 278
267 279 python -m IPython.external.mathjax --test -r
268 280
269 281 # download and install mathjax from command line:
270 282
271 283 python -m IPython.external.mathjax
272 284 python -m IPython.external.mathjax --test -r
273 285
274 286 # download and install from within python
275 287
276 288 python -c "from IPython.external.mathjax import install_mathjax; install_mathjax()"
277 289 python -m IPython.external.mathjax --test -r
278 290
279 291 # view http://www.mathjax.org/download/ in your browser
280 292 # save-as the link for MathJax-2.0 near the bottom of the page.
281 293 # The file it offers is mathjax-MathJax-v2.0-20-g07669ac.zip
282 294
283 295 python -m IPython.external.mathjax mathjax-MathJax-v2.0-20-g07669ac.zip
284 296 python -m IPython.external.mathjax --test -r
285 297
286 298 # download https://github.com/mathjax/MathJax/tarball/v2.0 in your browser
287 299 # (this is the url used internally by install_mathjax)
288 300 # The file it offers is mathjax-MathJax-v2.0-20-g07669ac.tar.gz
289 301
290 302 python -m IPython.external.mathjax mathjax-MathJax-v2.0-20-g07669ac.tar.gz
291 303
292 304 python -m IPython.external.mathjax --test
293 305 # note no -r
294 306
295 307 # install it again while it is already there
296 308
297 309 python -m IPython.external.mathjax mathjax-MathJax-v2.0-20-g07669ac.tar.gz
298 310 # says "offline MathJax apparently already installed"
299 311
300 312 python -m IPython.external.mathjax ~/mathjax-MathJax-v2.0-20-g07669ac.tar.gz
301 313 python -m IPython.external.mathjax --test
302 314
303 315
304 316 """
General Comments 0
You need to be logged in to leave comments. Login now