Преглед на файлове

HUE-457: Filebrowser cannot delete directories with spaces in the name.

Aditya Acharya преди 14 години
родител
ревизия
4a5e9e6977

+ 3 - 3
apps/filebrowser/src/filebrowser/templates/listdir_components.mako

@@ -86,13 +86,13 @@ from desktop.lib.django_util import reverse_with_get
               % if ".." != file['name']:
                 <ul class="fb-item-actions context-menu">
                   % if "dir" == file['type']:
-                    <li class="fb-rmdir-container"><a class="fb-rmdir confirm_and_post" alt="Are you sure you want to delete this directory and its contents?" href="${reverse_with_get('filebrowser.views.rmdir', get=dict(path=path,next=current_request_path))}">Delete</a></li>
-                    <li class="fb-rmtree-container"><a class="fb-rmtree confirm_and_post fb-default-rm" alt="Are you sure you want to delete ${display_name} and its contents?" href="${reverse_with_get('filebrowser.views.rmtree', get=dict(path=path,next=current_request_path))}"">Delete</a></li>
+                    <li class="fb-rmdir-container"><a class="fb-rmdir confirm_unencode_and_post" alt="Are you sure you want to delete this directory and its contents?" href="${reverse_with_get('filebrowser.views.rmdir', get=dict(path=path,next=current_request_path))}">Delete</a></li>
+                    <li class="fb-rmtree-container"><a class="fb-rmtree confirm_unencode_and_post fb-default-rm" alt="Are you sure you want to delete ${display_name} and its contents?" href="${reverse_with_get('filebrowser.views.rmtree', get=dict(path=path,next=current_request_path))}"">Delete</a></li>
                   % else:
                     <li><a class="fb-viewfile" href="${url('filebrowser.views.view', path=urlencode(path))}" target="FileViewer">View File</a></li>
                     <li><a class="fb-editfile" href="${url('filebrowser.views.edit', path=urlencode(path))}" target="FileEditor">Edit File</a></li>
                     <li><a class="fb-downloadfile" href="${url('filebrowser.views.download', path=urlencode(path))}" target="_blank">Download File</a></li>
-                    <li class="fb-rm-container"><a class="fb-rm fb-default-rm confirm_and_post" alt="Are you sure you want to delete ${display_name}?" href="${reverse_with_get('filebrowser.views.remove', get=dict(path=path, next=current_request_path))}">Delete</a></li>
+                    <li class="fb-rm-container"><a class="fb-rm fb-default-rm confirm_unencode_and_post" alt="Are you sure you want to delete ${display_name}?" href="${reverse_with_get('filebrowser.views.remove', get=dict(path=path, next=current_request_path))}">Delete</a></li>
                   % endif
                   <li class="fb-rename-container"><a class="fb-rename" href="${reverse_with_get('filebrowser.views.rename',get=dict(src_path=path,next=current_request_path))}">Rename</a></li>
                   <li class="fb-chown-container"><a class="fb-chown" href="${reverse_with_get('filebrowser.views.chown',get=dict(path=path,user=file['stats']['user'],group=file['stats']['group'],next=current_request_path))}">Change Owner / Group</a></li>

+ 1 - 1
apps/jobbrowser/src/jobbrowser/templates/job.mako

@@ -106,7 +106,7 @@
         <dl>
           <dt>Kill Job:</dt>
           <dd>
-          <a href="${url('jobbrowser.views.kill_job', jobid=job.jobId)}" class="frame_tip jt_kill confirm_and_post" title="Kill this job">kill</a>
+          <a href="${url('jobbrowser.views.kill_job', jobid=job.jobId)}" class="frame_tip jt_kill confirm_unencode_and_post" title="Kill this job">kill</a>
           </dd>
         </dl>
         % endif

+ 1 - 1
apps/jobbrowser/src/jobbrowser/templates/jobs.mako

@@ -97,7 +97,7 @@
               <td>
                 % if job.status.lower() == 'running' or job.status.lower() == 'pending':
                   % if request.user.is_superuser or request.user.username == job.user:
-                    <a href="${url('jobbrowser.views.kill_job', jobid=job.jobId)}?next=${request.get_full_path()|urlencode}" class="frame_tip jt_kill confirm_and_post" title="Kill this job">kill</a>
+                    <a href="${url('jobbrowser.views.kill_job', jobid=job.jobId)}?next=${request.get_full_path()|urlencode}" class="frame_tip jt_kill confirm_unencode_and_post" title="Kill this job">kill</a>
                   % endif
                 % endif
               </td>

+ 1 - 1
apps/useradmin/src/useradmin/templates/list_users.mako

@@ -43,7 +43,7 @@ ${wrappers.head()}
             </td>
             <td>
               <a title="Edit ${user.username}" class="edit frame_tip" href="${ url('useradmin.views.edit_user', username=urllib.quote(user.username)) }">Edit</a>
-              <a title="Delete ${user.username}" class="delete frame_tip confirm_and_post" alt="Are you sure you want to delete ${user.username}?" href="${ url('useradmin.views.delete_user', username=urllib.quote(user.username)) }">Delete</a>
+              <a title="Delete ${user.username}" class="delete frame_tip confirm_unencode_and_post" alt="Are you sure you want to delete ${user.username}?" href="${ url('useradmin.views.delete_user', username=urllib.quote_plus(user.username)) }">Delete</a>
             </td>
           </tr>
         % endfor

+ 1 - 0
desktop/core/static/js/Source/Hue/DesktopLoader.js

@@ -44,6 +44,7 @@ requires: [
   hue-shared/Hue.Desktop.Config,
   hue-shared/Hue.JFrame.Target,
   hue-shared/Hue.JFrame.Chooser,
+  hue-shared/Hue.JFrame.ConfirmUnencodeAndPost,
   hue-shared/Hue.Login,
   hue-shared/Hue.Profiler,
   hue-shared/Hue.Request,

+ 53 - 0
desktop/core/static/js/Source/JFrameLinkers/Hue.JFrame.ConfirmUnencodeAndPost.js

@@ -0,0 +1,53 @@
+/*
+---
+description: Makes all links with the css class .confirm_unencode_and_post un-URL encode the href of a URL, prompt the user and then send the link as a post if they confirm.
+provides: [Hue.JFrame.ConfirmUnencodeAndPost]
+requires: [JFrame/JFrame]
+script: Hue.JFrame.ConfirmUnencodeAndPost.js
+
+...
+*/
+
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// 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.
+
+JFrame.addGlobalLinkers({
+
+	'.confirm_unencode_and_post': function(e, link){
+		//for each link with the class .confirm_unencode_and_post, confirm with the user,
+		//then un-URL encode the query string, and POST the data parsed out.
+		//use the link's title for the caption of the popup, and the alt as the body,
+		//defaulting to "Confirm" and "Are you sure?" respectively.
+		if (e) e.preventDefault();
+
+		var win = this.getWindow();
+		var confirmer;
+		if (win) confirmer = win.confirm.bind(win);
+		else confirmer = ART.confirm;
+		var linkParts = link.get('href').split('?');
+                var unencodedParams = decodeURIComponent(linkParts[1].replace(/\+/g,' '))
+                var unencodedLink = linkParts[0] + '?' + unencodedParams;
+		confirmer(link.get('title') || link.retrieve('tip:title') || 'Confirm', link.get('alt') || "Are you sure?", function(){
+			this.load({
+				requestPath: linkParts[0],
+				data: new URI(unencodedLink).get('data'),
+				method: 'post',
+				skipPostConfirmation: true
+			});
+		}.bind(this));
+	}
+
+});

+ 1 - 0
desktop/core/static/js/ccs.package.yml

@@ -26,6 +26,7 @@ sources: [
   Source/UI/ThumbTack.js,
   Source/JFrameLinkers/Hue.JFrame.Target.js,
   Source/JFrameLinkers/Hue.JFrame.Chooser.js,
+  Source/JFrameLinkers/Hue.JFrame.ConfirmUnencodeAndPost.js,
   Source/Native/String.Hue.js,
   Source/Native/Number.Files.js,
   Source/StaticThirdParty/DynamicTextarea.js,

+ 1 - 0
desktop/core/static/js/package.yml

@@ -29,6 +29,7 @@ sources: [
   Source/UI/ThumbTack.js,
   Source/JFrameLinkers/Hue.JFrame.Target.js,
   Source/JFrameLinkers/Hue.JFrame.Chooser.js,
+  Source/JFrameLinkers/Hue.JFrame.ConfirmUnencodeAndPost.js,
   Source/Native/String.Hue.js,
   Source/Native/Number.Files.js,
   Source/StaticThirdParty/DynamicTextarea.js,