from functools import wraps
+import os
from django.core.files.uploadedfile import UploadedFile
from django.core.files.uploadhandler import FileUploadHandler, StopUpload, StopFutureHandlers
+from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt, csrf_protect
-from filex.ftp import FTPOperation
+from filex.forms import HostPathForm
+from filex.ftp import FTPOperation, FTPError
class FtpUploadHandler(FileUploadHandler):
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://{}/{}'.format(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)
def wrapped_view(request, *args, **kwargs):
request.upload_handlers = [FtpUploadHandler(request)]
- return csrf_protect(view_func)(request, *args, **kwargs)
+ try:
+ return csrf_protect(view_func)(request, *args, **kwargs)
+ except FTPError as e:
+ status = 400
+ if 'No such file or directory' in e.message:
+ status = 404
+ elif 'Permission denied' in e.message:
+ status = 403
+
+ return JsonResponse({'error': e.message}, status=status)
return csrf_exempt(wrapped_view)