Repository: ipython/ipython

Issue:
Allow distinction between notebook directory and home directory page.
I think it is important to make sure that it is easy for users of a multiuser JupyterHub deployment to share notebooks. Some of the requirements:
- They can navigate up to the /home directory to see the dirs of all users. This means that the single user notebook dir would be /home.
- But have the default dashboard view be their own home directory, rather than the possibly massive /home.

To address this I propose that we add a new config variable in the single user notebook that sets the default path that is used for the dashboard in the single user server.



Discussion:
What do you mean "share notebooks"? Do you mean: allow users to be able to open someone else's notebook for running/editing? This might might be useful for collaborative editing, but currently that sounds very dangerous.

Currently, we require users to:
- download and upload notebooks to use them; or
- use a "Copy" function that copies it into their own Incoming directory

Here is a browse of shared notebooks in Public with copy/download links (for copy, user must be logged in):

http://jupyter.cs.brynmawr.edu/hub/dblank/public/

Here is a rendered view, with Download link:

http://jupyter.cs.brynmawr.edu/hub/dblank/public/CS110%20Intro%20to%20Computing/2015/Notes/Jan26.ipynb

A basic deployment of jupyterhub allows users to set unix permissions on
files to allow others use them:
- Open, read and run but not write
- Of full read, run, write access.

This just works out of the box and is the default simple way of sharing
content that we should support (even if many users don't enable it by
setting permissions on their files). I like the idea of the "Make a Copy"
of a read only notebook making that copy in a sort of incoming directory.
How did you implement that?

On Tue, Jan 27, 2015 at 8:42 AM, Doug Blank notifications@github.com
wrote:

> What do you mean "share notebooks"? Do you mean: allow users to be able to
> open someone else's notebook for running/editing? This might might be
> useful for collaborative editing, but currently that sounds very dangerous.
> 
> Currently, we require users to:
> - download and upload notebooks to use them; or
> - use a "Copy" function that copies it into their own Incoming
>   directory
> 
> Here is a browse of shared notebooks in Public with copy/download links
> (for copy, user must be logged in):
> 
> http://jupyter.cs.brynmawr.edu/hub/dblank/public/
> 
> Here is a rendered view, with Download link:
> 
> http://jupyter.cs.brynmawr.edu/hub/dblank/public/CS110%20Intro%20to%20Computing/2015/Notes/Jan26.ipynb
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/ipython/ipython/issues/7607#issuecomment-71680549.

## 

Brian E. Granger
Cal Poly State University, San Luis Obispo
@ellisonbg on Twitter and GitHub
bgranger@calpoly.edu and ellisonbg@gmail.com

Also, I love the idea of a public folder that knows how to nbconvert
notebooks to static. How are you doing that?

On Tue, Jan 27, 2015 at 8:57 AM, Brian Granger ellisonbg@gmail.com wrote:

> A basic deployment of jupyterhub allows users to set unix permissions on
> files to allow others use them:
> - Open, read and run but not write
> - Of full read, run, write access.
> 
> This just works out of the box and is the default simple way of sharing
> content that we should support (even if many users don't enable it by
> setting permissions on their files). I like the idea of the "Make a Copy"
> of a read only notebook making that copy in a sort of incoming directory.
> How did you implement that?
> 
> On Tue, Jan 27, 2015 at 8:42 AM, Doug Blank notifications@github.com
> wrote:
> 
> > What do you mean "share notebooks"? Do you mean: allow users to be able
> > to open someone else's notebook for running/editing? This might might be
> > useful for collaborative editing, but currently that sounds very dangerous.
> > 
> > Currently, we require users to:
> > - download and upload notebooks to use them; or
> > - use a "Copy" function that copies it into their own Incoming
> >   directory
> > 
> > Here is a browse of shared notebooks in Public with copy/download links
> > (for copy, user must be logged in):
> > 
> > http://jupyter.cs.brynmawr.edu/hub/dblank/public/
> > 
> > Here is a rendered view, with Download link:
> > 
> > http://jupyter.cs.brynmawr.edu/hub/dblank/public/CS110%20Intro%20to%20Computing/2015/Notes/Jan26.ipynb
> > 
> > —
> > Reply to this email directly or view it on GitHub
> > https://github.com/ipython/ipython/issues/7607#issuecomment-71680549.
> 
> ## 
> 
> Brian E. Granger
> Cal Poly State University, San Luis Obispo
> @ellisonbg on Twitter and GitHub
> bgranger@calpoly.edu and ellisonbg@gmail.com

## 

Brian E. Granger
Cal Poly State University, San Luis Obispo
@ellisonbg on Twitter and GitHub
bgranger@calpoly.edu and ellisonbg@gmail.com

Both are seat-of-my-pants hacks at the moment:

https://github.com/dsblank/jupyter.brynmawr/blob/master/jupyterhub/publichandler.py

This is embarrassing code... but the main take-away I think is the functionality. Briefly:
- when you "Publish", it copies your notebook into your Public folder (creates it if necessary), and sets proper permissions. This is an even larger hack [1] where the javascript sends the kernel Python code to execute, using callbacks to confirm and show URL of nbconvert-view of notebook (via PublicHandler)
- PublicHandler will list files in directory, show HTML, images, and render ipynb files (with header)
- Make a copy will do similar as Publish, but copies other's notebooks into an Incoming folder. 

Next, I'm working on:
- browsing others' "published" notebooks
- a "Submit" button for turning in homework

This is all prototype code to be suggestive to a developer of _what_ we want, but not _how_ it should be done.

[1] - https://bitbucket.org/ipre/calico/src/master/notebooks/nbextensions/calico-publish.js

@ellisonbg how do you propose implementing the default path, in terms of URLs? Would `/tree/` redirect to `/tree/default/path/`? That would make listing the root directory impossible. Would `/` redirect to `/default/path/`? Would the logo link go to default or home?

I think using the default path for the logo and `/` (not `/tree/`) links should work.


Resolving patch:
diff --git a/IPython/html/base/handlers.py b/IPython/html/base/handlers.py
--- a/IPython/html/base/handlers.py
+++ b/IPython/html/base/handlers.py
@@ -137,6 +137,10 @@ def mathjax_url(self):
     def base_url(self):
         return self.settings.get('base_url', '/')
 
+    @property
+    def default_url(self):
+        return self.settings.get('default_url', '')
+
     @property
     def ws_url(self):
         return self.settings.get('websocket_url', '')
@@ -238,6 +242,7 @@ def render_template(self, name, **ns):
     def template_namespace(self):
         return dict(
             base_url=self.base_url,
+            default_url=self.default_url,
             ws_url=self.ws_url,
             logged_in=self.logged_in,
             login_available=self.login_available,
diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py
--- a/IPython/html/notebookapp.py
+++ b/IPython/html/notebookapp.py
@@ -243,7 +243,7 @@ def init_handlers(self, settings):
         # set the URL that will be redirected from `/`
         handlers.append(
             (r'/?', web.RedirectHandler, {
-                'url' : url_path_join(settings['base_url'], settings['default_url']),
+                'url' : settings['default_url'],
                 'permanent': False, # want 302, not 301
             })
         )
@@ -816,6 +816,9 @@ def init_webapp(self):
         if self.allow_origin_pat:
             self.tornado_settings['allow_origin_pat'] = re.compile(self.allow_origin_pat)
         self.tornado_settings['allow_credentials'] = self.allow_credentials
+        # ensure default_url starts with base_url
+        if not self.default_url.startswith(self.base_url):
+            self.default_url = url_path_join(self.base_url, self.default_url)
         
         self.web_app = NotebookWebApplication(
             self, self.kernel_manager, self.contents_manager,


Test patch: