Explorar o código

HUE-4866 [fb] Submit archives as batch job

krish %!s(int64=9) %!d(string=hai) anos
pai
achega
a396fca46f

+ 12 - 4
apps/filebrowser/src/filebrowser/templates/listdir.mako

@@ -18,6 +18,8 @@
 from django.template.defaultfilters import urlencode
 from desktop.views import commonheader, commonfooter
 from django.utils.translation import ugettext as _
+
+from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
 %>
 
 <%namespace name="actionbar" file="actionbar.mako" />
@@ -105,10 +107,16 @@ ${ fb_components.menubar() }
           <!-- /ko -->
           <!-- /ko -->
           % if 'oozie' in apps:
-          <button class="btn fileToolbarBtn" title="${_('Submit')}"
-            data-bind="visible: selectedFiles().length == 1 && $.inArray(selectedFile().name, ['workflow.xml', 'coordinator.xml', 'bundle.xml']) > -1, click: submitSelected">
-            <i class="fa fa-play"></i> ${_('Submit')}
-          </button>
+            <button class="btn fileToolbarBtn" title="${_('Submit')}"
+              data-bind="visible: selectedFiles().length == 1 && $.inArray(selectedFile().name, ['workflow.xml', 'coordinator.xml', 'bundle.xml']) > -1, click: submitSelected">
+              <i class="fa fa-play"></i> ${_('Submit')}
+            </button>
+            % if ENABLE_EXTRACT_UPLOADED_ARCHIVE.get():
+              <button class="btn extractArchiveBtn" title="${_('Extract')}"
+                data-bind="visible: selectedFiles().length == 1 && isArchive(), click: confirmExtractArchive">
+                <i class="fa fa-play"></i> ${_('Extract')}
+              </button>
+            % endif
           % endif
         </div>
       </%def>

+ 54 - 0
apps/filebrowser/src/filebrowser/templates/listdir_components.mako

@@ -96,6 +96,28 @@ from django.utils.translation import ugettext as _
     </p>
   </div>
 
+  <!-- extract modal -->
+  <div id="confirmExtractModal" class="modal hide fade">
+    <div class="modal-header">
+      <a href="#" class="close" data-dismiss="modal">&times;</a>
+      <h3>${_('Extract Archive')}</h3>
+    </div>
+    <!-- ko if: selectedFile -->
+    <div class="modal-body">
+      <p>${_('Start a task to extract the contents of this archive.')}</p>
+      <ul>
+        <li>
+          <span data-bind="text: selectedFile().name"> </span>
+        </li>
+      </ul>
+    </div>
+    <div class="modal-footer">
+      <a class="btn" data-dismiss="modal">${_('No')}</a>
+      <input type="submit" value="${_('Yes')}" class="btn btn-danger" data-bind="click: extractSelectedArchive"/>
+    </div>
+    <!-- /ko -->
+  </div>
+
   <!-- delete modal -->
   <div id="deleteModal" class="modal hide fade">
     <div class="modal-header">
@@ -1391,6 +1413,38 @@ from django.utils.translation import ugettext as _
         % endif
       };
 
+      self.isArchive = function() {
+        var fileName = self.selectedFile().name;
+        return fileName.endsWith('.zip') || fileName.endsWith('.tar.gz') || fileName.endsWith('.tgz') || fileName.endsWith('.bz2') || fileName.endsWith('.bzip2');
+      };
+
+      self.confirmExtractArchive = function() {
+        $("#confirmExtractModal").modal({
+          keyboard:true,
+          show:true
+        });
+      };
+
+      self.extractSelectedArchive = function() {
+        $("#confirmExtractModal").modal("hide");
+        $.post("/filebrowser/extract_archive", {
+          "archive_name": self.selectedFile().name,
+          "upload_path": self.currentPath(),
+        }, function (data) {
+          if (data.status == 0) {
+            var jobId = '';
+            if (data.handle) {
+              jobId = data.handle.id;
+            }
+            $.jHueNotify.info("${ _('Oozie job ') }" + jobId + "${_(' submitted for archive extraction.') }");
+          } else {
+            $(document).trigger("error", data.message);
+          }
+        }).fail(function (xhr, textStatus, errorThrown) {
+          $(document).trigger("error", xhr.responseText);
+        });
+      };
+
       self.createDirectory = function (formElement) {
         $(formElement).attr("action", "/filebrowser/mkdir?next=${url('filebrowser.views.view', path='')}" + self.currentPath());
         return true;

+ 1 - 0
apps/filebrowser/src/filebrowser/urls.py

@@ -39,6 +39,7 @@ urlpatterns = patterns('filebrowser.views',
   url(r'^save$', 'save_file'),
   url(r'^upload/file$', 'upload_file', name='upload_file'),
   url(r'^upload/archive$', 'upload_archive', name='upload_archive'),
+  url(r'^extract_archive', 'extract_archive_using_batch_job', name='extract_archive_using_batch_job'),
   url(r'^trash/restore$', 'trash_restore', name='trash_restore'),
   url(r'^trash/purge$', 'trash_purge', name='trash_purge'),
   url(r'^rename$', 'rename', name='rename'),

+ 20 - 3
apps/filebrowser/src/filebrowser/views.py

@@ -1228,7 +1228,6 @@ def _upload_file(request):
     if form.is_valid():
         uploaded_file = request.FILES['hdfs_file']
         dest = form.cleaned_data['dest']
-        extract_archive = form.cleaned_data.get('extract_archive')
         filepath = request.fs.join(dest, uploaded_file.name)
 
         if request.fs.isdir(dest) and posixpath.sep in uploaded_file.name:
@@ -1237,8 +1236,6 @@ def _upload_file(request):
         try:
             request.fs.upload(file=uploaded_file, path=dest, username=request.user.username)
             response['status'] = 0
-            if ENABLE_EXTRACT_UPLOADED_ARCHIVE.get() and extract_archive:
-              response['batch_job_response'] = extract_archive_in_hdfs(request, dest, uploaded_file.name)
 
         except IOError, ex:
             already_exists = False
@@ -1355,6 +1352,26 @@ def _upload_archive(request):
         raise PopupException(_("Error in upload form: %s") % (form.errors,))
 
 
+@require_http_methods(["POST"])
+def extract_archive_using_batch_job(request):
+
+  response = {'status': -1, 'data': ''}
+  if ENABLE_EXTRACT_UPLOADED_ARCHIVE.get():
+    upload_path = request.POST.get('upload_path', None)
+    archive_name = request.POST.get('archive_name', None)
+
+    if upload_path and archive_name:
+      try:
+        response = extract_archive_in_hdfs(request, upload_path, archive_name)
+      except Exception, e:
+        response['message'] = _('Exception occurred while extracting the archive: %s' % e)
+  else:
+    response['message'] = _('ERROR: Configuration parameter enable_extract_uploaded_archive ' +
+                            'has to be enabled before calling this method.')
+
+  return JsonResponse(response)
+
+
 def status(request):
     status = request.fs.status()
     data = {

+ 6 - 5
apps/filebrowser/src/filebrowser/views_test.py

@@ -920,15 +920,16 @@ alert("XSS")
 
       # Upload archive
       resp = self.c.post('/filebrowser/upload/file?dest=%s' % HDFS_DEST_DIR,
-                         dict(dest=HDFS_DEST_DIR, hdfs_file=file(ZIP_FILE), extract_archive=True))
+                         dict(dest=HDFS_DEST_DIR, hdfs_file=file(ZIP_FILE)))
       response = json.loads(resp.content)
       assert_equal(0, response['status'], response)
       assert_true(self.cluster.fs.exists(HDFS_ZIP_FILE))
 
-      assert_true('batch_job_response' in response)
-      batch_job_response = response['batch_job_response']
-      assert_equal(0, batch_job_response['status'], batch_job_response)
-      assert_true('handle' in batch_job_response and batch_job_response['handle']['id'], batch_job_response)
+      resp = self.c.post('/filebrowser/extract_archive',
+                         dict(upload_path=HDFS_DEST_DIR, archive_name='test.zip'))
+      response = json.loads(resp.content)
+      assert_equal(0, response['status'], response)
+      assert_true('handle' in response and response['handle']['id'], response)
     finally:
       cleanup_file(self.cluster, HDFS_ZIP_FILE)