Rafal's code for NMR restraints
[django_unres.git] / django_simple / directory / views.py
1 """Copyright Askbot SpA 2014, Licensed under GPLv3 license."""
2 import os
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
8
9 try:
10     from django.utils.module_loading import import_string as import_module
11 except ImportError:
12     from django.utils.module_loading import import_by_path as import_module
13
14 #utils functions
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':
19         return True
20     elif access_mode == 'use-perms':
21         if request.user.is_anonymous():
22             return False
23         else:
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)
32     else:
33         raise ImproperlyConfigured(
34             "Invalid setting DIRECTORY_ACCESS_MODE: only values "
35             "'public', 'use-perms', and 'custom' are allowed"
36         )
37
38
39 def get_file_names(directory):
40     """Returns list of file names within directory"""
41     contents = sorted(os.listdir(directory))
42     files = list()
43     for item in contents:
44         if os.path.isfile(os.path.join(directory, item)):
45             files.append(item)
46     return files
47
48 def read_file_chunkwise(file_obj):
49     """Reads file in 32Kb chunks"""
50     while True:
51         data = file_obj.read(32768)
52         if not data:
53             break
54         yield data
55
56
57 def list_directory(request, dir_name):
58     """default view - listing of the directory"""
59     if check_access(request):
60         directory = dir_name
61         data = {
62             'directory_name': os.path.basename(directory),
63             'directory_files': get_file_names(directory)
64         }
65         template = getattr(settings, 'DIRECTORY_TEMPLATE', 'directory/list.html')
66         return render(request, template, data)
67         
68     else:
69         raise PermissionDenied()
70
71
72 def download_file(request, dir_name, file_name):
73     """allows authorized user to download a given file"""
74
75     if os.path.sep in file_name:
76         raise PermissionDenied()
77
78     if check_access(request):
79         directory = dir_name
80
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)
89             return response
90         else:
91             raise Http404