Skip to content

Commit

Permalink
move read_only flag to page-level
Browse files Browse the repository at this point in the history
contents of LPanel are not drawn until after collapse

read_only is in a <meta> tag
  • Loading branch information
minrk committed Oct 28, 2011
1 parent 91d9381 commit 81edd9f
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 55 deletions.
47 changes: 26 additions & 21 deletions IPython/frontend/html/notebook/handlers.py
Expand Up @@ -41,7 +41,7 @@

@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)
Expand All @@ -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)
Expand All @@ -77,9 +77,20 @@ def get_current_user(self):
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):
Expand All @@ -90,21 +101,24 @@ def get(self):
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):
Expand All @@ -118,7 +132,8 @@ def get(self):
'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,
)


Expand All @@ -130,11 +145,13 @@ def get(self, notebook_id):
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,
)


Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -427,12 +438,6 @@ def get(self, notebook_id):
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)
Expand Down
1 change: 1 addition & 0 deletions IPython/frontend/html/notebook/notebookapp.py
Expand Up @@ -105,6 +105,7 @@ def __init__(self, ipython_app, kernel_manager, notebook_manager, log):
self.log = log
self.notebook_manager = notebook_manager
self.ipython_app = ipython_app
self.read_only = self.ipython_app.read_only


#-----------------------------------------------------------------------------
Expand Down
6 changes: 4 additions & 2 deletions IPython/frontend/html/notebook/static/js/leftpanel.js
Expand Up @@ -65,8 +65,10 @@ var IPython = (function (IPython) {

LeftPanel.prototype.create_children = function () {
this.notebook_section = new IPython.NotebookSection('div#notebook_section');
this.cell_section = new IPython.CellSection('div#cell_section');
this.kernel_section = new IPython.KernelSection('div#kernel_section');
if (! IPython.read_only){
this.cell_section = new IPython.CellSection('div#cell_section');
this.kernel_section = new IPython.KernelSection('div#kernel_section');
}
this.help_section = new IPython.HelpSection('div#help_section');
}

Expand Down
23 changes: 2 additions & 21 deletions IPython/frontend/html/notebook/static/js/notebook.js
Expand Up @@ -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);
Expand Down Expand Up @@ -979,23 +979,14 @@ 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();
};
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
Expand All @@ -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;


Expand Down
11 changes: 1 addition & 10 deletions IPython/frontend/html/notebook/static/js/notebooklist.js
Expand Up @@ -73,23 +73,14 @@ 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++) {
var notebook_id = data[i].notebook_id;
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);
}
Expand Down
24 changes: 24 additions & 0 deletions IPython/frontend/html/notebook/static/js/notebookmain.js
Expand Up @@ -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');
Expand All @@ -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.
Expand All @@ -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);
});

Expand Down
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions IPython/frontend/html/notebook/templates/login.html
Expand Up @@ -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>
Expand Down
3 changes: 2 additions & 1 deletion IPython/frontend/html/notebook/templates/notebook.html
Expand Up @@ -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>

Expand Down
Expand Up @@ -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}}
Expand Down

0 comments on commit 81edd9f

Please sign in to comment.