Repository: bokeh/bokeh

Issue:
Docs build/deploy improvements
Update docs build and deploy scripts to accommodate new URL layout:

```
http://bokeh.pydata.org/en/0.6.1
                       /en/0.7.0
                       /en/dev
```

Additionally `/en/latest` is a symlink to the latest released docs version and `/` redirects to `/en/latest/`

Other miscellaneous improvements:
- use CDN resources for gallery, remove `bokehjs_static` ugliness 
- make tutorial and main gallery builds more similar
- remove absolute paths 



Discussion:

Resolving patch:
diff --git a/sphinx/build_gallery.py b/sphinx/build_gallery.py
--- a/sphinx/build_gallery.py
+++ b/sphinx/build_gallery.py
@@ -11,7 +11,7 @@
 from bokeh import plotting
 from bokeh.document import Document
 from bokeh.embed import autoload_static
-from bokeh.resources import Resources
+from bokeh.resources import CDN
 
 # patch open and show and save to be no-ops
 def noop(*args, **kwargs):
@@ -48,7 +48,7 @@ def page_desc(module_desc):
         filename = name + "." + str(i) + ".js"
         js, tag = autoload_static(
             obj,
-            Resources(mode="server", root_url=HOSTED_STATIC_ROOT),
+            CDN,
             os.path.join(DETAIL_URL_ROOT, filename)
         )
         embed_snippet += tag
@@ -127,7 +127,7 @@ def make_gallery(module_descs):
     GALLERY_RST_PATH = gallery_info['gallery_rst_path']
     if len(sys.argv) >= 5:
         GALLERY_RST_PATH = os.path.join(BASE_DIR, GALLERY_RST_PATH)
-    HOSTED_STATIC_ROOT="/docs/"
+    HOSTED_STATIC_ROOT=".."
     DETAIL_URL_ROOT="./"
 
     make_gallery(gallery_info['details'])
diff --git a/sphinx/docserver.py b/sphinx/docserver.py
--- a/sphinx/docserver.py
+++ b/sphinx/docserver.py
@@ -15,12 +15,12 @@
 
 @app.route('/')
 def welcome():
-    return """ 
+    return """
     <h1>Welcome to the Bokeh documentation server</h1>
-    You probably want to go to <a href="/index.html"> Index</a>
+    You probably want to go to <a href="/en/latest/index.html"> Index</a>
     """
 
-@app.route('/<path:filename>')
+@app.route('/en/latest/<path:filename>')
 def send_pic(filename):
     return flask.send_from_directory(
         os.path.join(_basedir,"sphinx/_build/html/"), filename)
@@ -30,8 +30,8 @@ def send_pic(filename):
     #app.run(port=PORT)
     http_server = WSGIServer(('', PORT), app)
     print "\nStarting Bokeh plot server on port %d..." % PORT
-    print "Visit http://localhost:%d/index.html to see plots\n" % PORT
-    
+    print "Visit http://localhost:%d/en/latest/index.html to see plots\n" % PORT
+
     pid = os.fork()
     if pid != 0:
         # Parent process
@@ -41,6 +41,6 @@ def send_pic(filename):
         import time
         import webbrowser
         time.sleep(0.5)
-        webbrowser.open("http://localhost:%d/index.html"%PORT, new="tab")
+        webbrowser.open("http://localhost:%d/en/latest/index.html"%PORT, new="tab")
 
 
diff --git a/sphinx/fabfile.py b/sphinx/fabfile.py
--- a/sphinx/fabfile.py
+++ b/sphinx/fabfile.py
@@ -1,42 +1,59 @@
-from fabric.api import run, env, roles, put
+from fabric.api import run, env, roles
 from fabric.contrib.project import rsync_project
 
-env.roledefs = {
-    'web': ['bokeh.pydata.org']}
+import sys
+sys.path.append("source")
+import conf
 
-dirs = ['_images', '_sources', '_static', 'docs', 'tutorial']
-files = ['genindex.html', 'index.html', 'objects.inv', 'py-modindex.html', 'search.html', 'searchindex.js']
+env.roledefs = {
+    'web': ['bokeh.pydata.org']
+}
+env.user = "bokeh"
 
 @roles('web')
-def deploy(user=False):
-    if user:
-        env.user = user
-
-    # remove and archive old files and directories
-    for dir in dirs:
-        run("rm -rf /www/bokeh-old/%s" % dir)
-        run("cp -ar /www/bokeh-latest/%s /www/bokeh-old/%s" % (dir, dir))
-    for file in files:
-        run("rm -f /www/bokeh-old/%s" % file)
-        run("cp -a /www/bokeh-latest/%s /www/bokeh-old/%s" % (file, file))
-
-    # switch current symlink to archive docs
-    run("rm /www/bokeh")
-    run("ln -s /www/bokeh-old /www/bokeh")
-
-    # upload the new files and directories
-    for dir in dirs:
-        rsync_project(
-            local_dir="_build/html/%s/" % dir,
-            remote_dir="/www/bokeh-latest/%s" % dir, delete=True)
-    for file in files:
-        put(
-            local_path="_build/html/%s" % file,
-            remote_path="/www/bokeh-latest/%s" % file)
+def deploy():
+
+    v = conf.version
+
+    # make a backup of the old directory
+    run("rm -rf /www/bokeh/en/%s.bak" % v)
+    run("mkdir -p /www/bokeh/en/%s" % v)
+    run("cp -ar /www/bokeh/en/%s /www/bokeh/en/%s.bak" % (v, v))
+
+    # switch latest symlink to archive docs
+    run("rm /www/bokeh/en/latest")
+    run("ln -s /www/bokeh/en/%s.bak /www/bokeh/en/latest" % v)
+
+    rsync_project(
+        local_dir="_build/html/",
+        remote_dir="/www/bokeh/en/%s" % v,
+        delete=True
+    )
+
+    # set permissions
+    run("chmod -R g+w /www/bokeh/en/%s" % v)
 
     # switch the current symlink to new docs
-    run("rm /www/bokeh")
-    run("ln -s /www/bokeh-latest /www/bokeh")
+    run("rm /www/bokeh/en/latest")
+    run("ln -s /www/bokeh/en/%s /www/bokeh/en/latest" % v)
+
+@roles('web')
+def update(v=None):
+
+    # TODO (bev) confirm this version is not the latest
+    if v is None:
+        v = conf.version
+
+    # make a backup of the old directory
+    run("rm -rf /www/bokeh/en/%s.bak" % v)
+    run("mkdir -p /www/bokeh/en/%s" % v)
+    run("cp -ar /www/bokeh/en/%s /www/bokeh/en/%s.bak" % (v, v))
+
+    rsync_project(
+        local_dir="_build/html/",
+        remote_dir="/www/bokeh/en/%s" % v,
+        delete=True
+    )
 
     # set permissions
-    run("chmod -R g+w /www/bokeh-latest")
+    run("chmod -R g+w /www/bokeh/en/%s" % v)


Test patch: