Compare commits

...

13 Commits
main ... 5.2.2

Author SHA1 Message Date
Grant Nestor d1aa35800d back to dev
8 years ago
Grant Nestor 73850efd18 release 5.2.2
8 years ago
Grant Nestor 51fdd96e7f Add 5.2.2 to changelog
8 years ago
meeseeksdev[bot] d20e36f3e7 Backport PR #2959: set cookie on base_url (#3090)
8 years ago
Grant Nestor 4dc145bd7d back to dev
8 years ago
Grant Nestor a705940dca release 5.2.1
8 years ago
Grant Nestor a6c4940e4f Add 5.2.1 to changelog
8 years ago
meeseeksdev[bot] f755c969f8 Backport PR #2983: Add more border width to CodeMirror cursor (#2994)
8 years ago
M Pacer 21ece3e7a2 Fix nbconvert handler (#2981)
8 years ago
Jason Grout bc23e28d70 Fix the prompt_area argument of the output area constructor.
8 years ago
meeseeksdev[bot] 281255dcec Backport PR #2916: allow disabling offline message buffering (#2986)
8 years ago
meeseeksdev[bot] d81e329632 Backport PR #2949: Handle a compound extension in new_untitled (#2985)
8 years ago
meeseeksdev[bot] 3fe02b2883 Backport PR #2972: update version to dev version for master to not overwrite editable installs (#2984)
8 years ago

@ -21,22 +21,73 @@ We strongly recommend that you upgrade to version 9+ of pip before upgrading ``n
``pip --version``.
.. _release-5.2.2:
5.2.2
-----
- set cookie on base_urls (:ghpull:`2959`).
Thanks to Min RK (`minrk <https://github.com/minrk>`__).
.. _release-5.2.1:
5.2.1
-----
- Fix invisible CodeMirror cursor at specific browser zoom levels (:ghpull:`2983`).
- Fix nbconvert handler causing broken export to PDF (:ghpull:`2981`).
- Fix the prompt_area argument of the output area constructor. (:ghpull:`2961`).
- Handle a compound extension in new_untitled (:ghpull:`2949`).
- Allow disabling offline message buffering (:ghpull:`2916`).
Thanks to the following contributors:
- Steven Silvester (`blink1073 <https://github.com/blink1073>`__)
- Grant Nestor (`gnestor <https://github.com/gnestor>`__)
- Jason Grout (`jasongrout <https://github.com/jasongrout>`__)
- Min RK (`minrk <https://github.com/minrk>`__)
- M Pacer (`mpacer <https://github.com/mpacer>`__)
See the 5.2.1 milestone on GitHub for a complete list of
`pull requests <https://github.com/jupyter/notebook/pulls?utf8=%E2%9C%93&q=is%3Apr%20milestone%3A5.2.1>`__ involved in this release.
.. _release-5.2.0:
5.2.0
-----
- Make all files in the dashboard editable by default and provide a whitelist of viewable file extensions (:ghpull:`2911`).
- Ensure that the root directory is not hidden (:ghpull:`2907`).
- Fix CodeMirror styling issue (:ghpull:`2880`).
- Update error handling on ``APIHandlers`` (:ghpull:`2853`).
- Upgrade xterm.js to 2.9.2 (:ghpull:`2849`).
- Add Chinese translations (depends on upcoming UI implementation) (:ghpull:`2804`).
- Allow for simpler customization of ``output_prompt`` in custom.js (:ghpull:`2774`).
- Use RFC5987 encoding for filenames (:ghpull:`2767`).
- Add path to the resources metadata (:ghpull:`2753`).
- Make ``extraKeys`` consistent between notebook and editor views (:ghpull:`2745`).
- Add RTL (right-to-left) support (:ghpull:`2357`).
- Allow setting token via jupyter_token env (:ghpull:`2921`).
- Fix some errors caused by raising 403 in get_current_user (:ghpull:`2919`).
- Register contents_manager.files_handler_class directly (:ghpull:`2917`).
- Update viewable_extensions (:ghpull:`2913`).
- Show edit shortcuts modal after shortcuts modal is hidden (:ghpull:`2912`).
- Improve edit/view behavior (:ghpull:`2911`).
- The root directory of the notebook server should never be hidden (:ghpull:`2907`).
- Fix notebook require config to match tools/build-main (:ghpull:`2888`).
- Give page constructor default arguments (:ghpull:`2887`).
- Fix codemirror.less to match codemirror\'s expected padding layout (:ghpull:`2880`).
- Add x-xsrftoken to access-control-allow-headers (:ghpull:`2876`).
- Buffer messages when websocket connection is interrupted (:ghpull:`2871`).
- Load locale dynamically only when not en-us (:ghpull:`2866`).
- Changed key strength to 2048 bits (:ghpull:`2861`).
- Resync jsversion with python version (:ghpull:`2860`).
- Allow copy operation on modified, read-only notebook (:ghpull:`2854`).
- Update error handling on apihandlers (:ghpull:`2853`).
- Test python 3.6 on travis, drop 3.3 (:ghpull:`2852`).
- Avoid base64-literals in image tests (:ghpull:`2851`).
- Upgrade xterm.js to 2.9.2 (:ghpull:`2849`).
- Changed all python variables named file to file_name to not override built_in file (:ghpull:`2830`).
- Add more doc tests (:ghpull:`2823`).
- Typos fix (:ghpull:`2815`).
- Rename and update license [ci skip] (:ghpull:`2810`).
- Travis builds doc (:ghpull:`2808`).
- Pull request i18n (:ghpull:`2804`).
- Factor out output_prompt_function, as is done with input prompt (:ghpull:`2774`).
- Use rfc5987 encoding for filenames (:ghpull:`2767`).
- Added path to the resources metadata, the same as in from_filename(...) in nbconvert.exporters.py (:ghpull:`2753`).
- Make "extrakeys" consistent for notebook and editor (:ghpull:`2745`).
- Bidi support (:ghpull:`2357`).
Special thanks to `samarsultan <https://github.com/samarsultan>`__ and the Arabic Competence and Globalization Center Team at IBM Egypt for adding RTL (right-to-left) support to the notebook!

@ -9,5 +9,5 @@ store the current version info of the notebook.
# Next beta/alpha/rc release: The version number for beta is X.Y.ZbN **without dots**.
version_info = (5, 2, 0)
version_info = (5, 3, 0, ".dev")
__version__ = '.'.join(map(str, version_info[:3])) + ''.join(version_info[3:])

@ -94,6 +94,7 @@ class LoginHandler(IPythonHandler):
# 'secure' kwarg is passed to set_secure_cookie
if handler.settings.get('secure_cookie', handler.request.protocol == 'https'):
cookie_options.setdefault('secure', True)
cookie_options.setdefault('path', handler.base_url)
handler.set_secure_cookie(handler.cookie_name, user_id, **cookie_options)
return user_id

@ -89,10 +89,16 @@ class AuthenticatedHandler(web.RequestHandler):
# if method is unsupported (websocket and Access-Control-Allow-Origin
# for example, so just ignore)
self.log.debug(e)
def clear_login_cookie(self):
self.clear_cookie(self.cookie_name)
cookie_options = self.settings.get('cookie_options', {})
path = cookie_options.setdefault('path', self.base_url)
self.clear_cookie(self.cookie_name, path=path)
if path and path != '/':
# also clear cookie on / to ensure old cookies
# are cleared after the change in path behavior.
self.clear_cookie(self.cookie_name)
def get_current_user(self):
if self.login_handler is None:
return 'anonymous'

@ -60,13 +60,13 @@ def get_exporter(format, **kwargs):
from nbconvert.exporters.base import get_exporter
except ImportError as e:
raise web.HTTPError(500, "Could not import nbconvert: %s" % e)
try:
Exporter = get_exporter(format)
except KeyError:
# should this be 400?
raise web.HTTPError(404, u"No exporter for format: %s" % format)
try:
return Exporter(**kwargs)
except Exception as e:
@ -76,19 +76,20 @@ def get_exporter(format, **kwargs):
class NbconvertFileHandler(IPythonHandler):
SUPPORTED_METHODS = ('GET',)
@web.authenticated
def get(self, format, path):
exporter = get_exporter(format, config=self.config, log=self.log)
path = path.strip('/')
# If the notebook relates to a real file (default contents manager),
# give its path to nbconvert.
if hasattr(self.contents_manager, '_get_os_path'):
os_path = self.contents_manager._get_os_path(path)
ext_resources_dir, basename = os.path.split(os_path)
else:
os_path = ''
ext_resources_dir = None
model = self.contents_manager.get(path=path)
name = model['name']
@ -96,20 +97,29 @@ class NbconvertFileHandler(IPythonHandler):
# not a notebook, redirect to files
return FilesRedirectHandler.redirect_to_files(self, path)
nb = model['content']
self.set_header('Last-Modified', model['last_modified'])
# create resources dictionary
mod_date = model['last_modified'].strftime(text.date_format)
nb_title = os.path.splitext(name)[0]
resource_dict = {
"metadata": {
"name": nb_title,
"modified_date": mod_date
},
"config_dir": self.application.settings['config_dir']
}
if ext_resources_dir:
resource_dict['metadata']['path'] = ext_resources_dir
try:
output, resources = exporter.from_notebook_node(
model['content'],
resources={
"metadata": {
"name": name[:name.rfind('.')],
"modified_date": (model['last_modified']
.strftime(text.date_format)),
"path" : os_path
},
"config_dir": self.application.settings['config_dir'],
}
nb,
resources=resource_dict
)
except Exception as e:
self.log.exception("nbconvert failed: %s", e)
@ -136,11 +146,11 @@ class NbconvertPostHandler(IPythonHandler):
@web.authenticated
def post(self, format):
exporter = get_exporter(format, config=self.config)
model = self.get_json_body()
name = model.get('name', 'notebook.ipynb')
nbnode = from_dict(model['content'])
try:
output, resources = exporter.from_notebook_node(nbnode, resources={
"metadata": {"name": name[:name.rfind('.')],},

@ -4,7 +4,6 @@
# Distributed under the terms of the Modified BSD License.
from fnmatch import fnmatch
import gettext
import itertools
import json
import os
@ -32,6 +31,7 @@ from traitlets import (
from ipython_genutils.py3compat import string_types
from notebook.base.handlers import IPythonHandler
copy_pat = re.compile(r'\-Copy\d*\.')
@ -317,21 +317,26 @@ class ContentsManager(LoggingConfigurable):
The name of a file, including extension
path : unicode
The API path of the target's directory
insert: unicode
The characters to insert after the base filename
Returns
-------
name : unicode
A filename that is unique, based on the input filename.
"""
# Extract the full suffix from the filename (e.g. .tar.gz)
path = path.strip('/')
basename, ext = os.path.splitext(filename)
basename, dot, ext = filename.partition('.')
suffix = dot + ext
for i in itertools.count():
if i:
insert_i = '{}{}'.format(insert, i)
else:
insert_i = ''
name = u'{basename}{insert}{ext}'.format(basename=basename,
insert=insert_i, ext=ext)
name = u'{basename}{insert}{suffix}'.format(basename=basename,
insert=insert_i, suffix=suffix)
if not self.exists(u'{}/{}'.format(path, name)):
break
return name

@ -300,6 +300,12 @@ class TestContentsManager(TestCase):
self.assertEqual(model['name'], 'untitled')
self.assertEqual(model['path'], '%s/untitled' % sub_dir)
# Test with a compound extension
model = cm.new_untitled(path=sub_dir, ext='.foo.bar')
self.assertEqual(model['name'], 'untitled.foo.bar')
model = cm.new_untitled(path=sub_dir, ext='.foo.bar')
self.assertEqual(model['name'], 'untitled1.foo.bar')
def test_modified_date(self):
cm = self.contents_manager

@ -83,6 +83,17 @@ class MappingKernelManager(MultiKernelManager):
Only effective if cull_idle_timeout is not 0."""
)
buffer_offline_messages = Bool(True, config=True,
help="""Whether messages from kernels whose frontends have disconnected should be buffered in-memory.
When True (default), messages are buffered and replayed on reconnect,
avoiding lost messages due to interrupted connectivity.
Disable if long-running kernels will produce too much output while
no frontends are connected.
"""
)
_kernel_buffers = Any()
@default('_kernel_buffers')
def _default_kernel_buffers(self):
@ -105,7 +116,7 @@ class MappingKernelManager(MultiKernelManager):
while not os.path.isdir(os_path) and os_path != self.root_dir:
os_path = os.path.dirname(os_path)
return os_path
@gen.coroutine
def start_kernel(self, kernel_id=None, path=None, **kwargs):
"""Start a kernel for a session and return its kernel_id.
@ -148,7 +159,7 @@ class MappingKernelManager(MultiKernelManager):
# py2-compat
raise gen.Return(kernel_id)
def start_buffering(self, kernel_id, session_key, channels):
"""Start buffering messages for a kernel
@ -163,6 +174,12 @@ class MappingKernelManager(MultiKernelManager):
channels: dict({'channel': ZMQStream})
The zmq channels whose messages should be buffered.
"""
if not self.buffer_offline_messages:
for channel, stream in channels.items():
stream.close()
return
self.log.info("Starting buffering for %s", session_key)
self._check_kernel_id(kernel_id)
# clear previous buffering state
@ -182,7 +199,6 @@ class MappingKernelManager(MultiKernelManager):
for channel, stream in channels.items():
stream.on_recv(partial(buffer_msg, channel))
def get_buffer(self, kernel_id, session_key):
"""Get the buffer for a given kernel

@ -73,7 +73,7 @@ define(function(){
// tree
jglobal('SessionList','tree/js/sessionlist');
Jupyter.version = "5.2.0";
Jupyter.version = "5.3.0.dev";
Jupyter._target = '_blank';
return Jupyter;
});

@ -77,6 +77,9 @@ define([
OutputArea.prototype.style = function () {
this.collapse_button.hide();
if (!this.prompt_area) {
this.prompt_overlay.hide();
}
this.wrapper.addClass('output_wrapper');
this.element.addClass('output');

@ -52,3 +52,20 @@
.border-radius(0)
}
.CodeMirror-cursor {
border-left: 1.4px solid black;
}
// When zoomed out 67% and 33% on a screen of 1440 width x 900 height
@media screen and (min-width: 2138px) and (max-width: 4319px) {
.CodeMirror-cursor {
border-left: 2px solid black;
}
}
// When zoomed out less than 33%
@media screen and (min-width: 4320px) {
.CodeMirror-cursor {
border-left: 4px solid black;
}
}

Loading…
Cancel
Save