1 from itertools import islice
4 from django.contrib.auth.decorators import login_required
5 from django.core.exceptions import PermissionDenied, SuspiciousOperation
6 from django.http import JsonResponse, StreamingHttpResponse
7 from django.shortcuts import get_object_or_404
8 from django.template.defaultfilters import filesizeformat
9 from django.utils.formats import date_format
10 from django.views.decorators.http import require_POST
12 from filex.forms import NewDirForm, RenameForm, FavoriteForm
13 from filex.ftp import FTPOperation, FTPException
14 from filex.models import Favorite
15 from filex.uploadhandler import with_ftp_upload_handler
18 def check_auth(request):
19 if not request.user.is_authenticated():
20 raise PermissionDenied("Login required!")
21 if not request.session['proxy']:
22 raise PermissionDenied("No proxy found!")
25 def list_content(request):
28 # TODO data validation
29 host = request.GET.get('host')
30 path = request.GET.get('path')
31 if not host or not path:
32 raise SuspiciousOperation("No path or host given!")
34 url = 'gsiftp://' + host + path
37 listing = FTPOperation(request.session['proxy']).listing(url)
38 except FTPException as e:
39 return JsonResponse({'msg': e.message}, status=400)
42 # ignore . and .. from beginning of the listing
43 for item in islice(listing, 2, None):
44 item['size'] = filesizeformat(item['size'])
45 item['date'] = date_format(item['date'], 'CUSTOM_DATETIME_FORMAT')
49 return JsonResponse(data, safe=False)
52 def download(request):
55 # TODO data validation
56 host = request.GET.get('host')
57 path = request.GET.get('path')
58 name = request.GET.get('name')
59 if not host or not path or not name:
60 raise SuspiciousOperation("No path or host or name given!")
62 url = 'gsiftp://' + host + path + '/' + name
64 mime_type, encoding = mimetypes.guess_type(name)
66 response = StreamingHttpResponse(FTPOperation(request.session['proxy']).get(url),
67 content_type=mime_type or 'application/octet-stream')
68 response['Content-Disposition'] = 'attachment; filename={}'.format(name)
69 # TODO Content-Length (?)
72 response['Content-Encoding'] = encoding
77 @with_ftp_upload_handler
80 return JsonResponse({'success': True})
86 # TODO data validation
87 host = request.GET.get('host')
88 path = request.GET.get('path')
89 if not host or not path:
90 raise SuspiciousOperation("No path or host given!")
92 url = 'gsiftp://' + host + path
95 return JsonResponse(FTPOperation(request.session['proxy']).info(url))
96 except FTPException as e:
98 if 'No such file or directory' in e.message:
100 elif 'Permission denied' in e.message:
103 return JsonResponse({'msg': e.message}, status=status)
110 # TODO data validation
111 host = request.POST.get('host')
112 path = request.POST.get('path')
113 dirs = request.POST.getlist('dirs')
114 files = request.POST.getlist('files')
115 if not host or not path or not (files or dirs):
116 raise SuspiciousOperation("No path or host or files given!")
118 url = 'gsiftp://' + host + path + '/'
119 ftp = FTPOperation(request.session['proxy'])
125 ftp.rmdir(url + name)
126 except FTPException as e:
127 fail[name] = e.message
133 ftp.delete(url + name)
134 except FTPException as e:
135 fail[name] = e.message
139 return JsonResponse({'done': done, 'fail': fail})
146 # TODO actual data validation
147 form = NewDirForm(request.POST)
150 host = form.cleaned_data['host']
151 path = form.cleaned_data['path']
152 name = form.cleaned_data['name']
154 url = 'gsiftp://' + host + path + '/' + name
157 FTPOperation(request.session['proxy']).mkdir(url)
158 except FTPException as e:
161 return JsonResponse({'success': True})
165 return JsonResponse({'msg': msg}, status=400)
172 # TODO actual data validation
173 form = RenameForm(request.POST)
176 host = form.cleaned_data['host']
177 path = form.cleaned_data['path']
178 src = form.cleaned_data['src']
179 dst = form.cleaned_data['dst']
181 src_url = 'gsiftp://' + host + path + '/' + src
182 dst_url = 'gsiftp://' + host + path + '/' + dst
185 FTPOperation(request.session['proxy']).move(src_url, dst_url)
186 except FTPException as e:
189 return JsonResponse({'success': True})
193 return JsonResponse({'msg': msg}, status=400)
197 def compress(request):
200 # TODO data validation
201 host = request.POST.get('host')
202 path = request.POST.get('path')
203 files = request.POST.getlist('files')
204 archive = request.POST.get('archive')
205 if not host or not path or not files or not archive:
206 raise SuspiciousOperation("No path or host or files or archive given!")
208 server = 'gsiftp://' + host
211 # consume generator with command output
212 list(FTPOperation(request.session['proxy']).compress(server, path, files, archive))
213 except FTPException as e:
214 return JsonResponse({'msg': e.message}, status=400)
216 return JsonResponse({'success': True})
220 def extract(request):
223 # TODO data validation
224 host = request.POST.get('host')
225 archive = request.POST.get('archive')
226 dst = request.POST.get('dst')
227 if not host or not archive or not dst:
228 raise SuspiciousOperation("No path or host or files or archive given!")
230 server = 'gsiftp://' + host
233 # consume generator with command output
234 list(FTPOperation(request.session['proxy']).extract(server, archive, dst))
235 except FTPException as e:
236 return JsonResponse({'msg': e.message}, status=400)
238 return JsonResponse({'success': True})
243 def fav_add(request):
244 data = request.POST.copy()
245 data['owner'] = request.user.id
247 form = FavoriteForm(data)
249 # TODO check if path exists
251 instance = form.save()
253 return JsonResponse({'group': 'usr', 'host': instance.host, 'path': instance.path,
254 'value': instance.host + instance.path})
256 return JsonResponse({'msg': form.errors}, status=400)
261 def fav_delete(request):
262 fav = get_object_or_404(Favorite, owner=request.user, host=request.POST['host'], path=request.POST['path'])
265 return JsonResponse({'success': True})