Skip to content

Commit

Permalink
Merge branch 'stable/3.6.x' of github.com:sehmaschine/django-filebrow…
Browse files Browse the repository at this point in the history
…ser into stable/3.6.x
  • Loading branch information
sehmaschine committed Nov 6, 2015
2 parents b592320 + 0b56a0b commit f4cd243
Show file tree
Hide file tree
Showing 37 changed files with 1,584 additions and 1,935 deletions.
8 changes: 7 additions & 1 deletion docs/quickstart.rst
Expand Up @@ -63,11 +63,17 @@ Check the :ref:`settings`.
Testing
-------

Filebrowser is shipped with a minimal django project for testing.

Run the |filebrowser| tests:

.. note::
Using virtualenv is recommended for testing.

.. code-block:: console
python manage.py test filebrowser
pip install -r tests/requirements.txt
python runtests.py
.. warning::
Please note that the tests will copy files to your filesystem.
Expand Down
10 changes: 3 additions & 7 deletions filebrowser/actions.py
@@ -1,18 +1,14 @@
# coding: utf-8

# PYTHON IMPORTS
import os
from tempfile import NamedTemporaryFile
import tempfile

# DJANGO IMPORTS
from django.utils.translation import ugettext_lazy as _
from django.contrib import messages
from django.core.files import File
from django.utils.translation import ugettext_lazy as _

# FILEBROWSER IMPORTS
from filebrowser.settings import VERSION_QUALITY, STRICT_PIL

# PIL import
if STRICT_PIL:
from PIL import Image
else:
Expand All @@ -34,7 +30,7 @@ def transpose_image(request, fileobjects, operation):
f = fileobject.site.storage.open(fileobject.path)
im = Image.open(f)
new_image = im.transpose(operation)
tmpfile = File(NamedTemporaryFile())
tmpfile = File(tempfile.NamedTemporaryFile())

try:
new_image.save(tmpfile, format=Image.EXTENSION[ext], quality=VERSION_QUALITY, optimize=(os.path.splitext(fileobject.path)[1].lower() != '.gif'))
Expand Down
19 changes: 8 additions & 11 deletions filebrowser/base.py
@@ -1,24 +1,20 @@
# coding: utf-8

# PYTHON IMPORTS
import os
import datetime
import time
import platform
import mimetypes
from tempfile import NamedTemporaryFile
import os
import platform
import tempfile
import time
import warnings

# DJANGO IMPORTS
from django.core.files import File
from django.utils.encoding import python_2_unicode_compatible, smart_str
from django.utils.six import string_types

# FILEBROWSER IMPORTS
from filebrowser.settings import EXTENSIONS, VERSIONS, ADMIN_VERSIONS, VERSIONS_BASEDIR, VERSION_QUALITY, PLACEHOLDER, FORCE_PLACEHOLDER, SHOW_PLACEHOLDER, STRICT_PIL, IMAGE_MAXBLOCK, DEFAULT_PERMISSIONS, UPLOAD_TEMPDIR
from filebrowser.settings import EXTENSIONS, VERSIONS, ADMIN_VERSIONS, VERSIONS_BASEDIR, VERSION_QUALITY, STRICT_PIL, IMAGE_MAXBLOCK, DEFAULT_PERMISSIONS
from filebrowser.utils import path_strip, scale_and_crop
from django.utils.encoding import python_2_unicode_compatible, smart_str

# PIL import
if STRICT_PIL:
from PIL import Image
from PIL import ImageFile
Expand All @@ -30,6 +26,7 @@
import Image
import ImageFile


ImageFile.MAXBLOCK = IMAGE_MAXBLOCK # default is 64k


Expand Down Expand Up @@ -514,7 +511,7 @@ def _generate_version(self, version_suffix):
value has to be a path relative to the storage location.
"""

tmpfile = File(NamedTemporaryFile())
tmpfile = File(tempfile.NamedTemporaryFile())

try:
f = self.site.storage.open(self.path)
Expand Down
32 changes: 12 additions & 20 deletions filebrowser/decorators.py
@@ -1,39 +1,37 @@
# coding: utf-8

# PYTHON IMPORTS
import os

# DJANGO IMPORTS
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _

# FILEBROWSER IMPORTS
from filebrowser.templatetags.fb_tags import query_helper


def get_path(path, site):
"Get path."
if path.startswith('.') or os.path.isabs(path) or not site.storage.isdir(os.path.join(site.directory, path)):
return None
return path
converted_path = smart_text(os.path.join(site.directory, path))
if not path.startswith('.') and not os.path.isabs(converted_path):
if site.storage.isdir(converted_path):
return path


def get_file(path, filename, site):
"Get file (or folder)."
# Files and directories are valid
converted_path = smart_text(os.path.join(site.directory, path, filename))
if not site.storage.isfile(converted_path) and not site.storage.isdir(converted_path):
return None
return filename
if not path.startswith('.') and not filename.startswith('.') and not os.path.isabs(converted_path):
if site.storage.isfile(converted_path) or site.storage.isdir(converted_path):
return filename


def path_exists(site, function):
"Check if the given path exists."

def decorator(request, *args, **kwargs):
# TODO: This check should be moved to a better location than a decorator
if get_path('', site=site) is None:
# The storage location does not exist, raise an error to prevent eternal redirecting.
raise ImproperlyConfigured(_("Error finding Upload-Folder (site.storage.location + site.directory). Maybe it does not exist?"))
Expand All @@ -56,11 +54,5 @@ def decorator(request, *args, **kwargs):
messages.add_message(request, messages.ERROR, msg)
redirect_url = reverse("filebrowser:fb_browse", current_app=site.name) + query_helper(request.GET, u"", "dir")
return HttpResponseRedirect(redirect_url)
elif file_path.startswith('/') or file_path.startswith('..'):
# prevent path traversal
msg = _('You do not have permission to access this file!')
messages.add_message(request, messages.ERROR, msg)
redirect_url = reverse("filebrowser:fb_browse", current_app=site.name) + query_helper(request.GET, u"", "dir")
return HttpResponseRedirect(redirect_url)
return function(request, *args, **kwargs)
return decorator
10 changes: 3 additions & 7 deletions filebrowser/fields.py
@@ -1,21 +1,17 @@
# coding: utf-8

# PYTHON IMPORTS
import os

# DJANGO IMPORTS
from django import forms
from django.core import urlresolvers
from django.db import models
from django.db.models.fields import Field, CharField
from django import forms
from django.db.models.fields import CharField
from django.forms.widgets import Input
from django.template.loader import render_to_string
from django.utils.six import with_metaclass
from django.utils.translation import ugettext_lazy as _

# FILEBROWSER IMPORTS
from filebrowser.settings import *
from filebrowser.base import FileObject
from filebrowser.settings import ADMIN_THUMBNAIL, EXTENSIONS, UPLOAD_TEMPDIR
from filebrowser.sites import site


Expand Down
5 changes: 1 addition & 4 deletions filebrowser/forms.py
@@ -1,20 +1,17 @@
# coding: utf-8

# PYTHON IMPORTS
import os
import re

# DJANGO IMPORTS
from django import forms
from django.utils.translation import ugettext_lazy as _

# FILEBROWSER IMPORTS
from filebrowser.settings import FOLDER_REGEX
from filebrowser.utils import convert_filename


ALNUM_NAME_RE = re.compile(FOLDER_REGEX, re.U)

# CHOICES
TRANSPOSE_CHOICES = (
("", u"-----"),
("0", _(u"Flip horizontal")),
Expand Down
9 changes: 3 additions & 6 deletions filebrowser/management/commands/fb_version_generate.py
@@ -1,17 +1,14 @@
# coding: utf-8

# PYTHON IMPORTS
import os
import re

# DJANGO IMPORTS
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.utils.six.moves import input

# FILEBROWSER IMPORTS
from filebrowser.settings import EXTENSION_LIST, EXCLUDE, DIRECTORY, VERSIONS, EXTENSIONS
from filebrowser.base import FileListing, FileObject
from filebrowser.base import FileListing
from filebrowser.settings import EXTENSION_LIST, EXCLUDE, DIRECTORY, VERSIONS


filter_re = []
Expand Down
8 changes: 2 additions & 6 deletions filebrowser/management/commands/fb_version_remove.py
@@ -1,17 +1,13 @@
# coding: utf-8

# PYTHON IMPORTS
import os
import re
import sys

# DJANGO IMPORTS
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from django.utils.six.moves import input

# FILEBROWSER IMPORTS
from filebrowser.settings import EXTENSION_LIST, EXCLUDE, DIRECTORY, VERSIONS, EXTENSIONS
from filebrowser.settings import EXCLUDE, EXTENSIONS


class Command(BaseCommand):
Expand Down
2 changes: 1 addition & 1 deletion filebrowser/settings.py
@@ -1,9 +1,9 @@
# coding: utf-8

# django imports
from django.conf import settings
from django.utils.translation import ugettext_lazy as _


# Main FileBrowser Directory. Relative to site.storage.location.
# DO NOT USE A SLASH AT THE BEGINNING, DO NOT FORGET THE TRAILING SLASH AT THE END.
DIRECTORY = getattr(settings, "FILEBROWSER_DIRECTORY", 'uploads/')
Expand Down
2 changes: 1 addition & 1 deletion filebrowser/signals.py
@@ -1,8 +1,8 @@
# coding: utf-8

# DJANGO IMPORTS
from django.dispatch import Signal


# upload signals
# path: Absolute server path to the file/folder
# name: Name of the file/folder
Expand Down
47 changes: 21 additions & 26 deletions filebrowser/sites.py
@@ -1,52 +1,47 @@
# coding: utf-8

# PYTHON IMPORTS
import os
import re
from time import gmtime
from time import strftime
from time import localtime
from time import time
from time import gmtime, strftime, localtime, time

# DJANGO IMPORTS
from django import forms
from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
from django.core.files.storage import DefaultStorage, default_storage, FileSystemStorage
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse, get_urlconf, get_resolver
from django.http import HttpResponseRedirect, HttpResponseBadRequest
from django.shortcuts import render_to_response, HttpResponse
from django.template import RequestContext as Context
from django.http import HttpResponseRedirect, HttpResponseBadRequest
from django.contrib.admin.views.decorators import staff_member_required
from django.views.decorators.cache import never_cache
from django.utils.translation import ugettext as _
from django import forms
from django.core.urlresolvers import reverse, get_urlconf, get_resolver
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.contrib import messages
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_exempt
from django.core.files.storage import DefaultStorage, default_storage, FileSystemStorage
try:
from django.utils.encoding import smart_text
except ImportError:
from django.utils.encoding import smart_unicode as smart_text

# FILEBROWSER IMPORTS
from filebrowser.settings import DIRECTORY, EXTENSIONS, SELECT_FORMATS, ADMIN_VERSIONS, ADMIN_THUMBNAIL, MAX_UPLOAD_SIZE,\
NORMALIZE_FILENAME, CONVERT_FILENAME, SEARCH_TRAVERSE, EXCLUDE, VERSIONS, VERSIONS_BASEDIR, EXTENSION_LIST, DEFAULT_SORTING_BY, DEFAULT_SORTING_ORDER,\
LIST_PER_PAGE, OVERWRITE_EXISTING, DEFAULT_PERMISSIONS, UPLOAD_TEMPDIR
from filebrowser.templatetags.fb_tags import query_helper
from filebrowser import signals
from filebrowser.base import FileListing, FileObject
from filebrowser.decorators import path_exists, file_exists
from filebrowser.storage import FileSystemStorageMixin
from filebrowser.templatetags.fb_tags import query_helper
from filebrowser.utils import convert_filename
from filebrowser import signals
from filebrowser.settings import (DIRECTORY, EXTENSIONS, SELECT_FORMATS, ADMIN_VERSIONS, ADMIN_THUMBNAIL, MAX_UPLOAD_SIZE, NORMALIZE_FILENAME,
CONVERT_FILENAME, SEARCH_TRAVERSE, EXCLUDE, VERSIONS, VERSIONS_BASEDIR, EXTENSION_LIST, DEFAULT_SORTING_BY, DEFAULT_SORTING_ORDER,
LIST_PER_PAGE, OVERWRITE_EXISTING, DEFAULT_PERMISSIONS, UPLOAD_TEMPDIR)

# Add some required methods to FileSystemStorage
if FileSystemStorageMixin not in FileSystemStorage.__bases__:
FileSystemStorage.__bases__ += (FileSystemStorageMixin,)

# JSON import
try:
import json
except ImportError:
from django.utils import simplejson as json


# Add some required methods to FileSystemStorage
if FileSystemStorageMixin not in FileSystemStorage.__bases__:
FileSystemStorage.__bases__ += (FileSystemStorageMixin,)


# This cache contains all *instantiated* FileBrowser sites
_sites_cache = {}

Expand Down Expand Up @@ -523,7 +518,7 @@ def _upload_file(self, request):
"""
Upload file to the server.
If temporary is true, we upload to UPLOAD_TEMP_DIR, otherwise
If temporary is true, we upload to UPLOAD_TEMPDIR, otherwise
we upload to site.directory
"""
if request.method == "POST":
Expand Down
5 changes: 1 addition & 4 deletions filebrowser/storage.py
@@ -1,16 +1,13 @@
# coding: utf-8

# PYTHON IMPORTS
import os
import shutil

# DJANGO IMPORTS
from django.core.files.move import file_move_safe
from django.utils.encoding import smart_text

# FILEBROWSER IMPORTS
from filebrowser.settings import DEFAULT_PERMISSIONS
from filebrowser.base import FileObject
from filebrowser.settings import DEFAULT_PERMISSIONS


class StorageMixin(object):
Expand Down
6 changes: 3 additions & 3 deletions filebrowser/templatetags/fb_csrf.py
@@ -1,9 +1,9 @@
# coding: utf-8

# DJANGO IMPORTS
from django.template import Node
from django.template import Library
from django.template import Library, Node
from django.utils.safestring import mark_safe


register = Library()


Expand Down
4 changes: 1 addition & 3 deletions filebrowser/templatetags/fb_pagination.py
@@ -1,10 +1,8 @@
# coding: utf-8

# DJANGO IMPORTS
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.template import Library


register = Library()
DOT = '.'

Expand Down

0 comments on commit f4cd243

Please sign in to comment.