+ logger = logging.getLogger('gridftp')
+ logger.error(e.verbose, extra={'user': request.user, 'path': request.path, 'params': form.cleaned_data})
+
+ return JsonResponse({'error': msg}, status=status)
+
+ setattr(cls, cls.method, process)
+
+ return super(FTPView, cls).as_view(**initkwargs)
+
+ def handle(self, ftp, params):
+ raise NotImplementedError
+
+
+class ListView(FTPView):
+ def handle(self, ftp, params):
+ listing = ftp.listing(make_url(params, 'path'))
+
+ 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')
+
+ data.append(item)
+
+ return JsonResponse(data, safe=False)
+
+
+class DownloadView(FTPView):
+ def handle(self, ftp, params):
+ url = make_url(params, 'path')
+
+ try:
+ stats = ftp.info(url)
+ except FTPError as e:
+ msg, status = parse_ftp_error(e)
+
+ return render(self.request, 'qcg/download_error.html', {'msg': msg, 'url': url}, status=status)
+
+ data = ftp.get(url)
+
+ 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)
+ response['Content-Length'] = stats['size']
+
+ if encoding:
+ response['Content-Encoding'] = encoding
+
+ return response
+
+
+class InfoView(FTPView):
+ def handle(self, ftp, params):
+ return JsonResponse(ftp.info(make_url(params, 'path')))