move read_only flag to page-level

contents of LPanel are not drawn until after collapse

read_only is in a <meta> tag
MinRK 15 years ago
parent a3a0be08bb
commit 65a6cb3b1c

@ -41,7 +41,7 @@ except ImportError:
@decorator
def not_if_readonly(f, self, *args, **kwargs):
if self.application.ipython_app.read_only:
if self.application.read_only:
raise web.HTTPError(403, "Notebook server is read-only")
else:
return f(self, *args, **kwargs)
@ -57,7 +57,7 @@ def authenticate_unless_readonly(f, self, *args, **kwargs):
@web.authenticated
def auth_f(self, *args, **kwargs):
return f(self, *args, **kwargs)
if self.application.ipython_app.read_only:
if self.application.read_only:
return f(self, *args, **kwargs)
else:
return auth_f(self, *args, **kwargs)
@ -77,9 +77,20 @@ class AuthenticatedHandler(web.RequestHandler):
if user_id is None:
# prevent extra Invalid cookie sig warnings:
self.clear_cookie('username')
if not self.application.password and not self.application.ipython_app.read_only:
if not self.application.password and not self.application.read_only:
user_id = 'anonymous'
return user_id
@property
def read_only(self):
if self.application.read_only:
if self.application.password:
return self.get_current_user() is None
else:
return True
else:
return False
class ProjectDashboardHandler(AuthenticatedHandler):
@ -90,21 +101,24 @@ class ProjectDashboardHandler(AuthenticatedHandler):
project = nbm.notebook_dir
self.render(
'projectdashboard.html', project=project,
base_project_url=u'/', base_kernel_url=u'/'
base_project_url=u'/', base_kernel_url=u'/',
read_only=self.read_only,
)
class LoginHandler(AuthenticatedHandler):
def get(self):
self.render('login.html', next=self.get_argument('next', default='/'))
self.render('login.html',
next=self.get_argument('next', default='/'),
read_only=self.read_only,
)
def post(self):
pwd = self.get_argument('password', default=u'')
if self.application.password and pwd == self.application.password:
self.set_secure_cookie('username', str(uuid.uuid4()))
url = self.get_argument('next', default='/')
self.redirect(url)
self.redirect(self.get_argument('next', default='/'))
class NewHandler(AuthenticatedHandler):
@ -118,7 +132,8 @@ class NewHandler(AuthenticatedHandler):
'notebook.html', project=project,
notebook_id=notebook_id,
base_project_url=u'/', base_kernel_url=u'/',
kill_kernel=False
kill_kernel=False,
read_only=False,
)
@ -130,11 +145,13 @@ class NamedNotebookHandler(AuthenticatedHandler):
project = nbm.notebook_dir
if not nbm.notebook_exists(notebook_id):
raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
self.render(
'notebook.html', project=project,
notebook_id=notebook_id,
base_project_url=u'/', base_kernel_url=u'/',
kill_kernel=False
kill_kernel=False,
read_only=self.read_only,
)
@ -393,12 +410,6 @@ class NotebookRootHandler(AuthenticatedHandler):
@authenticate_unless_readonly
def get(self):
# communicate read-only via Allow header
if self.application.ipython_app.read_only and not self.get_current_user():
self.set_header('Allow', 'GET')
else:
self.set_header('Allow', ', '.join(self.SUPPORTED_METHODS))
nbm = self.application.notebook_manager
files = nbm.list_notebooks()
self.finish(jsonapi.dumps(files))
@ -427,12 +438,6 @@ class NotebookHandler(AuthenticatedHandler):
format = self.get_argument('format', default='json')
last_mod, name, data = nbm.get_notebook(notebook_id, format)
# communicate read-only via Allow header
if self.application.ipython_app.read_only and not self.get_current_user():
self.set_header('Allow', 'GET')
else:
self.set_header('Allow', ', '.join(self.SUPPORTED_METHODS))
if format == u'json':
self.set_header('Content-Type', 'application/json')
self.set_header('Content-Disposition','attachment; filename="%s.ipynb"' % name)

@ -105,6 +105,7 @@ class NotebookWebApplication(web.Application):
self.log = log
self.notebook_manager = notebook_manager
self.ipython_app = ipython_app
self.read_only = self.ipython_app.read_only
#-----------------------------------------------------------------------------

@ -14,7 +14,7 @@ var IPython = (function (IPython) {
var utils = IPython.utils;
var Notebook = function (selector) {
this.read_only = false;
this.read_only = IPython.read_only;
this.element = $(selector);
this.element.scroll();
this.element.data("notebook", this);
@ -979,13 +979,6 @@ var IPython = (function (IPython) {
Notebook.prototype.notebook_loaded = function (data, status, xhr) {
var allowed = xhr.getResponseHeader('Allow');
if (allowed && allowed.indexOf('PUT') == -1){
this.read_only = true;
// unhide login button if it's relevant
$('span#login_widget').removeClass('hidden');
}else{
this.read_only = false;
}
this.fromJSON(data);
if (this.ncells() === 0) {
this.insert_code_cell_below();
@ -993,9 +986,7 @@ var IPython = (function (IPython) {
IPython.save_widget.status_save();
IPython.save_widget.set_notebook_name(data.metadata.name);
this.dirty = false;
if (this.read_only) {
this.handle_read_only();
}else{
if (! this.read_only) {
this.start_kernel();
}
// fromJSON always selects the last cell inserted. We need to wait
@ -1006,16 +997,6 @@ var IPython = (function (IPython) {
}, 50);
};
Notebook.prototype.handle_read_only = function(){
IPython.left_panel.collapse();
IPython.save_widget.element.find('button#save_notebook').addClass('hidden');
$('button#new_notebook').addClass('hidden');
$('div#cell_section').addClass('hidden');
$('div#kernel_section').addClass('hidden');
}
IPython.Notebook = Notebook;

@ -73,15 +73,6 @@ var IPython = (function (IPython) {
NotebookList.prototype.list_loaded = function (data, status, xhr) {
var allowed = xhr.getResponseHeader('Allow');
if (allowed && allowed.indexOf('PUT') == -1){
this.read_only = true;
$('#new_notebook').addClass('hidden');
// unhide login button if it's relevant
$('span#login_widget').removeClass('hidden');
}else{
this.read_only = false;
}
var len = data.length;
// Todo: remove old children
for (var i=0; i<len; i++) {
@ -89,7 +80,7 @@ var IPython = (function (IPython) {
var nbname = data[i].name;
var item = this.new_notebook_item(i);
this.add_link(notebook_id, nbname, item);
if (!this.read_only){
if (!IPython.read_only){
// hide delete buttons when readonly
this.add_delete_button(item);
}

@ -23,6 +23,7 @@ $(document).ready(function () {
}
});
IPython.markdown_converter = new Markdown.Converter();
IPython.read_only = $('meta[name=read_only]').attr("content") == 'True';
$('div#header').addClass('border-box-sizing');
$('div#main_app').addClass('border-box-sizing ui-widget ui-widget-content');
@ -43,6 +44,21 @@ $(document).ready(function () {
// These have display: none in the css file and are made visible here to prevent FLOUC.
$('div#header').css('display','block');
if(IPython.read_only){
// hide various elements from read-only view
IPython.save_widget.element.find('button#save_notebook').addClass('hidden');
IPython.quick_help.element.addClass('hidden'); // shortcuts are disabled in read_only
$('button#new_notebook').addClass('hidden');
$('div#cell_section').addClass('hidden');
$('div#kernel_section').addClass('hidden');
$('span#login_widget').removeClass('hidden');
// left panel starts collapsed, but the collapse must happen after
// elements start drawing. Don't draw contents of the panel until
// after they are collapsed
IPython.left_panel.left_panel_element.css('visibility', 'hidden');
}
$('div#main_app').css('display','block');
// Perform these actions after the notebook has been loaded.
@ -53,6 +69,14 @@ $(document).ready(function () {
IPython.save_widget.update_url();
IPython.layout_manager.do_resize();
IPython.pager.collapse();
if(IPython.read_only){
// collapse the left panel on read-only
IPython.left_panel.collapse();
// and finally unhide the panel contents after collapse
setTimeout(function(){
IPython.left_panel.left_panel_element.css('visibility', 'visible');
}, 200)
}
},100);
});

@ -27,8 +27,16 @@ $(document).ready(function () {
$('div#left_panel').addClass('box-flex');
$('div#right_panel').addClass('box-flex');
IPython.read_only = $('meta[name=read_only]').attr("content") == 'True';
IPython.notebook_list = new IPython.NotebookList('div#notebook_list');
IPython.login_widget = new IPython.LoginWidget('span#login_widget');
if (IPython.read_only){
$('#new_notebook').addClass('hidden');
// unhide login button if it's relevant
$('span#login_widget').removeClass('hidden');
}
IPython.notebook_list.load_list();
// These have display: none in the css file and are made visible here to prevent FLOUC.

@ -11,6 +11,8 @@
<link rel="stylesheet" href="static/css/layout.css" type="text/css" />
<link rel="stylesheet" href="static/css/base.css" type="text/css" />
<meta name="read_only" content="{{read_only}}"/>
</head>
<body>

@ -40,7 +40,8 @@
<link rel="stylesheet" href="static/css/base.css" type="text/css" />
<link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
<link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
<meta name="read_only" content="{{read_only}}"/>
</head>

@ -12,6 +12,8 @@
<link rel="stylesheet" href="static/css/base.css" type="text/css" />
<link rel="stylesheet" href="static/css/projectdashboard.css" type="text/css" />
<meta name="read_only" content="{{read_only}}"/>
</head>
<body data-project={{project}} data-base-project-url={{base_project_url}}

Loading…
Cancel
Save