1 """Copyright Askbot SpA 2014, Licensed under GPLv3 license."""
3 from django.conf import settings
4 from django.core.exceptions import PermissionDenied, ImproperlyConfigured
5 from django.core.urlresolvers import reverse
6 from django.http import StreamingHttpResponse, Http404, HttpResponseRedirect
7 from django.shortcuts import render
10 from django.utils.module_loading import import_string as import_module
12 from django.utils.module_loading import import_by_path as import_module
15 def check_access(request):
16 """Returns true if user has access to the directory"""
17 access_mode = getattr(settings, 'DIRECTORY_ACCESS_MODE', 'public')
18 if access_mode == 'public':
20 elif access_mode == 'use-perms':
21 if request.user.is_anonymous():
24 return request.user.has_perm('directory.read')
25 elif access_mode == 'custom':
26 check_perm = settings.DIRECTORY_ACCESS_FUNCTION
27 if isinstance(check_perm, basestring):
28 check_perm = import_module(check_perm)
29 elif not hasattr(check_perm, '__call__'):
30 raise ImproperlyConfigured('DIRECTORY_ACCESS_FUNCTION must either be a function or python path')
31 return check_perm(request)
33 raise ImproperlyConfigured(
34 "Invalid setting DIRECTORY_ACCESS_MODE: only values "
35 "'public', 'use-perms', and 'custom' are allowed"
39 def get_file_names(directory):
40 """Returns list of file names within directory"""
41 contents = sorted(os.listdir(directory))
44 if os.path.isfile(os.path.join(directory, item)):
48 def read_file_chunkwise(file_obj):
49 """Reads file in 32Kb chunks"""
51 data = file_obj.read(32768)
57 def list_directory(request, dir_name):
58 """default view - listing of the directory"""
59 if check_access(request):
62 'directory_name': os.path.basename(directory),
63 'directory_files': get_file_names(directory)
65 template = getattr(settings, 'DIRECTORY_TEMPLATE', 'directory/list.html')
66 return render(request, template, data)
69 raise PermissionDenied()
72 def download_file(request, dir_name, file_name):
73 """allows authorized user to download a given file"""
75 if os.path.sep in file_name:
76 raise PermissionDenied()
78 if check_access(request):
81 #make sure that file exists within current directory
82 files = get_file_names(directory)
83 if file_name in files:
84 file_path = os.path.join(directory, file_name)
85 response = StreamingHttpResponse(content_type='application/force-download')
86 response['Content-Disposition'] = 'attachment; filename=%s' % file_name
87 file_obj = open(os.path.join(directory, file_name))
88 response.streaming_content = read_file_chunkwise(file_obj)