Skip to content

Commit

Permalink
Trac #30972: Versioned installation of threejs
Browse files Browse the repository at this point in the history
From Matthias Koeppe on #30915:

When we start using Sage with a system jupyter notebook (Meta-ticket
#30306), there is an issue involving the installation directory
`share/jupyter/nbextensions/threejs`, and the fact that there will be
several unrelated (and possibly mutually incompatible) copies of that.

Here is an example.

Let's say:
- system jupyter is installed in `/usr`, so the notebook server is
accessing `/usr/share/jupyter/nbextensions`.
- Sage-9.x may be installed in `/home/x/sage-9.x/local/` and may need
threejs r122.
- Sage-9.y may be installed in `/home/x/sage-9.y/local/` and may need
threejs r155.
- Let's say r122 and r155 are mutually incompatible.

As @enriqueartal has reported in #30915, our offline threejs graphics
needs `/usr/share/jupyter/nbextensions/threejs/`. But the system does
not provide it -- it is only provided by Sage (and, after #30915 is the
result of a custom build (fork) of threejs).

If we create a symlink `/usr/share/jupyter/nbextensions/threejs` ->
`/home/x/sage-9.x/local/share/jupyter/nbextensions/threejs`, then Sage
9.x will work with the system jupyter notebook; but Sage 9.y will not.

This means that we need a versioned installation scheme so that offline
threejs graphics can access the specific version it needs even if the
user is accessing Sage through the system notebook.

In this ticket we also rename directories from `threejs` to `threejs-
sage` (in `share/` and `share/jupyter/nbextensions/`) to reflect the
fact that it is a Sage-specific fork.  This will reduce the need for
downstream patching.

(On this ticket we ignore the separate issue that installing such
symlinks is not user-friendly -- see #30123 Repackage Sage's cropped
`threejs` as a pip-installable package `jupyter-threejs-sage` for a
follow-up.)

URL: https://trac.sagemath.org/30972
Reported by: paulmasson
Ticket author(s): Matthias Koeppe, Joshua Campbell
Reviewer(s): Joshua Campbell, Matthias Koeppe, Dima Pasechnik
  • Loading branch information
Release Manager committed Jun 29, 2021
2 parents 70c0b07 + 935dcef commit 098a247
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 14 deletions.
2 changes: 1 addition & 1 deletion build/pkgs/sage_conf/src/sage_conf.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ SAGE_PKG_CONFIG_PATH = "@SAGE_PKG_CONFIG_PATH@".replace('$SAGE_LOCAL', SAGE_LOCA

# Used in sage.repl.ipython_kernel.install
MATHJAX_DIR = SAGE_LOCAL + "/share/mathjax"
THREEJS_DIR = SAGE_LOCAL + "/share/threejs"
THREEJS_DIR = SAGE_LOCAL + "/share/threejs-sage"

# OpenMP flags, if available.
OPENMP_CFLAGS = "@OPENMP_CFLAGS@"
Expand Down
2 changes: 1 addition & 1 deletion build/pkgs/threejs/package-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
r122
r122.p0
3 changes: 2 additions & 1 deletion build/pkgs/threejs/spkg-install.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
sdh_install src/* "${SAGE_SHARE}/threejs"
sdh_install src/version "${SAGE_SHARE}/threejs-sage/"
sdh_install -T src/build "${SAGE_SHARE}/threejs-sage/$(cat src/version)"
2 changes: 1 addition & 1 deletion src/sage/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st
JMOL_DIR = var("JMOL_DIR", join(SAGE_SHARE, "jmol"))
MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax"))
MTXLIB = var("MTXLIB", join(SAGE_SHARE, "meataxe"))
THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs"))
THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs-sage"))
SINGULARPATH = var("SINGULARPATH", join(SAGE_SHARE, "singular"))
PPLPY_DOCS = var("PPLPY_DOCS", join(SAGE_SHARE, "doc", "pplpy"))
MAXIMA = var("MAXIMA", "maxima")
Expand Down
1 change: 1 addition & 0 deletions src/sage/ext_data/threejs/threejs-version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
r122
4 changes: 2 additions & 2 deletions src/sage/repl/ipython_kernel/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ def use_local_threejs(self):
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
sage: spec = SageKernelSpec(prefix=tmp_dir())
sage: spec.use_local_threejs()
sage: threejs = os.path.join(spec.nbextensions_dir, 'threejs')
sage: threejs = os.path.join(spec.nbextensions_dir, 'threejs-sage')
sage: os.path.isdir(threejs)
True
"""
src = THREEJS_DIR
dst = os.path.join(self.nbextensions_dir, 'threejs')
dst = os.path.join(self.nbextensions_dir, 'threejs-sage')
self.symlink(src, dst)

def _kernel_cmd(self):
Expand Down
11 changes: 7 additions & 4 deletions src/sage/repl/rich_output/backend_ipython.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,9 @@ def threejs_offline_scripts(self):
'...<script ...</script>...'
"""
from sage.env import THREEJS_DIR
from sage.repl.rich_output.display_manager import _required_threejs_version

script = os.path.join(THREEJS_DIR, 'build/three.min.js')
script = os.path.join(THREEJS_DIR, '{}/three.min.js'.format(_required_threejs_version()))

if sys.platform == 'cygwin':
import cygwin
Expand Down Expand Up @@ -597,13 +598,15 @@ def threejs_offline_scripts(self):
sage: from sage.repl.rich_output.backend_ipython import BackendIPythonNotebook
sage: backend = BackendIPythonNotebook()
sage: backend.threejs_offline_scripts()
'...<script src="/nbextensions/threejs/build/three.min...<\\/script>...'
'...<script src="/nbextensions/threejs-sage/r.../three.min.js...<\\/script>...'
"""
from sage.repl.rich_output import get_display_manager
from sage.repl.rich_output.display_manager import _required_threejs_version
CDN_script = get_display_manager().threejs_scripts(online=True)
CDN_script = CDN_script.replace('</script>', r'<\/script>').replace('\n', ' \\\n')
return """
<script src="/nbextensions/threejs/build/three.min.js"></script>
<script src="/nbextensions/threejs-sage/{}/three.min.js"></script>
<script>
if ( !window.THREE ) document.write('{}');
</script>
""".format(CDN_script.replace('</script>', r'<\/script>').replace('\n', ' \\\n'))
""".format(_required_threejs_version(), CDN_script)
19 changes: 15 additions & 4 deletions src/sage/repl/rich_output/display_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@
)
from sage.repl.rich_output.preferences import DisplayPreferences

def _required_threejs_version():
"""
Return the version of threejs that Sage requires.
EXAMPLES::
sage: from sage.repl.rich_output.display_manager import _required_threejs_version
sage: _required_threejs_version()
'r...'
"""
import os
import sage.env
with open(os.path.join(sage.env.SAGE_EXTCODE, 'threejs', 'threejs-version.txt')) as f:
return f.read().strip()

class DisplayException(Exception):
"""
Expand Down Expand Up @@ -749,10 +763,7 @@ def threejs_scripts(self, online):
offline threejs graphics
"""
if online:
import sage.env
import os
with open(os.path.join(sage.env.THREEJS_DIR, 'version')) as f:
version = f.read().strip()
version = _required_threejs_version()
return """
<script src="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@{0}/build/three.min.js"></script>
""".format(version)
Expand Down

0 comments on commit 098a247

Please sign in to comment.