# coding=utf-8
+import os
+
from django import forms
+from django.core.exceptions import ValidationError
+from django.core.validators import RegexValidator
from filex.models import Favorite
+msg = u'Invalid value'
+host_validator = RegexValidator(r'^(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+'
+ r'(?:[a-zA-Z]{2,6}\.?|[a-zA-Z0-9-]{2,}(?<!-)\.?))(?::\d+)?$', msg)
+path_validator = RegexValidator(r'^/(?:[^/\0]+/?)*$', msg)
+name_validator = RegexValidator(r'^[^/\0]+$', msg)
+
+
class FavoriteForm(forms.ModelForm):
class Meta:
model = Favorite
widgets = {'owner': forms.HiddenInput()}
-class NewDirForm(forms.Form):
- host = forms.CharField(label=u'Host', max_length=256, widget=forms.HiddenInput())
- path = forms.CharField(label=u'Ścieżka', max_length=1024, widget=forms.HiddenInput())
- name = forms.CharField(label=u'Nazwa', max_length=256)
+class HostForm(forms.Form):
+ host = forms.CharField(label=u'Host', max_length=256, validators=[host_validator], widget=forms.HiddenInput())
+
+
+class HostPathForm(HostForm):
+ path = forms.CharField(label=u'Ścieżka', max_length=1024, validators=[path_validator], widget=forms.HiddenInput())
+
+ def clean_path(self):
+ return os.path.normpath(self.cleaned_data['path'])
+
+
+class HostPathNameForm(HostPathForm):
+ name = forms.CharField(label=u'Nazwa', max_length=256, validators=[name_validator])
+
+
+class HostItemsForm(HostForm):
+ dirs = forms.MultipleChoiceField(label=u'Katalogi', required=False, widget=forms.MultipleHiddenInput())
+ files = forms.MultipleChoiceField(label=u'Pliki', required=False, widget=forms.MultipleHiddenInput())
+
+ def __init__(self, data=None, *args, **kwargs):
+ super(HostItemsForm, self).__init__(data, *args, **kwargs)
+
+ if data is not None:
+ # accept user defined choices
+ self.fields['dirs'].choices += ((v, v) for v in data.getlist('dirs'))
+ self.fields['files'].choices += ((v, v) for v in data.getlist('files'))
+
+ def clean(self):
+ data = super(HostItemsForm, self).clean()
+
+ if not (data.get('dirs') or data.get('files')):
+ raise ValidationError('No items specified')
+
+ return data
+
+ @staticmethod
+ def _clean_paths(values):
+ errors, cleaned = [], []
+ for name in values:
+ try:
+ path_validator(name)
+ except ValidationError as e:
+ e.message += ' - ' + name
+ errors.append(e)
+ else:
+ cleaned.append(os.path.normpath(name))
+ if errors:
+ raise ValidationError(errors)
+
+ return cleaned
+
+ def clean_dirs(self):
+ return self._clean_paths(self.cleaned_data['dirs'])
+
+ def clean_files(self):
+ return self._clean_paths(self.cleaned_data['files'])
+
+
+class RenameForm(HostForm):
+ src = forms.CharField(label=u'Stara nazwa', max_length=1024, validators=[path_validator], widget=forms.HiddenInput())
+ dst = forms.CharField(label=u'Nowa nazwa', max_length=1024, validators=[path_validator])
+
+ def clean_src(self):
+ return os.path.normpath(self.cleaned_data['src'])
+
+ def clean_dst(self):
+ return os.path.normpath(self.cleaned_data['dst'])
+
+
+class ExtractForm(HostPathForm):
+ dst = forms.CharField(label=u'Katalog docelowy', max_length=1024, validators=[path_validator])
+
+ def clean_dst(self):
+ return os.path.normpath(self.cleaned_data['dst'])
+
+
+class CompressForm(HostPathForm):
+ archive = forms.CharField(label=u'Nazwa', max_length=1024, validators=[path_validator])
+ files = forms.MultipleChoiceField(label=u'Pliki', widget=forms.MultipleHiddenInput())
+
+ def __init__(self, data=None, *args, **kwargs):
+ super(CompressForm, self).__init__(data, *args, **kwargs)
+
+ if data is not None:
+ # accept user defined choices
+ self.fields['files'].choices += ((v, v) for v in data.getlist('files'))
+
+ def clean_files(self):
+ errors, cleaned = [], []
+ for name in self.cleaned_data['files']:
+ try:
+ name_validator(name)
+ except ValidationError as e:
+ e.message += ' - ' + name
+ errors.append(e)
+ else:
+ cleaned.append(os.path.normpath(name))
+ if errors:
+ raise ValidationError(errors)
+ return cleaned
-class RenameForm(forms.Form):
- host = forms.CharField(label=u'Host', max_length=256, widget=forms.HiddenInput())
- path = forms.CharField(label=u'Ścieżka', max_length=1024, widget=forms.HiddenInput())
- src = forms.CharField(label=u'Stara nazwa', max_length=256, widget=forms.HiddenInput())
- dst = forms.CharField(label=u'Nowa nazwa', max_length=256)
+ def clean_archive(self):
+ return os.path.normpath(self.cleaned_data['archive'])
-class ArchiveForm(NewDirForm):
+class ArchiveForm(CompressForm):
ZIP = '.zip'
GZIP = '.tar.gz'
BZIP = '.tar.bz2'
TYPE_CHOICES = (
- (ZIP, 'Archiwum zip'),
- (GZIP, 'Archiwum tar.gz'),
- (BZIP, 'Archiwum tar.bz2'),
+ (ZIP, 'zip'),
+ (GZIP, 'tar.gz'),
+ (BZIP, 'tar.bz2'),
)
- type = forms.ChoiceField(label=u'Typ', choices=TYPE_CHOICES, initial=ZIP)
+ type = forms.ChoiceField(label=u'Typ archiwum', choices=TYPE_CHOICES, initial=ZIP)
import os
import re
from threading import Event
-from urlparse import urlparse
from django.utils.timezone import localtime, UTC
from gridftp import FTPClient, Buffer, HandleAttr, OperationAttr
data = self.listing(url).next()
if data['name'] == '.':
- data['name'] = os.path.basename(urlparse(url).path.rstrip('/')) or u'/'
+ data['name'] = os.path.basename(os.path.normpath(url))
return data
return False
def compress(self, server, path, files, archive):
+ for value in [path, archive] + files:
+ if '#' in value:
+ raise ValueError('Illegal character `#` in {}'.format(value))
+
if self.match_ext(archive, '.tar.gz', '.tgz'):
- cmd, args = 'tar', ['cvzf', os.path.join(path, archive), '-C', path] + files
+ cmd, args = 'tar', ['cvzf', archive, '-C', path] + files
elif self.match_ext(archive, '.tar.bz2', '.tbz'):
- cmd, args = 'tar', ['cvjf', os.path.join(path, archive), '-C', path] + files
+ cmd, args = 'tar', ['cvjf', archive, '-C', path] + files
elif self.match_ext(archive, '.zip'):
- cmd, args = 'jar', (['cvMf', os.path.join(path, archive)] +
- list(chain.from_iterable(('-C', path, f) for f in files)))
+ cmd, args = 'jar', (['cvMf', archive] + list(chain.from_iterable(('-C', path, f) for f in files)))
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)
def extract(self, server, archive, dst):
+ for value in [archive, dst]:
+ if '#' in value:
+ raise ValueError('Illegal character `#` in {}'.format(value))
+
if self.match_ext(archive, '.tar.gz', '.tgz'):
cmd, args = 'tar', ('xvzf', archive, '-C', dst)
elif self.match_ext(archive, '.tar.bz2', '.tbz'):
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)
var data = this.model.toJSON();
data['url_params'] = $.param({
host: this.view.host,
- path: this.view.path.full(),
- name: this.model.get('name')
+ path: this.view.path.full() + '/' + this.model.get('name')
});
data['cid'] = this.model.cid;
error: function(collection, response) {
view.files.reset();
- var msg = (response.responseJSON || {}).msg || 'Błąd serwera';
+ var msg = (response.responseJSON || {}).error || 'Błąd serwera';
view.$noItems.hide();
view.$error.find('.msg').text(msg);
data.context.find('.progress-info').text('Pominięto');
}
- $.getJSON('{% url 'filex:info' %}', {host: host, path: path + file.name}, function(response) {
+ $.getJSON('{% url 'filex:info' %}', {host: host, path: path + '/' + file.name}, function(response) {
if (applyToAll != undefined) {
finish(applyToAll);
return;
from functools import wraps
+import os
from django.core.files.uploadedfile import UploadedFile
from django.core.files.uploadhandler import FileUploadHandler, StopUpload, StopFutureHandlers
from django.views.decorators.csrf import csrf_exempt, csrf_protect
+from filex.forms import HostPathForm
from filex.ftp import FTPOperation
def new_file(self, file_name, *args, **kwargs):
super(FtpUploadHandler, self).new_file(file_name, *args, **kwargs)
- # TODO limit to selected request.path
- # TODO validate host and path
- host = self.request.GET.get('host')
- path = self.request.GET.get('path')
+ form = HostPathForm(self.request.GET)
- if self.request.user.is_anonymous() or not host or not path:
+ if self.request.user.is_anonymous() or not form.is_valid():
raise StopUpload(connection_reset=True)
if self.ftp is None:
self.ftp = FTPOperation(self.request.session['proxy'], self.chunk_size)
- self.url = 'gsiftp://' + host + path + self.file_name
- self.tmp_url = 'gsiftp://' + host + path + self.file_name + '.part'
+ self.url = 'gsiftp://' + form.cleaned_data['host'] + os.path.join(form.cleaned_data['path'], self.file_name)
+ self.tmp_url = self.url + '.part'
self.ftp.put(self.tmp_url)
from filex import views
urlpatterns = patterns('',
- url(r'^list/$', views.list_content, name='list'),
- url(r'^download/$', views.download, name='download'),
+ url(r'^list/$', views.ListView.as_view(), name='list'),
+ url(r'^download/$', views.DownloadView.as_view(), name='download'),
url(r'^upload/$', views.upload, name='upload'),
- url(r'^info/$', views.info, name='info'),
- url(r'^delete/$', views.delete, name='delete'),
- 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'),
+ url(r'^info/$', views.InfoView.as_view(), name='info'),
+ url(r'^delete/$', views.DeleteView.as_view(), name='delete'),
+ url(r'^mkdir/$', views.MkdirView.as_view(), name='mkdir'),
+ url(r'^move/$', views.MoveView.as_view(), name='move'),
+ url(r'^compress/$', views.CompressView.as_view(), name='compress'),
+ url(r'^extract/$', views.ExtractView.as_view(), name='extract'),
url(r'^fav/add/$', views.fav_add, name='fav_add'),
url(r'^fav/delete/$', views.fav_delete, name='fav_delete'),
from itertools import islice
import mimetypes
+import os
from django.contrib.auth.decorators import login_required
-from django.core.exceptions import PermissionDenied, SuspiciousOperation
+from django.core.exceptions import PermissionDenied
from django.http import JsonResponse, StreamingHttpResponse
from django.shortcuts import get_object_or_404
from django.template.defaultfilters import filesizeformat
from django.utils.formats import date_format
from django.views.decorators.http import require_POST
+from django.views.generic import View
-from filex.forms import NewDirForm, RenameForm, FavoriteForm
+from filex.forms import HostPathNameForm, RenameForm, FavoriteForm, HostPathForm, ExtractForm, HostItemsForm, \
+ CompressForm
from filex.ftp import FTPOperation, FTPException
from filex.models import Favorite
from filex.uploadhandler import with_ftp_upload_handler
-def check_auth(request):
- if not request.user.is_authenticated():
- raise PermissionDenied("Login required!")
- if not request.session['proxy']:
- raise PermissionDenied("No proxy found!")
+class FTPView(View):
+ method = 'get'
+ form_class = HostPathForm
+ @classmethod
+ def as_view(cls, **initkwargs):
+ def process(self, request):
+ if not request.user.is_authenticated():
+ raise PermissionDenied("Login required!")
+ if not request.session['proxy']:
+ raise PermissionDenied("No proxy found!")
-def list_content(request):
- check_auth(request)
+ form = self.form_class(request.POST if self.method == 'post' else request.GET)
- # TODO data validation
- host = request.GET.get('host')
- path = request.GET.get('path')
- if not host or not path:
- raise SuspiciousOperation("No path or host given!")
+ if not form.is_valid():
+ return JsonResponse({'error': form.errors}, status=400)
- url = 'gsiftp://' + host + path
+ try:
+ return self.handle(FTPOperation(request.session['proxy']), form.cleaned_data)
+ except FTPException as e:
+ status = 400
+ if 'No such file or directory' in e.message:
+ status = 404
+ elif 'Permission denied' in e.message:
+ status = 403
- try:
- listing = FTPOperation(request.session['proxy']).listing(url)
- except FTPException as e:
- return JsonResponse({'msg': e.message}, status=400)
+ return JsonResponse({'error': e.message}, status=status)
- data = []
- # ignore . and .. from beginning of the listing
- for item in islice(listing, 2, None):
- item['size'] = filesizeformat(item['size'])
- item['date'] = date_format(item['date'], 'CUSTOM_DATETIME_FORMAT')
+ setattr(cls, cls.method, process)
- data.append(item)
+ return super(FTPView, cls).as_view(**initkwargs)
- return JsonResponse(data, safe=False)
+ def handle(self, ftp, params):
+ raise NotImplementedError
-def download(request):
- check_auth(request)
+class ListView(FTPView):
+ def handle(self, ftp, params):
+ listing = ftp.listing(make_url(params, 'path'))
- # TODO data validation
- host = request.GET.get('host')
- path = request.GET.get('path')
- name = request.GET.get('name')
- if not host or not path or not name:
- raise SuspiciousOperation("No path or host or name given!")
+ data = []
+ # ignore . and .. from beginning of the listing
+ for item in islice(listing, 2, None):
+ item['size'] = filesizeformat(item['size'])
+ item['date'] = date_format(item['date'], 'CUSTOM_DATETIME_FORMAT')
- url = 'gsiftp://' + host + path + '/' + name
+ data.append(item)
- mime_type, encoding = mimetypes.guess_type(name)
+ return JsonResponse(data, safe=False)
- response = StreamingHttpResponse(FTPOperation(request.session['proxy']).get(url),
- content_type=mime_type or 'application/octet-stream')
- response['Content-Disposition'] = 'attachment; filename={}'.format(name)
- # TODO Content-Length (?)
- if encoding:
- response['Content-Encoding'] = encoding
+class DownloadView(FTPView):
+ def handle(self, ftp, params):
+ data = ftp.get(make_url(params, 'path'))
- return response
+ name = os.path.basename(params['path'])
+ mime_type, encoding = mimetypes.guess_type(name)
+ response = StreamingHttpResponse(data, content_type=mime_type or 'application/octet-stream')
+ response['Content-Disposition'] = u'attachment; filename={}'.format(name)
+ # TODO Content-Length (?)
-@with_ftp_upload_handler
-def upload(request):
- # TODO error handling
- return JsonResponse({'success': True})
+ if encoding:
+ response['Content-Encoding'] = encoding
+ return response
-def info(request):
- check_auth(request)
- # TODO data validation
- host = request.GET.get('host')
- path = request.GET.get('path')
- if not host or not path:
- raise SuspiciousOperation("No path or host given!")
+class InfoView(FTPView):
+ def handle(self, ftp, params):
+ return JsonResponse(ftp.info(make_url(params, 'path')))
- url = 'gsiftp://' + host + path
- try:
- return JsonResponse(FTPOperation(request.session['proxy']).info(url))
- except FTPException as e:
- status = 400
- if 'No such file or directory' in e.message:
- status = 404
- elif 'Permission denied' in e.message:
- status = 403
+class DeleteView(FTPView):
+ method = 'post'
+ form_class = HostItemsForm
- return JsonResponse({'msg': e.message}, status=status)
+ def handle(self, ftp, params):
+ url = make_url(params)
+ done, fail = [], {}
+ for path in params['dirs']:
+ try:
+ ftp.rmdir(url + path)
+ except FTPException as e:
+ fail[path] = e.message
+ else:
+ done.append(path)
-@require_POST
-def delete(request):
- check_auth(request)
+ for path in params['files']:
+ try:
+ ftp.delete(url + path)
+ except FTPException as e:
+ fail[path] = e.message
+ else:
+ done.append(path)
- # TODO data validation
- host = request.POST.get('host')
- path = request.POST.get('path')
- dirs = request.POST.getlist('dirs')
- files = request.POST.getlist('files')
- if not host or not path or not (files or dirs):
- raise SuspiciousOperation("No path or host or files given!")
+ return JsonResponse({'done': done, 'fail': fail})
- url = 'gsiftp://' + host + path + '/'
- ftp = FTPOperation(request.session['proxy'])
- done, fail = [], {}
+class MkdirView(FTPView):
+ method = 'post'
+ form_class = HostPathNameForm
- for name in dirs:
- try:
- ftp.rmdir(url + name)
- except FTPException as e:
- fail[name] = e.message
- else:
- done.append(name)
+ def handle(self, ftp, params):
+ ftp.mkdir(make_url(params, 'path', 'name'))
- for name in files:
- try:
- ftp.delete(url + name)
- except FTPException as e:
- fail[name] = e.message
- else:
- done.append(name)
+ return JsonResponse({'success': True})
- return JsonResponse({'done': done, 'fail': fail})
+class MoveView(FTPView):
+ method = 'post'
+ form_class = RenameForm
-@require_POST
-def mkdir(request):
- check_auth(request)
+ def handle(self, ftp, params):
+ print params
+ ftp.move(make_url(params, 'src'), make_url(params, 'dst'))
- # TODO actual data validation
- form = NewDirForm(request.POST)
+ return JsonResponse({'success': True})
- if form.is_valid():
- host = form.cleaned_data['host']
- path = form.cleaned_data['path']
- name = form.cleaned_data['name']
- url = 'gsiftp://' + host + path + '/' + name
+class CompressView(FTPView):
+ method = 'post'
+ form_class = CompressForm
+ def handle(self, ftp, params):
try:
- FTPOperation(request.session['proxy']).mkdir(url)
- except FTPException as e:
- msg = e.message
- else:
- return JsonResponse({'success': True})
- else:
- msg = form.errors
-
- return JsonResponse({'msg': msg}, status=400)
-
+ # consume generator with command output
+ list(ftp.compress(make_url(params), params['path'], params['files'], params['archive']))
+ except ValueError as e:
+ return JsonResponse({'error': e.message}, status=400)
-@require_POST
-def move(request):
- check_auth(request)
-
- # TODO actual data validation
- form = RenameForm(request.POST)
+ return JsonResponse({'success': True})
- if form.is_valid():
- host = form.cleaned_data['host']
- path = form.cleaned_data['path']
- src = form.cleaned_data['src']
- dst = form.cleaned_data['dst']
- src_url = 'gsiftp://' + host + path + '/' + src
- dst_url = 'gsiftp://' + host + path + '/' + dst
+class ExtractView(FTPView):
+ method = 'post'
+ form_class = ExtractForm
+ def handle(self, ftp, params):
try:
- FTPOperation(request.session['proxy']).move(src_url, dst_url)
- except FTPException as e:
- msg = e.message
- else:
- return JsonResponse({'success': True})
- else:
- msg = form.errors
+ # consume generator with command output
+ list(ftp.extract(make_url(params), params['path'], params['dst']))
+ except ValueError as e:
+ return JsonResponse({'error': e.message}, status=400)
- return JsonResponse({'msg': msg}, status=400)
+ return JsonResponse({'success': True})
-@require_POST
-def compress(request):
- check_auth(request)
-
- # TODO data validation
- host = request.POST.get('host')
- path = request.POST.get('path')
- files = request.POST.getlist('files')
- archive = request.POST.get('archive')
- 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
-
- try:
- # consume generator with command output
- list(FTPOperation(request.session['proxy']).compress(server, path, files, archive))
- except FTPException as e:
- return JsonResponse({'msg': e.message}, status=400)
- else:
- return JsonResponse({'success': True})
+def make_url(params, *parts):
+ return 'gsiftp://' + params['host'] + (os.path.join(*[params[part] for part in parts]) if parts else '')
@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})
+@with_ftp_upload_handler
+def upload(request):
+ return JsonResponse({'success': True})
@require_POST
return JsonResponse({'group': 'usr', 'host': instance.host, 'path': instance.path,
'value': instance.host + instance.path})
- return JsonResponse({'msg': form.errors}, status=400)
+ return JsonResponse({'error': form.errors}, status=400)
@require_POST
}
function failModal(msg) {
- return function() {
+ return function(xhr) {
var $errorModal = $('#error-modal');
$errorModal.find('#error-modal-label').text('Błąd serwera');
$errorModal.find('.modal-body').html($('<h4>', {text: msg}));
+ var error = (xhr.responseJSON || {}).error || undefined;
+
+ if (typeof error === 'string')
+ $errorModal.find('.modal-body').append($('<pre>', {text: error}));
+
filex.idle();
$errorModal.modal();
};
}
+ function conflictingName(name, modal) {
+ if (filex.files.some(function(item) { return item.get('name') == name })) {
+ modal.find('.alert').remove();
+
+ $('<div>', {
+ 'class': 'alert alert-danger',
+ html: '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> Plik o podanej już nazwie istnieje!'
+ }).prependTo(modal.find('.modal-body'));
+
+ return true;
+ }
+
+ return false;
+ }
+
filex.files.on('change:checked reset', function() {
var selected = filex.selectedFiles().length;
});
$('#btn-upload').on('click', function() {
- var url = '{% url 'gridftp_upload' %}?' + $.param({host: filex.host, path: filex.path.full() + '/'});
+ var url = '{% url 'gridftp_upload' %}?' + $.param({host: filex.host, path: filex.path.full()});
var win = window.open(url, url, 'height=500,width=800');
win.focus();
$('#btn-delete').on('click', function() {
var selected = _.groupBy(filex.selectedFiles(), function(item) { return item.get('type') }),
- dirs = _.map(selected.directory || [], function (item) { return item.get('name') }),
- files = _.map(selected.file || [], function (item) { return item.get('name') }),
+ path = filex.path.full() + '/',
+ dirs = _.map(selected.directory || [], function (item) { return path + item.get('name') }),
+ files = _.map(selected.file || [], function (item) { return path + item.get('name') }),
data = {
host: filex.host,
- path: filex.path.full() + '/',
dirs: dirs,
files: files
},
$errorModal.find('#error-modal-label').text('Błąd');
for (var i in keys) {
- $('<dt>', {text: keys[i]}).appendTo($errorList);
- $('<dd>', {text: response.fail[keys[i]]}).appendTo($errorList);
+ if(keys.hasOwnProperty(i)) {
+ $('<dt>', {text: keys[i].replace(path, '')}).appendTo($errorList);
+ $('<dd>', {text: response.fail[keys[i]]}).appendTo($errorList);
+ }
}
$errorModal.modal();
var $this = $(this);
e.preventDefault();
+
+ if (conflictingName($this.find('#id_name').val(), $this))
+ return;
+
filex.busy();
$this.modal('hide');
});
$('#rename-form').on('show.bs.modal', function() {
- var $this = $(this);
+ $(this).find('#id_dst').val(filex.selectedFiles()[0].get('name'));
+ }).on('submit', function(e) {
+ e.preventDefault();
- var file = filex.selectedFiles()[0];
+ var $this = $(this),
+ path = filex.path.full() + '/',
+ newName = $this.find('#id_dst').val(),
+ data = {
+ host: filex.host,
+ src: path + filex.selectedFiles()[0].get('name'),
+ dst: path + newName
+ };
- $this.find('#id_host').val(filex.host);
- $this.find('#id_path').val(filex.path.full());
- $this.find('#id_src').val(file.get('name'));
- $this.find('#id_dst').val(file.get('name'));
- }).on('submit', function(e) {
- var $this = $(this);
+ if (conflictingName(newName, $this))
+ return;
- e.preventDefault();
filex.busy();
$this.modal('hide');
- $.post($this.attr('action'), $this.serialize(), function() {
+ $.post($this.attr('action'), data, function() {
status('Nazwę zmieniono pomyślnie');
filex.reloadFiles();
}, 'json').fail(failModal('Nie udało się zmienić nazwy'));
e.preventDefault();
var $this = $(this),
- name = $this.find('#id_name').val(),
+ name = $this.find('#id_archive').val(),
type = $this.find('#id_type').val(),
+ path = filex.path.full(),
archive = name + (name.endsWith(type) ? '' : type),
data = {
host: filex.host,
- path: filex.path.full(),
+ path: path,
files: _.map(filex.selectedFiles(), function (item) { return item.get('name') }),
- archive: archive
+ archive: path + '/' + archive
};
- // check if maybe file with given name exists
- if (filex.files.some(function(item) { return item.get('name') == archive })) {
- $this.find('.alert').remove();
-
- $('<div>', {
- 'class': 'alert alert-danger',
- html: '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> Plik o podanej już nazwie istnieje!'
- }).prependTo($this.find('.modal-body'));
-
+ if (conflictingName(archive, $this))
return;
- }
filex.busy();
$this.modal('hide');
var data = {
host: filex.host,
- archive: filex.path.full() + '/' + filex.selectedFiles()[0].get('name'),
+ path: filex.path.full() + '/' + filex.selectedFiles()[0].get('name'),
dst: filex.path.full()
};
from django_openid_auth.views import make_consumer
from openid.extensions import ax
-from filex.forms import NewDirForm, RenameForm, ArchiveForm
+from filex.forms import HostPathNameForm, RenameForm, ArchiveForm
from qcg.forms import FiltersForm, ColumnsForm, JobDescriptionForm, EnvFormSet
from qcg.utils import paginator_context
from qcg.service import update_user_data, submit_job
@login_required
def gridftp(request):
return render(request, 'qcg/gridftp.html',
- {'new_dir_form': NewDirForm(), 'rename_form': RenameForm(), 'archive_form': ArchiveForm()})
+ {'new_dir_form': HostPathNameForm(), 'rename_form': RenameForm(), 'archive_form': ArchiveForm()})
def gridftp_upload(request):