This file is indexed.

/usr/share/sagemath/bin/sage-notebook is in sagemath-common 7.4-9.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import ast
import argparse
import logging
import textwrap
logging.basicConfig()
logger = logging.getLogger()

from sage.env import SAGE_ROOT
from sage.misc.banner import banner


class NotebookSageNB(object):

    def print_banner(self):
        banner()
        print('Please wait while the old SageNB Notebook server starts...')

    @classmethod
    def print_help(cls):
        cls([], help=True)
    
    def cmdline2argspec(self, cmdline_args):
        """
        Convert command line arguments to Python argspec

        AKA the crappy copy of argparse. Only here for the legacy
        notebook, do not use.

        INPUT:
    
        - ``cmdline_args`` -- list of string.
    
        OUTPUT:
    
        A python argspec: A pair consisting of a tuple and a dict.
        """
        args = []
        kwds = dict()
        for x in cmdline_args:
            logger.info('Parsing %s', x)
            if '=' in x:
                key, value = x.split('=', 2)
                logger.debug('keyword argument %s = %s', key, value)
                try:
                    value = ast.literal_eval(value)
                except Exception:
                    logger.debug('cannot evaluate, treat as string')
                kwds[key] = value
            else:
                logger.debug('positional argument %s', x)
                try:
                    value = ast.literal_eval(x)
                except Exception:
                    value = x
                    logger.debug('cannot evaluate, treat as string')
                args.append(value)
        return tuple(args), kwds

    def __init__(self, argv, help=False):
        self.print_banner()
        self.args, self.kwds = self.cmdline2argspec(argv)
        logger.info('notebook positional arguments = %s', self.args)
        logger.info('notebook keyword arguments = %s', self.kwds)
        from sagenb.notebook.notebook_object import notebook
        if help:
            from sage.misc.sageinspect import sage_getdoc
            print(sage_getdoc(notebook))
        else:
            notebook(*self.args, **self.kwds)


class NotebookJupyter(object):

    PREREQUISITE_ERROR = textwrap.dedent("""
    The Jupyter notebook requires ssl, even if you do not use
    https. Install the openssl development packages in your system and
    then rebuild Python (sage -f python2).
    """)

    def print_banner(self):
        banner()
        print('Please wait while the Sage Jupyter Notebook server starts...')

    @classmethod
    def print_help(cls):
        cls(['help'])

    def __init__(self, argv):
        self.print_banner()
        from sage.repl.ipython_kernel.install import have_prerequisites
        if not have_prerequisites():
            print(self.PREREQUISITE_ERROR)
            raise SystemExit(1)
        from notebook.notebookapp import main
        main(argv)


class SageNBExport(NotebookJupyter):

    def print_banner(self):
        banner()
        print('Please wait while the SageNB export server starts...')

    @classmethod
    def print_help(cls):
        cls(['--help'])

    def __init__(self, argv):
        if argv:
            SAGENB_EXPORT = 'sagenb-export'
            os.execvp(SAGENB_EXPORT, [SAGENB_EXPORT] + argv)
        argv += [
            "--NotebookApp.server_extensions=['sagenb_export.nbextension']",
            "--NotebookApp.default_url='/sagenb'",
        ]
        super(SageNBExport, self).__init__(argv)
        

description = \
"""
The Sage notebook launcher is used to start the notebook, and allows
you to choose between different implementations. Any further command
line options are passed to the respective notebook.
"""

help_help = \
"""
show this help message and exit. Can be combined with
"--notebook=[...]" to see notebook-specific options
"""

epilog = \
"""
EXAMPLES: 

* Run default notebook on port 1234. Note that the first argument
  after "-n" will be interpreted as notebook name unless you stop
  processing with "--":

      sage -n default port=1234
      sage -n -- port=1234      # equivalent
      sage -n port=1234         # ERROR: invalid notebook name

* Run Jupyter notebook in custom directory:

      sage --notebook=jupyter --notebook-dir=/home/foo/bar
"""


notebook_launcher = {
    'default': NotebookSageNB,   # change this to change the default
    'sagenb': NotebookSageNB,
    'ipython': NotebookJupyter,
    'jupyter': NotebookJupyter,
    'export': SageNBExport,
} 

notebook_names = ', '.join(notebook_launcher.keys())


def make_parser():
    """
    The main parser handling the selection of the notebook.

    Any arguments that are not parsed here are supposed to be handled
    by the notebook implementation.
    """
    parser = argparse.ArgumentParser(
        description=description, epilog=epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        add_help=False)
    parser.add_argument('-h', '--help',
                        dest='option_help', action='store_true',
                        default=False, 
                        help=help_help)
    parser.add_argument('--log', dest='log', default=None,
                        help='one of [DEBUG, INFO, ERROR, WARNING, CRITICAL]')
    default = None
    for name, launcher in notebook_launcher.items():
        if launcher == notebook_launcher['default'] and name != 'default':
            default = name
    if default is None:
        raise RuntimeError('default launcher is defined but not known under a specific name')
    parser.add_argument('--notebook',    # long style
                        '-n',            # short style
                        '-notebook',     # wtf style, we can't decide (legacy support)
                        dest='notebook', type=str, nargs='?', const='default',
                        help='The notebook to run [one of: {0}]. Default is {1}'.format(
                            notebook_names, default))
    return parser


if __name__ == '__main__':
    parser = make_parser()
    args, unknown = parser.parse_known_args(sys.argv[1:])
    if len(unknown) > 0 and unknown[0] == '--':
        unknown = unknown[1:]
    if args.log is not None:
        import logging
        level = getattr(logging, args.log.upper())
        logger.setLevel(level=level)
    logger.info('Main parser got arguments %s', args)
    logger.info('Passing on to notebook implementation: %s', unknown)

    try:
        launcher = notebook_launcher[args.notebook]
    except KeyError:
        logger.critical('unknown notebook: %s', args.notebook)
        print('Error, notebook must be one of {0} but got {1}'.
              format(notebook_names, args.notebook))
        sys.exit(1)

    if args.option_help:
        if args.notebook == 'default':
            parser.print_help()
        else:
            launcher.print_help()
        sys.exit(0)

    launcher(unknown)