delete view
[qcg-portal.git] / filex / views.py
1 import mimetypes
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.views.decorators.http import require_POST
8
9 from filex.ftp import FTPOperation, FTPException
10 from filex.uploadhandler import with_ftp_upload_handler
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     for item in listing:
38         item['size'] = filesizeformat(item['size'])
39         item['date'] = date_format(item['date'], 'CUSTOM_DATETIME_FORMAT')
40
41         data.append(item)
42
43     return JsonResponse(data, safe=False)
44
45
46 def download(request):
47     check_auth(request)
48
49     # TODO data validation
50     host = request.GET.get('host')
51     path = request.GET.get('path')
52     name = request.GET.get('name')
53     if not host or not path or not name:
54         raise SuspiciousOperation("No path or host or name given!")
55
56     url = 'gsiftp://' + host + path + '/' + name
57
58     mime_type, encoding = mimetypes.guess_type(name)
59
60     response = StreamingHttpResponse(FTPOperation(request.session['proxy']).get(url),
61                                      content_type=mime_type or 'application/octet-stream')
62     response['Content-Disposition'] = 'attachment; filename={}'.format(name)
63     # TODO Content-Length (?)
64
65     if encoding:
66         response['Content-Encoding'] = encoding
67
68     return response
69
70
71 @with_ftp_upload_handler
72 def upload(request):
73     # TODO error handling
74     return JsonResponse({'success': True})
75
76
77 def info(request):
78     check_auth(request)
79
80     # TODO data validation
81     host = request.GET.get('host')
82     path = request.GET.get('path')
83     if not host or not path:
84         raise SuspiciousOperation("No path or host given!")
85
86     url = 'gsiftp://' + host + path
87
88     try:
89         return JsonResponse(FTPOperation(request.session['proxy']).info(url))
90     except FTPException as e:
91         status = 400
92         if 'No such file or directory' in e.message:
93             status = 404
94         elif 'Permission denied' in e.message:
95             status = 403
96
97         return JsonResponse({'msg': e.message}, status=status)
98
99
100 @require_POST
101 def delete(request):
102     check_auth(request)
103
104     # TODO data validation
105     host = request.POST.get('host')
106     path = request.POST.get('path')
107     dirs = request.POST.getlist('dirs')
108     files = request.POST.getlist('files')
109     if not host or not path or not (files or dirs):
110         raise SuspiciousOperation("No path or host or files given!")
111
112     url = 'gsiftp://' + host + path + '/'
113     ftp = FTPOperation(request.session['proxy'])
114
115     done, fail = [], {}
116
117     for name in dirs:
118         try:
119             ftp.rmdir(url + name)
120         except FTPException as e:
121             fail[name] = e.message
122         else:
123             done.append(name)
124
125     for name in files:
126         try:
127             ftp.delete(url + name)
128         except FTPException as e:
129             fail[name] = e.message
130         else:
131             done.append(name)
132
133     return JsonResponse({'done': done, 'fail': fail})