]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
web: remove /vdrive/private, replace with a start.html file that points at the /uri...
authorBrian Warner <warner@allmydata.com>
Wed, 22 Aug 2007 21:54:34 +0000 (14:54 -0700)
committerBrian Warner <warner@allmydata.com>
Wed, 22 Aug 2007 21:54:34 +0000 (14:54 -0700)
setup.py
src/allmydata/client.py
src/allmydata/test/test_system.py
src/allmydata/test/test_web.py
src/allmydata/vdrive.py
src/allmydata/webish.py

index 726dd47b080c64c2b61753c0b6eb3292cb3a43e4..2066bdde12774b8fa82023d94caee62d27f96c84 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -82,7 +82,7 @@ majority of the nodes are no longer available.""",
                 "allmydata.scripts",],
       package_dir={ "allmydata": "src/allmydata",},
       scripts = ["bin/allmydata-tahoe"],
-      package_data={ 'allmydata': ['web/*.xhtml', 'web/*.css'] },
+      package_data={ 'allmydata': ['web/*.xhtml', 'web/*.html', 'web/*.css'] },
       classifiers=trove_classifiers,
       test_suite="allmydata.test",
       )
index 5976a7b17a55017effd51b9ed4fd5edce49b572f..55e364ad1b43b9842d719e6b67265ca5e39cba31 100644 (file)
@@ -50,10 +50,7 @@ class Client(node.Node, Referenceable):
         except EnvironmentError:
             pass # absent or unreadable webport file
         else:
-            ws = WebishServer(webport)
-            ws.allow_local_access(os.path.exists(os.path.join(self.basedir,
-                                  self.WEB_ALLOW_LOCAL_ACCESS_FILE)))
-            self.add_service(ws)
+            self.init_web(webport)
 
         INTRODUCER_FURL_FILE = os.path.join(self.basedir,
                                             self.INTRODUCER_FURL_FILE)
@@ -100,6 +97,18 @@ class Client(node.Node, Referenceable):
         if os.path.exists(filename):
             self.push_to_ourselves = True
 
+    def init_web(self, webport):
+        # this must be called after the VirtualDrive is attached
+        ws = WebishServer(webport)
+        ws.allow_local_access(os.path.exists(os.path.join(self.basedir,
+                              self.WEB_ALLOW_LOCAL_ACCESS_FILE)))
+        self.add_service(ws)
+        vd = self.getServiceNamed("vdrive")
+        startfile = os.path.join(self.basedir, "start.html")
+        d = vd.when_private_root_available()
+        d.addCallback(ws.create_start_html, startfile)
+
+
     def _check_hotline(self, hotline_file):
         if os.path.exists(hotline_file):
             mtime = os.stat(hotline_file)[stat.ST_MTIME]
index 09c9e243638b8d478ff942cf0254df4ee3ba0cf4..606839cda9741edf9568b66227afb34fa7377f5d 100644 (file)
@@ -285,6 +285,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
         d.addCallback(self._check_publish_private)
         d.addCallback(self.log, "did _check_publish_private")
         d.addCallback(self._test_web)
+        d.addCallback(self._test_web_start)
         d.addCallback(self._test_runner)
         return d
     test_vdrive.timeout = 1100
@@ -582,6 +583,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
         d.addCallback(lambda res: self.GET("vdrive/global/subdir3/new.txt"))
         d.addCallback(self.failUnlessEqual, "NEWER contents")
 
+
         # TODO: mangle the second segment of a file, to test errors that
         # occur after we've already sent some good data, which uses a
         # different error path.
@@ -594,6 +596,16 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
 
         return d
 
+    def _test_web_start(self, res):
+        basedir = self.clients[0].basedir
+        startfile = os.path.join(basedir, "start.html")
+        self.failUnless(os.path.exists(startfile))
+        start_html = open(startfile, "r").read()
+        self.failUnless(self.webish_url in start_html)
+        private_uri = self.clients[0].getServiceNamed("vdrive")._private_uri
+        private_url = self.webish_url + "uri/" + private_uri.replace("/","!")
+        self.failUnless(private_url in start_html)
+
     def _test_runner(self, res):
         # exercise some of the diagnostic tools in runner.py
 
index b1edc1e1cdbe494a0e0df2a0cde62f43b19c36bc..74fcec6d3948d73ddaee9312799b9f02898e37ea 100644 (file)
@@ -16,6 +16,7 @@ import itertools
 
 class MyClient(service.MultiService):
     nodeid = "fake_nodeid"
+    basedir = "fake_basedir"
     def get_versions(self):
         return {'allmydata': "fake",
                 'foolscap': "fake",
@@ -378,10 +379,33 @@ class Web(WebMixin, unittest.TestCase):
             self.failUnless('Welcome To AllMyData' in res)
             self.failUnless('Tahoe' in res)
             self.failUnless('To view the global shared filestore' in res)
-            self.failUnless('To view your personal private non-shared' in res)
+            self.failUnless('personal vdrive not available.' in res)
+
+            self.s.basedir = 'web/test_welcome'
+            fileutil.make_dirs("web/test_welcome")
+            self.ws.create_start_html("private_uri",
+                                      "web/test_welcome/start.html")
+            return self.GET("/")
         d.addCallback(_check)
+        def _check2(res):
+            self.failUnless('To view your personal private non-shared' in res)
+            self.failUnless('from your local filesystem:' in res)
+            self.failUnless(os.path.abspath('web/test_welcome/start.html')
+                            in res)
+        d.addCallback(_check2)
         return d
 
+    def test_start_html(self):
+        fileutil.make_dirs("web")
+        startfile = "web/start.html"
+        self.ws.create_start_html("private_uri", startfile)
+
+        self.failUnless(os.path.exists(startfile))
+        start_html = open(startfile, "r").read()
+        self.failUnless(self.webish_url in start_html)
+        private_url = self.webish_url + "/uri/private_uri"
+        self.failUnless(private_url in start_html)
+
     def test_GET_FILEURL(self):
         d = self.GET("/vdrive/global/foo/bar.txt")
         d.addCallback(self.failUnlessIsBarDotTxt)
@@ -646,13 +670,6 @@ class Web(WebMixin, unittest.TestCase):
                                       '</td>\s+<td>DIR-RO</td>', res))
         d.addCallback(_check3)
 
-        # and take a quick peek at the private vdrive
-        d.addCallback(lambda res:
-                      self.GET("/vdrive/private", followRedirect=True))
-        def _check4(res):
-            pass
-        d.addCallback(_check4)
-
         return d
 
     def test_GET_DIRURL_json(self):
index 694fb0202e7d338c5ae5f3f43aaf5266489d699e..7bafda49a41f1e76ba62984b25a9fafec0e565cc 100644 (file)
@@ -3,6 +3,7 @@ import os
 from twisted.application import service
 from zope.interface import implements
 from allmydata.interfaces import IVirtualDrive, IDirnodeURI, IURI
+from allmydata.util import observer
 from allmydata import dirnode
 from twisted.internet import defer
 
@@ -24,6 +25,7 @@ class VirtualDrive(service.MultiService):
         service.MultiService.__init__(self)
         self._global_uri = None
         self._private_uri = None
+        self._private_root_observer = observer.OneShotObserverList()
 
     def log(self, msg):
         self.parent.log(msg)
@@ -46,6 +48,7 @@ class VirtualDrive(service.MultiService):
             self._private_uri = f.read().strip()
             f.close()
             self.log("using private vdrive uri %s" % self._private_uri)
+            self._private_root_observer.fire(self._private_uri)
 
         furl_file = os.path.join(basedir, self.GLOBAL_VDRIVE_FURL_FILE)
         if os.path.exists(furl_file):
@@ -94,6 +97,7 @@ class VirtualDrive(service.MultiService):
                 f = open(private_uri_file, "w")
                 f.write(self._private_uri + "\n")
                 f.close()
+                self._private_root_observer.fire(self._private_uri)
             d.addCallback(_got_directory)
 
 
@@ -104,6 +108,15 @@ class VirtualDrive(service.MultiService):
             return defer.fail(NoGlobalVirtualDriveError())
         return self.get_node(self._global_uri)
 
+    def when_private_root_available(self):
+        """Return a Deferred that will fire with the URI of the private
+        vdrive root, when it is available.
+
+        This might be right away if the private vdrive was already present.
+        The first time the node is started, this will take a bit longer.
+        """
+        return self._private_root_observer.when_fired()
+
     def have_private_root(self):
         return bool(self._private_uri)
     def get_private_root(self):
index 14ed4111e0b5f80cdf4378b6e2422ceb86eda766..76bcf8d48ec49d967ff62e132a949b4e9842fb32 100644 (file)
@@ -1,7 +1,7 @@
 
 from base64 import b32encode
 import os.path
-from twisted.application import service, strports
+from twisted.application import service, strports, internet
 from twisted.web import static, resource, server, html, http
 from twisted.python import util, log
 from twisted.internet import defer
@@ -1021,9 +1021,6 @@ class Root(rend.Page):
             if segments[1] == "global":
                 d = vdrive.get_public_root()
                 name = "public vdrive"
-            elif segments[1] == "private":
-                d = vdrive.get_private_root()
-                name = "private vdrive"
             else:
                 return rend.NotFound
             d.addCallback(lambda dirnode: VDrive(dirnode, name))
@@ -1099,9 +1096,13 @@ class Root(rend.Page):
                    "responding), no vdrive available."]
 
     def render_private_vdrive(self, ctx, data):
-        if IClient(ctx).getServiceNamed("vdrive").have_private_root():
+        basedir = IClient(ctx).basedir
+        start_html = os.path.abspath(os.path.join(basedir, "start.html"))
+        if os.path.exists(start_html):
             return T.p["To view your personal private non-shared filestore, ",
-                       T.a(href="vdrive/private")["Click Here!"],
+                       "use this browser to open the following file from ",
+                       "your local filesystem:",
+                       T.pre[start_html],
                        ]
         return T.p["personal vdrive not available."]
 
@@ -1131,8 +1132,9 @@ class LocalAccess:
 class WebishServer(service.MultiService):
     name = "webish"
 
-    def __init__(self, webport, local_access=False):
+    def __init__(self, webport):
         service.MultiService.__init__(self)
+        self.webport = webport
         self.root = Root()
         self.site = site = appserver.NevowSite(self.root)
         self.site.requestFactory = MyRequest
@@ -1155,3 +1157,23 @@ class WebishServer(service.MultiService):
         # I thought you could do the same with an existing interface, but
         # apparently 'ISite' does not exist
         #self.site._client = self.parent
+
+    def create_start_html(self, private_uri, startfile):
+        f = open(startfile, "w")
+        os.chmod(startfile, 0600)
+        template = open(util.sibpath(__file__, "web/start.html"), "r").read()
+        # what is our webport?
+        s = self.listener
+        if isinstance(s, internet.TCPServer):
+            base_url = "http://localhost:%d" % s._port.getHost().port
+        elif isinstance(s, internet.SSLServer):
+            base_url = "https://localhost:%d" % s._port.getHost().port
+        else:
+            base_url = "UNKNOWN"  # this will break the href
+            # TODO: emit a start.html that explains that we don't know
+            # how to create a suitable URL
+        fields = {"private_uri": private_uri.replace("/","!"),
+                  "base_url": base_url,
+                  }
+        f.write(template % fields)
+        f.close()