upload handler for streamed files upload to ftp
[qcg-portal.git] / filex / views.py
1 from datetime import datetime
2
3 from django.core.exceptions import PermissionDenied, SuspiciousOperation
4 from django.http import JsonResponse, StreamingHttpResponse
5 from django.template.defaultfilters import filesizeformat
6 from django.utils.formats import date_format
7 from django.utils.timezone import UTC, localtime
8 import mimetypes
9
10 from filex.ftp import FTPOperation, FTPException
11
12
13 def check_auth(request):
14     if not request.user.is_authenticated():
15         raise PermissionDenied("Login required!")
16     if not request.session['proxy']:
17         raise PermissionDenied("No proxy found!")
18
19
20 def list_content(request):
21     check_auth(request)
22
23     # TODO data validation
24     host = request.GET.get('host')
25     path = request.GET.get('path')
26     if not host or not path:
27         raise SuspiciousOperation("No path or host given!")
28
29     url = 'gsiftp://' + host + path
30
31     try:
32         listing = FTPOperation(request.session['proxy']).listing(url)
33     except FTPException as e:
34         return JsonResponse({'msg': e.message}, status=400)
35
36     data = []
37
38     # ignore first two: '.' and '..'
39     for item in listing.strip().splitlines()[2:]:
40         # we may receive empty string when there are multiple consecutive newlines in listing
41         if item:
42             attrs, name = item.split(' ', 1)
43
44             attrs = dict((attr.split('=') for attr in attrs.split(';') if attr))
45
46             date = localtime(datetime.strptime(attrs['Modify'], "%Y%m%d%H%M%S").replace(tzinfo=UTC()))
47
48             data.append({
49                 'name': name,
50                 'type': 'file' if attrs['Type'] == 'file' else 'directory',
51                 'size': filesizeformat(attrs['Size']),
52                 'date': date_format(date, 'DATETIME_FORMAT'),
53             })
54
55     return JsonResponse(data, safe=False)
56
57
58 def download(request):
59     check_auth(request)
60
61     # TODO data validation
62     host = request.GET.get('host')
63     path = request.GET.get('path')
64     name = request.GET.get('name')
65     if not host or not path or not name:
66         raise SuspiciousOperation("No path or host or name given!")
67
68     url = 'gsiftp://' + host + path + '/' + name
69
70     mime_type, encoding = mimetypes.guess_type(name)
71
72     response = StreamingHttpResponse(FTPOperation(request.session['proxy']).get(url),
73                                      content_type=mime_type or 'application/octet-stream')
74     response['Content-Disposition'] = 'attachment; filename={}'.format(name)
75     # TODO Content-Length (?)
76
77     if encoding:
78         response['Content-Encoding'] = encoding
79
80     return response