瀏覽代碼

[fb] Trash opens up on user current path if possible

Romain Rigaux 12 年之前
父節點
當前提交
d370148

+ 1 - 1
apps/filebrowser/src/filebrowser/templates/fb_components.mako

@@ -32,7 +32,7 @@ from django.utils.translation import ugettext as _
         </li>
         <li class="pull-right">
           <a href="${url('filebrowser.views.view', path=urlencode(path))}?default_to_trash" style="line-height:18px" title="${_('View trash')}">
-            <i class="fa fa-trash-o"></i> ${_('View trash')}
+            <i class="fa fa-trash-o"></i> ${_('Trash')}
           </a>
         </li>
         % else:

+ 7 - 9
apps/filebrowser/src/filebrowser/views.py

@@ -14,11 +14,6 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-#
-# Implements simple file system browsing operations.
-#
-# Useful resources:
-#   django/views/static.py manages django's internal directory index
 
 import errno
 import logging
@@ -46,6 +41,7 @@ from django.template.defaultfilters import urlencode
 from django.utils.functional import curry
 from django.utils.http import http_date, urlquote
 from django.utils.html import escape
+from django.utils.translation import ugettext as _
 from cStringIO import StringIO
 from gzip import GzipFile
 from avro import datafile, io
@@ -54,6 +50,9 @@ from desktop.lib import i18n, paginator
 from desktop.lib.conf import coerce_bool
 from desktop.lib.django_util import make_absolute, render, render_json, format_preserving_redirect
 from desktop.lib.exceptions_renderable import PopupException
+from hadoop.fs.hadoopfs import Hdfs
+from hadoop.fs.exceptions import WebHdfsException
+
 from filebrowser.conf import MAX_SNAPPY_DECOMPRESSION_SIZE
 from filebrowser.lib.archives import archive_factory
 from filebrowser.lib.rwx import filetype, rwx
@@ -61,10 +60,6 @@ from filebrowser.lib import xxd
 from filebrowser.forms import RenameForm, UploadFileForm, UploadArchiveForm, MkDirForm, EditorForm, TouchForm,\
                               RenameFormSet, RmTreeFormSet, ChmodFormSet, ChownFormSet, CopyFormSet, RestoreFormSet,\
                               TrashPurgeForm
-from hadoop.fs.hadoopfs import Hdfs
-from hadoop.fs.exceptions import WebHdfsException
-
-from django.utils.translation import ugettext as _
 
 
 DEFAULT_CHUNK_SIZE_BYTES = 1024 * 4 # 4KB
@@ -144,6 +139,9 @@ def view(request, path):
 
     # default_to_home is set in bootstrap.js
     if 'default_to_trash' in request.GET:
+        home_trash = request.fs.join(request.fs.trash_path, 'Current', request.user.get_home_directory()[1:])
+        if request.fs.isdir(home_trash):
+            return format_preserving_redirect(request, reverse(view, kwargs=dict(path=home_trash)))
         if request.fs.isdir(request.fs.trash_path):
             return format_preserving_redirect(request, reverse(view, kwargs=dict(path=request.fs.trash_path)))
 

+ 41 - 0
apps/filebrowser/src/filebrowser/views_test.py

@@ -1130,3 +1130,44 @@ def test_location_to_url():
   assert_equal('/filebrowser/view/var/lib/hadoop-hdfs', location_to_url('hdfs://localhost:8020/var/lib/hadoop-hdfs'))
   assert_equal('/filebrowser/view/', location_to_url('hdfs://localhost:8020'))
   assert_equal(None, location_to_url('thrift://10.0.0.1:9083'))
+
+@attr('requires_hadoop')
+def test_trash():
+  cluster = pseudo_hdfs4.shared_cluster()
+
+  try:
+    c = make_logged_in_client()
+    USERNAME = 'test'
+    cluster.fs.setuser(USERNAME)
+
+    cluster.fs.do_as_superuser(cluster.fs.chown, '/user/%s' % USERNAME, USERNAME, USERNAME)
+
+    HOME_TRASH_DIR = '/user/%s/.Trash/Current/user/%s' % (USERNAME, USERNAME)
+    prefix = '/tmp/test_trash'
+    PATH_1 = '/%s/1' % prefix
+    cluster.fs.mkdir(prefix)
+    cluster.fs.mkdir(PATH_1)
+
+    c.post('/filebrowser/rmtree?skip_trash=true', dict(path=[HOME_TRASH_DIR]))
+
+    # No trash folder
+    response = c.get('/filebrowser/view/user/test?default_to_trash', follow=True)
+    assert_equal([], response.redirect_chain)
+
+    c.post('/filebrowser/rmtree', dict(path=[PATH_1]))
+
+    # We have a trash folder so a redirect (Current not always there)
+    response = c.get('/filebrowser/view/user/test?default_to_trash', follow=True)
+    assert_true(any(['.Trash' in page for page, code in response.redirect_chain]), response.redirect_chain)
+
+    c.post('/filebrowser/rmtree?skip_trash=true', dict(path=[HOME_TRASH_DIR]))
+
+    # No home trash, just regular root trash
+    response = c.get('/filebrowser/view/user/test?default_to_trash', follow=True)
+    assert_true(any(['.Trash' in page for page, code in response.redirect_chain]), response.redirect_chain)
+  finally:
+    try:
+      cluster.fs.rmtree(prefix)     # Clean up
+    except:
+      pass      # Don't let cleanup errors mask earlier failures
+

+ 4 - 12
desktop/libs/hadoop/src/hadoop/fs/webhdfs.py

@@ -69,8 +69,7 @@ class WebHdfs(Hdfs):
     self._client = self._make_client(url, security_enabled)
     self._root = resource.Resource(self._client)
 
-    # To store user info
-    self._thread_local = threading.local()
+    self._user = None
 
     LOG.debug("Initializing Hadoop WebHdfs: %s (security: %s, superuser: %s)" %
               (self._url, self._security_enabled, self._superuser))
@@ -126,20 +125,13 @@ class WebHdfs(Hdfs):
   @property
   def user(self):
     try:
-      return self._thread_local.user
+      return self._user
     except AttributeError:
       return WebHdfs.DEFAULT_USER
 
   @property
   def trash_path(self):
-    try:
-      return self._thread_local.trash_path[self.user]
-    except AttributeError:
-      self._thread_local.trash_paths = {}
-      self._thread_local.trash_paths[self.user] = self.join(self.get_home_dir(), '.Trash')
-    except KeyError:
-      self._thread_local.trash_paths[self.user] = self.join(self.get_home_dir(), '.Trash')
-    return self._thread_local.trash_paths[self.user]
+    return self.join(self.get_home_dir(), '.Trash')
 
   @property
   def current_trash_path(self):
@@ -154,7 +146,7 @@ class WebHdfs(Hdfs):
   def setuser(self, user):
     """Set a new user. Return the current user."""
     curr = self.user
-    self._thread_local.user = user
+    self._user = user
     return curr
 
   def listdir_stats(self, path, glob=None):