X-Git-Url: http://mmka.chem.univ.gda.pl/gitweb/?a=blobdiff_plain;f=filex%2Fviews.py;h=8ef9d5b9689f43248958928d8c69e599fddda64e;hb=edd1abec6c3948dd007a7a7d75ddcc28e9197e41;hp=a4516ed1d9348b4736e259a4d891a3e6816cfa78;hpb=8fa091024d4e474722fd81df48852625f926aa86;p=qcg-portal.git diff --git a/filex/views.py b/filex/views.py index a4516ed..8ef9d5b 100644 --- a/filex/views.py +++ b/filex/views.py @@ -1,241 +1,180 @@ 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 @@ -253,7 +192,7 @@ def fav_add(request): 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