|
| 1 | +import json |
| 2 | +import os |
| 3 | +import re |
| 4 | + |
| 5 | +from django.core.urlresolvers import reverse |
| 6 | +from django.http import HttpResponse, HttpResponseBadRequest |
| 7 | +from django.utils.encoding import smart_text |
| 8 | + |
| 9 | +from filebrowser import signals |
| 10 | +from filebrowser.base import FileObject |
| 11 | +from filebrowser.sites import FileBrowserSite, storage, handle_file_upload |
| 12 | +from filebrowser.utils import convert_filename |
| 13 | + |
| 14 | +from filebrowser.settings import ADMIN_THUMBNAIL, OVERWRITE_EXISTING, DEFAULT_PERMISSIONS, UPLOAD_TEMPDIR |
| 15 | + |
| 16 | + |
| 17 | +class CustomFileBrowserSite(FileBrowserSite): |
| 18 | + |
| 19 | + def _upload_file(self, request): |
| 20 | + """ |
| 21 | + Upload file to the server. |
| 22 | +
|
| 23 | + If temporary is true, we upload to UPLOAD_TEMP_DIR, otherwise |
| 24 | + we upload to site.directory |
| 25 | + """ |
| 26 | + if request.method == "POST": |
| 27 | + folder = request.GET.get('folder', '') |
| 28 | + temporary = request.GET.get('temporary', '') |
| 29 | + temp_filename = None |
| 30 | + |
| 31 | + if len(request.FILES) == 0: |
| 32 | + return HttpResponseBadRequest('Invalid request! No files included.') |
| 33 | + if len(request.FILES) > 1: |
| 34 | + return HttpResponseBadRequest('Invalid request! Multiple files included.') |
| 35 | + |
| 36 | + filedata = list(request.FILES.values())[0] |
| 37 | + |
| 38 | + fb_uploadurl_re = re.compile(r'^.*(%s)' % reverse("filebrowser:fb_upload", current_app=self.name)) |
| 39 | + folder = fb_uploadurl_re.sub('', folder) |
| 40 | + |
| 41 | + # temporary upload folder should be outside self.directory |
| 42 | + if folder == UPLOAD_TEMPDIR and temporary == "true": |
| 43 | + path = folder |
| 44 | + else: |
| 45 | + path = os.path.join(self.directory, folder) |
| 46 | + # we convert the filename before uploading in order |
| 47 | + # to check for existing files/folders |
| 48 | + file_name = convert_filename(filedata.name) |
| 49 | + filedata.name = file_name |
| 50 | + file_path = os.path.join(path, file_name) |
| 51 | + file_already_exists = self.storage.exists(file_path) |
| 52 | + |
| 53 | + # construct temporary filename by adding the upload folder, because |
| 54 | + # otherwise we don't have any clue if the file has temporary been |
| 55 | + # uploaded or not |
| 56 | + if folder == UPLOAD_TEMPDIR and temporary == "true": |
| 57 | + temp_filename = os.path.join(folder, file_name) |
| 58 | + |
| 59 | + # Check for name collision with a directory |
| 60 | + if file_already_exists and self.storage.isdir(file_path): |
| 61 | + ret_json = {'success': False, 'filename': file_name} |
| 62 | + return HttpResponse(json.dumps(ret_json)) |
| 63 | + |
| 64 | + signals.filebrowser_pre_upload.send(sender=request, path=folder, file=filedata, site=self) |
| 65 | + uploadedfile = handle_file_upload(path, filedata, site=self) |
| 66 | + |
| 67 | + if file_already_exists and OVERWRITE_EXISTING: |
| 68 | + old_file = smart_text(file_path) |
| 69 | + new_file = smart_text(uploadedfile) |
| 70 | + self.storage.move(new_file, old_file, allow_overwrite=True) |
| 71 | + full_path = FileObject(smart_text(old_file), site=self).path_full |
| 72 | + else: |
| 73 | + file_name = smart_text(uploadedfile) |
| 74 | + filedata.name = os.path.relpath(file_name, path) |
| 75 | + full_path = FileObject(smart_text(file_name), site=self).path_full |
| 76 | + |
| 77 | + # set permissions |
| 78 | + if DEFAULT_PERMISSIONS is not None: |
| 79 | + os.chmod(full_path, DEFAULT_PERMISSIONS) |
| 80 | + |
| 81 | + f = FileObject(smart_text(file_name), site=self) |
| 82 | + signals.filebrowser_post_upload.send(sender=request, path=folder, file=f, site=self) |
| 83 | + |
| 84 | + # let Ajax Upload know whether we saved it or not |
| 85 | + ret_json = { |
| 86 | + 'success': True, |
| 87 | + 'filename': f.filename, |
| 88 | + 'temp_filename': temp_filename, |
| 89 | + 'url': f.url, |
| 90 | + 'admin_thumbnail_url': f.version_generate(ADMIN_THUMBNAIL).url, |
| 91 | + } |
| 92 | + return HttpResponse(json.dumps(ret_json), content_type="application/json") |
| 93 | + |
| 94 | + |
| 95 | +custom_filebrowser_site = CustomFileBrowserSite(name='filebrowser', storage=storage) |
0 commit comments