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