From: Maciej Tronowski Date: Mon, 13 Apr 2015 16:27:35 +0000 (+0200) Subject: extracting archive in gridftp X-Git-Tag: v1.0~72 X-Git-Url: http://mmka.chem.univ.gda.pl/gitweb/?a=commitdiff_plain;h=273c0546c3f3154497c6554efeba805d9bbde526;p=qcg-portal.git extracting archive in gridftp --- diff --git a/filex/ftp.py b/filex/ftp.py index c2f3b3a..39ee807 100644 --- a/filex/ftp.py +++ b/filex/ftp.py @@ -154,18 +154,19 @@ class FTPOperation: self.wait() - def compress(self, server, path, files, archive): - def match_ext(*extensions): - for ext in extensions: - if archive.endswith(ext): - return True - return False + @staticmethod + def match_ext(archive, *extensions): + for ext in extensions: + if archive.endswith(ext): + return True + return False - if match_ext('.tar.gz', '.tgz'): + def compress(self, server, path, files, archive): + if self.match_ext(archive, '.tar.gz', '.tgz'): cmd, args = 'tar', ['cvzf', os.path.join(path, archive), '-C', path] + files - elif match_ext('.tar.bz2', '.tbz'): + elif self.match_ext(archive, '.tar.bz2', '.tbz'): cmd, args = 'tar', ['cvjf', os.path.join(path, archive), '-C', path] + files - elif match_ext('.zip'): + elif self.match_ext(archive, '.zip'): cmd, args = 'zip', ['-r', os.path.join(path, archive)] + [os.path.join(path, f) for f in files] else: raise ValueError('Unknown archive type: {}'.format(archive)) @@ -174,3 +175,18 @@ class FTPOperation: self.op_attr.set_disk_stack('#'.join(["popen:argv=", cmd] + args)) return self.get(server) + + def extract(self, server, archive, dst): + if self.match_ext(archive, '.tar.gz', '.tgz'): + cmd, args = 'tar', ['xvzf', archive, '-C', dst] + elif self.match_ext(archive, '.tar.bz2', '.tbz'): + cmd, args = 'tar', ['xvjf', archive, '-C', dst] + elif self.match_ext(archive, '.zip'): + cmd, args = 'unzip', [archive, '-d', dst] + else: + raise ValueError('Unknown archive type: {}'.format(archive)) + + # FIXME handling filename with # + self.op_attr.set_disk_stack('#'.join(["popen:argv=", cmd] + args)) + + return self.get(server) diff --git a/filex/urls.py b/filex/urls.py index 2221c26..883b8b4 100644 --- a/filex/urls.py +++ b/filex/urls.py @@ -11,4 +11,5 @@ urlpatterns = patterns('', url(r'^mkdir/$', views.mkdir, name='mkdir'), url(r'^move/$', views.move, name='move'), url(r'^compress/$', views.compress, name='compress'), + url(r'^extract/$', views.extract, name='extract'), ) diff --git a/filex/views.py b/filex/views.py index 1a02ddb..a85c265 100644 --- a/filex/views.py +++ b/filex/views.py @@ -197,7 +197,7 @@ def compress(request): path = request.POST.get('path') files = request.POST.getlist('files') archive = request.POST.get('archive') - if not host or not path or not files: + if not host or not path or not files or not archive: raise SuspiciousOperation("No path or host or files or archive given!") server = 'gsiftp://' + host @@ -209,3 +209,25 @@ def compress(request): return JsonResponse({'msg': e.message}, status=400) else: return JsonResponse({'success': True}) + + +@require_POST +def extract(request): + check_auth(request) + + # TODO data validation + host = request.POST.get('host') + archive = request.POST.get('archive') + dst = request.POST.get('dst') + if not host or not archive or not dst: + raise SuspiciousOperation("No path or host or files or archive given!") + + server = 'gsiftp://' + host + + try: + # consume generator with command output + list(FTPOperation(request.session['proxy']).extract(server, archive, dst)) + except FTPException as e: + return JsonResponse({'msg': e.message}, status=400) + else: + return JsonResponse({'success': True}) diff --git a/qcg/templates/qcg/gridftp.html b/qcg/templates/qcg/gridftp.html index 9b354de..dd24d7e 100644 --- a/qcg/templates/qcg/gridftp.html +++ b/qcg/templates/qcg/gridftp.html @@ -14,6 +14,10 @@ $(function () { var statusTimeout; + String.prototype.endsWith = function(suffix) { + return this.indexOf(suffix, this.length - suffix.length) !== -1; + }; + function status(msg) { clearTimeout(statusTimeout); statusTimeout = setTimeout(function() { @@ -23,9 +27,9 @@ $('#status').text(msg); } - function fail(xhr) { - status('Wystąpił błąd: ' + ((xhr.responseJSON || {}).msg || "Server error")); - console.error(xhr); + function fail() { + status('Wystąpił błąd.'); + console.error(arguments); filex.idle(); } @@ -35,7 +39,18 @@ $('#btn-rename').toggleClass('disabled', selected != 1); $('#btn-delete').toggleClass('disabled', selected == 0); $('#btn-compress').toggleClass('disabled', selected == 0); - $('#btn-extract').toggleClass('disabled', selected != 1); + + if (selected == 1) { + var filename = filex.selectedFiles()[0].get('name'), + is_archive = _.some(['.zip', '.tar.gz', '.tgz', '.tar.bz2', 'tbz'], function(ext) { + return filename.endsWith(ext); + }); + + $('#btn-extract').toggleClass('disabled', !is_archive); + } + else { + $('#btn-extract').toggleClass('disabled', true); + } }); $('#btn-upload').on('click', function() { @@ -105,7 +120,7 @@ $this.find('#id_host').val(filex.host); $this.find('#id_path').val(filex.path.full()); - $.post($this.attr('action'), $this.serialize(), function(response) { + $.post($this.attr('action'), $this.serialize(), function() { status('Katalog utworzono pomyślnie'); filex.reloadFiles(); }, 'json').fail(fail); @@ -127,7 +142,7 @@ filex.busy(); $this.modal('hide'); - $.post($this.attr('action'), $this.serialize(), function(response) { + $.post($this.attr('action'), $this.serialize(), function() { status('Nazwę zmieniono pomyślnie'); filex.reloadFiles(); }, 'json').fail(fail); @@ -139,7 +154,7 @@ var $this = $(this), name = $this.find('#id_name').val(), type = $this.find('#id_type').val(), - archive = name + (name.indexOf(type, name.length - type.length) === -1 ? type : ''), + archive = name + (name.endsWith(type) ? '' : type), data = { host: filex.host, path: filex.path.full(), @@ -162,11 +177,26 @@ filex.busy(); $this.modal('hide'); - $.post($this.attr('action'), data, function(response) { + $.post($this.attr('action'), data, function() { status('Archiwum utworzono pomyślnie'); filex.reloadFiles(); }, 'json').fail(fail); }); + + $('#btn-extract').on('click', function() { + filex.busy(); + + var data = { + host: filex.host, + archive: filex.path.full() + '/' + filex.selectedFiles()[0].get('name'), + dst: filex.path.full() + }; + + $.post('{% url 'filex:extract' %}', data, function() { + status('Archiwum rozpakowano pomyślnie'); + filex.reloadFiles(); + }, 'json').fail(fail); + }); }) {% endblock extra_js %}