##// END OF EJS Templates
move read_only flag to page-level...
MinRK -
Show More
@@ -41,7 +41,7 b' except ImportError:'
41 41
42 42 @decorator
43 43 def not_if_readonly(f, self, *args, **kwargs):
44 if self.application.ipython_app.read_only:
44 if self.application.read_only:
45 45 raise web.HTTPError(403, "Notebook server is read-only")
46 46 else:
47 47 return f(self, *args, **kwargs)
@@ -57,7 +57,7 b' def authenticate_unless_readonly(f, self, *args, **kwargs):'
57 57 @web.authenticated
58 58 def auth_f(self, *args, **kwargs):
59 59 return f(self, *args, **kwargs)
60 if self.application.ipython_app.read_only:
60 if self.application.read_only:
61 61 return f(self, *args, **kwargs)
62 62 else:
63 63 return auth_f(self, *args, **kwargs)
@@ -77,10 +77,21 b' class AuthenticatedHandler(web.RequestHandler):'
77 77 if user_id is None:
78 78 # prevent extra Invalid cookie sig warnings:
79 79 self.clear_cookie('username')
80 if not self.application.password and not self.application.ipython_app.read_only:
80 if not self.application.password and not self.application.read_only:
81 81 user_id = 'anonymous'
82 82 return user_id
83 83
84 @property
85 def read_only(self):
86 if self.application.read_only:
87 if self.application.password:
88 return self.get_current_user() is None
89 else:
90 return True
91 else:
92 return False
93
94
84 95
85 96 class ProjectDashboardHandler(AuthenticatedHandler):
86 97
@@ -90,21 +101,24 b' class ProjectDashboardHandler(AuthenticatedHandler):'
90 101 project = nbm.notebook_dir
91 102 self.render(
92 103 'projectdashboard.html', project=project,
93 base_project_url=u'/', base_kernel_url=u'/'
104 base_project_url=u'/', base_kernel_url=u'/',
105 read_only=self.read_only,
94 106 )
95 107
96 108
97 109 class LoginHandler(AuthenticatedHandler):
98 110
99 111 def get(self):
100 self.render('login.html', next=self.get_argument('next', default='/'))
112 self.render('login.html',
113 next=self.get_argument('next', default='/'),
114 read_only=self.read_only,
115 )
101 116
102 117 def post(self):
103 118 pwd = self.get_argument('password', default=u'')
104 119 if self.application.password and pwd == self.application.password:
105 120 self.set_secure_cookie('username', str(uuid.uuid4()))
106 url = self.get_argument('next', default='/')
107 self.redirect(url)
121 self.redirect(self.get_argument('next', default='/'))
108 122
109 123
110 124 class NewHandler(AuthenticatedHandler):
@@ -118,7 +132,8 b' class NewHandler(AuthenticatedHandler):'
118 132 'notebook.html', project=project,
119 133 notebook_id=notebook_id,
120 134 base_project_url=u'/', base_kernel_url=u'/',
121 kill_kernel=False
135 kill_kernel=False,
136 read_only=False,
122 137 )
123 138
124 139
@@ -130,11 +145,13 b' class NamedNotebookHandler(AuthenticatedHandler):'
130 145 project = nbm.notebook_dir
131 146 if not nbm.notebook_exists(notebook_id):
132 147 raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
148
133 149 self.render(
134 150 'notebook.html', project=project,
135 151 notebook_id=notebook_id,
136 152 base_project_url=u'/', base_kernel_url=u'/',
137 kill_kernel=False
153 kill_kernel=False,
154 read_only=self.read_only,
138 155 )
139 156
140 157
@@ -393,12 +410,6 b' class NotebookRootHandler(AuthenticatedHandler):'
393 410 @authenticate_unless_readonly
394 411 def get(self):
395 412
396 # communicate read-only via Allow header
397 if self.application.ipython_app.read_only and not self.get_current_user():
398 self.set_header('Allow', 'GET')
399 else:
400 self.set_header('Allow', ', '.join(self.SUPPORTED_METHODS))
401
402 413 nbm = self.application.notebook_manager
403 414 files = nbm.list_notebooks()
404 415 self.finish(jsonapi.dumps(files))
@@ -427,12 +438,6 b' class NotebookHandler(AuthenticatedHandler):'
427 438 format = self.get_argument('format', default='json')
428 439 last_mod, name, data = nbm.get_notebook(notebook_id, format)
429 440
430 # communicate read-only via Allow header
431 if self.application.ipython_app.read_only and not self.get_current_user():
432 self.set_header('Allow', 'GET')
433 else:
434 self.set_header('Allow', ', '.join(self.SUPPORTED_METHODS))
435
436 441 if format == u'json':
437 442 self.set_header('Content-Type', 'application/json')
438 443 self.set_header('Content-Disposition','attachment; filename="%s.ipynb"' % name)
@@ -105,6 +105,7 b' class NotebookWebApplication(web.Application):'
105 105 self.log = log
106 106 self.notebook_manager = notebook_manager
107 107 self.ipython_app = ipython_app
108 self.read_only = self.ipython_app.read_only
108 109
109 110
110 111 #-----------------------------------------------------------------------------
@@ -65,8 +65,10 b' var IPython = (function (IPython) {'
65 65
66 66 LeftPanel.prototype.create_children = function () {
67 67 this.notebook_section = new IPython.NotebookSection('div#notebook_section');
68 if (! IPython.read_only){
68 69 this.cell_section = new IPython.CellSection('div#cell_section');
69 70 this.kernel_section = new IPython.KernelSection('div#kernel_section');
71 }
70 72 this.help_section = new IPython.HelpSection('div#help_section');
71 73 }
72 74
@@ -14,7 +14,7 b' var IPython = (function (IPython) {'
14 14 var utils = IPython.utils;
15 15
16 16 var Notebook = function (selector) {
17 this.read_only = false;
17 this.read_only = IPython.read_only;
18 18 this.element = $(selector);
19 19 this.element.scroll();
20 20 this.element.data("notebook", this);
@@ -979,13 +979,6 b' var IPython = (function (IPython) {'
979 979
980 980 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
981 981 var allowed = xhr.getResponseHeader('Allow');
982 if (allowed && allowed.indexOf('PUT') == -1){
983 this.read_only = true;
984 // unhide login button if it's relevant
985 $('span#login_widget').removeClass('hidden');
986 }else{
987 this.read_only = false;
988 }
989 982 this.fromJSON(data);
990 983 if (this.ncells() === 0) {
991 984 this.insert_code_cell_below();
@@ -993,9 +986,7 b' var IPython = (function (IPython) {'
993 986 IPython.save_widget.status_save();
994 987 IPython.save_widget.set_notebook_name(data.metadata.name);
995 988 this.dirty = false;
996 if (this.read_only) {
997 this.handle_read_only();
998 }else{
989 if (! this.read_only) {
999 990 this.start_kernel();
1000 991 }
1001 992 // fromJSON always selects the last cell inserted. We need to wait
@@ -1006,16 +997,6 b' var IPython = (function (IPython) {'
1006 997 }, 50);
1007 998 };
1008 999
1009
1010 Notebook.prototype.handle_read_only = function(){
1011 IPython.left_panel.collapse();
1012 IPython.save_widget.element.find('button#save_notebook').addClass('hidden');
1013 $('button#new_notebook').addClass('hidden');
1014 $('div#cell_section').addClass('hidden');
1015 $('div#kernel_section').addClass('hidden');
1016 }
1017
1018
1019 1000 IPython.Notebook = Notebook;
1020 1001
1021 1002
@@ -73,15 +73,6 b' var IPython = (function (IPython) {'
73 73
74 74
75 75 NotebookList.prototype.list_loaded = function (data, status, xhr) {
76 var allowed = xhr.getResponseHeader('Allow');
77 if (allowed && allowed.indexOf('PUT') == -1){
78 this.read_only = true;
79 $('#new_notebook').addClass('hidden');
80 // unhide login button if it's relevant
81 $('span#login_widget').removeClass('hidden');
82 }else{
83 this.read_only = false;
84 }
85 76 var len = data.length;
86 77 // Todo: remove old children
87 78 for (var i=0; i<len; i++) {
@@ -89,7 +80,7 b' var IPython = (function (IPython) {'
89 80 var nbname = data[i].name;
90 81 var item = this.new_notebook_item(i);
91 82 this.add_link(notebook_id, nbname, item);
92 if (!this.read_only){
83 if (!IPython.read_only){
93 84 // hide delete buttons when readonly
94 85 this.add_delete_button(item);
95 86 }
@@ -23,6 +23,7 b' $(document).ready(function () {'
23 23 }
24 24 });
25 25 IPython.markdown_converter = new Markdown.Converter();
26 IPython.read_only = $('meta[name=read_only]').attr("content") == 'True';
26 27
27 28 $('div#header').addClass('border-box-sizing');
28 29 $('div#main_app').addClass('border-box-sizing ui-widget ui-widget-content');
@@ -43,6 +44,21 b' $(document).ready(function () {'
43 44
44 45 // These have display: none in the css file and are made visible here to prevent FLOUC.
45 46 $('div#header').css('display','block');
47
48 if(IPython.read_only){
49 // hide various elements from read-only view
50 IPython.save_widget.element.find('button#save_notebook').addClass('hidden');
51 IPython.quick_help.element.addClass('hidden'); // shortcuts are disabled in read_only
52 $('button#new_notebook').addClass('hidden');
53 $('div#cell_section').addClass('hidden');
54 $('div#kernel_section').addClass('hidden');
55 $('span#login_widget').removeClass('hidden');
56 // left panel starts collapsed, but the collapse must happen after
57 // elements start drawing. Don't draw contents of the panel until
58 // after they are collapsed
59 IPython.left_panel.left_panel_element.css('visibility', 'hidden');
60 }
61
46 62 $('div#main_app').css('display','block');
47 63
48 64 // Perform these actions after the notebook has been loaded.
@@ -53,6 +69,14 b' $(document).ready(function () {'
53 69 IPython.save_widget.update_url();
54 70 IPython.layout_manager.do_resize();
55 71 IPython.pager.collapse();
72 if(IPython.read_only){
73 // collapse the left panel on read-only
74 IPython.left_panel.collapse();
75 // and finally unhide the panel contents after collapse
76 setTimeout(function(){
77 IPython.left_panel.left_panel_element.css('visibility', 'visible');
78 }, 200)
79 }
56 80 },100);
57 81 });
58 82
@@ -27,8 +27,16 b' $(document).ready(function () {'
27 27 $('div#left_panel').addClass('box-flex');
28 28 $('div#right_panel').addClass('box-flex');
29 29
30 IPython.read_only = $('meta[name=read_only]').attr("content") == 'True';
31
30 32 IPython.notebook_list = new IPython.NotebookList('div#notebook_list');
31 33 IPython.login_widget = new IPython.LoginWidget('span#login_widget');
34
35 if (IPython.read_only){
36 $('#new_notebook').addClass('hidden');
37 // unhide login button if it's relevant
38 $('span#login_widget').removeClass('hidden');
39 }
32 40 IPython.notebook_list.load_list();
33 41
34 42 // These have display: none in the css file and are made visible here to prevent FLOUC.
@@ -11,6 +11,8 b''
11 11 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
12 12 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
13 13
14 <meta name="read_only" content="{{read_only}}"/>
15
14 16 </head>
15 17
16 18 <body>
@@ -41,6 +41,7 b''
41 41 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
42 42 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
43 43
44 <meta name="read_only" content="{{read_only}}"/>
44 45
45 46 </head>
46 47
@@ -12,6 +12,8 b''
12 12 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
13 13 <link rel="stylesheet" href="static/css/projectdashboard.css" type="text/css" />
14 14
15 <meta name="read_only" content="{{read_only}}"/>
16
15 17 </head>
16 18
17 19 <body data-project={{project}} data-base-project-url={{base_project_url}}
General Comments 0
You need to be logged in to leave comments. Login now