예제 #1
0
def new_author(name=None, email=None, affiliation=None, url=None):
    """Create a new author."""
    author = NotebookNode()
    if name is not None:
        author.name = cast_unicode(name)
    if email is not None:
        author.email = cast_unicode(email)
    if affiliation is not None:
        author.affiliation = cast_unicode(affiliation)
    if url is not None:
        author.url = cast_unicode(url)
    return author
예제 #2
0
def new_author(name=None, email=None, affiliation=None, url=None):
    """Create a new author."""
    author = NotebookNode()
    if name is not None:
        author.name = cast_unicode(name)
    if email is not None:
        author.email = cast_unicode(email)
    if affiliation is not None:
        author.affiliation = cast_unicode(affiliation)
    if url is not None:
        author.url = cast_unicode(url)
    return author
예제 #3
0
def persist_config(config_file=None, mode=0o600):
    """Context manager that can be used to modify a config object

    On exit of the context manager, the config will be written back to disk, 
    by default with user-only (600) permissions.
    """

    if config_file is None:
        config_file = os.path.join(jupyter_config_dir(), 'jupyter_notebook_config.json')

    loader = JSONFileConfigLoader(os.path.basename(config_file), os.path.dirname(config_file))
    try:
        config = loader.load_config()
    except ConfigFileNotFound:
        config = Config()

    yield config

    with io.open(config_file, 'w', encoding='utf8') as f:
        f.write(cast_unicode(json.dumps(config, indent=2)))

    try:
        os.chmod(config_file, mode)
    except Exception as e:
        tb = traceback.format_exc()
        warnings.warn("Failed to set permissions on %s:\n%s" % (config_file, tb),
            RuntimeWarning)
예제 #4
0
 def get(self, kernel_id):
     self.kernel_id = cast_unicode(kernel_id, 'ascii')
     print("kernelid+   " + self.kernel_id)
     if options.kernel_lock.get(self.kernel_id) is None:
         lock = threading.Lock()
         options.kernel_lock[kernel_id] = lock
     yield super(ZMQChannelsHandler, self).get(kernel_id=kernel_id)
예제 #5
0
 def get(self, kernel_id, *args, **kwargs):
     self.authenticate()
     self.kernel_id = cast_unicode(kernel_id, 'ascii')
     yield gen.maybe_future(
         super(WebSocketChannelsHandler, self).get(kernel_id=kernel_id,
                                                   *args,
                                                   **kwargs))
예제 #6
0
    def complete_request(self, text):
        line = str_to_unicode(readline.get_line_buffer())
        byte_cursor_pos = readline.get_endidx()

        # get_endidx is a byte offset
        # account for multi-byte characters to get correct cursor_pos
        bytes_before_cursor = cast_bytes(line)[:byte_cursor_pos]
        cursor_pos = len(cast_unicode(bytes_before_cursor))

        # send completion request to kernel
        # Give the kernel up to 5s to respond
        msg_id = self.client.complete(
            code=line,
            cursor_pos=cursor_pos,
        )

        msg = self.client.shell_channel.get_msg(timeout=self.timeout)
        if msg['parent_header']['msg_id'] == msg_id:
            content = msg['content']
            cursor_start = content['cursor_start']
            matches = [line[:cursor_start] + m for m in content['matches']]
            if content["cursor_end"] < cursor_pos:
                extra = line[content["cursor_end"]:cursor_pos]
                matches = [m + extra for m in matches]
            matches = [unicode_to_str(m) for m in matches]
            return matches
        return []
예제 #7
0
def is_file_hidden_win(abs_path, stat_res=None):
    """Is a file hidden?

    This only checks the file itself; it should be called in combination with
    checking the directory containing the file.

    Use is_hidden() instead to check the file and its parent directories.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check.
    stat_res : os.stat_result, optional
        Ignored on Windows, exists for compatibility with POSIX version of the
        function.
    """
    if os.path.basename(abs_path).startswith('.'):
        return True

    win32_FILE_ATTRIBUTE_HIDDEN = 0x02
    try:
        attrs = ctypes.windll.kernel32.GetFileAttributesW(
            py3compat.cast_unicode(abs_path))
    except AttributeError:
        pass
    else:
        if attrs > 0 and attrs & win32_FILE_ATTRIBUTE_HIDDEN:
            return True

    return False
예제 #8
0
    def _reserialize_reply(self, msg_or_list, channel=None):
        """Reserialize a reply message using JSON.

        msg_or_list can be an already-deserialized msg dict or the zmq buffer list.
        If it is the zmq list, it will be deserialized with self.session.

        This takes the msg list from the ZMQ socket and serializes the result for the websocket.
        This method should be used by self._on_zmq_reply to build messages that can
        be sent back to the browser.

        """
        if isinstance(msg_or_list, dict):
            # already unpacked
            msg = msg_or_list
        else:
            idents, msg_list = self.session.feed_identities(msg_or_list)
            msg = self.session.deserialize(msg_list)
        if channel:
            msg['channel'] = channel
        if msg['buffers']:
            buf = serialize_binary_message(msg)
            return buf
        else:
            smsg = json.dumps(msg, default=date_default)
            return cast_unicode(smsg)
예제 #9
0
 def complete_request(self, text):
     line = str_to_unicode(readline.get_line_buffer())
     byte_cursor_pos = readline.get_endidx()
     
     # get_endidx is a byte offset
     # account for multi-byte characters to get correct cursor_pos
     bytes_before_cursor = cast_bytes(line)[:byte_cursor_pos]
     cursor_pos = len(cast_unicode(bytes_before_cursor))
     
     # send completion request to kernel
     # Give the kernel up to 5s to respond
     msg_id = self.client.complete(
         code=line,
         cursor_pos=cursor_pos,
     )
 
     msg = self.client.shell_channel.get_msg(timeout=self.timeout)
     if msg['parent_header']['msg_id'] == msg_id:
         content = msg['content']
         cursor_start = content['cursor_start']
         matches = [ line[:cursor_start] + m for m in content['matches'] ]
         if content["cursor_end"] < cursor_pos:
             extra = line[content["cursor_end"]: cursor_pos]
             matches = [m + extra for m in matches]
         matches = [ unicode_to_str(m) for m in matches ]
         return matches
     return []
예제 #10
0
    def _reserialize_reply(self, msg_or_list, channel=None):
        """Reserialize a reply message using JSON.

        msg_or_list can be an already-deserialized msg dict or the zmq buffer list.
        If it is the zmq list, it will be deserialized with self.session.
        
        This takes the msg list from the ZMQ socket and serializes the result for the websocket.
        This method should be used by self._on_zmq_reply to build messages that can
        be sent back to the browser.
        
        """
        if isinstance(msg_or_list, dict):
            # already unpacked
            msg = msg_or_list
        else:
            idents, msg_list = self.session.feed_identities(msg_or_list)
            msg = self.session.deserialize(msg_list)
        if channel:
            msg['channel'] = channel
        if msg['buffers']:
            buf = serialize_binary_message(msg)
            return buf
        else:
            smsg = json.dumps(msg, default=date_default)
            return cast_unicode(smsg)
예제 #11
0
def persist_config(config_file=None, mode=0o600):
    """Context manager that can be used to modify a config object

    On exit of the context manager, the config will be written back to disk, 
    by default with user-only (600) permissions.
    """

    if config_file is None:
        config_file = os.path.join(jupyter_config_dir(), 'jupyter_notebook_config.json')

    os.makedirs(os.path.dirname(config_file), exist_ok=True)

    loader = JSONFileConfigLoader(os.path.basename(config_file), os.path.dirname(config_file))
    try:
        config = loader.load_config()
    except ConfigFileNotFound:
        config = Config()

    yield config

    with io.open(config_file, 'w', encoding='utf8') as f:
        f.write(cast_unicode(json.dumps(config, indent=2)))

    try:
        os.chmod(config_file, mode)
    except Exception as e:
        tb = traceback.format_exc()
        warnings.warn("Failed to set permissions on %s:\n%s" % (config_file, tb),
            RuntimeWarning)
예제 #12
0
def new_metadata(name=None, authors=None, license=None, created=None, modified=None, gistid=None):
    """Create a new metadata node."""
    metadata = NotebookNode()
    if name is not None:
        metadata.name = cast_unicode(name)
    if authors is not None:
        metadata.authors = list(authors)
    if created is not None:
        metadata.created = cast_unicode(created)
    if modified is not None:
        metadata.modified = cast_unicode(modified)
    if license is not None:
        metadata.license = cast_unicode(license)
    if gistid is not None:
        metadata.gistid = cast_unicode(gistid)
    return metadata
예제 #13
0
    def pre_get(self):
        # authenticate first
        super().pre_get()
        # check session collision:
        yield self._register_session()
        # then request kernel info, waiting up to a certain time before giving up.
        # We don't want to wait forever, because browsers don't take it well when
        # servers never respond to websocket connection requests.
        kernel = self.kernel_manager.get_kernel(self.kernel_id)
        self.session.key = kernel.session.key
        self.buffer_key = cast_unicode(kernel.session.key, "utf-8")
        future = self.request_kernel_info()

        def give_up():
            """Don't wait forever for the kernel to reply"""
            if future.done():
                return
            self.log.warning("Timeout waiting for kernel_info reply from %s",
                             self.kernel_id)
            future.set_result({})

        loop = IOLoop.current()
        loop.add_timeout(loop.time() + self.kernel_info_timeout, give_up)
        # actually wait for it
        yield future
예제 #14
0
파일: utils.py 프로젝트: JCEmmons/notebook
def is_file_hidden_win(abs_path, stat_res=None):
    """Is a file hidden?

    This only checks the file itself; it should be called in combination with
    checking the directory containing the file.

    Use is_hidden() instead to check the file and its parent directories.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check.
    stat_res : os.stat_result, optional
        Ignored on Windows, exists for compatibility with POSIX version of the
        function.
    """
    if os.path.basename(abs_path).startswith('.'):
        return True

    win32_FILE_ATTRIBUTE_HIDDEN = 0x02
    try:
        attrs = ctypes.windll.kernel32.GetFileAttributesW(
            py3compat.cast_unicode(abs_path)
        )
    except AttributeError:
        pass
    else:
        if attrs > 0 and attrs & win32_FILE_ATTRIBUTE_HIDDEN:
            return True

    return False
예제 #15
0
def new_heading_cell(source=None, level=1, rendered=None, metadata=None):
    """Create a new section cell with a given integer level."""
    cell = NotebookNode()
    cell.cell_type = u"heading"
    if source is not None:
        cell.source = cast_unicode(source)
    cell.level = int(level)
    cell.metadata = NotebookNode(metadata or {})
    return cell
예제 #16
0
def test_is_hidden_win32():
    with TemporaryDirectory() as root:
        root = cast_unicode(root)
        subdir1 = os.path.join(root, u'subdir')
        os.makedirs(subdir1)
        assert not is_hidden(subdir1, root)
        r = ctypes.windll.kernel32.SetFileAttributesW(subdir1, 0x02)
        print(r)
        assert is_hidden(subdir1, root)
예제 #17
0
def test_is_hidden_win32():
    with TemporaryDirectory() as root:
        root = cast_unicode(root)
        subdir1 = os.path.join(root, u'subdir')
        os.makedirs(subdir1)
        assert not is_hidden(subdir1, root)
        r = ctypes.windll.kernel32.SetFileAttributesW(subdir1, 0x02)
        print(r)
        assert is_hidden(subdir1, root)
예제 #18
0
def test_is_hidden_win32(tmp_path):
    root = str(tmp_path)
    root = cast_unicode(root)
    subdir1 = tmp_path / 'subdir'
    subdir1.mkdir()
    assert not is_hidden(str(subdir1), root)
    ctypes.windll.kernel32.SetFileAttributesW(str(subdir1), 0x02)
    assert is_hidden(str(subdir1), root)
    assert is_file_hidden(str(subdir1))
예제 #19
0
def new_heading_cell(source=None, level=1, rendered=None, metadata=None):
    """Create a new section cell with a given integer level."""
    cell = NotebookNode()
    cell.cell_type = u'heading'
    if source is not None:
        cell.source = cast_unicode(source)
    cell.level = int(level)
    cell.metadata = NotebookNode(metadata or {})
    return cell
예제 #20
0
파일: utils.py 프로젝트: DT021/wau
def is_hidden(abs_path, abs_root=''):
    """Is a file hidden or contained in a hidden directory?
    
    This will start with the rightmost path element and work backwards to the
    given root to see if a path is hidden or in a hidden directory. Hidden is
    determined by either name starting with '.' or the UF_HIDDEN flag as 
    reported by stat.
    
    Parameters
    ----------
    abs_path : unicode
        The absolute path to check for hidden directories.
    abs_root : unicode
        The absolute path of the root directory in which hidden directories
        should be checked for.
    """
    if not abs_root:
        abs_root = abs_path.split(os.sep, 1)[0] + os.sep
    inside_root = abs_path[len(abs_root):]
    if any(part.startswith('.') for part in inside_root.split(os.sep)):
        return True

    # check that dirs can be listed
    # may fail on Windows junctions or non-user-readable dirs
    if os.path.isdir(abs_path):
        try:
            os.listdir(abs_path)
        except OSError:
            return True

    # check UF_HIDDEN on any location up to root
    path = abs_path
    while path and path.startswith(abs_root) and path != abs_root:
        if not os.path.exists(path):
            path = os.path.dirname(path)
            continue
        try:
            # may fail on Windows junctions
            st = os.stat(path)
        except OSError:
            return True
        if getattr(st, 'st_flags', 0) & UF_HIDDEN:
            return True
        path = os.path.dirname(path)

    if sys.platform == 'win32':
        try:
            attrs = ctypes.windll.kernel32.GetFileAttributesW(
                py3compat.cast_unicode(path))
        except AttributeError:
            pass
        else:
            if attrs > 0 and attrs & _win32_FILE_ATTRIBUTE_HIDDEN:
                return True

    return False
예제 #21
0
def new_code_cell(input=None, prompt_number=None, outputs=None, language=u"python", collapsed=False, metadata=None):
    """Create a new code cell with input and output"""
    cell = NotebookNode()
    cell.cell_type = u"code"
    if language is not None:
        cell.language = cast_unicode(language)
    if input is not None:
        cell.input = cast_unicode(input)
    if prompt_number is not None:
        cell.prompt_number = int(prompt_number)
    if outputs is None:
        cell.outputs = []
    else:
        cell.outputs = outputs
    if collapsed is not None:
        cell.collapsed = bool(collapsed)
    cell.metadata = NotebookNode(metadata or {})

    return cell
예제 #22
0
파일: utils.py 프로젝트: AFJay/notebook
def is_hidden(abs_path, abs_root=''):
    """Is a file hidden or contained in a hidden directory?
    
    This will start with the rightmost path element and work backwards to the
    given root to see if a path is hidden or in a hidden directory. Hidden is
    determined by either name starting with '.' or the UF_HIDDEN flag as 
    reported by stat.
    
    Parameters
    ----------
    abs_path : unicode
        The absolute path to check for hidden directories.
    abs_root : unicode
        The absolute path of the root directory in which hidden directories
        should be checked for.
    """
    if not abs_root:
        abs_root = abs_path.split(os.sep, 1)[0] + os.sep
    inside_root = abs_path[len(abs_root):]
    if any(part.startswith('.') for part in inside_root.split(os.sep)):
        return True
    
    # check that dirs can be listed
    # may fail on Windows junctions or non-user-readable dirs
    if os.path.isdir(abs_path):
        try:
            os.listdir(abs_path)
        except OSError:
            return True
    
    # check UF_HIDDEN on any location up to root
    path = abs_path
    while path and path.startswith(abs_root) and path != abs_root:
        if not os.path.exists(path):
            path = os.path.dirname(path)
            continue
        try:
            # may fail on Windows junctions
            st = os.stat(path)
        except OSError:
            return True
        if getattr(st, 'st_flags', 0) & UF_HIDDEN:
            return True
        path = os.path.dirname(path)
    
    if sys.platform == 'win32':
        try:
            attrs = ctypes.windll.kernel32.GetFileAttributesW(py3compat.cast_unicode(path))
        except AttributeError:
            pass
        else:
            if attrs > 0 and attrs & _win32_FILE_ATTRIBUTE_HIDDEN:
                return True

    return False
예제 #23
0
def setup_kernel(cmd):
    """start an embedded kernel in a subprocess, and wait for it to be ready

    Returns
    -------
    kernel_manager: connected KernelManager instance
    """

    def connection_file_ready(connection_file):
        """Check if connection_file is a readable json file."""
        if not os.path.exists(connection_file):
            return False
        try:
            with open(connection_file) as f:
                json.load(f)
            return True
        except ValueError:
            return False

    kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE)
    try:
        connection_file = os.path.join(
            paths.jupyter_runtime_dir(),
            'kernel-%i.json' % kernel.pid,
        )
        # wait for connection file to exist, timeout after 5s
        tic = time.time()
        while not connection_file_ready(connection_file) \
            and kernel.poll() is None \
            and time.time() < tic + SETUP_TIMEOUT:
            time.sleep(0.1)

        # Wait 100ms for the writing to finish
        time.sleep(0.1)

        if kernel.poll() is not None:
            o,e = kernel.communicate()
            e = py3compat.cast_unicode(e)
            raise IOError("Kernel failed to start:\n%s" % e)

        if not os.path.exists(connection_file):
            if kernel.poll() is None:
                kernel.terminate()
            raise IOError("Connection file %r never arrived" % connection_file)

        client = BlockingKernelClient(connection_file=connection_file)
        client.load_connection_file()
        client.start_channels()
        client.wait_for_ready()
        try:
            yield client
        finally:
            client.stop_channels()
    finally:
        kernel.terminate()
예제 #24
0
def passwd(passphrase=None, algorithm='argon2'):
    """Generate hashed password and salt for use in notebook configuration.

    In the notebook configuration, set `c.NotebookApp.password` to
    the generated string.

    Parameters
    ----------
    passphrase : str
        Password to hash.  If unspecified, the user is asked to input
        and verify a password.
    algorithm : str
        Hashing algorithm to use (e.g, 'sha1' or any argument supported
        by :func:`hashlib.new`, or 'argon2').

    Returns
    -------
    hashed_passphrase : str
        Hashed password, in the format 'hash_algorithm:salt:passphrase_hash'.

    Examples
    --------
    >>> passwd('mypassword')
    'sha1:7cf3:b7d6da294ea9592a9480c8f52e63cd42cfb9dd12'

    """
    if passphrase is None:
        for i in range(3):
            p0 = getpass.getpass('Enter password: '******'Verify password: '******'Passwords do not match.')
        else:
            raise ValueError('No matching passwords found. Giving up.')

    if algorithm == 'argon2':
        from argon2 import PasswordHasher
        ph = PasswordHasher(
            memory_cost=10240,
            time_cost=10,
            parallelism=8,
        )
        h = ph.hash(passphrase)

        return ':'.join((algorithm, cast_unicode(h, 'ascii')))
    else:
        h = hashlib.new(algorithm)
        salt = ('%0' + str(salt_len) + 'x') % random.getrandbits(4 * salt_len)
        h.update(cast_bytes(passphrase, 'utf-8') + str_to_bytes(salt, 'ascii'))

        return ':'.join((algorithm, salt, h.hexdigest()))
예제 #25
0
def new_metadata(name=None,
                 authors=None,
                 license=None,
                 created=None,
                 modified=None,
                 gistid=None):
    """Create a new metadata node."""
    metadata = NotebookNode()
    if name is not None:
        metadata.name = cast_unicode(name)
    if authors is not None:
        metadata.authors = list(authors)
    if created is not None:
        metadata.created = cast_unicode(created)
    if modified is not None:
        metadata.modified = cast_unicode(modified)
    if license is not None:
        metadata.license = cast_unicode(license)
    if gistid is not None:
        metadata.gistid = cast_unicode(gistid)
    return metadata
예제 #26
0
def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
    """Create a new text cell."""
    cell = NotebookNode()
    # VERSIONHACK: plaintext -> raw
    # handle never-released plaintext name for raw cells
    if cell_type == "plaintext":
        cell_type = "raw"
    if source is not None:
        cell.source = cast_unicode(source)
    cell.metadata = NotebookNode(metadata or {})
    cell.cell_type = cell_type
    return cell
예제 #27
0
def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
    """Create a new text cell."""
    cell = NotebookNode()
    # VERSIONHACK: plaintext -> raw
    # handle never-released plaintext name for raw cells
    if cell_type == 'plaintext':
        cell_type = 'raw'
    if source is not None:
        cell.source = cast_unicode(source)
    cell.metadata = NotebookNode(metadata or {})
    cell.cell_type = cell_type
    return cell
예제 #28
0
def new_code_cell(input=None,
                  prompt_number=None,
                  outputs=None,
                  language=u'python',
                  collapsed=False,
                  metadata=None):
    """Create a new code cell with input and output"""
    cell = NotebookNode()
    cell.cell_type = u'code'
    if language is not None:
        cell.language = cast_unicode(language)
    if input is not None:
        cell.input = cast_unicode(input)
    if prompt_number is not None:
        cell.prompt_number = int(prompt_number)
    if outputs is None:
        cell.outputs = []
    else:
        cell.outputs = outputs
    if collapsed is not None:
        cell.collapsed = bool(collapsed)
    cell.metadata = NotebookNode(metadata or {})

    return cell
예제 #29
0
 def start(self):
     if self.reset:
         if os.path.exists(self.notary.db_file):
             print("Removing trusted signature cache: %s" % self.notary.db_file)
             os.remove(self.notary.db_file)
         self.generate_new_key()
         return
     if not self.extra_args:
         self.log.debug("Reading notebook from stdin")
         nb_s = cast_unicode(sys.stdin.read())
         nb = reads(nb_s, NO_CONVERT)
         self.sign_notebook(nb, '<stdin>')
     else:
         for notebook_path in self.extra_args:
             self.sign_notebook_file(notebook_path)
예제 #30
0
 def pre_get(self):
     """Run before finishing the GET request
     
     Extend this method to add logic that should fire before
     the websocket finishes completing.
     """
     # authenticate the request before opening the websocket
     if self.get_current_user() is None:
         self.log.warning("Couldn't authenticate WebSocket connection")
         raise web.HTTPError(403)
     
     if self.get_argument('session_id', False):
         self.session.session = cast_unicode(self.get_argument('session_id'))
     else:
         self.log.warning("No session ID specified")
예제 #31
0
파일: handlers.py 프로젝트: piepacker/nb2kg
    def authenticate(self):
        """Run before finishing the GET request

        Extend this method to add logic that should fire before
        the websocket finishes completing.
        """
        # authenticate the request before opening the websocket
        if self.get_current_user() is None:
            self.log.warning("Couldn't authenticate WebSocket connection")
            raise web.HTTPError(403)

        if self.get_argument('session_id', False):
            self.session.session = cast_unicode(self.get_argument('session_id'))
        else:
            self.log.warning("No session ID specified")
예제 #32
0
파일: sign.py 프로젝트: takluyver/nbformat
 def start(self):
     if self.reset:
         if os.path.exists(self.notary.db_file):
             print("Removing trusted signature cache: %s" % self.notary.db_file)
             os.remove(self.notary.db_file)
         self.generate_new_key()
         return
     if not self.extra_args:
         self.log.debug("Reading notebook from stdin")
         nb_s = cast_unicode(sys.stdin.read())
         nb = reads(nb_s, NO_CONVERT)
         self.sign_notebook(nb, '<stdin>')
     else:
         for notebook_path in self.extra_args:
             self.sign_notebook_file(notebook_path)
예제 #33
0
def new_notebook(name=None, metadata=None, worksheets=None):
    """Create a notebook by name, id and a list of worksheets."""
    nb = NotebookNode()
    nb.nbformat = nbformat
    nb.nbformat_minor = nbformat_minor
    if worksheets is None:
        nb.worksheets = []
    else:
        nb.worksheets = list(worksheets)
    if metadata is None:
        nb.metadata = new_metadata()
    else:
        nb.metadata = NotebookNode(metadata)
    if name is not None:
        nb.metadata.name = cast_unicode(name)
    return nb
예제 #34
0
def new_notebook(name=None, metadata=None, worksheets=None):
    """Create a notebook by name, id and a list of worksheets."""
    nb = NotebookNode()
    nb.nbformat = nbformat
    nb.nbformat_minor = nbformat_minor
    if worksheets is None:
        nb.worksheets = []
    else:
        nb.worksheets = list(worksheets)
    if metadata is None:
        nb.metadata = new_metadata()
    else:
        nb.metadata = NotebookNode(metadata)
    if name is not None:
        nb.metadata.name = cast_unicode(name)
    return nb
예제 #35
0
    def setUp(self):
        """Build an isolated config environment."""
        td = TemporaryDirectory()

        self.test_dir = py3compat.cast_unicode(td.name)
        self.data_dir = os.path.join(self.test_dir, 'data')
        self.config_dir = os.path.join(self.test_dir, 'config')
        self.system_data_dir = os.path.join(self.test_dir, 'system_data')
        self.system_path = [self.system_data_dir]

        # Use temp directory, not real user or system config paths
        self.patch_env = patch.dict(
            'os.environ', {
                'JUPYTER_CONFIG_DIR': self.config_dir,
                'JUPYTER_DATA_DIR': self.data_dir,
            })
        self.patch_env.start()
예제 #36
0
 def test_get_nb_invalid(self):
     nb = {
         'nbformat': 4,
         'metadata': {},
         'cells': [{
             'cell_type': 'wrong',
             'metadata': {},
         }],
     }
     path = u'å b/Validate tést.ipynb'
     self.make_txt(path, py3compat.cast_unicode(json.dumps(nb)))
     model = self.api.read(path).json()
     self.assertEqual(model['path'], path)
     self.assertEqual(model['type'], 'notebook')
     self.assertIn('content', model)
     self.assertIn('message', model)
     self.assertIn("validation failed", model['message'].lower())
예제 #37
0
 def test_get_nb_invalid(self):
     nb = {
         'nbformat': 4,
         'metadata': {},
         'cells': [{
             'cell_type': 'wrong',
             'metadata': {},
         }],
     }
     path = u'å b/Validate tést.ipynb'
     self.make_txt(path, py3compat.cast_unicode(json.dumps(nb)))
     model = self.api.read(path).json()
     self.assertEqual(model['path'], path)
     self.assertEqual(model['type'], 'notebook')
     self.assertIn('content', model)
     self.assertIn('message', model)
     self.assertIn("validation failed", model['message'].lower())
예제 #38
0
    def _reserialize_reply(self, msg_list, channel=None):
        """Reserialize a reply message using JSON.

        This takes the msg list from the ZMQ socket, deserializes it using
        self.session and then serializes the result using JSON. This method
        should be used by self._on_zmq_reply to build messages that can
        be sent back to the browser.
        """
        idents, msg_list = self.session.feed_identities(msg_list)
        msg = self.session.deserialize(msg_list)
        if channel:
            msg['channel'] = channel
        if msg['buffers']:
            buf = serialize_binary_message(msg)
            return buf
        else:
            smsg = json.dumps(msg, default=date_default)
            return cast_unicode(smsg)
예제 #39
0
    def _reserialize_reply(self, msg_list, channel=None):
        """Reserialize a reply message using JSON.

        This takes the msg list from the ZMQ socket, deserializes it using
        self.session and then serializes the result using JSON. This method
        should be used by self._on_zmq_reply to build messages that can
        be sent back to the browser.
        """
        idents, msg_list = self.session.feed_identities(msg_list)
        msg = self.session.deserialize(msg_list)
        if channel:
            msg["channel"] = channel
        if msg["buffers"]:
            buf = serialize_binary_message(msg)
            return buf
        else:
            smsg = json.dumps(msg, default=date_default)
            return cast_unicode(smsg)
예제 #40
0
def setup_kernel(cmd):
    """start an embedded kernel in a subprocess, and wait for it to be ready

    This function was taken from the ipykernel project.
    We plan to remove it when dropping support for python 2.

    Returns
    -------
    kernel_manager: connected KernelManager instance
    """
    kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE)
    try:
        connection_file = os.path.join(
            paths.jupyter_runtime_dir(),
            'kernel-%i.json' % kernel.pid,
        )
        # wait for connection file to exist, timeout after 5s
        tic = time.time()
        while not os.path.exists(connection_file) \
            and kernel.poll() is None \
            and time.time() < tic + SETUP_TIMEOUT:
            time.sleep(0.1)

        if kernel.poll() is not None:
            o, e = kernel.communicate()
            e = py3compat.cast_unicode(e)
            raise IOError("Kernel failed to start:\n%s" % e)

        if not os.path.exists(connection_file):
            if kernel.poll() is None:
                kernel.terminate()
            raise IOError("Connection file %r never arrived" % connection_file)

        client = BlockingKernelClient(connection_file=connection_file)
        client.load_connection_file()
        client.start_channels()
        client.wait_for_ready()
        try:
            yield client
        finally:
            client.stop_channels()
    finally:
        kernel.terminate()
예제 #41
0
 def setUp(self):
     """Build an isolated config environment."""
     td = TemporaryDirectory()
     
     self.test_dir = py3compat.cast_unicode(td.name)
     self.data_dir = os.path.join(self.test_dir, 'data')
     self.config_dir = os.path.join(self.test_dir, 'config')
     self.system_data_dir = os.path.join(self.test_dir, 'system_data')
     self.system_path = [self.system_data_dir]
     
     # Use temp directory, not real user or system config paths
     self.patch_env = patch.dict('os.environ', {
         'JUPYTER_CONFIG_DIR': self.config_dir,
         'JUPYTER_DATA_DIR': self.data_dir,
     })
     self.patch_env.start()
     self.patch_system_path = patch.object(nbextensions,
         'SYSTEM_JUPYTER_PATH', self.system_path)
     self.patch_system_path.start()
예제 #42
0
 def rlcomplete(self, text, state):
     if state == 0:
         line = str_to_unicode(readline.get_line_buffer())
         byte_cursor_pos = readline.get_endidx()
         # get_endidx is a byte offset
         # account for multi-byte characters to get correct cursor_pos
         bytes_before_cursor = cast_bytes(line)[:byte_cursor_pos]
         cursor_pos = len(cast_unicode(bytes_before_cursor))
         try:
             content = self.complete_request(line, cursor_pos)
             self.matches = _construct_readline_matches(line, cursor_pos, content)
         except Empty:
             #print('WARNING: Kernel timeout on tab completion.')
             pass
     
     try:
         return self.matches[state]
     except IndexError:
         return None
예제 #43
0
    def parse_command_line(self, argv=None):
        """Parse the command line arguments."""
        argv = sys.argv[1:] if argv is None else argv
        self.argv = [py3compat.cast_unicode(arg) for arg in argv]

        if argv and argv[0] == 'help':
            # turn `ipython help notebook` into `ipython notebook -h`
            argv = argv[1:] + ['-h']

        if self.subcommands and len(argv) > 0:
            # we have subcommands, and one may have been specified
            subc, subargv = argv[0], argv[1:]
            if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
                # it's a subcommand, and *not* a flag or class parameter
                return self.initialize_subcommand(subc, subargv)

        # Arguments after a '--' argument are for the script IPython may be
        # about to run, not IPython iteslf. For arguments parsed here (help and
        # version), we want to only search the arguments up to the first
        # occurrence of '--', which we're calling interpreted_argv.
        try:
            interpreted_argv = argv[:argv.index('--')]
        except ValueError:
            interpreted_argv = argv

        if any(x in interpreted_argv for x in ('-h', '--help-all', '--help')):
            self.print_help('--help-all' in interpreted_argv)
            self.exit(0)

        if '--version' in interpreted_argv or '-V' in interpreted_argv:
            self.print_version()
            self.exit(0)

        # flatten flags&aliases, so cl-args get appropriate priority:
        flags, aliases = self.flatten_flags()
        loader = KVArgParseConfigLoader(argv=argv,
                                        aliases=aliases,
                                        flags=flags,
                                        log=self.log)
        config = loader.load_config()
        self.update_config(config)
        # store unparsed args in extra_args
        self.extra_args = loader.extra_args
예제 #44
0
    def rlcomplete(self, text, state):
        if state == 0:
            line = str_to_unicode(readline.get_line_buffer())
            byte_cursor_pos = readline.get_endidx()
            # get_endidx is a byte offset
            # account for multi-byte characters to get correct cursor_pos
            bytes_before_cursor = cast_bytes(line)[:byte_cursor_pos]
            cursor_pos = len(cast_unicode(bytes_before_cursor))
            try:
                content = self.complete_request(line, cursor_pos)
                self.matches = _construct_readline_matches(
                    line, cursor_pos, content)
            except Empty:
                #print('WARNING: Kernel timeout on tab completion.')
                pass

        try:
            return self.matches[state]
        except IndexError:
            return None
예제 #45
0
    def parse_command_line(self, argv=None):
        """Parse the command line arguments."""
        argv = sys.argv[1:] if argv is None else argv
        self.argv = [ py3compat.cast_unicode(arg) for arg in argv ]
        
        if argv and argv[0] == 'help':
            # turn `ipython help notebook` into `ipython notebook -h`
            argv = argv[1:] + ['-h']

        if self.subcommands and len(argv) > 0:
            # we have subcommands, and one may have been specified
            subc, subargv = argv[0], argv[1:]
            if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
                # it's a subcommand, and *not* a flag or class parameter
                return self.initialize_subcommand(subc, subargv)

        # Arguments after a '--' argument are for the script IPython may be
        # about to run, not IPython iteslf. For arguments parsed here (help and
        # version), we want to only search the arguments up to the first
        # occurrence of '--', which we're calling interpreted_argv.
        try:
            interpreted_argv = argv[:argv.index('--')]
        except ValueError:
            interpreted_argv = argv

        if any(x in interpreted_argv for x in ('-h', '--help-all', '--help')):
            self.print_help('--help-all' in interpreted_argv)
            self.exit(0)

        if '--version' in interpreted_argv or '-V' in interpreted_argv:
            self.print_version()
            self.exit(0)
        
        # flatten flags&aliases, so cl-args get appropriate priority:
        flags,aliases = self.flatten_flags()
        loader = KVArgParseConfigLoader(argv=argv, aliases=aliases,
                                        flags=flags, log=self.log)
        config = loader.load_config()
        self.update_config(config)
        # store unparsed args in extra_args
        self.extra_args = loader.extra_args
예제 #46
0
def setup_kernel(cmd):
    """start an embedded kernel in a subprocess, and wait for it to be ready

    Returns
    -------
    kernel_manager: connected KernelManager instance
    """
    kernel = Popen([sys.executable, '-c', cmd], stdout=PIPE, stderr=PIPE)
    connection_file = os.path.join(
        paths.jupyter_runtime_dir(),
        'kernel-%i.json' % kernel.pid,
    )
    # wait for connection file to exist, timeout after 5s
    tic = time.time()
    while not os.path.exists(connection_file) \
        and kernel.poll() is None \
        and time.time() < tic + SETUP_TIMEOUT:
        time.sleep(0.1)

    if kernel.poll() is not None:
        o,e = kernel.communicate()
        e = py3compat.cast_unicode(e)
        raise IOError("Kernel failed to start:\n%s" % e)

    if not os.path.exists(connection_file):
        if kernel.poll() is None:
            kernel.terminate()
        raise IOError("Connection file %r never arrived" % connection_file)

    client = BlockingKernelClient(connection_file=connection_file)
    client.load_connection_file()
    client.start_channels()
    client.wait_for_ready()

    try:
        yield client
    finally:
        client.stop_channels()
        kernel.terminate()
예제 #47
0
def is_file_hidden_win(abs_path, stat_res=None):
    """Is a file hidden?

    This only checks the file itself; it should be called in combination with
    checking the directory containing the file.

    Use is_hidden() instead to check the file and its parent directories.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check.
    stat_res : os.stat_result, optional
        Ignored on Windows, exists for compatibility with POSIX version of the
        function.
    """
    if os.path.basename(abs_path).startswith('.'):
        return True

    # check that dirs can be listed
    if os.path.isdir(abs_path):
        # can't trust os.access on Windows because it seems to always return True
        try:
            os.stat(abs_path)
        except OSError:
            # stat may fail on Windows junctions or non-user-readable dirs
            return True

    try:
        attrs = ctypes.windll.kernel32.GetFileAttributesW(
            py3compat.cast_unicode(abs_path))
    except AttributeError:
        pass
    else:
        if attrs > 0 and attrs & _win32_FILE_ATTRIBUTE_HIDDEN:
            return True

    return False
예제 #48
0
def is_file_hidden_win(abs_path, stat_res=None):
    """Is a file hidden?

    This only checks the file itself; it should be called in combination with
    checking the directory containing the file.

    Use is_hidden() instead to check the file and its parent directories.

    Parameters
    ----------
    abs_path : unicode
        The absolute path to check.
    stat_res : os.stat_result, optional
        Ignored on Windows, exists for compatibility with POSIX version of the
        function.
    """
    if os.path.basename(abs_path).startswith('.'):
        return True

    # check that dirs can be listed
    if os.path.isdir(abs_path):
        # can't trust os.access on Windows because it seems to always return True
        try:
            os.stat(abs_path)
        except OSError:
            # stat may fail on Windows junctions or non-user-readable dirs
            return True

    try:
        attrs = ctypes.windll.kernel32.GetFileAttributesW(
            py3compat.cast_unicode(abs_path))
    except AttributeError:
        pass
    else:
        if attrs > 0 and attrs & _win32_FILE_ATTRIBUTE_HIDDEN:
            return True

    return False
예제 #49
0
def ascii_only(s):
    """ensure a string is ascii"""
    s = py3compat.cast_unicode(s)
    return s.encode('ascii', 'replace').decode('ascii')
예제 #50
0
 def get(self, kernel_id, *args, **kwargs):
     self.authenticate()
     self.kernel_id = cast_unicode(kernel_id, 'ascii')
     super(WebSocketChannelsHandler, self).get(kernel_id=kernel_id, *args, **kwargs)
예제 #51
0
 def tempdir(self):
     td = TemporaryDirectory()
     self.tempdirs.append(td)
     return py3compat.cast_unicode(td.name)
예제 #52
0
파일: strings.py 프로젝트: CaptainAL/Spyder
def ascii_only(s):
    """ensure a string is ascii"""
    s = py3compat.cast_unicode(s)
    return s.encode('ascii', 'replace').decode('ascii')
예제 #53
0
 def tempdir(self):
     td = TemporaryDirectory()
     self.tempdirs.append(td)
     return py3compat.cast_unicode(td.name)
예제 #54
0
def new_output(
    output_type,
    output_text=None,
    output_png=None,
    output_html=None,
    output_svg=None,
    output_latex=None,
    output_json=None,
    output_javascript=None,
    output_jpeg=None,
    prompt_number=None,
    ename=None,
    evalue=None,
    traceback=None,
    stream=None,
    metadata=None,
):
    """Create a new output, to go in the ``cell.outputs`` list of a code cell.
    """
    output = NotebookNode()
    output.output_type = unicode_type(output_type)

    if metadata is None:
        metadata = {}
    if not isinstance(metadata, dict):
        raise TypeError("metadata must be dict")

    if output_type in {u"pyout", "display_data"}:
        output.metadata = metadata

    if output_type != "pyerr":
        if output_text is not None:
            output.text = cast_unicode(output_text)
        if output_png is not None:
            output.png = cast_unicode(output_png)
        if output_jpeg is not None:
            output.jpeg = cast_unicode(output_jpeg)
        if output_html is not None:
            output.html = cast_unicode(output_html)
        if output_svg is not None:
            output.svg = cast_unicode(output_svg)
        if output_latex is not None:
            output.latex = cast_unicode(output_latex)
        if output_json is not None:
            output.json = cast_unicode(output_json)
        if output_javascript is not None:
            output.javascript = cast_unicode(output_javascript)

    if output_type == u"pyout":
        if prompt_number is not None:
            output.prompt_number = int(prompt_number)

    if output_type == u"pyerr":
        if ename is not None:
            output.ename = cast_unicode(ename)
        if evalue is not None:
            output.evalue = cast_unicode(evalue)
        if traceback is not None:
            output.traceback = [cast_unicode(frame) for frame in list(traceback)]

    if output_type == u"stream":
        output.stream = "stdout" if stream is None else cast_unicode(stream)

    return output
예제 #55
0
 def get(self, kernel_id):
     self.kernel_id = cast_unicode(kernel_id, 'ascii')
     yield super(ZMQChannelsHandler, self).get(kernel_id=kernel_id)
예제 #56
0
class APITest(NotebookTestBase):
    """Test the kernels web service API"""
    dirs_nbs = [
        ('', 'inroot'),
        ('Directory with spaces in', 'inspace'),
        (u'unicodé', 'innonascii'),
        ('foo', 'a'),
        ('foo', 'b'),
        ('foo', 'name with spaces'),
        ('foo', u'unicodé'),
        ('foo/bar', 'baz'),
        ('ordering', 'A'),
        ('ordering', 'b'),
        ('ordering', 'C'),
        (u'å b', u'ç d'),
    ]
    hidden_dirs = ['.hidden', '__pycache__']

    # Don't include root dir.
    dirs = uniq_stable([py3compat.cast_unicode(d) for (d, n) in dirs_nbs[1:]])
    top_level_dirs = {normalize('NFC', d.split('/')[0]) for d in dirs}

    @staticmethod
    def _blob_for_name(name):
        return name.encode('utf-8') + b'\xFF'

    @staticmethod
    def _txt_for_name(name):
        return u'%s text file' % name

    def to_os_path(self, api_path):
        return to_os_path(api_path, root=self.notebook_dir)

    def make_dir(self, api_path):
        """Create a directory at api_path"""
        os_path = self.to_os_path(api_path)
        try:
            os.makedirs(os_path)
        except OSError:
            print("Directory already exists: %r" % os_path)

    def make_txt(self, api_path, txt):
        """Make a text file at a given api_path"""
        os_path = self.to_os_path(api_path)
        with io.open(os_path, 'w', encoding='utf-8') as f:
            f.write(txt)

    def make_blob(self, api_path, blob):
        """Make a binary file at a given api_path"""
        os_path = self.to_os_path(api_path)
        with io.open(os_path, 'wb') as f:
            f.write(blob)

    def make_nb(self, api_path, nb):
        """Make a notebook file at a given api_path"""
        os_path = self.to_os_path(api_path)

        with io.open(os_path, 'w', encoding='utf-8') as f:
            write(nb, f, version=4)

    def delete_dir(self, api_path):
        """Delete a directory at api_path, removing any contents."""
        os_path = self.to_os_path(api_path)
        shutil.rmtree(os_path, ignore_errors=True)

    def delete_file(self, api_path):
        """Delete a file at the given path if it exists."""
        if self.isfile(api_path):
            os.unlink(self.to_os_path(api_path))

    def isfile(self, api_path):
        return os.path.isfile(self.to_os_path(api_path))

    def isdir(self, api_path):
        return os.path.isdir(self.to_os_path(api_path))

    def setUp(self):
        for d in (self.dirs + self.hidden_dirs):
            self.make_dir(d)
            self.addCleanup(partial(self.delete_dir, d))

        for d, name in self.dirs_nbs:
            # create a notebook
            nb = new_notebook()
            nbname = u'{}/{}.ipynb'.format(d, name)
            self.make_nb(nbname, nb)
            self.addCleanup(partial(self.delete_file, nbname))

            # create a text file
            txt = self._txt_for_name(name)
            txtname = u'{}/{}.txt'.format(d, name)
            self.make_txt(txtname, txt)
            self.addCleanup(partial(self.delete_file, txtname))

            blob = self._blob_for_name(name)
            blobname = u'{}/{}.blob'.format(d, name)
            self.make_blob(blobname, blob)
            self.addCleanup(partial(self.delete_file, blobname))

        self.api = API(self.request)

    def test_list_notebooks(self):
        nbs = notebooks_only(self.api.list().json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'inroot.ipynb')

        nbs = notebooks_only(
            self.api.list('/Directory with spaces in/').json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'inspace.ipynb')

        nbs = notebooks_only(self.api.list(u'/unicodé/').json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'innonascii.ipynb')
        self.assertEqual(nbs[0]['path'], u'unicodé/innonascii.ipynb')

        nbs = notebooks_only(self.api.list('/foo/bar/').json())
        self.assertEqual(len(nbs), 1)
        self.assertEqual(nbs[0]['name'], 'baz.ipynb')
        self.assertEqual(nbs[0]['path'], 'foo/bar/baz.ipynb')

        nbs = notebooks_only(self.api.list('foo').json())
        self.assertEqual(len(nbs), 4)
        nbnames = {normalize('NFC', n['name']) for n in nbs}
        expected = [
            u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodé.ipynb'
        ]
        expected = {normalize('NFC', name) for name in expected}
        self.assertEqual(nbnames, expected)

        nbs = notebooks_only(self.api.list('ordering').json())
        nbnames = {n['name'] for n in nbs}
        expected = {'A.ipynb', 'b.ipynb', 'C.ipynb'}
        self.assertEqual(nbnames, expected)

    def test_list_dirs(self):
        dirs = dirs_only(self.api.list().json())
        dir_names = {normalize('NFC', d['name']) for d in dirs}
        self.assertEqual(dir_names,
                         self.top_level_dirs)  # Excluding hidden dirs

    def test_get_dir_no_content(self):
        for d in self.dirs:
            model = self.api.read(d, content=False).json()
            self.assertEqual(model['path'], d)
            self.assertEqual(model['type'], 'directory')
            self.assertIn('content', model)
            self.assertEqual(model['content'], None)

    def test_list_nonexistant_dir(self):
        with assert_http_error(404):
            self.api.list('nonexistant')

    def test_get_nb_contents(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.ipynb')
            nb = self.api.read(path).json()
            self.assertEqual(nb['name'], u'%s.ipynb' % name)
            self.assertEqual(nb['path'], path)
            self.assertEqual(nb['type'], 'notebook')
            self.assertIn('content', nb)
            self.assertEqual(nb['format'], 'json')
            self.assertIn('metadata', nb['content'])
            self.assertIsInstance(nb['content']['metadata'], dict)

    def test_get_nb_no_content(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.ipynb')
            nb = self.api.read(path, content=False).json()
            self.assertEqual(nb['name'], u'%s.ipynb' % name)
            self.assertEqual(nb['path'], path)
            self.assertEqual(nb['type'], 'notebook')
            self.assertIn('content', nb)
            self.assertEqual(nb['content'], None)

    def test_get_nb_invalid(self):
        nb = {
            'nbformat': 4,
            'metadata': {},
            'cells': [{
                'cell_type': 'wrong',
                'metadata': {},
            }],
        }
        path = u'å b/Validate tést.ipynb'
        self.make_txt(path, py3compat.cast_unicode(json.dumps(nb)))
        model = self.api.read(path).json()
        self.assertEqual(model['path'], path)
        self.assertEqual(model['type'], 'notebook')
        self.assertIn('content', model)
        self.assertIn('message', model)
        self.assertIn("validation failed", model['message'].lower())

    def test_get_contents_no_such_file(self):
        # Name that doesn't exist - should be a 404
        with assert_http_error(404):
            self.api.read('foo/q.ipynb')

    def test_get_text_file_contents(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.txt')
            model = self.api.read(path).json()
            self.assertEqual(model['name'], u'%s.txt' % name)
            self.assertEqual(model['path'], path)
            self.assertIn('content', model)
            self.assertEqual(model['format'], 'text')
            self.assertEqual(model['type'], 'file')
            self.assertEqual(model['content'], self._txt_for_name(name))

        # Name that doesn't exist - should be a 404
        with assert_http_error(404):
            self.api.read('foo/q.txt')

        # Specifying format=text should fail on a non-UTF-8 file
        with assert_http_error(400):
            self.api.read('foo/bar/baz.blob', type='file', format='text')

    def test_get_binary_file_contents(self):
        for d, name in self.dirs_nbs:
            path = url_path_join(d, name + '.blob')
            model = self.api.read(path).json()
            self.assertEqual(model['name'], u'%s.blob' % name)
            self.assertEqual(model['path'], path)
            self.assertIn('content', model)
            self.assertEqual(model['format'], 'base64')
            self.assertEqual(model['type'], 'file')
            self.assertEqual(
                decodebytes(model['content'].encode('ascii')),
                self._blob_for_name(name),
            )

        # Name that doesn't exist - should be a 404
        with assert_http_error(404):
            self.api.read('foo/q.txt')

    def test_get_bad_type(self):
        with assert_http_error(400):
            self.api.read(u'unicodé', type='file')  # this is a directory

        with assert_http_error(400):
            self.api.read(u'unicodé/innonascii.ipynb', type='directory')

    def _check_created(self, resp, path, type='notebook'):
        self.assertEqual(resp.status_code, 201)
        location_header = py3compat.str_to_unicode(resp.headers['Location'])
        self.assertEqual(
            location_header,
            url_path_join(self.url_prefix, u'api/contents', url_escape(path)))
        rjson = resp.json()
        self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1])
        self.assertEqual(rjson['path'], path)
        self.assertEqual(rjson['type'], type)
        isright = self.isdir if type == 'directory' else self.isfile
        assert isright(path)

    def test_create_untitled(self):
        resp = self.api.create_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled.ipynb')

        # Second time
        resp = self.api.create_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled1.ipynb')

        # And two directories down
        resp = self.api.create_untitled(path='foo/bar')
        self._check_created(resp, 'foo/bar/Untitled.ipynb')

    def test_create_untitled_txt(self):
        resp = self.api.create_untitled(path='foo/bar', ext='.txt')
        self._check_created(resp, 'foo/bar/untitled.txt', type='file')

        resp = self.api.read(path='foo/bar/untitled.txt')
        model = resp.json()
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['format'], 'text')
        self.assertEqual(model['content'], '')

    def test_upload(self):
        nb = new_notebook()
        nbmodel = {'content': nb, 'type': 'notebook'}
        path = u'å b/Upload tést.ipynb'
        resp = self.api.upload(path, body=json.dumps(nbmodel))
        self._check_created(resp, path)

    def test_mkdir_untitled(self):
        resp = self.api.mkdir_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled Folder', type='directory')

        # Second time
        resp = self.api.mkdir_untitled(path=u'å b')
        self._check_created(resp, u'å b/Untitled Folder 1', type='directory')

        # And two directories down
        resp = self.api.mkdir_untitled(path='foo/bar')
        self._check_created(resp, 'foo/bar/Untitled Folder', type='directory')

    def test_mkdir(self):
        path = u'å b/New ∂ir'
        resp = self.api.mkdir(path)
        self._check_created(resp, path, type='directory')

    def test_mkdir_hidden_400(self):
        with assert_http_error(400):
            resp = self.api.mkdir(u'å b/.hidden')

    def test_upload_txt(self):
        body = u'ünicode téxt'
        model = {
            'content': body,
            'format': 'text',
            'type': 'file',
        }
        path = u'å b/Upload tést.txt'
        resp = self.api.upload(path, body=json.dumps(model))

        # check roundtrip
        resp = self.api.read(path)
        model = resp.json()
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['format'], 'text')
        self.assertEqual(model['content'], body)

    def test_upload_b64(self):
        body = b'\xFFblob'
        b64body = encodebytes(body).decode('ascii')
        model = {
            'content': b64body,
            'format': 'base64',
            'type': 'file',
        }
        path = u'å b/Upload tést.blob'
        resp = self.api.upload(path, body=json.dumps(model))

        # check roundtrip
        resp = self.api.read(path)
        model = resp.json()
        self.assertEqual(model['type'], 'file')
        self.assertEqual(model['path'], path)
        self.assertEqual(model['format'], 'base64')
        decoded = decodebytes(model['content'].encode('ascii'))
        self.assertEqual(decoded, body)

    def test_upload_v2(self):
        nb = v2.new_notebook()
        ws = v2.new_worksheet()
        nb.worksheets.append(ws)
        ws.cells.append(v2.new_code_cell(input='print("hi")'))
        nbmodel = {'content': nb, 'type': 'notebook'}
        path = u'å b/Upload tést.ipynb'
        resp = self.api.upload(path, body=json.dumps(nbmodel))
        self._check_created(resp, path)
        resp = self.api.read(path)
        data = resp.json()
        self.assertEqual(data['content']['nbformat'], 4)

    def test_copy(self):
        resp = self.api.copy(u'å b/ç d.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy1.ipynb')

        resp = self.api.copy(u'å b/ç d.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy2.ipynb')

    def test_copy_copy(self):
        resp = self.api.copy(u'å b/ç d.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy1.ipynb')

        resp = self.api.copy(u'å b/ç d-Copy1.ipynb', u'å b')
        self._check_created(resp, u'å b/ç d-Copy2.ipynb')

    def test_copy_path(self):
        resp = self.api.copy(u'foo/a.ipynb', u'å b')
        self._check_created(resp, u'å b/a.ipynb')

        resp = self.api.copy(u'foo/a.ipynb', u'å b')
        self._check_created(resp, u'å b/a-Copy1.ipynb')

    def test_copy_put_400(self):
        with assert_http_error(400):
            resp = self.api.copy_put(u'å b/ç d.ipynb', u'å b/cøpy.ipynb')

    def test_copy_dir_400(self):
        # can't copy directories
        with assert_http_error(400):
            resp = self.api.copy(u'å b', u'foo')

    def test_delete(self):
        for d, name in self.dirs_nbs:
            print('%r, %r' % (d, name))
            resp = self.api.delete(url_path_join(d, name + '.ipynb'))
            self.assertEqual(resp.status_code, 204)

        for d in self.dirs + ['/']:
            nbs = notebooks_only(self.api.list(d).json())
            print('------')
            print(d)
            print(nbs)
            self.assertEqual(nbs, [])

    def test_delete_dirs(self):
        # depth-first delete everything, so we don't try to delete empty directories
        for name in sorted(self.dirs + ['/'], key=len, reverse=True):
            listing = self.api.list(name).json()['content']
            for model in listing:
                self.api.delete(model['path'])
        listing = self.api.list('/').json()['content']
        self.assertEqual(listing, [])

    def test_delete_non_empty_dir(self):
        # Test that non empty directory can be deleted
        self.api.delete(u'å b')
        # Check if directory has actually been deleted
        with assert_http_error(404):
            self.api.list(u'å b')

    def test_rename(self):
        resp = self.api.rename('foo/a.ipynb', 'foo/z.ipynb')
        self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb')
        self.assertEqual(resp.json()['name'], 'z.ipynb')
        self.assertEqual(resp.json()['path'], 'foo/z.ipynb')
        assert self.isfile('foo/z.ipynb')

        nbs = notebooks_only(self.api.list('foo').json())
        nbnames = set(n['name'] for n in nbs)
        self.assertIn('z.ipynb', nbnames)
        self.assertNotIn('a.ipynb', nbnames)

    def test_checkpoints_follow_file(self):

        # Read initial file state
        orig = self.api.read('foo/a.ipynb')

        # Create a checkpoint of initial state
        r = self.api.new_checkpoint('foo/a.ipynb')
        cp1 = r.json()

        # Modify file and save
        nbcontent = json.loads(orig.text)['content']
        nb = from_dict(nbcontent)
        hcell = new_markdown_cell('Created by test')
        nb.cells.append(hcell)
        nbmodel = {'content': nb, 'type': 'notebook'}
        self.api.save('foo/a.ipynb', body=json.dumps(nbmodel))

        # Rename the file.
        self.api.rename('foo/a.ipynb', 'foo/z.ipynb')

        # Looking for checkpoints in the old location should yield no results.
        self.assertEqual(self.api.get_checkpoints('foo/a.ipynb').json(), [])

        # Looking for checkpoints in the new location should work.
        cps = self.api.get_checkpoints('foo/z.ipynb').json()
        self.assertEqual(cps, [cp1])

        # Delete the file.  The checkpoint should be deleted as well.
        self.api.delete('foo/z.ipynb')
        cps = self.api.get_checkpoints('foo/z.ipynb').json()
        self.assertEqual(cps, [])

    def test_rename_existing(self):
        with assert_http_error(409):
            self.api.rename('foo/a.ipynb', 'foo/b.ipynb')

    def test_save(self):
        resp = self.api.read('foo/a.ipynb')
        nbcontent = json.loads(resp.text)['content']
        nb = from_dict(nbcontent)
        nb.cells.append(new_markdown_cell(u'Created by test ³'))

        nbmodel = {'content': nb, 'type': 'notebook'}
        resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel))

        nbcontent = self.api.read('foo/a.ipynb').json()['content']
        newnb = from_dict(nbcontent)
        self.assertEqual(newnb.cells[0].source, u'Created by test ³')

    def test_checkpoints(self):
        resp = self.api.read('foo/a.ipynb')
        r = self.api.new_checkpoint('foo/a.ipynb')
        self.assertEqual(r.status_code, 201)
        cp1 = r.json()
        self.assertEqual(set(cp1), {'id', 'last_modified'})
        self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])

        # Modify it
        nbcontent = json.loads(resp.text)['content']
        nb = from_dict(nbcontent)
        hcell = new_markdown_cell('Created by test')
        nb.cells.append(hcell)
        # Save
        nbmodel = {'content': nb, 'type': 'notebook'}
        resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel))

        # List checkpoints
        cps = self.api.get_checkpoints('foo/a.ipynb').json()
        self.assertEqual(cps, [cp1])

        nbcontent = self.api.read('foo/a.ipynb').json()['content']
        nb = from_dict(nbcontent)
        self.assertEqual(nb.cells[0].source, 'Created by test')

        # Restore cp1
        r = self.api.restore_checkpoint('foo/a.ipynb', cp1['id'])
        self.assertEqual(r.status_code, 204)
        nbcontent = self.api.read('foo/a.ipynb').json()['content']
        nb = from_dict(nbcontent)
        self.assertEqual(nb.cells, [])

        # Delete cp1
        r = self.api.delete_checkpoint('foo/a.ipynb', cp1['id'])
        self.assertEqual(r.status_code, 204)
        cps = self.api.get_checkpoints('foo/a.ipynb').json()
        self.assertEqual(cps, [])

    def test_file_checkpoints(self):
        """
        Test checkpointing of non-notebook files.
        """
        filename = 'foo/a.txt'
        resp = self.api.read(filename)
        orig_content = json.loads(resp.text)['content']

        # Create a checkpoint.
        r = self.api.new_checkpoint(filename)
        self.assertEqual(r.status_code, 201)
        cp1 = r.json()
        self.assertEqual(set(cp1), {'id', 'last_modified'})
        self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])

        # Modify the file and save.
        new_content = orig_content + '\nsecond line'
        model = {
            'content': new_content,
            'type': 'file',
            'format': 'text',
        }
        resp = self.api.save(filename, body=json.dumps(model))

        # List checkpoints
        cps = self.api.get_checkpoints(filename).json()
        self.assertEqual(cps, [cp1])

        content = self.api.read(filename).json()['content']
        self.assertEqual(content, new_content)

        # Restore cp1
        r = self.api.restore_checkpoint(filename, cp1['id'])
        self.assertEqual(r.status_code, 204)
        restored_content = self.api.read(filename).json()['content']
        self.assertEqual(restored_content, orig_content)

        # Delete cp1
        r = self.api.delete_checkpoint(filename, cp1['id'])
        self.assertEqual(r.status_code, 204)
        cps = self.api.get_checkpoints(filename).json()
        self.assertEqual(cps, [])

    @contextmanager
    def patch_cp_root(self, dirname):
        """
        Temporarily patch the root dir of our checkpoint manager.
        """
        cpm = self.notebook.contents_manager.checkpoints
        old_dirname = cpm.root_dir
        cpm.root_dir = dirname
        try:
            yield
        finally:
            cpm.root_dir = old_dirname

    def test_checkpoints_separate_root(self):
        """
        Test that FileCheckpoints functions correctly even when it's
        using a different root dir from FileContentsManager.  This also keeps
        the implementation honest for use with ContentsManagers that don't map
        models to the filesystem

        Override this method to a no-op when testing other managers.
        """
        with TemporaryDirectory() as td:
            with self.patch_cp_root(td):
                self.test_checkpoints()

        with TemporaryDirectory() as td:
            with self.patch_cp_root(td):
                self.test_file_checkpoints()
예제 #57
0
 def _parse_args(self, args):
     """self.parser->self.parsed_data"""
     # decode sys.argv to support unicode command-line options
     enc = DEFAULT_ENCODING
     uargs = [py3compat.cast_unicode(a, enc) for a in args]
     self.parsed_data, self.extra_args = self.parser.parse_known_args(uargs)
예제 #58
0
    def export(self):
        """ Displays a dialog for exporting HTML generated by Qt's rich text
        system.

        Returns
        -------
        The name of the file that was saved, or None if no file was saved.
        """
        parent = self.control.window()
        dialog = QtGui.QFileDialog(parent, "Save as...")
        dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
        filters = ["HTML with PNG figures (*.html *.htm)", "XHTML with inline SVG figures (*.xhtml *.xml)"]
        dialog.setNameFilters(filters)
        if self.filename:
            dialog.selectFile(self.filename)
            root, ext = os.path.splitext(self.filename)
            if ext.lower() in (".xml", ".xhtml"):
                dialog.selectNameFilter(filters[-1])

        if dialog.exec_():
            self.filename = dialog.selectedFiles()[0]
            choice = dialog.selectedNameFilter()
            html = py3compat.cast_unicode(self.control.document().toHtml())

            # Configure the exporter.
            if choice.startswith("XHTML"):
                exporter = export_xhtml
            else:
                # If there are PNGs, decide how to export them.
                inline = self.inline_png
                if inline is None and IMG_RE.search(html):
                    dialog = QtGui.QDialog(parent)
                    dialog.setWindowTitle("Save as...")
                    layout = QtGui.QVBoxLayout(dialog)
                    msg = "Exporting HTML with PNGs"
                    info = "Would you like inline PNGs (single large html " "file) or external image files?"
                    checkbox = QtGui.QCheckBox("&Don't ask again")
                    checkbox.setShortcut("D")
                    ib = QtGui.QPushButton("&Inline")
                    ib.setShortcut("I")
                    eb = QtGui.QPushButton("&External")
                    eb.setShortcut("E")
                    box = QtGui.QMessageBox(QtGui.QMessageBox.Question, dialog.windowTitle(), msg)
                    box.setInformativeText(info)
                    box.addButton(ib, QtGui.QMessageBox.NoRole)
                    box.addButton(eb, QtGui.QMessageBox.YesRole)
                    layout.setSpacing(0)
                    layout.addWidget(box)
                    layout.addWidget(checkbox)
                    dialog.setLayout(layout)
                    dialog.show()
                    reply = box.exec_()
                    dialog.hide()
                    inline = reply == 0
                    if checkbox.checkState():
                        # Don't ask anymore; always use this choice.
                        self.inline_png = inline
                exporter = lambda h, f, i: export_html(h, f, i, inline)

            # Perform the export!
            try:
                return exporter(html, self.filename, self.image_tag)
            except Exception as e:
                msg = "Error exporting HTML to %s\n" % self.filename + str(e)
                reply = QtGui.QMessageBox.warning(parent, "Error", msg, QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok)

        return None