├── .coveragerc ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .hgignore ├── .isort.cfg ├── .releaserc ├── LICENSE ├── MANIFEST.in ├── README.rst ├── filebrowser_safe ├── __init__.py ├── base.py ├── fields.py ├── forms.py ├── functions.py ├── locale │ ├── ar │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── ca │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── cs │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── de │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── es │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── fr │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── it │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── nb │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── nl │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── ru │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── sr │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── sr_Latn │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ ├── zh_CN │ │ └── LC_MESSAGES │ │ │ ├── django.mo │ │ │ └── django.po │ └── zh_TW │ │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po ├── models.py ├── settings.py ├── static │ └── filebrowser │ │ ├── css │ │ ├── filebrowser.css │ │ └── rtl.css │ │ ├── img │ │ ├── filebrowser_icon_delete.gif │ │ ├── filebrowser_icon_delete_hover.gif │ │ ├── filebrowser_icon_rename.gif │ │ ├── filebrowser_icon_rename_hover.gif │ │ ├── filebrowser_icon_select.gif │ │ ├── filebrowser_icon_select_disabled.gif │ │ ├── filebrowser_icon_select_hover.gif │ │ ├── filebrowser_icon_show.gif │ │ ├── filebrowser_icon_show_hover.gif │ │ ├── filebrowser_icon_showversions.gif │ │ ├── filebrowser_icon_showversions_hover.gif │ │ ├── filebrowser_type_.gif │ │ ├── filebrowser_type_audio.gif │ │ ├── filebrowser_type_code.gif │ │ ├── filebrowser_type_document.gif │ │ ├── filebrowser_type_folder.gif │ │ ├── filebrowser_type_image.gif │ │ └── filebrowser_type_video.gif │ │ └── js │ │ ├── AddFileBrowser.js │ │ ├── FB_CKEditor.js │ │ ├── FB_FileBrowseField.js │ │ ├── FB_TinyMCE.js │ │ ├── FB_TinyMCE4.js │ │ ├── TinyMCEAdmin.js │ │ ├── filebrowser-popup.js │ │ └── upload.js ├── storage.py ├── templates │ └── filebrowser │ │ ├── append.html │ │ ├── custom_field.html │ │ ├── include │ │ ├── _response.html │ │ ├── breadcrumbs.html │ │ ├── filelisting.html │ │ ├── filter.html │ │ ├── paginator.html │ │ ├── search.html │ │ ├── tableheader.html │ │ └── toolbar.html │ │ ├── index.html │ │ ├── makedir.html │ │ ├── rename.html │ │ └── upload.html ├── templatetags │ ├── __init__.py │ ├── fb_pagination.py │ └── fb_tags.py ├── urls.py └── views.py ├── pytest.ini ├── setup.cfg ├── setup.py ├── tests ├── __init__.py ├── settings.py ├── test_anonymous.py ├── test_staff.py └── urls.py └── tox.ini /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | omit = 3 | filebrowser_safe/*/migrations/* 4 | */tests/* 5 | 6 | [report] 7 | show_missing = True 8 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Test and release 2 | 3 | # Fires on all incoming commits 4 | on: 5 | pull_request: 6 | push: 7 | 8 | jobs: 9 | 10 | # Test all supported Python & Django versions 11 | test: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | include: 17 | # Django 2.2 18 | - tox-env: "py36-dj22" 19 | python-version: "3.6" 20 | - tox-env: "py37-dj22" 21 | python-version: "3.7" 22 | - tox-env: "py38-dj22" 23 | python-version: "3.8" 24 | - tox-env: "py39-dj22" 25 | python-version: "3.9" 26 | # Django 3.0 27 | - tox-env: "py36-dj30" 28 | python-version: "3.6" 29 | - tox-env: "py37-dj30" 30 | python-version: "3.7" 31 | - tox-env: "py38-dj30" 32 | python-version: "3.8" 33 | - tox-env: "py39-dj30" 34 | python-version: "3.9" 35 | # Django 3.1 36 | - tox-env: "py36-dj31" 37 | python-version: "3.6" 38 | - tox-env: "py37-dj31" 39 | python-version: "3.7" 40 | - tox-env: "py38-dj31" 41 | python-version: "3.8" 42 | - tox-env: "py39-dj31" 43 | python-version: "3.9" 44 | # Django 3.2 45 | - tox-env: "py36-dj32" 46 | python-version: "3.6" 47 | - tox-env: "py37-dj32" 48 | python-version: "3.7" 49 | - tox-env: "py38-dj32" 50 | python-version: "3.8" 51 | - tox-env: "py39-dj32" 52 | python-version: "3.9" 53 | - tox-env: "py310-dj32" 54 | python-version: "3.10" 55 | # Django 4.0 56 | - tox-env: "py38-dj40" 57 | python-version: "3.8" 58 | - tox-env: "py39-dj40" 59 | python-version: "3.9" 60 | - tox-env: "py310-dj40" 61 | python-version: "3.10" 62 | 63 | steps: 64 | - uses: actions/checkout@v2 65 | - uses: actions/setup-python@v2 66 | with: 67 | python-version: ${{ matrix.python-version }} 68 | - name: Install dependencies 69 | run: pip install -U pip tox 70 | - name: Run tests 71 | run: tox -e ${{ matrix.tox-env }} 72 | - name: Publish Test Report 73 | uses: mikepenz/action-junit-report@v2 74 | with: 75 | report_paths: '**/junit/TEST-*.xml' 76 | 77 | # Lint 78 | lint: 79 | runs-on: ubuntu-latest 80 | steps: 81 | - uses: actions/checkout@v2 82 | - uses: actions/setup-python@v2 83 | with: 84 | python-version: 3.9 85 | - name: Install dependencies 86 | run: pip install tox -U pip 87 | - name: Lint 88 | run: tox -e package -e lint -e pyupgrade 89 | 90 | # Create a new semantic release 91 | # Only runs on the original repo, not forks 92 | release: 93 | if: github.repository_owner == 'stephenmcd' 94 | needs: [test, lint] 95 | runs-on: ubuntu-latest 96 | steps: 97 | - uses: actions/checkout@v2 98 | - uses: actions/setup-python@v2 99 | with: 100 | python-version: 3.9 101 | - uses: actions/setup-node@v2 102 | with: 103 | node-version: '14' # https://github.com/cycjimmy/semantic-release-action/issues/79#issuecomment-955463633 104 | - uses: cycjimmy/semantic-release-action@v2 105 | with: 106 | semantic_version: 18 107 | extra_plugins: | 108 | @semantic-release/exec@5 109 | env: 110 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 111 | TWINE_USERNAME: __token__ 112 | TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} 113 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info 2 | *.eggs/ 3 | *.pyc 4 | .DS_Store 5 | .coverage 6 | .idea 7 | .pytest_cache 8 | .tox 9 | .vscode 10 | /build/ 11 | /dist/ 12 | /htmlcov/ 13 | /junit/ 14 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.pyc 3 | build/* 4 | dist/* 5 | filebrowser_safe.egg-info/* 6 | mezzanine-git/ 7 | -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | profile = black 3 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "+([0-9])?(.{+([0-9]),x}).x", 4 | "stable", 5 | {"name": "alpha", "prerelease": true}, 6 | {"name": "beta", "prerelease": true}, 7 | {"name": "rc", "prerelease": true} 8 | ], 9 | "plugins": [ 10 | "@semantic-release/commit-analyzer", 11 | "@semantic-release/release-notes-generator", 12 | "@semantic-release/github", 13 | ["@semantic-release/exec", { 14 | "verifyConditionsCmd": "python -m pip install -U pip setuptools wheel twine", 15 | "prepareCmd": "sed -i 's/9999dev0/${nextRelease.version}/' filebrowser_safe/__init__.py", 16 | "publishCmd": "python setup.py sdist bdist_wheel && twine upload dist/*" 17 | }] 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, Patrick Kranzlmueller (vonautomatisch werkstaetten), 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 3. Neither the name of FileBrowser nor the names of its contributors may be used 13 | to endorse or promote products derived from this software without specific prior 14 | written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 17 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 19 | THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | 4 | recursive-include filebrowser_safe/static * 5 | recursive-include filebrowser_safe/templates *.html 6 | recursive-include filebrowser_safe/locale *.mo *.po 7 | 8 | prune tests 9 | exclude .releaserc .isort.cfg tox.ini pytest.ini .coveragerc 10 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. image:: https://img.shields.io/pypi/v/filebrowser-safe.svg 2 | :target: https://pypi.org/project/filebrowser-safe/ 3 | .. image:: https://img.shields.io/pypi/pyversions/filebrowser-safe.svg 4 | .. image:: https://github.com/stephenmcd/filebrowser-safe/workflows/Test%20and%20release/badge.svg 5 | :target: https://github.com/stephenmcd/filebrowser-safe/actions?query=workflow%3A%22Test+and+release%22 6 | .. image:: https://img.shields.io/badge/code%20style-black-000000.svg 7 | :target: https://github.com/psf/black 8 | 9 | Overview 10 | ======== 11 | 12 | filebrowser_safe is a permanent fork of 13 | `FileBrowser asset manager `_ 14 | for `Django `_, to be referenced as a 15 | dependency for the `Mezzanine CMS for Django `_. 16 | 17 | At the time of filebrowser_safe's creation, FileBrowser was incorrectly 18 | packaged on `PyPI `_, and had also dropped 19 | compatibility with Django 1.1 -- filebrowser_safe was therefore created to 20 | address these specific issues. 21 | 22 | For further details, see 23 | `Why are Grappelli and Filebrowser Forked? `_. 24 | 25 | Contributing 26 | ============ 27 | 28 | Please refer to `Mezzanine's Contribution Guidelines `_ 29 | -------------------------------------------------------------------------------- /filebrowser_safe/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "9999dev0" # Do not edit, managed by semantic-release 2 | -------------------------------------------------------------------------------- /filebrowser_safe/base.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import mimetypes 3 | import os 4 | import time 5 | import warnings 6 | 7 | from django.core.files.storage import default_storage 8 | from django.db.models.fields.files import FieldFile 9 | from django.utils.encoding import smart_str 10 | from django.utils.functional import cached_property 11 | 12 | from filebrowser_safe.functions import get_directory, get_file_type, path_strip 13 | 14 | 15 | class FileObjectAPI: 16 | """A mixin class providing file properties.""" 17 | 18 | def __init__(self, path): 19 | self.head = os.path.dirname(path) 20 | self.filename = os.path.basename(path) 21 | self.filename_lower = self.filename.lower() 22 | self.filename_root, self.extension = os.path.splitext(self.filename) 23 | self.mimetype = mimetypes.guess_type(self.filename) 24 | 25 | def __str__(self): 26 | return smart_str(self.name) 27 | 28 | def __unicode__(self): 29 | return smart_str(self.name) 30 | 31 | def __repr__(self): 32 | return smart_str("<{}: {}>".format(self.__class__.__name__, self or "None")) 33 | 34 | def __len__(self): 35 | return len(self.name) 36 | 37 | # GENERAL ATTRIBUTES 38 | 39 | @cached_property 40 | def filetype(self): 41 | if self.is_folder: 42 | return "Folder" 43 | return get_file_type(self.filename) 44 | 45 | @cached_property 46 | def filesize(self): 47 | if self.exists: 48 | return default_storage.size(self.name) 49 | return None 50 | 51 | @cached_property 52 | def date(self): 53 | if self.exists: 54 | return time.mktime(default_storage.get_modified_time(self.path).timetuple()) 55 | return None 56 | 57 | @property 58 | def datetime(self): 59 | if self.date: 60 | return datetime.datetime.fromtimestamp(self.date) 61 | return None 62 | 63 | @cached_property 64 | def exists(self): 65 | return default_storage.exists(self.name) 66 | 67 | # PATH/URL ATTRIBUTES 68 | 69 | @property 70 | def path_relative_directory(self): 71 | """path relative to the path returned by get_directory()""" 72 | return path_strip(self.name, get_directory()).lstrip("/") 73 | 74 | # FOLDER ATTRIBUTES 75 | 76 | @property 77 | def directory(self): 78 | return path_strip(self.name, get_directory()) 79 | 80 | @property 81 | def folder(self): 82 | return os.path.dirname(path_strip(os.path.join(self.head, ""), get_directory())) 83 | 84 | @cached_property 85 | def is_folder(self): 86 | return default_storage.isdir(self.path) 87 | 88 | @property 89 | def is_empty(self): 90 | if self.is_folder: 91 | try: 92 | dirs, files = default_storage.listdir(self.name) 93 | except UnicodeDecodeError: 94 | from mezzanine.core.exceptions import FileSystemEncodingChanged 95 | 96 | raise FileSystemEncodingChanged() 97 | if not dirs and not files: 98 | return True 99 | return False 100 | 101 | 102 | class FileObject(FileObjectAPI): 103 | """ 104 | The FileObject represents a file (or directory) on the server. 105 | 106 | An example:: 107 | 108 | from filebrowser.base import FileObject 109 | 110 | fileobject = FileObject(path) 111 | 112 | where path is a relative path to a storage location. 113 | """ 114 | 115 | def __init__(self, path): 116 | self.path = path 117 | super().__init__(path) 118 | 119 | @property 120 | def name(self): 121 | return self.path 122 | 123 | @property 124 | def url(self): 125 | return default_storage.url(self.name) 126 | 127 | 128 | class FieldFileObject(FieldFile, FileObjectAPI): 129 | """ 130 | Returned when a FileBrowseField is accessed on a model instance. 131 | 132 | - Implements the FieldFile API so FileBrowseField can act as substitute for 133 | django's built-in FileField. 134 | - Implements the FileObject API for historical reasons. 135 | """ 136 | 137 | def __init__(self, instance, field, path): 138 | FieldFile.__init__(self, instance, field, path) 139 | FileObjectAPI.__init__(self, path or "") 140 | 141 | def delete(self, **kwargs): 142 | if self.is_folder: 143 | default_storage.rmtree(self.name) 144 | else: 145 | super().delete(**kwargs) 146 | 147 | @property 148 | def path(self): 149 | warnings.warn( 150 | "In future versions of filebrowser-safe, the `path` property will " 151 | "be absolute. To continue getting the same behavior please use " 152 | "the `name` property instead.", 153 | FutureWarning, 154 | stacklevel=2, 155 | ) 156 | return self.name 157 | -------------------------------------------------------------------------------- /filebrowser_safe/fields.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import os 3 | 4 | from django import forms 5 | from django.core.files.storage import default_storage 6 | from django.db.models.fields import Field 7 | from django.db.models.fields.files import FileDescriptor 8 | from django.forms.widgets import Input 9 | from django.template.loader import render_to_string 10 | from django.utils.encoding import smart_str 11 | from django.utils.safestring import mark_safe 12 | from django.utils.translation import gettext_lazy as _ 13 | 14 | from filebrowser_safe import settings as fb_settings 15 | from filebrowser_safe.base import FieldFileObject 16 | from filebrowser_safe.functions import get_directory 17 | 18 | 19 | class FileBrowseWidget(Input): 20 | input_type = "text" 21 | 22 | class Media: 23 | js = (os.path.join(fb_settings.URL_FILEBROWSER_MEDIA, "js/AddFileBrowser.js"),) 24 | 25 | def __init__(self, attrs=None): 26 | self.directory = attrs.get("directory", "") 27 | self.extensions = attrs.get("extensions", "") 28 | self.format = attrs.get("format", "") 29 | if attrs is not None: 30 | self.attrs = attrs.copy() 31 | else: 32 | self.attrs = {} 33 | 34 | def render(self, name, value, attrs=None, renderer=None): 35 | if value is None: 36 | value = "" 37 | directory = self.directory 38 | if self.directory: 39 | if callable(self.directory): 40 | directory = self.directory() 41 | directory = os.path.normpath(datetime.datetime.now().strftime(directory)) 42 | fullpath = os.path.join(get_directory(), directory) 43 | if not default_storage.isdir(fullpath): 44 | default_storage.makedirs(fullpath) 45 | final_attrs = dict(type=self.input_type, name=name, **attrs) 46 | final_attrs["search_icon"] = ( 47 | fb_settings.URL_FILEBROWSER_MEDIA + "img/filebrowser_icon_show.gif" 48 | ) 49 | final_attrs["directory"] = directory 50 | final_attrs["extensions"] = self.extensions 51 | final_attrs["format"] = self.format 52 | final_attrs["DEBUG"] = fb_settings.DEBUG 53 | if renderer is not None: 54 | return mark_safe( 55 | renderer.render( 56 | "filebrowser/custom_field.html", 57 | dict(locals(), MEDIA_URL=fb_settings.MEDIA_URL), 58 | ) 59 | ) 60 | else: 61 | return render_to_string( 62 | "filebrowser/custom_field.html", 63 | dict(locals(), MEDIA_URL=fb_settings.MEDIA_URL), 64 | ) 65 | 66 | 67 | class FileBrowseFormField(forms.CharField): 68 | widget = FileBrowseWidget 69 | 70 | default_error_messages = { 71 | "extension": _( 72 | "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 73 | ), 74 | } 75 | 76 | def __init__( 77 | self, 78 | max_length=None, 79 | min_length=None, 80 | directory=None, 81 | extensions=None, 82 | format=None, 83 | *args, 84 | **kwargs 85 | ): 86 | self.max_length, self.min_length = max_length, min_length 87 | self.directory = directory 88 | self.extensions = extensions 89 | if format: 90 | self.format = format or "" 91 | self.extensions = extensions or fb_settings.EXTENSIONS.get(format) 92 | super().__init__(*args, **kwargs) 93 | 94 | def clean(self, value): 95 | value = super().clean(value) 96 | if value == "": 97 | return value 98 | file_extension = os.path.splitext(value)[1].lower().split("?")[0] 99 | if self.extensions and file_extension not in self.extensions: 100 | raise forms.ValidationError( 101 | self.error_messages["extension"] 102 | % {"ext": file_extension, "allowed": ", ".join(self.extensions)} 103 | ) 104 | return value 105 | 106 | 107 | class FileBrowseField(Field): 108 | # These attributes control how the field is accessed on a model instance. 109 | # Due to contribute_to_class, FileDescriptor will cause this field to be 110 | # represented by a FileFieldObject on model instances. 111 | # Adapted from django.db.models.fields.files.FileField. 112 | attr_class = FieldFileObject 113 | descriptor_class = FileDescriptor 114 | 115 | def __init__(self, *args, **kwargs): 116 | self.directory = kwargs.pop("directory", "") 117 | self.extensions = kwargs.pop("extensions", "") 118 | self.format = kwargs.pop("format", "") 119 | self.storage = kwargs.pop("storage", default_storage) 120 | super().__init__(*args, **kwargs) 121 | 122 | def get_db_prep_value(self, value, connection, prepared=False): 123 | if value is None: 124 | return None 125 | return smart_str(value) 126 | 127 | def get_manipulator_field_objs(self): 128 | return [forms.TextField] 129 | 130 | def get_internal_type(self): 131 | return "CharField" 132 | 133 | def formfield(self, **kwargs): 134 | attrs = { 135 | "directory": self.directory, 136 | "extensions": self.extensions, 137 | "format": self.format, 138 | "storage": self.storage, 139 | } 140 | defaults = { 141 | "form_class": FileBrowseFormField, 142 | "widget": FileBrowseWidget(attrs=attrs), 143 | "directory": self.directory, 144 | "extensions": self.extensions, 145 | "format": self.format, 146 | } 147 | defaults.update(kwargs) 148 | return super().formfield(**defaults) 149 | 150 | def contribute_to_class(self, cls, name, **kwargs): 151 | """ 152 | From django.db.models.fields.files.FileField.contribute_to_class 153 | """ 154 | super().contribute_to_class(cls, name, **kwargs) 155 | setattr(cls, self.name, self.descriptor_class(self)) 156 | -------------------------------------------------------------------------------- /filebrowser_safe/forms.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | from django import forms 5 | from django.utils.translation import gettext as _ 6 | 7 | from filebrowser_safe.settings import FOLDER_REGEX 8 | 9 | # coding: utf-8 10 | 11 | ALLOWED_CHARS_MSG = ( 12 | "Only letters, numbers, underscores, spaces and hyphens are allowed." 13 | ) 14 | 15 | alnum_name_re = re.compile(FOLDER_REGEX) 16 | 17 | 18 | class MakeDirForm(forms.Form): 19 | """ 20 | Form for creating Folder. 21 | """ 22 | 23 | def __init__(self, path, *args, **kwargs): 24 | self.path = path 25 | super().__init__(*args, **kwargs) 26 | 27 | dir_name = forms.CharField( 28 | widget=forms.TextInput( 29 | attrs=dict({"class": "vTextField"}, max_length=50, min_length=3) 30 | ), 31 | label=_("Name"), 32 | help_text=_(ALLOWED_CHARS_MSG), 33 | required=True, 34 | ) 35 | 36 | def clean_dir_name(self): 37 | if self.cleaned_data["dir_name"]: 38 | # only letters, numbers, underscores, spaces and hyphens are allowed. 39 | if not alnum_name_re.search(self.cleaned_data["dir_name"]): 40 | raise forms.ValidationError(_(ALLOWED_CHARS_MSG)) 41 | # Folder must not already exist. 42 | if os.path.isdir(os.path.join(self.path, self.cleaned_data["dir_name"])): 43 | raise forms.ValidationError(_("The Folder already exists.")) 44 | return self.cleaned_data["dir_name"] 45 | 46 | 47 | class RenameForm(forms.Form): 48 | """ 49 | Form for renaming Folder/File. 50 | """ 51 | 52 | def __init__(self, path, file_extension, *args, **kwargs): 53 | self.path = path 54 | self.file_extension = file_extension 55 | super().__init__(*args, **kwargs) 56 | 57 | name = forms.CharField( 58 | widget=forms.TextInput( 59 | attrs=dict({"class": "vTextField"}, max_length=50, min_length=3) 60 | ), 61 | label=_("New Name"), 62 | help_text=_(ALLOWED_CHARS_MSG), 63 | required=True, 64 | ) 65 | 66 | def clean_name(self): 67 | if self.cleaned_data["name"]: 68 | # only letters, numbers, underscores, spaces and hyphens are allowed. 69 | if not alnum_name_re.search( 70 | self.cleaned_data["name"] 71 | ) or not alnum_name_re.search(self.path): 72 | raise forms.ValidationError(_(ALLOWED_CHARS_MSG)) 73 | # folder/file must not already exist. 74 | if os.path.isdir(os.path.join(self.path, self.cleaned_data["name"])): 75 | raise forms.ValidationError(_("The Folder already exists.")) 76 | elif os.path.isfile( 77 | os.path.join(self.path, self.cleaned_data["name"] + self.file_extension) 78 | ): 79 | raise forms.ValidationError(_("The File already exists.")) 80 | return self.cleaned_data["name"] 81 | -------------------------------------------------------------------------------- /filebrowser_safe/functions.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import unicodedata 4 | import warnings 5 | from time import gmtime, localtime, strftime, time 6 | 7 | from django.conf import settings as dj_settings 8 | from django.core.files.storage import default_storage 9 | 10 | from filebrowser_safe import settings as fb_settings 11 | 12 | try: 13 | from mezzanine.utils.sites import current_site_id 14 | except ImportError: 15 | # TODO: filebrowser-safe should not rely on `current_site_id` at all since its 16 | # provided by Mezzanine. 17 | # 18 | # For now we just want to be able tu run the test suite without having mezzanine 19 | # installed, and this will do. Remove once filebrowser-safe is completely decoupled 20 | # from mezzanine. 21 | warnings.warn( 22 | """ 23 | You are using a placeholder implementation of the current_site_id function 24 | intended for test purposes only. If you're seeing this you might have a problem 25 | with your Mezzanine installation. 26 | """ 27 | ) 28 | 29 | def current_site_id(): 30 | return dj_settings.SITE_ID 31 | 32 | 33 | def get_directory(): 34 | """ 35 | Returns FB's ``DIRECTORY`` setting, appending a directory using 36 | the site's ID if ``MEDIA_LIBRARY_PER_SITE`` is ``True``, and also 37 | creating the root directory if missing. 38 | """ 39 | 40 | dirname = fb_settings.DIRECTORY 41 | if getattr(dj_settings, "MEDIA_LIBRARY_PER_SITE", False): 42 | dirname = os.path.join(dirname, "site-%s" % current_site_id()) 43 | fullpath = os.path.join(dj_settings.MEDIA_ROOT, dirname) 44 | if not default_storage.isdir(fullpath): 45 | default_storage.makedirs(fullpath) 46 | return dirname 47 | 48 | 49 | def path_strip(path, root): 50 | if not path or not root: 51 | return path 52 | path = os.path.normcase(path) 53 | root = os.path.normcase(root) 54 | if path.startswith(root): 55 | return path[len(root) :] 56 | return path 57 | 58 | 59 | def path_to_url(value): 60 | """ 61 | Change PATH to URL. 62 | Value has to be a PATH relative to MEDIA_ROOT. 63 | 64 | Return an URL relative to MEDIA_ROOT. 65 | """ 66 | mediaroot_re = re.compile(r"^(%s)" % (fb_settings.MEDIA_ROOT)) 67 | value = mediaroot_re.sub("", value) 68 | return url_join(fb_settings.MEDIA_URL, value) 69 | 70 | 71 | def dir_from_url(value): 72 | """ 73 | Get the relative server directory from a URL. 74 | URL has to be an absolute URL including MEDIA_URL or 75 | an URL relative to MEDIA_URL. 76 | """ 77 | mediaurl_re = re.compile(r"^(%s)" % (fb_settings.MEDIA_URL)) 78 | value = mediaurl_re.sub("", value) 79 | directory_re = re.compile(r"^(%s)" % (get_directory())) 80 | value = directory_re.sub("", value) 81 | return os.path.split(value)[0] 82 | 83 | 84 | def url_join(*args): 85 | """ 86 | URL join routine. 87 | """ 88 | if args[0].startswith("http://"): 89 | url = "http://" 90 | else: 91 | url = "/" 92 | for arg in args: 93 | arg = str(arg).replace("\\", "/") 94 | arg_split = arg.split("/") 95 | for elem in arg_split: 96 | if elem != "" and elem != "http:": 97 | url = url + elem + "/" 98 | # remove trailing slash for filenames 99 | if os.path.splitext(args[-1])[1]: 100 | url = url.rstrip("/") 101 | return url 102 | 103 | 104 | def get_path(path): 105 | """ 106 | Get Path. 107 | """ 108 | if ( 109 | path.startswith(".") 110 | or "../" in path 111 | or os.path.isabs(path) 112 | or not default_storage.isdir(os.path.join(get_directory(), path)) 113 | ): 114 | return None 115 | return path 116 | 117 | 118 | def get_file(path, filename): 119 | """ 120 | Get File. 121 | """ 122 | if not default_storage.exists(os.path.join(get_directory(), path, filename)): 123 | return None 124 | return filename 125 | 126 | 127 | def get_breadcrumbs(query, path): 128 | """ 129 | Get breadcrumbs. 130 | """ 131 | breadcrumbs = [] 132 | dir_query = "" 133 | if path: 134 | for item in path.split(os.sep): 135 | dir_query = os.path.join(dir_query, item) 136 | breadcrumbs.append([item, dir_query]) 137 | return breadcrumbs 138 | 139 | 140 | def get_filterdate(filterDate, dateTime): 141 | """ 142 | Get filterdate. 143 | """ 144 | returnvalue = "" 145 | dateYear = strftime("%Y", gmtime(dateTime)) 146 | dateMonth = strftime("%m", gmtime(dateTime)) 147 | dateDay = strftime("%d", gmtime(dateTime)) 148 | if ( 149 | filterDate == "today" 150 | and int(dateYear) == int(localtime()[0]) 151 | and int(dateMonth) == int(localtime()[1]) 152 | and int(dateDay) == int(localtime()[2]) 153 | ): 154 | returnvalue = "true" 155 | elif filterDate == "thismonth" and dateTime >= time() - 2592000: 156 | returnvalue = "true" 157 | elif filterDate == "thisyear" and int(dateYear) == int(localtime()[0]): 158 | returnvalue = "true" 159 | elif filterDate == "past7days" and dateTime >= time() - 604800: 160 | returnvalue = "true" 161 | elif filterDate == "": 162 | returnvalue = "true" 163 | return returnvalue 164 | 165 | 166 | def get_settings_var(): 167 | """ 168 | Get settings variables used for FileBrowser listing. 169 | """ 170 | settings_var = {} 171 | # Main 172 | settings_var["DEBUG"] = fb_settings.DEBUG 173 | settings_var["MEDIA_ROOT"] = fb_settings.MEDIA_ROOT 174 | settings_var["MEDIA_URL"] = fb_settings.MEDIA_URL 175 | settings_var["DIRECTORY"] = get_directory() 176 | # FileBrowser 177 | settings_var["URL_FILEBROWSER_MEDIA"] = fb_settings.URL_FILEBROWSER_MEDIA 178 | settings_var["PATH_FILEBROWSER_MEDIA"] = fb_settings.PATH_FILEBROWSER_MEDIA 179 | # TinyMCE 180 | settings_var["URL_TINYMCE"] = fb_settings.URL_TINYMCE 181 | settings_var["PATH_TINYMCE"] = fb_settings.PATH_TINYMCE 182 | # Extensions/Formats (for FileBrowseField) 183 | settings_var["EXTENSIONS"] = fb_settings.EXTENSIONS 184 | settings_var["SELECT_FORMATS"] = fb_settings.SELECT_FORMATS 185 | # FileBrowser Options 186 | settings_var["MAX_UPLOAD_SIZE"] = fb_settings.MAX_UPLOAD_SIZE 187 | # Convert Filenames 188 | settings_var["CONVERT_FILENAME"] = fb_settings.CONVERT_FILENAME 189 | return settings_var 190 | 191 | 192 | def get_file_type(filename): 193 | """ 194 | Get file type as defined in EXTENSIONS. 195 | """ 196 | file_extension = os.path.splitext(filename)[1].lower() 197 | file_type = "" 198 | for k, v in fb_settings.EXTENSIONS.items(): 199 | for extension in v: 200 | if file_extension == extension.lower(): 201 | file_type = k 202 | return file_type 203 | 204 | 205 | def is_selectable(filename, selecttype): 206 | """ 207 | Get select type as defined in FORMATS. 208 | """ 209 | file_extension = os.path.splitext(filename)[1].lower() 210 | select_types = [] 211 | for k, v in fb_settings.SELECT_FORMATS.items(): 212 | for extension in v: 213 | if file_extension == extension.lower(): 214 | select_types.append(k) 215 | return select_types 216 | 217 | 218 | def convert_filename(value): 219 | """ 220 | Convert Filename. 221 | https://github.com/sehmaschine/django-filebrowser/blob/master/filebrowser/functions.py 222 | """ 223 | 224 | if fb_settings.NORMALIZE_FILENAME: 225 | chunks = value.split(os.extsep) 226 | normalized = [] 227 | 228 | for v in chunks: 229 | v = ( 230 | unicodedata.normalize("NFKD", str(v)) 231 | .encode("ascii", "ignore") 232 | .decode("ascii") 233 | ) 234 | v = re.sub(r"[^\w\s-]", "", v).strip() 235 | normalized.append(v) 236 | 237 | if len(normalized) > 1: 238 | value = ".".join(normalized) 239 | else: 240 | value = normalized[0] 241 | 242 | if fb_settings.CONVERT_FILENAME: 243 | value = value.replace(" ", "_").lower() 244 | 245 | return value 246 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/ar/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/ar/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/ar/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: FileBrowser-safe\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2013-01-12 19:48-0500\n" 11 | "PO-Revision-Date: 2013-01-12 20:16-0500\n" 12 | "Last-Translator: Ahmad Khayyat \n" 13 | "Language-Team: ar\n" 14 | "Language: ar\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5\n" 19 | "X-Poedit-Language: ar\n" 20 | 21 | #: fields.py:57 22 | #, python-format 23 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 24 | msgstr "الامتداد %(ext)s غير مسموح به. يمكنك فقط استخدام هذه الامتدادات: %(allowed)s." 25 | 26 | #: forms.py:26 27 | msgid "Name" 28 | msgstr "الاسم" 29 | 30 | #: forms.py:26 31 | #: forms.py:32 32 | #: forms.py:49 33 | #: forms.py:55 34 | msgid "Only letters, numbers, underscores, spaces and hyphens are allowed." 35 | msgstr "يمكنك فقط استخدام الحروف والأرقام والخط السفلي (_) والمسافات والشرطات (-)." 36 | 37 | #: forms.py:35 38 | #: forms.py:58 39 | msgid "The Folder already exists." 40 | msgstr "هذا المجلد موجود حالياً." 41 | 42 | #: forms.py:49 43 | msgid "New Name" 44 | msgstr "الاسم الجديد" 45 | 46 | #: forms.py:60 47 | msgid "The File already exists." 48 | msgstr "هذا الملف موجود حالياً." 49 | 50 | #: settings.py:126 51 | msgid "Folder" 52 | msgstr "مجلد" 53 | 54 | #: settings.py:127 55 | msgid "Image" 56 | msgstr "صورة" 57 | 58 | #: settings.py:128 59 | msgid "Video" 60 | msgstr "فيديو" 61 | 62 | #: settings.py:129 63 | msgid "Document" 64 | msgstr "مستند" 65 | 66 | #: settings.py:130 67 | msgid "Audio" 68 | msgstr "صوت" 69 | 70 | #: settings.py:131 71 | msgid "Code" 72 | msgstr "شفرة" 73 | 74 | #: views.py:72 75 | #: views.py:182 76 | #: views.py:236 77 | #: views.py:332 78 | #: views.py:391 79 | msgid "The requested Folder does not exist." 80 | msgstr "المجلد المطلوب غير موجود." 81 | 82 | #: views.py:76 83 | msgid "Error finding Upload-Folder. Maybe it does not exist?" 84 | msgstr "حصل خطأ أثناء محاولة العثور على مجلد الرفع. هل أنت متأكد من أنه موجود؟" 85 | 86 | #: views.py:159 87 | #: templates/filebrowser/include/breadcrumbs.html:6 88 | #: templates/filebrowser/include/breadcrumbs.html:8 89 | msgid "Media Library" 90 | msgstr "مكتبة الوسائط" 91 | 92 | #: views.py:199 93 | #, python-format 94 | msgid "The Folder %s was successfully created." 95 | msgstr "تم إنشاء المجلد %s بنجاح." 96 | 97 | #: views.py:208 98 | msgid "Permission denied." 99 | msgstr "أنت غير مصرح لك بهذه العملية." 100 | 101 | #: views.py:210 102 | msgid "Error creating folder." 103 | msgstr "حصل خطأ أثناء إنشاء المجلد." 104 | 105 | #: views.py:217 106 | #: views.py:220 107 | #: templates/filebrowser/index.html:54 108 | msgid "New Folder" 109 | msgstr "مجلد جديد" 110 | 111 | #: views.py:247 112 | msgid "Select files to upload" 113 | msgstr "اختر ملفات لرفعها" 114 | 115 | #: views.py:251 116 | #: templates/filebrowser/index.html:55 117 | #: templates/filebrowser/upload.html:118 118 | msgid "Upload" 119 | msgstr "رفع" 120 | 121 | #: views.py:334 122 | #: views.py:393 123 | msgid "The requested File does not exist." 124 | msgstr "الملف المطلوب غير موجود." 125 | 126 | #: views.py:348 127 | #, python-format 128 | msgid "The file %s was successfully deleted." 129 | msgstr "تم حذف الملف %s بنجاح." 130 | 131 | #: views.py:351 132 | #: views.py:365 133 | msgid "An error occurred" 134 | msgstr "حصل خطأ" 135 | 136 | #: views.py:362 137 | #, python-format 138 | msgid "The folder %s was successfully deleted." 139 | msgstr "تم حذف المجلد %s بنجاح." 140 | 141 | #: views.py:413 142 | msgid "Renaming was successful." 143 | msgstr "تم تغيير الاسم بنجاح." 144 | 145 | #: views.py:418 146 | msgid "Error." 147 | msgstr "خطأ." 148 | 149 | #: views.py:426 150 | #, python-format 151 | msgid "Rename \"%s\"" 152 | msgstr "تغيير اسم \"%s\"" 153 | 154 | #: views.py:429 155 | #: templates/filebrowser/include/filelisting.html:83 156 | msgid "Rename" 157 | msgstr "إعادة التسمية" 158 | 159 | #: templates/filebrowser/append.html:5 160 | #: templates/filebrowser/append.html:7 161 | msgid "FileBrowser" 162 | msgstr "" 163 | 164 | #: templates/filebrowser/custom_field.html:27 165 | msgid "Clear" 166 | msgstr "مسح" 167 | 168 | #: templates/filebrowser/makedir.html:25 169 | #: templates/filebrowser/rename.html:26 170 | msgid "Please correct the following errors." 171 | msgstr "فضلاً صحح الأخطاء التالية." 172 | 173 | #: templates/filebrowser/makedir.html:33 174 | #: templates/filebrowser/upload.html:108 175 | msgid "The Name will be converted to lowercase. Spaces will be replaced with underscores." 176 | msgstr "سيتم استبدال المسافات بخطوط سفلية." 177 | 178 | #: templates/filebrowser/makedir.html:38 179 | #: templates/filebrowser/rename.html:37 180 | msgid "Submit" 181 | msgstr "تسليم" 182 | 183 | #: templates/filebrowser/upload.html:52 184 | msgid "BROWSE" 185 | msgstr "تصفح" 186 | 187 | #: templates/filebrowser/upload.html:53 188 | msgid "An Error occured" 189 | msgstr "حصل خطأ" 190 | 191 | #: templates/filebrowser/upload.html:54 192 | msgid "Completed" 193 | msgstr "تم" 194 | 195 | #: templates/filebrowser/upload.html:55 196 | msgid "Do you want to replace the file" 197 | msgstr "هل تريد استبدال الملف" 198 | 199 | #: templates/filebrowser/upload.html:56 200 | msgid "KB" 201 | msgstr "" 202 | 203 | #: templates/filebrowser/upload.html:57 204 | msgid "MB" 205 | msgstr "" 206 | 207 | #: templates/filebrowser/upload.html:91 208 | msgid "Help" 209 | msgstr "مساعدة" 210 | 211 | #: templates/filebrowser/upload.html:95 212 | msgid "Allowed" 213 | msgstr "مسموح" 214 | 215 | #: templates/filebrowser/upload.html:101 216 | msgid "Max. Filesize" 217 | msgstr "حجم الملف الأقصى" 218 | 219 | #: templates/filebrowser/upload.html:116 220 | msgid "Clear Queue" 221 | msgstr "" 222 | 223 | #: templates/filebrowser/include/filelisting.html:12 224 | msgid "Select" 225 | msgstr "اختر" 226 | 227 | #: templates/filebrowser/include/filelisting.html:26 228 | #: templates/filebrowser/include/filelisting.html:40 229 | #: templates/filebrowser/include/filelisting.html:54 230 | msgid "Select File" 231 | msgstr "اختر ملفاً" 232 | 233 | #: templates/filebrowser/include/filelisting.html:70 234 | msgid "View Image" 235 | msgstr "عرض الصورة" 236 | 237 | #: templates/filebrowser/include/filelisting.html:95 238 | msgid "Are you sure you want to delete this file?" 239 | msgstr "هل أنت متأكد من أنك تريد حذف هذا الملف؟" 240 | 241 | #: templates/filebrowser/include/filelisting.html:95 242 | msgid "Delete File" 243 | msgstr "حذف الملف" 244 | 245 | #: templates/filebrowser/include/filelisting.html:98 246 | msgid "Are you sure you want to delete this Folder?" 247 | msgstr "هل أنت متأكد من أنك تريد حذف هذا المجلد؟" 248 | 249 | #: templates/filebrowser/include/filelisting.html:98 250 | msgid "Delete Folder" 251 | msgstr "حذف المجلد" 252 | 253 | #: templates/filebrowser/include/filter.html:3 254 | msgid "Filter" 255 | msgstr "مرشّح" 256 | 257 | #: templates/filebrowser/include/filter.html:9 258 | msgid "By Date" 259 | msgstr "حسب التاريخ" 260 | 261 | #: templates/filebrowser/include/filter.html:11 262 | msgid "Any Date" 263 | msgstr "أي تاريخ" 264 | 265 | #: templates/filebrowser/include/filter.html:13 266 | msgid "Today" 267 | msgstr "اليوم" 268 | 269 | #: templates/filebrowser/include/filter.html:15 270 | msgid "Past 7 days" 271 | msgstr "٧ أيام الماضية" 272 | 273 | #: templates/filebrowser/include/filter.html:17 274 | msgid "Past 30 days" 275 | msgstr "٣٠ يوماً الماضية" 276 | 277 | #: templates/filebrowser/include/filter.html:19 278 | msgid "This year" 279 | msgstr "هذا العام" 280 | 281 | #: templates/filebrowser/include/filter.html:27 282 | msgid "By Type" 283 | msgstr "حسب النوع" 284 | 285 | #: templates/filebrowser/include/filter.html:29 286 | msgid "All" 287 | msgstr "الجميع" 288 | 289 | #: templates/filebrowser/include/paginator.html:5 290 | msgid "No Items Found" 291 | msgstr "لم يتم العثور على شيء" 292 | 293 | #: templates/filebrowser/include/paginator.html:11 294 | #, python-format 295 | msgid "%(counter)s Item" 296 | msgid_plural "%(counter)s Items" 297 | msgstr[0] "لا يوجد شيء" 298 | msgstr[1] "عنصر واحد" 299 | msgstr[2] "عنصران" 300 | msgstr[3] "%(counter)s عناصر" 301 | msgstr[4] "%(counter)s عنصراً" 302 | msgstr[5] "%(counter)s عنصر" 303 | 304 | #: templates/filebrowser/include/paginator.html:26 305 | msgid "No Items" 306 | msgstr "لا يوجد شيء" 307 | 308 | #: templates/filebrowser/include/search.html:3 309 | #, python-format 310 | msgid "1 result" 311 | msgid_plural "%(counter)s results" 312 | msgstr[0] "لا يوجد نتائج" 313 | msgstr[1] "نتيجة واحدة" 314 | msgstr[2] "نتيجتان" 315 | msgstr[3] "%(counter)s نتائج" 316 | msgstr[4] "%(counter)s نتيجة" 317 | msgstr[5] "%(counter)s نتيجة" 318 | 319 | #: templates/filebrowser/include/search.html:4 320 | #: templates/filebrowser/include/toolbar.html:9 321 | #, python-format 322 | msgid "%(full_result_count)s total" 323 | msgstr "المجموع: %(full_result_count)s" 324 | 325 | #: templates/filebrowser/include/search.html:5 326 | msgid "Clear Restrictions" 327 | msgstr "إزالة القيود" 328 | 329 | #: templates/filebrowser/include/search.html:7 330 | #: templates/filebrowser/include/toolbar.html:16 331 | msgid "Search" 332 | msgstr "بحث" 333 | 334 | #: templates/filebrowser/include/search.html:19 335 | msgid "Go" 336 | msgstr "انطلق" 337 | 338 | #: templates/filebrowser/include/search.html:24 339 | #, python-format 340 | msgid "%(counter)s Item found" 341 | msgid_plural "%(counter)s Items found" 342 | msgstr[0] "لم بتم العثور على شيء" 343 | msgstr[1] "تم العثور على عنصر واحد" 344 | msgstr[2] "تم العثور على عنصرين" 345 | msgstr[3] "تم العثور على %(counter)s عناصر" 346 | msgstr[4] "تم العثور على %(counter)s عنصراً" 347 | msgstr[5] "تم العثور على %(counter)s عنصر" 348 | 349 | #: templates/filebrowser/include/search.html:25 350 | #, python-format 351 | msgid "%(counter)s Item total" 352 | msgid_plural "%(counter)s Items total" 353 | msgstr[0] "المجموع: %(counter)s" 354 | msgstr[1] "المجموع: عنصر واحد" 355 | msgstr[2] "المجموع: عنصران" 356 | msgstr[3] "المجموع: %(counter)s عناصر" 357 | msgstr[4] "المجموع: %(counter)s عنصراً" 358 | msgstr[5] "المجموع: %(counter)s عنصر" 359 | 360 | #: templates/filebrowser/include/tableheader.html:20 361 | #: templates/filebrowser/include/tableheader.html:21 362 | msgid "Filename" 363 | msgstr "اسم الملف" 364 | 365 | #: templates/filebrowser/include/tableheader.html:25 366 | #: templates/filebrowser/include/tableheader.html:26 367 | msgid "Size" 368 | msgstr "الحجم" 369 | 370 | #: templates/filebrowser/include/tableheader.html:28 371 | #: templates/filebrowser/include/tableheader.html:29 372 | msgid "Date" 373 | msgstr "التاريخ" 374 | 375 | #: templates/filebrowser/include/toolbar.html:6 376 | msgid "Results" 377 | msgstr "النتائج" 378 | 379 | #: templates/filebrowser/include/toolbar.html:8 380 | #, python-format 381 | msgid "%(counter)s result" 382 | msgid_plural "%(counter)s results" 383 | msgstr[0] "لا يوجد نتائج" 384 | msgstr[1] "نتيجة واحدة" 385 | msgstr[2] "نتيجتان" 386 | msgstr[3] "%(counter)s نتائج" 387 | msgstr[4] "%(counter)s نتيجة" 388 | msgstr[5] "%(counter)s نتيجة" 389 | 390 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/ca/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/ca/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/ca/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # translation of django.po to Catalan 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # PATRICK KRANZLMUELLER , 2009. 6 | # Antoni Aloy , 2009. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: django\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2009-02-19 21:24+0000\n" 12 | "PO-Revision-Date: 2009-02-15 19:00+0100\n" 13 | "Last-Translator: Antoni Aloy \n" 14 | "Language-Team: Catalan \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: KBabel 1.11.4\n" 19 | 20 | #: fields.py:27 21 | #, python-format 22 | msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." 23 | msgstr "" 24 | "Confirma que aquest valor té com a màxim %(max)d caràcters (té longitud %" 25 | "(length)d)." 26 | 27 | #: fields.py:28 28 | #, python-format 29 | msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." 30 | msgstr "" 31 | "Confirma que aquest valor té com a mínim %(min)d caràcters (té longitud %" 32 | "(length)d)." 33 | 34 | #: fields.py:29 35 | #, python-format 36 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 37 | msgstr "" 38 | "L'extensió %(ext)s no està permesa. Sols es permeten les extensions %" 39 | "(allowed)s." 40 | 41 | #: forms.py:23 42 | msgid "Name" 43 | msgstr "Nom" 44 | 45 | #: forms.py:23 forms.py:46 46 | msgid "" 47 | "The Name will automatically be converted to lowercase. Only letters, " 48 | "numbers, underscores and hyphens are allowed." 49 | msgstr "" 50 | "El nom serà convertit automàticament a minúscules. Sols estan permeses le " 51 | "lletres, nombres, subratllats i guions." 52 | 53 | #: forms.py:30 forms.py:53 54 | msgid "Only letters, numbers, underscores and hyphens are allowed." 55 | msgstr "Sols es permeten lletres, nombres, subratllats i guions." 56 | 57 | #: forms.py:33 58 | msgid "The Folder already exists." 59 | msgstr "La carpeta ja existeix." 60 | 61 | #: forms.py:46 62 | msgid "New Name" 63 | msgstr "Nou nom" 64 | 65 | #: forms.py:56 66 | msgid "The File/Folder already exists." 67 | msgstr "La carpeta/arixu ja existeix" 68 | 69 | #: forms.py:92 70 | msgid "File" 71 | msgstr "Arxiu" 72 | 73 | #: forms.py:93 74 | msgid "Use Image Generator" 75 | msgstr "Fer servir el generador d'imatges" 76 | 77 | #: forms.py:102 78 | msgid "File already exists." 79 | msgstr "L'arxiu ja existeix" 80 | 81 | #: forms.py:108 82 | msgid "Filename is not allowed." 83 | msgstr "El nom d'arxiu no està permès" 84 | 85 | #: forms.py:113 86 | msgid "File extension is not allowed." 87 | msgstr "L'extensió de l'arxiu no està permesa" 88 | 89 | #: forms.py:118 90 | msgid "Filesize exceeds allowed Upload Size." 91 | msgstr "El tamany de l'arxiu supera el límit permès" 92 | 93 | #: functions.py:84 94 | msgid "Home" 95 | msgstr "Inici" 96 | 97 | #: functions.py:276 98 | msgid "Thumbnail creation failed." 99 | msgstr "Ha fallat la creació de la miniatura" 100 | 101 | #: functions.py:331 functions.py:398 102 | msgid "Image creation failed." 103 | msgstr "La creació de la imatge ha fallat" 104 | 105 | #: views.py:165 106 | msgid "FileBrowser" 107 | msgstr "Visor d'arxius" 108 | 109 | #: views.py:188 110 | #, python-format 111 | msgid "The Folder %s was successfully created." 112 | msgstr "La carpeta %s ha estat creada amb èxit." 113 | 114 | #: views.py:194 115 | msgid "Permission denied." 116 | msgstr "Permís denegat." 117 | 118 | #: views.py:196 119 | msgid "Error creating directory." 120 | msgstr "Error creant el directori." 121 | 122 | #: views.py:204 views.py:205 templates/filebrowser/index.html:30 123 | msgid "New Folder" 124 | msgstr "Nova carpeta" 125 | 126 | #: views.py:250 127 | msgid "Upload successful." 128 | msgstr "Pujada completada" 129 | 130 | #: views.py:263 templates/filebrowser/index.html:33 131 | #: templates/filebrowser/upload.html:62 132 | msgid "Upload" 133 | msgstr "Pujar" 134 | 135 | #: views.py:264 136 | msgid "Select files to upload" 137 | msgstr "Selecciona arxius a pujar." 138 | 139 | #: views.py:294 140 | msgid "Thumbnail creation successful." 141 | msgstr "S'han creat les miniatures satisfactòriament." 142 | 143 | #: views.py:344 144 | #, python-format 145 | msgid "The file %s was successfully deleted." 146 | msgstr "L'arxiu %s ha estat borrat amb èxit." 147 | 148 | #: views.py:356 149 | #, python-format 150 | msgid "The directory %s was successfully deleted." 151 | msgstr "El directori %s ha estat borrat amb èxit." 152 | 153 | #: views.py:407 154 | msgid "Error renaming Thumbnail." 155 | msgstr "Error reanomenant la miniatura" 156 | 157 | #: views.py:413 158 | msgid "Renaming was successful." 159 | msgstr "El canvi de nom ha tingut èxit." 160 | 161 | #: views.py:418 162 | msgid "Error." 163 | msgstr "Error." 164 | 165 | #: views.py:427 templates/filebrowser/include/filelisting.html:52 166 | msgid "Rename" 167 | msgstr "Reanomenar" 168 | 169 | #: views.py:428 170 | #, python-format 171 | msgid "Rename \"%s\"" 172 | msgstr "Reanomena \"%s\"" 173 | 174 | #: views.py:465 175 | msgid "Successfully generated Images." 176 | msgstr "Imatges generades satisfactòriament." 177 | 178 | #: templates/filebrowser/index.html:31 179 | msgid "Make Thumbs" 180 | msgstr "Crear miniatures" 181 | 182 | #: templates/filebrowser/index.html:32 183 | msgid "Generate Images" 184 | msgstr "Generar imatges" 185 | 186 | #: templates/filebrowser/makedir.html:24 templates/filebrowser/rename.html:22 187 | msgid "Please correct the following errors." 188 | msgstr "Per favor, corregeix els següents errors" 189 | 190 | #: templates/filebrowser/makedir.html:34 templates/filebrowser/rename.html:33 191 | msgid "Submit" 192 | msgstr "Enviar" 193 | 194 | #: templates/filebrowser/upload.html:37 195 | msgid "Will use image generator." 196 | msgstr "Usaré el generador d'imatges" 197 | 198 | #: templates/filebrowser/upload.html:47 199 | msgid "Help" 200 | msgstr "Ajuda" 201 | 202 | #: templates/filebrowser/upload.html:51 203 | msgid "Allowed" 204 | msgstr "Permès" 205 | 206 | #: templates/filebrowser/upload.html:57 207 | msgid "Max. Filesize" 208 | msgstr "Tamay màxim" 209 | 210 | #: templates/filebrowser/include/filelisting.html:8 211 | msgid "Select" 212 | msgstr "Selecciona" 213 | 214 | #: templates/filebrowser/include/filelisting.html:15 215 | msgid "Select File" 216 | msgstr "Selecciona fitxer" 217 | 218 | #: templates/filebrowser/include/filelisting.html:26 219 | msgid "Make Thumbnail" 220 | msgstr "Crear miniatura" 221 | 222 | #: templates/filebrowser/include/filelisting.html:29 223 | msgid "View Image" 224 | msgstr "Veure imatge" 225 | 226 | #: templates/filebrowser/include/filelisting.html:46 227 | msgid "Generate Image Versions" 228 | msgstr "Generar versions de la imatge" 229 | 230 | #: templates/filebrowser/include/filelisting.html:61 231 | msgid "Are you sure you want to delete this file?" 232 | msgstr "" 233 | 234 | #: templates/filebrowser/include/filelisting.html:61 235 | msgid "Delete File" 236 | msgstr "Esborrar fitxer" 237 | 238 | #: templates/filebrowser/include/filelisting.html:64 239 | msgid "Are you sure you want to delete this Folder?" 240 | msgstr "" 241 | 242 | #: templates/filebrowser/include/filelisting.html:64 243 | msgid "Delete Folder" 244 | msgstr "Esborrar carpeta" 245 | 246 | #: templates/filebrowser/include/filter.html:15 247 | msgid "Filter" 248 | msgstr "Filtrar" 249 | 250 | #: templates/filebrowser/include/filter.html:21 251 | msgid "By Date" 252 | msgstr "Per data" 253 | 254 | #: templates/filebrowser/include/filter.html:23 255 | msgid "Any Date" 256 | msgstr "Qualsevol data" 257 | 258 | #: templates/filebrowser/include/filter.html:25 259 | msgid "Today" 260 | msgstr "Avui" 261 | 262 | #: templates/filebrowser/include/filter.html:27 263 | msgid "Past 7 days" 264 | msgstr "Fa 7 dies" 265 | 266 | #: templates/filebrowser/include/filter.html:29 267 | msgid "Past 30 days" 268 | msgstr "Fa 30 dies" 269 | 270 | #: templates/filebrowser/include/filter.html:31 271 | msgid "This year" 272 | msgstr "Enguany" 273 | 274 | #: templates/filebrowser/include/filter.html:39 275 | msgid "By Type" 276 | msgstr "Per tipus" 277 | 278 | #: templates/filebrowser/include/filter.html:41 279 | msgid "All" 280 | msgstr "Tots" 281 | 282 | #: templates/filebrowser/include/paginator.html:5 283 | msgid "No Items Found." 284 | msgstr "No s'han trobat items" 285 | 286 | #: templates/filebrowser/include/paginator.html:10 287 | #, python-format 288 | msgid "%(counter)s Item" 289 | msgid_plural "%(counter)s Items" 290 | msgstr[0] "%(counter)s Item" 291 | msgstr[1] "%(counter)s Item" 292 | 293 | #: templates/filebrowser/include/paginator.html:16 294 | msgid "No Items." 295 | msgstr "No hi ha items" 296 | 297 | #: templates/filebrowser/include/tableheader.html:13 298 | #: templates/filebrowser/include/tableheader.html:14 299 | msgid "Filename" 300 | msgstr "Nom de fitxer" 301 | 302 | #: templates/filebrowser/include/tableheader.html:20 303 | #: templates/filebrowser/include/tableheader.html:21 304 | msgid "Size" 305 | msgstr "Tamany" 306 | 307 | #: templates/filebrowser/include/tableheader.html:23 308 | #: templates/filebrowser/include/tableheader.html:24 309 | msgid "Date" 310 | msgstr "Data" 311 | 312 | #: templates/filebrowser/include/toolbar.html:14 313 | msgid "Go" 314 | msgstr "Ves" 315 | 316 | #: templates/filebrowser/include/toolbar.html:16 317 | #, python-format 318 | msgid "%(counter)s Item found" 319 | msgid_plural "%(counter)s Items found" 320 | msgstr[0] "%(counter)s trobat" 321 | msgstr[1] "%(counter)s trobats" 322 | 323 | #: templates/filebrowser/include/toolbar.html:17 324 | #, python-format 325 | msgid "%(counter)s Item total" 326 | msgid_plural "%(counter)s Items total" 327 | msgstr[0] "total %(counter)s item" 328 | msgstr[1] "total %(counter)s Items" 329 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/cs/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/cs/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/de/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/de/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/es/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/es/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/es/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # translation of django.po to Spanish 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # PATRICK KRANZLMUELLER , 2009. 6 | # Antoni Aloy , 2009. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: django\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2009-02-19 21:24+0000\n" 12 | "PO-Revision-Date: 2009-02-15 19:14+0100\n" 13 | "Last-Translator: Antoni Aloy \n" 14 | "Language-Team: Spanish\n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | "X-Generator: KBabel 1.11.4\n" 19 | 20 | #: fields.py:27 21 | #, python-format 22 | msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." 23 | msgstr "" 24 | "Compruebe que este valor tiene como máximo %(max)d carácters (tiene %(length)" 25 | "d)." 26 | 27 | #: fields.py:28 28 | #, python-format 29 | msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." 30 | msgstr "" 31 | "Compruebe que este valor tiene como mínimo %(min)d carácteres (tiene %" 32 | "(length)d)." 33 | 34 | #: fields.py:29 35 | #, python-format 36 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 37 | msgstr "" 38 | "La extensión %(ext)s no está permitida. Sólo se permiten las extensiones %" 39 | "(allowed)s." 40 | 41 | #: forms.py:23 42 | msgid "Name" 43 | msgstr "Nombre" 44 | 45 | #: forms.py:23 forms.py:46 46 | msgid "" 47 | "The Name will automatically be converted to lowercase. Only letters, " 48 | "numbers, underscores and hyphens are allowed." 49 | msgstr "" 50 | "El nombre se convertirá automáticamente a minúsculas. Sólo se permiten " 51 | "letras, números, subrayado y guiones." 52 | 53 | #: forms.py:30 forms.py:53 54 | msgid "Only letters, numbers, underscores and hyphens are allowed." 55 | msgstr "Sólo se permiten letras, números, subrayado y guiones." 56 | 57 | #: forms.py:33 58 | msgid "The Folder already exists." 59 | msgstr "La carpeta ya existe." 60 | 61 | #: forms.py:46 62 | msgid "New Name" 63 | msgstr "Nuevo nombre" 64 | 65 | #: forms.py:56 66 | msgid "The File/Folder already exists." 67 | msgstr "El archivo/carpeta ya existe." 68 | 69 | #: forms.py:92 70 | msgid "File" 71 | msgstr "Archivo" 72 | 73 | #: forms.py:93 74 | msgid "Use Image Generator" 75 | msgstr "Emplear el generador de imágenes" 76 | 77 | #: forms.py:102 78 | msgid "File already exists." 79 | msgstr "El archivo ya existe." 80 | 81 | #: forms.py:108 82 | msgid "Filename is not allowed." 83 | msgstr "Nombre de archivo no permitido." 84 | 85 | #: forms.py:113 86 | msgid "File extension is not allowed." 87 | msgstr "Extensión de archivo no permitida." 88 | 89 | #: forms.py:118 90 | msgid "Filesize exceeds allowed Upload Size." 91 | msgstr "El tamaño del archivo excede el máximo permitido." 92 | 93 | #: functions.py:84 94 | msgid "Home" 95 | msgstr "Inicio" 96 | 97 | #: functions.py:276 98 | msgid "Thumbnail creation failed." 99 | msgstr "Falló la creación de la miniatura." 100 | 101 | #: functions.py:331 functions.py:398 102 | msgid "Image creation failed." 103 | msgstr "Falló la creación de la Imagen." 104 | 105 | #: views.py:165 106 | msgid "FileBrowser" 107 | msgstr "Visor de archivos" 108 | 109 | #: views.py:188 110 | #, python-format 111 | msgid "The Folder %s was successfully created." 112 | msgstr "La carpeta %s se creó con éxito." 113 | 114 | #: views.py:194 115 | msgid "Permission denied." 116 | msgstr "Permiso denegado." 117 | 118 | #: views.py:196 119 | msgid "Error creating directory." 120 | msgstr "Error creando el directorio." 121 | 122 | #: views.py:204 views.py:205 templates/filebrowser/index.html:30 123 | msgid "New Folder" 124 | msgstr "Nueva carpeta." 125 | 126 | #: views.py:250 127 | msgid "Upload successful." 128 | msgstr "Subida completada." 129 | 130 | #: views.py:263 templates/filebrowser/index.html:33 131 | #: templates/filebrowser/upload.html:62 132 | msgid "Upload" 133 | msgstr "Subir" 134 | 135 | #: views.py:264 136 | msgid "Select files to upload" 137 | msgstr "Seleccione archivos a subir." 138 | 139 | #: views.py:294 140 | msgid "Thumbnail creation successful." 141 | msgstr "Se creó la miniatura con éxito." 142 | 143 | #: views.py:344 144 | #, python-format 145 | msgid "The file %s was successfully deleted." 146 | msgstr "El archivo %s se eliminó con éxito." 147 | 148 | #: views.py:356 149 | #, python-format 150 | msgid "The directory %s was successfully deleted." 151 | msgstr "El directorio %s se eliminó con éxito." 152 | 153 | #: views.py:407 154 | msgid "Error renaming Thumbnail." 155 | msgstr "Error renombrando la miniatura." 156 | 157 | #: views.py:413 158 | msgid "Renaming was successful." 159 | msgstr "Renombrado satisfactorio." 160 | 161 | #: views.py:418 162 | msgid "Error." 163 | msgstr "Error." 164 | 165 | #: views.py:427 templates/filebrowser/include/filelisting.html:52 166 | msgid "Rename" 167 | msgstr "Renombrar" 168 | 169 | #: views.py:428 170 | #, python-format 171 | msgid "Rename \"%s\"" 172 | msgstr "Renombrar \"%s\"" 173 | 174 | #: views.py:465 175 | msgid "Successfully generated Images." 176 | msgstr "Las imágenes se generaron satisfactoriamente." 177 | 178 | #: templates/filebrowser/index.html:31 179 | msgid "Make Thumbs" 180 | msgstr "Crear miniaturas" 181 | 182 | #: templates/filebrowser/index.html:32 183 | msgid "Generate Images" 184 | msgstr "Generar imágenes" 185 | 186 | #: templates/filebrowser/makedir.html:24 templates/filebrowser/rename.html:22 187 | msgid "Please correct the following errors." 188 | msgstr "Por favor, corrija los siguientes errores." 189 | 190 | #: templates/filebrowser/makedir.html:34 templates/filebrowser/rename.html:33 191 | msgid "Submit" 192 | msgstr "Enviar" 193 | 194 | #: templates/filebrowser/upload.html:37 195 | msgid "Will use image generator." 196 | msgstr "Usa el generador de imágenes." 197 | 198 | #: templates/filebrowser/upload.html:47 199 | msgid "Help" 200 | msgstr "Ayuda" 201 | 202 | #: templates/filebrowser/upload.html:51 203 | msgid "Allowed" 204 | msgstr "Permitido" 205 | 206 | #: templates/filebrowser/upload.html:57 207 | msgid "Max. Filesize" 208 | msgstr "Tamaño máx." 209 | 210 | #: templates/filebrowser/include/filelisting.html:8 211 | msgid "Select" 212 | msgstr "Selecciona" 213 | 214 | #: templates/filebrowser/include/filelisting.html:15 215 | msgid "Select File" 216 | msgstr "Selecciona archivo" 217 | 218 | #: templates/filebrowser/include/filelisting.html:26 219 | msgid "Make Thumbnail" 220 | msgstr "Crear miniatura" 221 | 222 | #: templates/filebrowser/include/filelisting.html:29 223 | msgid "View Image" 224 | msgstr "Ver imagen" 225 | 226 | #: templates/filebrowser/include/filelisting.html:46 227 | msgid "Generate Image Versions" 228 | msgstr "Generar versiones de la imagen" 229 | 230 | #: templates/filebrowser/include/filelisting.html:61 231 | msgid "Are you sure you want to delete this file?" 232 | msgstr "" 233 | 234 | #: templates/filebrowser/include/filelisting.html:61 235 | msgid "Delete File" 236 | msgstr "Borrar archivo" 237 | 238 | #: templates/filebrowser/include/filelisting.html:64 239 | msgid "Are you sure you want to delete this Folder?" 240 | msgstr "" 241 | 242 | #: templates/filebrowser/include/filelisting.html:64 243 | msgid "Delete Folder" 244 | msgstr "Borrar carpeta" 245 | 246 | #: templates/filebrowser/include/filter.html:15 247 | msgid "Filter" 248 | msgstr "Filtrar" 249 | 250 | #: templates/filebrowser/include/filter.html:21 251 | msgid "By Date" 252 | msgstr "Por fecha" 253 | 254 | #: templates/filebrowser/include/filter.html:23 255 | msgid "Any Date" 256 | msgstr "Cualquier fecha" 257 | 258 | #: templates/filebrowser/include/filter.html:25 259 | msgid "Today" 260 | msgstr "Hoy" 261 | 262 | #: templates/filebrowser/include/filter.html:27 263 | msgid "Past 7 days" 264 | msgstr "Hace 7 días" 265 | 266 | #: templates/filebrowser/include/filter.html:29 267 | msgid "Past 30 days" 268 | msgstr "Hace 30 días" 269 | 270 | #: templates/filebrowser/include/filter.html:31 271 | msgid "This year" 272 | msgstr "Este año" 273 | 274 | #: templates/filebrowser/include/filter.html:39 275 | msgid "By Type" 276 | msgstr "Por tipo" 277 | 278 | #: templates/filebrowser/include/filter.html:41 279 | msgid "All" 280 | msgstr "Todo" 281 | 282 | #: templates/filebrowser/include/paginator.html:5 283 | msgid "No Items Found." 284 | msgstr "No se encontraron items" 285 | 286 | #: templates/filebrowser/include/paginator.html:10 287 | #, python-format 288 | msgid "%(counter)s Item" 289 | msgid_plural "%(counter)s Items" 290 | msgstr[0] "%(counter)s item" 291 | msgstr[1] "%(counter)s items" 292 | 293 | #: templates/filebrowser/include/paginator.html:16 294 | msgid "No Items." 295 | msgstr "No hay items." 296 | 297 | #: templates/filebrowser/include/tableheader.html:13 298 | #: templates/filebrowser/include/tableheader.html:14 299 | msgid "Filename" 300 | msgstr "Nombre de archivo" 301 | 302 | #: templates/filebrowser/include/tableheader.html:20 303 | #: templates/filebrowser/include/tableheader.html:21 304 | msgid "Size" 305 | msgstr "Tamaño" 306 | 307 | #: templates/filebrowser/include/tableheader.html:23 308 | #: templates/filebrowser/include/tableheader.html:24 309 | msgid "Date" 310 | msgstr "Fecha" 311 | 312 | #: templates/filebrowser/include/toolbar.html:14 313 | msgid "Go" 314 | msgstr "Ir" 315 | 316 | #: templates/filebrowser/include/toolbar.html:16 317 | #, python-format 318 | msgid "%(counter)s Item found" 319 | msgid_plural "%(counter)s Items found" 320 | msgstr[0] "encontrado %(counter)s Item" 321 | msgstr[1] "encontrados %(counter)s Items" 322 | 323 | #: templates/filebrowser/include/toolbar.html:17 324 | #, python-format 325 | msgid "%(counter)s Item total" 326 | msgid_plural "%(counter)s Items total" 327 | msgstr[0] "total %(counter)s item" 328 | msgstr[1] "total %(counter)s items" 329 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/fr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/fr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/it/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/it/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/it/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # translation of django.po to 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # 5 | # Alberto BOTTARINI , 2009. 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: django\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2009-02-19 21:24+0000\n" 11 | "PO-Revision-Date: 2009-02-04 14:02+0100\n" 12 | "Last-Translator: Alberto BOTTARINI \n" 13 | "MIME-Version: 1.0\n" 14 | "Content-Type: text/plain; charset=UTF-8\n" 15 | "Content-Transfer-Encoding: 8bit\n" 16 | "X-Generator: KBabel 1.11.4\n" 17 | 18 | #: fields.py:27 19 | #, python-format 20 | msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." 21 | msgstr "" 22 | "Assicurati che il testo abbia al massimo %(max)d caratteri (ora sono %" 23 | "(length)d)" 24 | 25 | #: fields.py:28 26 | #, python-format 27 | msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." 28 | msgstr "" 29 | "Assicurati che il testo abbia come minimo %(min)d caratteri (ora sono %" 30 | "(length)d)" 31 | 32 | #: fields.py:29 33 | #, python-format 34 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 35 | msgstr "L'estensione %(ext)s è vietata. Sono accettate: %(allowed)s" 36 | 37 | #: forms.py:23 38 | msgid "Name" 39 | msgstr "" 40 | 41 | #: forms.py:23 forms.py:46 42 | #, fuzzy 43 | msgid "" 44 | "The Name will automatically be converted to lowercase. Only letters, " 45 | "numbers, underscores and hyphens are allowed." 46 | msgstr "" 47 | "Il nome del file verrà sostituito con le lettere minuscole.Sono accettati " 48 | "solo lettere. numeri, underscore e accenti." 49 | 50 | #: forms.py:30 forms.py:53 51 | msgid "Only letters, numbers, underscores and hyphens are allowed." 52 | msgstr "Sono accettati solo lettere. numeri, underscore e accenti." 53 | 54 | #: forms.py:33 55 | #, fuzzy 56 | msgid "The Folder already exists." 57 | msgstr "La cartella esiste già" 58 | 59 | #: forms.py:46 60 | msgid "New Name" 61 | msgstr "" 62 | 63 | #: forms.py:56 64 | #, fuzzy 65 | msgid "The File/Folder already exists." 66 | msgstr "Il file/cartella esiste già" 67 | 68 | #: forms.py:92 69 | #, fuzzy 70 | msgid "File" 71 | msgstr "Filtro" 72 | 73 | #: forms.py:93 74 | #, fuzzy 75 | msgid "Use Image Generator" 76 | msgstr "Usa il generatore di immagini" 77 | 78 | #: forms.py:102 79 | msgid "File already exists." 80 | msgstr "Il file esiste già" 81 | 82 | #: forms.py:108 83 | msgid "Filename is not allowed." 84 | msgstr "Filename non permesso" 85 | 86 | #: forms.py:113 87 | msgid "File extension is not allowed." 88 | msgstr "Estensione non permessa" 89 | 90 | #: forms.py:118 91 | msgid "Filesize exceeds allowed Upload Size." 92 | msgstr "Il file eccede il limite" 93 | 94 | #: functions.py:84 95 | msgid "Home" 96 | msgstr "Home" 97 | 98 | #: functions.py:276 99 | msgid "Thumbnail creation failed." 100 | msgstr "Errore nella creazione delle thumbnail" 101 | 102 | #: functions.py:331 functions.py:398 103 | msgid "Image creation failed." 104 | msgstr "Errore nella creazione dell'immagine" 105 | 106 | #: views.py:165 107 | msgid "FileBrowser" 108 | msgstr "FileBrowser" 109 | 110 | #: views.py:188 111 | #, fuzzy, python-format 112 | msgid "The Folder %s was successfully created." 113 | msgstr "Cartella %s creata con successo" 114 | 115 | #: views.py:194 116 | msgid "Permission denied." 117 | msgstr "Permesso negato" 118 | 119 | #: views.py:196 120 | msgid "Error creating directory." 121 | msgstr "Errore nella creazione della cartella" 122 | 123 | #: views.py:204 views.py:205 templates/filebrowser/index.html:30 124 | #, fuzzy 125 | msgid "New Folder" 126 | msgstr "Elimina la cartella" 127 | 128 | #: views.py:250 129 | msgid "Upload successful." 130 | msgstr "Upload effettuato con successo" 131 | 132 | #: views.py:263 templates/filebrowser/index.html:33 133 | #: templates/filebrowser/upload.html:62 134 | msgid "Upload" 135 | msgstr "" 136 | 137 | #: views.py:264 138 | msgid "Select files to upload" 139 | msgstr "Seleziona i file da uploadare" 140 | 141 | #: views.py:294 142 | msgid "Thumbnail creation successful." 143 | msgstr "Creazione thumbnail effettuata con successo" 144 | 145 | #: views.py:344 146 | #, python-format 147 | msgid "The file %s was successfully deleted." 148 | msgstr "Eliminazione di %s effettuata con successo" 149 | 150 | #: views.py:356 151 | #, python-format 152 | msgid "The directory %s was successfully deleted." 153 | msgstr "Eliminazione di %s effettuata con successo" 154 | 155 | #: views.py:407 156 | msgid "Error renaming Thumbnail." 157 | msgstr "Errore nella rinominazione delle thumbnail" 158 | 159 | #: views.py:413 160 | msgid "Renaming was successful." 161 | msgstr "Rinominazione effettuata con successo" 162 | 163 | #: views.py:418 164 | msgid "Error." 165 | msgstr "Errore" 166 | 167 | #: views.py:427 templates/filebrowser/include/filelisting.html:52 168 | #, fuzzy 169 | msgid "Rename" 170 | msgstr "Nome del file" 171 | 172 | #: views.py:428 173 | #, python-format 174 | msgid "Rename \"%s\"" 175 | msgstr "Rinomina \"%s\"" 176 | 177 | #: views.py:465 178 | msgid "Successfully generated Images." 179 | msgstr "Immagini generate con successo" 180 | 181 | #: templates/filebrowser/index.html:31 182 | msgid "Make Thumbs" 183 | msgstr "Genera le thumbnail" 184 | 185 | #: templates/filebrowser/index.html:32 186 | msgid "Generate Images" 187 | msgstr "Genera le immagini" 188 | 189 | #: templates/filebrowser/makedir.html:24 templates/filebrowser/rename.html:22 190 | msgid "Please correct the following errors." 191 | msgstr "" 192 | 193 | #: templates/filebrowser/makedir.html:34 templates/filebrowser/rename.html:33 194 | msgid "Submit" 195 | msgstr "Invia" 196 | 197 | #: templates/filebrowser/upload.html:37 198 | #, fuzzy 199 | msgid "Will use image generator." 200 | msgstr "Usa il generatore di immagini" 201 | 202 | #: templates/filebrowser/upload.html:47 203 | msgid "Help" 204 | msgstr "Aiuto" 205 | 206 | #: templates/filebrowser/upload.html:51 207 | msgid "Allowed" 208 | msgstr "Accettate" 209 | 210 | #: templates/filebrowser/upload.html:57 211 | msgid "Max. Filesize" 212 | msgstr "Dimensione massima" 213 | 214 | #: templates/filebrowser/include/filelisting.html:8 215 | #, fuzzy 216 | msgid "Select" 217 | msgstr "Seleziona un file" 218 | 219 | #: templates/filebrowser/include/filelisting.html:15 220 | msgid "Select File" 221 | msgstr "Seleziona un file" 222 | 223 | #: templates/filebrowser/include/filelisting.html:26 224 | msgid "Make Thumbnail" 225 | msgstr "Genera la thumbnail" 226 | 227 | #: templates/filebrowser/include/filelisting.html:29 228 | msgid "View Image" 229 | msgstr "Guarda immagine" 230 | 231 | #: templates/filebrowser/include/filelisting.html:46 232 | msgid "Generate Image Versions" 233 | msgstr "Genera le immagini" 234 | 235 | #: templates/filebrowser/include/filelisting.html:61 236 | msgid "Are you sure you want to delete this file?" 237 | msgstr "" 238 | 239 | #: templates/filebrowser/include/filelisting.html:61 240 | msgid "Delete File" 241 | msgstr "Elimina il file" 242 | 243 | #: templates/filebrowser/include/filelisting.html:64 244 | msgid "Are you sure you want to delete this Folder?" 245 | msgstr "" 246 | 247 | #: templates/filebrowser/include/filelisting.html:64 248 | msgid "Delete Folder" 249 | msgstr "Elimina la cartella" 250 | 251 | #: templates/filebrowser/include/filter.html:15 252 | msgid "Filter" 253 | msgstr "Filtro" 254 | 255 | #: templates/filebrowser/include/filter.html:21 256 | msgid "By Date" 257 | msgstr "Per data" 258 | 259 | #: templates/filebrowser/include/filter.html:23 260 | msgid "Any Date" 261 | msgstr "Qualsiasi data" 262 | 263 | #: templates/filebrowser/include/filter.html:25 264 | msgid "Today" 265 | msgstr "Oggi" 266 | 267 | #: templates/filebrowser/include/filter.html:27 268 | msgid "Past 7 days" 269 | msgstr "Ultimi 7 giorni" 270 | 271 | #: templates/filebrowser/include/filter.html:29 272 | msgid "Past 30 days" 273 | msgstr "Questo mese" 274 | 275 | #: templates/filebrowser/include/filter.html:31 276 | msgid "This year" 277 | msgstr "Quest'anno" 278 | 279 | #: templates/filebrowser/include/filter.html:39 280 | msgid "By Type" 281 | msgstr "Per tipo" 282 | 283 | #: templates/filebrowser/include/filter.html:41 284 | msgid "All" 285 | msgstr "Tutti" 286 | 287 | #: templates/filebrowser/include/paginator.html:5 288 | #, fuzzy 289 | msgid "No Items Found." 290 | msgstr "Nessun file trovato" 291 | 292 | #: templates/filebrowser/include/paginator.html:10 293 | #, python-format 294 | msgid "%(counter)s Item" 295 | msgid_plural "%(counter)s Items" 296 | msgstr[0] "" 297 | msgstr[1] "" 298 | 299 | #: templates/filebrowser/include/paginator.html:16 300 | msgid "No Items." 301 | msgstr "" 302 | 303 | #: templates/filebrowser/include/tableheader.html:13 304 | #: templates/filebrowser/include/tableheader.html:14 305 | msgid "Filename" 306 | msgstr "Nome del file" 307 | 308 | #: templates/filebrowser/include/tableheader.html:20 309 | #: templates/filebrowser/include/tableheader.html:21 310 | msgid "Size" 311 | msgstr "Dimensione" 312 | 313 | #: templates/filebrowser/include/tableheader.html:23 314 | #: templates/filebrowser/include/tableheader.html:24 315 | msgid "Date" 316 | msgstr "Data" 317 | 318 | #: templates/filebrowser/include/toolbar.html:14 319 | msgid "Go" 320 | msgstr "" 321 | 322 | #: templates/filebrowser/include/toolbar.html:16 323 | #, python-format 324 | msgid "%(counter)s Item found" 325 | msgid_plural "%(counter)s Items found" 326 | msgstr[0] "" 327 | msgstr[1] "" 328 | 329 | #: templates/filebrowser/include/toolbar.html:17 330 | #, python-format 331 | msgid "%(counter)s Item total" 332 | msgid_plural "%(counter)s Items total" 333 | msgstr[0] "" 334 | msgstr[1] "" 335 | 336 | #~ msgid "" 337 | #~ "The directory will automatically be converted to lowercase. Only letters, " 338 | #~ "numbers, underscores and hyphens are allowed." 339 | #~ msgstr "" 340 | #~ "Il nome della cartella verrà sostituito con le lettere minuscole.Sono " 341 | #~ "accettati solo lettere. numeri, underscore e accenti." 342 | 343 | #~ msgid "Make directory" 344 | #~ msgstr "Nuova cartella" 345 | 346 | #~ msgid "Make Directory" 347 | #~ msgstr "Nuova cartella" 348 | 349 | #~ msgid "Multiple Upload" 350 | #~ msgstr "Chargement de fichiers" 351 | 352 | #~ msgid "Rename File" 353 | #~ msgstr "Rinomina il file" 354 | 355 | #~ msgid "No Files" 356 | #~ msgstr "Nessun file" 357 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/nb/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/nb/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/nb/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Norwegian Bokmål translation of filebrowser_safe. 2 | # Copyright (C) 2009 Patrick Kranzlmueller (vonautomatisch werkstaetten) 3 | # This file is distributed under the same license as the filebrowser_safe 4 | # package. 5 | # Simen Heggestøyl , 2018. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: \n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2018-05-20 14:28+0200\n" 12 | "PO-Revision-Date: 2018-05-20 17:30+0200\n" 13 | "Last-Translator: Simen Heggestøyl \n" 14 | "Language: nb\n" 15 | "Language-Team: Norwegian Bokmål\n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=utf-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Generated-By: Babel 2.5.3\n" 21 | "X-Generator: Poedit 2.0.7\n" 22 | 23 | #: fields.py:61 24 | #, python-format 25 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 26 | msgstr "Filtypen %(ext)s er ikke tillatt. Kun %(allowed)s er tillatt." 27 | 28 | #: forms.py:32 29 | msgid "Name" 30 | msgstr "Navn" 31 | 32 | #: forms.py:33 forms.py:41 forms.py:62 forms.py:70 33 | msgid "Only letters, numbers, underscores, spaces and hyphens are allowed." 34 | msgstr "Kun bokstaver, tall, understrek, mellomrom og bindestrek er tillatt." 35 | 36 | #: forms.py:44 forms.py:73 37 | msgid "The Folder already exists." 38 | msgstr "Mappen finnes allerede." 39 | 40 | #: forms.py:61 41 | msgid "New Name" 42 | msgstr "Nytt navn" 43 | 44 | #: forms.py:75 45 | msgid "The File already exists." 46 | msgstr "Filen finnes allerede." 47 | 48 | #: settings.py:103 49 | msgid "Folder" 50 | msgstr "Mappe" 51 | 52 | #: settings.py:104 53 | msgid "Image" 54 | msgstr "Bilde" 55 | 56 | #: settings.py:105 57 | msgid "Video" 58 | msgstr "Video" 59 | 60 | #: settings.py:106 61 | msgid "Document" 62 | msgstr "Dokument" 63 | 64 | #: settings.py:107 65 | msgid "Audio" 66 | msgstr "Lyd" 67 | 68 | #: settings.py:108 69 | msgid "Code" 70 | msgstr "Kode" 71 | 72 | #: views.py:95 views.py:210 views.py:266 views.py:379 views.py:446 73 | msgid "The requested Folder does not exist." 74 | msgstr "Den etterspurte mappen finnes ikke." 75 | 76 | #: views.py:99 77 | msgid "Error finding Upload-Folder. Maybe it does not exist?" 78 | msgstr "Fant ikke opplastingsmappe. Kanskje den ikke finnes?" 79 | 80 | #: templates/filebrowser/include/breadcrumbs.html:6 81 | #: templates/filebrowser/include/breadcrumbs.html:8 views.py:185 82 | msgid "Media Library" 83 | msgstr "Mediebibliotek" 84 | 85 | #: views.py:227 86 | #, python-format 87 | msgid "The Folder %s was successfully created." 88 | msgstr "Opprettelsen av mappen %s var vellykket." 89 | 90 | #: views.py:237 91 | msgid "Permission denied." 92 | msgstr "Ikke tilgang." 93 | 94 | #: views.py:239 95 | msgid "Error creating folder." 96 | msgstr "Feil ved opprettelse av mappe." 97 | 98 | #: templates/filebrowser/index.html:63 views.py:246 views.py:249 99 | msgid "New Folder" 100 | msgstr "Ny mappe" 101 | 102 | #: views.py:277 103 | msgid "Select files to upload" 104 | msgstr "Velg filer å laste opp" 105 | 106 | #: templates/filebrowser/index.html:64 templates/filebrowser/upload.html:104 107 | #: views.py:281 108 | msgid "Upload" 109 | msgstr "Last opp" 110 | 111 | #: views.py:381 views.py:448 112 | msgid "The requested File does not exist." 113 | msgstr "Den etterspurte filen finnes ikke." 114 | 115 | #: views.py:389 views.py:404 views.py:418 116 | msgid "An error occurred" 117 | msgstr "En feil oppstod" 118 | 119 | #: views.py:401 120 | #, python-format 121 | msgid "The file %s was successfully deleted." 122 | msgstr "Filen %s ble slettet." 123 | 124 | #: views.py:415 125 | #, python-format 126 | msgid "The folder %s was successfully deleted." 127 | msgstr "Mappen %s ble slettet." 128 | 129 | #: views.py:469 130 | msgid "Renaming was successful." 131 | msgstr "Navneendring vellykket." 132 | 133 | #: views.py:475 134 | msgid "Error." 135 | msgstr "Feil." 136 | 137 | #: views.py:484 138 | #, python-format 139 | msgid "Rename \"%s\"" 140 | msgstr "Gi nytt navn til \"%s\"" 141 | 142 | #: templates/filebrowser/include/filelisting.html:89 views.py:487 143 | msgid "Rename" 144 | msgstr "Endre navn" 145 | 146 | #: templates/filebrowser/append.html:5 templates/filebrowser/append.html:7 147 | msgid "FileBrowser" 148 | msgstr "FileBrowser" 149 | 150 | #: templates/filebrowser/custom_field.html:34 151 | msgid "Clear" 152 | msgstr "Fjern" 153 | 154 | #: templates/filebrowser/makedir.html:30 templates/filebrowser/rename.html:31 155 | msgid "Please correct the following errors." 156 | msgstr "Vennligst rett opp i følgende feil." 157 | 158 | #: templates/filebrowser/makedir.html:38 templates/filebrowser/upload.html:93 159 | msgid "" 160 | "The Name will be converted to lowercase. Spaces will be replaced with " 161 | "underscores." 162 | msgstr "" 163 | "Navnet vil bli gjort om til små bokstaver. Mellomrom vil erstattes med " 164 | "understrek." 165 | 166 | #: templates/filebrowser/makedir.html:43 templates/filebrowser/rename.html:42 167 | msgid "Submit" 168 | msgstr "Send inn" 169 | 170 | #: templates/filebrowser/upload.html:41 171 | msgid "Do you want to replace the file" 172 | msgstr "Vil du erstatte filen" 173 | 174 | #: templates/filebrowser/upload.html:45 175 | msgid "There was a server error when uploading the file." 176 | msgstr "Det oppstod en tjenerfeil under opplasting av filen." 177 | 178 | #: templates/filebrowser/upload.html:46 179 | msgid "The file size is larger than the limit." 180 | msgstr "Filen er større enn det som er tillatt." 181 | 182 | #: templates/filebrowser/upload.html:47 183 | msgid "The file extension is not allowed." 184 | msgstr "Filtypen er ikke tillatt." 185 | 186 | #: templates/filebrowser/upload.html:58 187 | msgid "Remove" 188 | msgstr "Fjern" 189 | 190 | #: templates/filebrowser/upload.html:63 191 | msgid "Browse" 192 | msgstr "Bla gjennom" 193 | 194 | #: templates/filebrowser/upload.html:76 195 | msgid "Help" 196 | msgstr "Hjelp" 197 | 198 | #: templates/filebrowser/upload.html:80 199 | msgid "Allowed" 200 | msgstr "Tillatt" 201 | 202 | #: templates/filebrowser/upload.html:86 203 | msgid "Max. Filesize" 204 | msgstr "Maksimal filstørrelse" 205 | 206 | #: templates/filebrowser/upload.html:98 207 | msgid "" 208 | "Once you've selected all the files you want to upload, click the upload " 209 | "button in the bottom right corner to begin the upload process." 210 | msgstr "" 211 | "Når du har valgt alle filene som du vil laste opp, klikk på " 212 | "opplastingsknappen nede i høyre hjørne for å starte opplastingsprosessen." 213 | 214 | #: templates/filebrowser/upload.html:102 215 | msgid "Clear Queue" 216 | msgstr "Tøm kø" 217 | 218 | #: templates/filebrowser/include/filelisting.html:18 219 | msgid "Select" 220 | msgstr "Velg" 221 | 222 | #: templates/filebrowser/include/filelisting.html:32 223 | #: templates/filebrowser/include/filelisting.html:46 224 | #: templates/filebrowser/include/filelisting.html:60 225 | msgid "Select File" 226 | msgstr "Velg fil" 227 | 228 | #: templates/filebrowser/include/filelisting.html:75 229 | msgid "View Image" 230 | msgstr "Vis bilde" 231 | 232 | #: templates/filebrowser/include/filelisting.html:102 233 | msgid "Are you sure you want to delete this file?" 234 | msgstr "Er du sikker på at du vil slette denne filen?" 235 | 236 | #: templates/filebrowser/include/filelisting.html:102 237 | msgid "Delete File" 238 | msgstr "Slett fil" 239 | 240 | #: templates/filebrowser/include/filelisting.html:105 241 | msgid "Are you sure you want to delete this Folder?" 242 | msgstr "Er du sikker på at du vil slette denne mappen?" 243 | 244 | #: templates/filebrowser/include/filelisting.html:105 245 | msgid "Delete Folder" 246 | msgstr "Slett mappe" 247 | 248 | #: templates/filebrowser/include/filter.html:3 249 | msgid "Filter" 250 | msgstr "Filtrer" 251 | 252 | #: templates/filebrowser/include/filter.html:9 253 | msgid "By Date" 254 | msgstr "Etter dato" 255 | 256 | #: templates/filebrowser/include/filter.html:11 257 | msgid "Any Date" 258 | msgstr "Når som helst" 259 | 260 | #: templates/filebrowser/include/filter.html:13 261 | msgid "Today" 262 | msgstr "I dag" 263 | 264 | #: templates/filebrowser/include/filter.html:15 265 | msgid "Past 7 days" 266 | msgstr "Siste syv dager" 267 | 268 | #: templates/filebrowser/include/filter.html:17 269 | msgid "Past 30 days" 270 | msgstr "Siste 30 dager" 271 | 272 | #: templates/filebrowser/include/filter.html:19 273 | msgid "This year" 274 | msgstr "I år" 275 | 276 | #: templates/filebrowser/include/filter.html:27 277 | msgid "By Type" 278 | msgstr "Etter type" 279 | 280 | #: templates/filebrowser/include/filter.html:29 281 | msgid "All" 282 | msgstr "Alle" 283 | 284 | #: templates/filebrowser/include/paginator.html:5 285 | msgid "No Items Found" 286 | msgstr "Ingen treff" 287 | 288 | #: templates/filebrowser/include/paginator.html:11 289 | #, python-format 290 | msgid "%(counter)s Item" 291 | msgid_plural "%(counter)s Items" 292 | msgstr[0] "%(counter)s element" 293 | msgstr[1] "%(counter)s elementer" 294 | 295 | #: templates/filebrowser/include/paginator.html:26 296 | msgid "No Items" 297 | msgstr "Ingen elementer" 298 | 299 | #: templates/filebrowser/include/search.html:3 300 | #, python-format 301 | msgid "1 result" 302 | msgid_plural "%(counter)s results" 303 | msgstr[0] "Ett resultat" 304 | msgstr[1] "%(counter) resultater" 305 | 306 | #: templates/filebrowser/include/search.html:4 307 | #: templates/filebrowser/include/toolbar.html:9 308 | #, python-format 309 | msgid "%(full_result_count)s total" 310 | msgstr "%(full_result_count)s totalt" 311 | 312 | #: templates/filebrowser/include/search.html:5 313 | msgid "Clear Restrictions" 314 | msgstr "Fjern begrensninger" 315 | 316 | #: templates/filebrowser/include/search.html:7 317 | #: templates/filebrowser/include/toolbar.html:16 318 | msgid "Search" 319 | msgstr "Søk" 320 | 321 | #: templates/filebrowser/include/search.html:19 322 | msgid "Go" 323 | msgstr "Søk" 324 | 325 | #: templates/filebrowser/include/search.html:24 326 | #, python-format 327 | msgid "%(counter)s Item found" 328 | msgid_plural "%(counter)s Items found" 329 | msgstr[0] "%(counter)s element funnet" 330 | msgstr[1] "%(counter)s elementer funnet" 331 | 332 | #: templates/filebrowser/include/search.html:25 333 | #, python-format 334 | msgid "%(counter)s Item total" 335 | msgid_plural "%(counter)s Items total" 336 | msgstr[0] "%(counter)s element totalt" 337 | msgstr[1] "%(counter)s elementer totalt" 338 | 339 | #: templates/filebrowser/include/tableheader.html:16 340 | #: templates/filebrowser/include/tableheader.html:17 341 | msgid "Filename" 342 | msgstr "Filnavn" 343 | 344 | #: templates/filebrowser/include/tableheader.html:23 345 | #: templates/filebrowser/include/tableheader.html:24 346 | msgid "Size" 347 | msgstr "Størrelse" 348 | 349 | #: templates/filebrowser/include/tableheader.html:26 350 | #: templates/filebrowser/include/tableheader.html:27 351 | msgid "Date" 352 | msgstr "Dato" 353 | 354 | #: templates/filebrowser/include/toolbar.html:6 355 | msgid "Results" 356 | msgstr "Resultater" 357 | 358 | #: templates/filebrowser/include/toolbar.html:8 359 | #, python-format 360 | msgid "%(counter)s result" 361 | msgid_plural "%(counter)s results" 362 | msgstr[0] "%(counter)s resultat" 363 | msgstr[1] "%(counter)s resultater" 364 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/nl/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/nl/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/nl/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Dutch translation for django-filebrowser. 2 | # Copyright (C) 2009 Patrick Kranzlmueller 3 | # This file is distributed under the same license as the django-filebrowser package. 4 | # Joost Cassee , 2009. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2009-02-16 13:51+0100\n" 12 | "PO-Revision-Date: 2009-02-20 22:53+0100\n" 13 | "Last-Translator: Joost Cassee \n" 14 | "Language-Team: Dutch \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=UTF-8\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #: fields.py:27 20 | #, python-format 21 | msgid "Ensure this value has at most %(max)d characters (it has %(length)d)." 22 | msgstr "" 23 | "Dit veld mag maximaal %(max)d karakters bevatten (de huidige lengte is " 24 | "%(length)d)." 25 | 26 | #: fields.py:28 27 | #, python-format 28 | msgid "Ensure this value has at least %(min)d characters (it has %(length)d)." 29 | msgstr "" 30 | "Dit veld moet minstens %(min)d karakters bevatten (de huidige lengte is " 31 | "%(length)d)." 32 | 33 | #: fields.py:29 34 | #, python-format 35 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 36 | msgstr "Extensie %(ext)s is niet toegestaand. Toegestaan zijn: %(allowed)s." 37 | 38 | #: forms.py:23 39 | msgid "Name" 40 | msgstr "Naam" 41 | 42 | #: forms.py:23 forms.py:46 43 | msgid "" 44 | "The Name will automatically be converted to lowercase. Only letters, " 45 | "numbers, underscores and hyphens are allowed." 46 | msgstr "" 47 | "De naam wordt automatisch geconverteerd naar kleine letters. Alleen letters, " 48 | "nummers, liggende streepjes en verbindingstreepjes zijn toegestaan." 49 | 50 | #: forms.py:30 forms.py:53 51 | msgid "Only letters, numbers, underscores and hyphens are allowed." 52 | msgstr "" 53 | "Alleen letters, nummers, liggende streepjes en verbindingstreepjes zijn " 54 | "toegestaan." 55 | 56 | #: forms.py:33 57 | msgid "The Folder already exists." 58 | msgstr "Deze map bestaat reeds." 59 | 60 | #: forms.py:46 61 | msgid "New Name" 62 | msgstr "Nieuwe naam" 63 | 64 | #: forms.py:56 65 | msgid "The File/Folder already exists." 66 | msgstr "Een map of bestand met deze naam bestaat reeds." 67 | 68 | #: forms.py:92 69 | msgid "File" 70 | msgstr "Bestand" 71 | 72 | #: forms.py:93 73 | msgid "Use Image Generator" 74 | msgstr "Maak afbeeldingsversies" 75 | 76 | #: forms.py:102 77 | msgid "File already exists." 78 | msgstr "Bestand bestaat reeds." 79 | 80 | #: forms.py:108 81 | msgid "Filename is not allowed." 82 | msgstr "Bestandsnaam is niet toegestaan." 83 | 84 | #: forms.py:113 85 | msgid "File extension is not allowed." 86 | msgstr "Bestandsextensie is niet toegestaand" 87 | 88 | #: forms.py:118 89 | msgid "Filesize exceeds allowed Upload Size." 90 | msgstr "Het bestand overschreidt de maximale upload grootte." 91 | 92 | #: functions.py:75 93 | msgid "Home" 94 | msgstr "Start" 95 | 96 | #: functions.py:267 97 | msgid "Thumbnail creation failed." 98 | msgstr "Fout bij het aanmaken van de voorbeeldafbeeldingen." 99 | 100 | #: functions.py:316 functions.py:377 101 | msgid "Image creation failed." 102 | msgstr "Fout bij het aanmaken van de afbeeldingsversies." 103 | 104 | #: views.py:156 105 | msgid "FileBrowser" 106 | msgstr "FileBrowser" 107 | 108 | #: views.py:179 109 | #, python-format 110 | msgid "The Folder %s was successfully created." 111 | msgstr "De map %s is aangemaakt." 112 | 113 | #: views.py:185 114 | msgid "Permission denied." 115 | msgstr "Geen toestemming." 116 | 117 | #: views.py:187 118 | msgid "Error creating directory." 119 | msgstr "Fout bij het aanmaken van de map." 120 | 121 | #: views.py:195 views.py:196 templates/filebrowser/index.html:30 122 | msgid "New Folder" 123 | msgstr "Nieuwe map" 124 | 125 | #: views.py:235 126 | msgid "Upload successful." 127 | msgstr "Upload geslaagd." 128 | 129 | #: views.py:248 templates/filebrowser/index.html:33 130 | #: templates/filebrowser/upload.html:62 131 | msgid "Upload" 132 | msgstr "Uploaden" 133 | 134 | #: views.py:249 135 | msgid "Select files to upload" 136 | msgstr "Selecteer bestanden voor upload" 137 | 138 | #: views.py:279 139 | msgid "Thumbnail creation successful." 140 | msgstr "Voorbeeldafbeeldingen aangemaakt." 141 | 142 | #: views.py:329 143 | #, python-format 144 | msgid "The file %s was successfully deleted." 145 | msgstr "Bestand %s verwijderd." 146 | 147 | #: views.py:341 148 | #, python-format 149 | msgid "The directory %s was successfully deleted." 150 | msgstr "Map %s verwijderd." 151 | 152 | #: views.py:392 153 | msgid "Error renaming Thumbnail." 154 | msgstr "Fout bij het hernoemen van de voorbeeldafbeelding." 155 | 156 | #: views.py:398 157 | msgid "Renaming was successful." 158 | msgstr "Hernoemen geslaagd." 159 | 160 | #: views.py:403 161 | msgid "Error." 162 | msgstr "Fout." 163 | 164 | #: views.py:412 templates/filebrowser/include/filelisting.html:52 165 | msgid "Rename" 166 | msgstr "Hernoemen" 167 | 168 | #: views.py:413 169 | #, python-format 170 | msgid "Rename \"%s\"" 171 | msgstr "Hernoem \"%s\"" 172 | 173 | #: views.py:450 174 | msgid "Successfully generated Images." 175 | msgstr "Afbeeldingsversies aangemaakt." 176 | 177 | #: templates/filebrowser/index.html:31 178 | msgid "Make Thumbs" 179 | msgstr "Voorbeeldafbeeldingen aanmaken" 180 | 181 | #: templates/filebrowser/index.html:32 182 | msgid "Generate Images" 183 | msgstr "Afbeeldingsversies aanmaken" 184 | 185 | #: templates/filebrowser/makedir.html:24 templates/filebrowser/rename.html:22 186 | msgid "Please correct the following errors." 187 | msgstr "Corrigeer onderstaande fouten." 188 | 189 | #: templates/filebrowser/makedir.html:34 templates/filebrowser/rename.html:33 190 | msgid "Submit" 191 | msgstr "OK" 192 | 193 | #: templates/filebrowser/upload.html:37 194 | msgid "Will use image generator." 195 | msgstr "Afbeeldingsversies zullen worden aangemaakt." 196 | 197 | #: templates/filebrowser/upload.html:47 198 | msgid "Help" 199 | msgstr "Help" 200 | 201 | #: templates/filebrowser/upload.html:51 202 | msgid "Allowed" 203 | msgstr "Toegestaan" 204 | 205 | #: templates/filebrowser/upload.html:57 206 | msgid "Max. Filesize" 207 | msgstr "Max. bestandsgrootte" 208 | 209 | #: templates/filebrowser/include/filelisting.html:8 210 | msgid "Select" 211 | msgstr "Selecteren" 212 | 213 | #: templates/filebrowser/include/filelisting.html:15 214 | msgid "Select File" 215 | msgstr "Selecteer bestand" 216 | 217 | #: templates/filebrowser/include/filelisting.html:26 218 | msgid "Make Thumbnail" 219 | msgstr "Maak voorbeeldafbeelding" 220 | 221 | #: templates/filebrowser/include/filelisting.html:29 222 | msgid "View Image" 223 | msgstr "Afbeelding tonen" 224 | 225 | #: templates/filebrowser/include/filelisting.html:46 226 | msgid "Generate Image Versions" 227 | msgstr "Afbeeldingsversies aanmaken" 228 | 229 | #: templates/filebrowser/include/filelisting.html:61 230 | msgid "Delete File" 231 | msgstr "Bestand verwijderen" 232 | 233 | #: templates/filebrowser/include/filelisting.html:64 234 | msgid "Delete Folder" 235 | msgstr "Verwijder map" 236 | 237 | #: templates/filebrowser/include/filter.html:15 238 | msgid "Filter" 239 | msgstr "Filter" 240 | 241 | #: templates/filebrowser/include/filter.html:21 242 | msgid "By Date" 243 | msgstr "Op datum" 244 | 245 | #: templates/filebrowser/include/filter.html:23 246 | msgid "Any Date" 247 | msgstr "Alle" 248 | 249 | #: templates/filebrowser/include/filter.html:25 250 | msgid "Today" 251 | msgstr "Vandaag" 252 | 253 | #: templates/filebrowser/include/filter.html:27 254 | msgid "Past 7 days" 255 | msgstr "Afgelopen 7 dagen" 256 | 257 | #: templates/filebrowser/include/filter.html:29 258 | msgid "Past 30 days" 259 | msgstr "Afgelopen 30 dagen" 260 | 261 | #: templates/filebrowser/include/filter.html:31 262 | msgid "This year" 263 | msgstr "Dit jaar" 264 | 265 | #: templates/filebrowser/include/filter.html:39 266 | msgid "By Type" 267 | msgstr "Op type" 268 | 269 | #: templates/filebrowser/include/filter.html:41 270 | msgid "All" 271 | msgstr "Alle" 272 | 273 | #: templates/filebrowser/include/paginator.html:5 274 | msgid "No Items Found." 275 | msgstr "Geen objecten gevonden" 276 | 277 | #: templates/filebrowser/include/paginator.html:10 278 | #, python-format 279 | msgid "%(counter)s Item" 280 | msgid_plural "%(counter)s Items" 281 | msgstr[0] "%(counter)s object" 282 | msgstr[1] "(counter)s objecten" 283 | 284 | #: templates/filebrowser/include/paginator.html:16 285 | msgid "No Items." 286 | msgstr "Geen objecten." 287 | 288 | #: templates/filebrowser/include/tableheader.html:13 289 | #: templates/filebrowser/include/tableheader.html:14 290 | msgid "Filename" 291 | msgstr "Bestandsnaam" 292 | 293 | #: templates/filebrowser/include/tableheader.html:20 294 | #: templates/filebrowser/include/tableheader.html:21 295 | msgid "Size" 296 | msgstr "Grootte" 297 | 298 | #: templates/filebrowser/include/tableheader.html:23 299 | #: templates/filebrowser/include/tableheader.html:24 300 | msgid "Date" 301 | msgstr "Datum" 302 | 303 | #: templates/filebrowser/include/toolbar.html:14 304 | msgid "Go" 305 | msgstr "Ga" 306 | 307 | #: templates/filebrowser/include/toolbar.html:16 308 | #, python-format 309 | msgid "%(counter)s Item found" 310 | msgid_plural "%(counter)s Items found" 311 | msgstr[0] "%(counter)s object gevonden" 312 | msgstr[1] "%(counter)s objecten gevonden" 313 | 314 | #: templates/filebrowser/include/toolbar.html:17 315 | #, python-format 316 | msgid "%(counter)s Item total" 317 | msgid_plural "%(counter)s Items total" 318 | msgstr[0] "Totaal %(counter)s object" 319 | msgstr[1] "Totaal %(counter)s objecten" 320 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/ru/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/ru/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/sr/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/sr/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/sr/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2009 Janos Guljas 2 | # This file is distributed under the same license as the django-filebrowser package. 3 | # Janos Guljas , 2009. 4 | # 5 | #, fuzzy 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: django-filebrowser 3.0\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2009-11-12 18:14+0100\n" 11 | "PO-Revision-Date: 2009-05-06 22:18+0200\n" 12 | "Last-Translator: Janos Guljas \n" 13 | "Language-Team: Serbian\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" 18 | "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" 19 | 20 | #: fields.py:58 21 | #, python-format 22 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 23 | msgstr "" 24 | "Фајлови са екстензијом %(ext)s нису дозвољени. Само %(allowed)s екстензије " 25 | "су дозвољене." 26 | 27 | #: forms.py:27 templates/filebrowser/versions.html:64 28 | msgid "Name" 29 | msgstr "Назив" 30 | 31 | #: forms.py:27 forms.py:33 forms.py:50 forms.py:56 32 | msgid "Only letters, numbers, underscores, spaces and hyphens are allowed." 33 | msgstr "Само слова, цифре, доња црта и црта су дозвољени карактери." 34 | 35 | #: forms.py:36 forms.py:59 36 | msgid "The Folder already exists." 37 | msgstr "Фолдер већ постоји." 38 | 39 | #: forms.py:50 40 | msgid "New Name" 41 | msgstr "Нови назив" 42 | 43 | #: forms.py:61 44 | msgid "The File already exists." 45 | msgstr "Фајл већ постоји." 46 | 47 | #: settings.py:105 48 | msgid "Folder" 49 | msgstr "Фолдер" 50 | 51 | #: settings.py:106 52 | msgid "Image" 53 | msgstr "Слика" 54 | 55 | #: settings.py:107 56 | msgid "Video" 57 | msgstr "Видео" 58 | 59 | #: settings.py:108 60 | msgid "Document" 61 | msgstr "Документ" 62 | 63 | #: settings.py:109 64 | msgid "Audio" 65 | msgstr "Аудио" 66 | 67 | #: settings.py:110 68 | msgid "Code" 69 | msgstr "Код" 70 | 71 | #: views.py:47 views.py:138 views.py:191 views.py:285 views.py:366 72 | #: views.py:426 73 | msgid "The requested Folder does not exist." 74 | msgstr "Тражен фолдер не постоји." 75 | 76 | #: views.py:51 77 | msgid "Error finding Upload-Folder. Maybe it does not exist?" 78 | msgstr "Фолдер за постављање фајлова не постоји." 79 | 80 | #: views.py:116 templates/filebrowser/append.html:5 81 | #: templates/filebrowser/append.html:7 82 | #: templates/filebrowser/include/breadcrumbs.html:7 83 | #: templates/filebrowser/include/breadcrumbs.html:9 84 | msgid "FileBrowser" 85 | msgstr "Фајл брузер" 86 | 87 | #: views.py:156 88 | #, python-format 89 | msgid "The Folder %s was successfully created." 90 | msgstr "Фолдер %s је успешно направљен." 91 | 92 | #: views.py:164 93 | msgid "Permission denied." 94 | msgstr "Одбијен приступ." 95 | 96 | #: views.py:166 97 | msgid "Error creating folder." 98 | msgstr "Грешка при креирању фолдера." 99 | 100 | #: views.py:173 views.py:175 templates/filebrowser/index.html:57 101 | msgid "New Folder" 102 | msgstr "Нови фолдер" 103 | 104 | #: views.py:203 105 | msgid "Select files to upload" 106 | msgstr "Изаберите фајлове за пренос" 107 | 108 | #: views.py:205 templates/filebrowser/index.html:58 109 | #: templates/filebrowser/upload.html:106 110 | msgid "Upload" 111 | msgstr "Пренос фајла" 112 | 113 | #: views.py:287 views.py:368 views.py:428 114 | msgid "The requested File does not exist." 115 | msgstr "Тражен фајл не постоји" 116 | 117 | #: views.py:310 118 | #, python-format 119 | msgid "The file %s was successfully deleted." 120 | msgstr "Фајл %s је супешно обрисан." 121 | 122 | #: views.py:326 123 | #, python-format 124 | msgid "The folder %s was successfully deleted." 125 | msgstr "Фолдер %s је супешно обрисан." 126 | 127 | #: views.py:395 128 | msgid "Renaming was successful." 129 | msgstr "Успешна промена назива." 130 | 131 | #: views.py:400 132 | msgid "Error." 133 | msgstr "Грешка." 134 | 135 | #: views.py:408 136 | #, python-format 137 | msgid "Rename \"%s\"" 138 | msgstr "Промени назив: „%s“" 139 | 140 | #: views.py:410 templates/filebrowser/include/filelisting.html:73 141 | msgid "Rename" 142 | msgstr "Промени назив" 143 | 144 | #: views.py:436 views.py:438 145 | #, python-format 146 | msgid "Versions for \"%s\"" 147 | msgstr "Верзије за „%s“" 148 | 149 | #: templates/filebrowser/makedir.html:25 templates/filebrowser/rename.html:25 150 | msgid "Please correct the following errors." 151 | msgstr "Исправите следеће грешке." 152 | 153 | #: templates/filebrowser/makedir.html:33 templates/filebrowser/upload.html:96 154 | msgid "" 155 | "The Name will be converted to lowercase. Spaces will be replaced with " 156 | "underscores." 157 | msgstr "" 158 | "Слова у називу ће аутоматски бити конвертована у мала. Празна поља ће бити " 159 | "замењена доњим цртама." 160 | 161 | #: templates/filebrowser/makedir.html:38 templates/filebrowser/rename.html:36 162 | msgid "Submit" 163 | msgstr "Изврши" 164 | 165 | #: templates/filebrowser/upload.html:44 166 | msgid "BROWSE" 167 | msgstr "БИРАЈ" 168 | 169 | #: templates/filebrowser/upload.html:45 170 | msgid "An Error occured" 171 | msgstr "Грешка се десила" 172 | 173 | #: templates/filebrowser/upload.html:46 174 | msgid "Completed" 175 | msgstr "Завршено" 176 | 177 | #: templates/filebrowser/upload.html:47 178 | msgid "Do you want to replace the file" 179 | msgstr "Да ли желите да замените овај фајл?" 180 | 181 | #: templates/filebrowser/upload.html:48 182 | msgid "KB" 183 | msgstr "KB" 184 | 185 | #: templates/filebrowser/upload.html:49 186 | msgid "MB" 187 | msgstr "MB" 188 | 189 | #: templates/filebrowser/upload.html:79 190 | msgid "Help" 191 | msgstr "Помоћ" 192 | 193 | #: templates/filebrowser/upload.html:83 194 | msgid "Allowed" 195 | msgstr "Дозвољено" 196 | 197 | #: templates/filebrowser/upload.html:89 198 | msgid "Max. Filesize" 199 | msgstr "Највећа величина фајла" 200 | 201 | #: templates/filebrowser/upload.html:104 202 | msgid "Clear Queue" 203 | msgstr "Очисти листу" 204 | 205 | #: templates/filebrowser/versions.html:67 206 | msgid "Image Version" 207 | msgstr "Верзија слике" 208 | 209 | #: templates/filebrowser/versions.html:70 210 | msgid "Debug" 211 | msgstr "Исправљање грешака" 212 | 213 | #: templates/filebrowser/versions.html:84 214 | #: templates/filebrowser/include/filelisting.html:10 215 | msgid "Select" 216 | msgstr "Изаберите" 217 | 218 | #: templates/filebrowser/versions.html:96 219 | #: templates/filebrowser/versions.html:108 220 | #: templates/filebrowser/include/filelisting.html:24 221 | #: templates/filebrowser/include/filelisting.html:38 222 | msgid "Select File" 223 | msgstr "Изаберите фајл" 224 | 225 | #: templates/filebrowser/versions.html:119 226 | msgid "Width" 227 | msgstr "Висина" 228 | 229 | #: templates/filebrowser/versions.html:120 230 | msgid "Height" 231 | msgstr "Ширина" 232 | 233 | #: templates/filebrowser/include/breadcrumbs.html:4 234 | msgid "Home" 235 | msgstr "Почетни фолдер" 236 | 237 | #: templates/filebrowser/include/filelisting.html:49 238 | msgid "Show Versions" 239 | msgstr "Прикажи верзије" 240 | 241 | #: templates/filebrowser/include/filelisting.html:60 242 | msgid "View Image" 243 | msgstr "Преглед слике" 244 | 245 | #: templates/filebrowser/include/filelisting.html:85 246 | msgid "Are you sure you want to delete this file?" 247 | msgstr "Да ли сте сигурни да желите да избришете овај фајл?" 248 | 249 | #: templates/filebrowser/include/filelisting.html:85 250 | msgid "Delete File" 251 | msgstr "Избриши фајл" 252 | 253 | #: templates/filebrowser/include/filelisting.html:88 254 | msgid "Are you sure you want to delete this Folder?" 255 | msgstr "Да ли сте сигурни да желите да избришете овај фолдер?" 256 | 257 | #: templates/filebrowser/include/filelisting.html:88 258 | msgid "Delete Folder" 259 | msgstr "Избриши фолдер" 260 | 261 | #: templates/filebrowser/include/filter.html:3 262 | msgid "Filter" 263 | msgstr "Филтер" 264 | 265 | #: templates/filebrowser/include/filter.html:9 266 | msgid "By Date" 267 | msgstr "По датуму" 268 | 269 | #: templates/filebrowser/include/filter.html:11 270 | msgid "Any Date" 271 | msgstr "Сви датуми" 272 | 273 | #: templates/filebrowser/include/filter.html:13 274 | msgid "Today" 275 | msgstr "Данас" 276 | 277 | #: templates/filebrowser/include/filter.html:15 278 | msgid "Past 7 days" 279 | msgstr "Последњих 7 дана" 280 | 281 | #: templates/filebrowser/include/filter.html:17 282 | msgid "Past 30 days" 283 | msgstr "Последњих 30 дана" 284 | 285 | #: templates/filebrowser/include/filter.html:19 286 | msgid "This year" 287 | msgstr "Ове године" 288 | 289 | #: templates/filebrowser/include/filter.html:27 290 | msgid "By Type" 291 | msgstr "По типу" 292 | 293 | #: templates/filebrowser/include/filter.html:29 294 | msgid "All" 295 | msgstr "Сви" 296 | 297 | #: templates/filebrowser/include/paginator.html:4 298 | msgid "No Items Found" 299 | msgstr "Ништа није пронађено." 300 | 301 | #: templates/filebrowser/include/paginator.html:9 302 | #, python-format 303 | msgid "%(counter)s Item" 304 | msgid_plural "%(counter)s Items" 305 | msgstr[0] "%(counter)s ставка" 306 | msgstr[1] "%(counter)s ставки" 307 | 308 | #: templates/filebrowser/include/paginator.html:15 309 | msgid "No Items" 310 | msgstr "Ниједна ставка" 311 | 312 | #: templates/filebrowser/include/search.html:3 313 | #, python-format 314 | msgid "1 result" 315 | msgid_plural "%(counter)s results" 316 | msgstr[0] "1 резултат" 317 | msgstr[1] "%(counter)s резултата" 318 | 319 | #: templates/filebrowser/include/search.html:4 320 | #: templates/filebrowser/include/toolbar.html:9 321 | #, python-format 322 | msgid "%(full_result_count)s total" 323 | msgstr "%(full_result_count)s укупно" 324 | 325 | #: templates/filebrowser/include/search.html:5 326 | msgid "Clear Restrictions" 327 | msgstr "Очисти забране" 328 | 329 | #: templates/filebrowser/include/search.html:7 330 | #: templates/filebrowser/include/toolbar.html:16 331 | msgid "Search" 332 | msgstr "Претрага" 333 | 334 | #: templates/filebrowser/include/search.html:19 335 | msgid "Go" 336 | msgstr "Иди" 337 | 338 | #: templates/filebrowser/include/search.html:24 339 | #, python-format 340 | msgid "%(counter)s Item found" 341 | msgid_plural "%(counter)s Items found" 342 | msgstr[0] "%(counter)s ставка нађена" 343 | msgstr[1] "%(counter)s ставки нађено" 344 | 345 | #: templates/filebrowser/include/search.html:25 346 | #, python-format 347 | msgid "%(counter)s Item total" 348 | msgid_plural "%(counter)s Items total" 349 | msgstr[0] "%(counter)s ставка укупно" 350 | msgstr[1] "%(counter)s ставки укупно" 351 | 352 | #: templates/filebrowser/include/tableheader.html:16 353 | #: templates/filebrowser/include/tableheader.html:17 354 | msgid "Filename" 355 | msgstr "Назив фајла" 356 | 357 | #: templates/filebrowser/include/tableheader.html:21 358 | #: templates/filebrowser/include/tableheader.html:22 359 | msgid "Size" 360 | msgstr "Величина" 361 | 362 | #: templates/filebrowser/include/tableheader.html:24 363 | #: templates/filebrowser/include/tableheader.html:25 364 | msgid "Date" 365 | msgstr "Датум" 366 | 367 | #: templates/filebrowser/include/toolbar.html:6 368 | msgid "Results" 369 | msgstr "Резултати" 370 | 371 | #: templates/filebrowser/include/toolbar.html:8 372 | #, python-format 373 | msgid "%(counter)s result" 374 | msgid_plural "%(counter)s results" 375 | msgstr[0] "%(counter)s резултат" 376 | msgstr[1] "%(counter)s резултата" 377 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/sr_Latn/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/sr_Latn/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/zh_CN/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/zh_CN/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/zh_CN/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: filebrowser 3\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2009-12-20 17:59+0800\n" 11 | "PO-Revision-Date: 2009-12-20 17:58+0800\n" 12 | "Last-Translator: jianaijun \n" 13 | "Language-Team: freeren.org \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=1; plural=0;\n" 18 | "X-Poedit-Language: Chinese\n" 19 | "X-Poedit-Country: CHINA\n" 20 | "X-Poedit-SourceCharset: utf-8\n" 21 | "X-Poedit-Bookmarks: 0,1,-1,-1,-1,-1,-1,-1,-1,-1\n" 22 | 23 | #: fields.py:58 24 | #, python-format 25 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 26 | msgstr "扩展名 %(ext)s 是不允许的。只允许 %(allowed)s 。" 27 | 28 | #: forms.py:27 templates/filebrowser/versions.html:64 29 | msgid "Name" 30 | msgstr "名称" 31 | 32 | #: forms.py:27 forms.py:33 forms.py:50 forms.py:56 33 | msgid "Only letters, numbers, underscores, spaces and hyphens are allowed." 34 | msgstr "只允许字母、数字、下划线、空格和连字符。" 35 | 36 | #: forms.py:36 forms.py:59 37 | msgid "The Folder already exists." 38 | msgstr "这个文件夹已经存在。" 39 | 40 | #: forms.py:50 41 | msgid "New Name" 42 | msgstr "新名称" 43 | 44 | #: forms.py:61 45 | msgid "The File already exists." 46 | msgstr "这个文件已经存在。" 47 | 48 | #: settings.py:114 49 | msgid "Folder" 50 | msgstr "目录" 51 | 52 | #: settings.py:115 53 | msgid "Image" 54 | msgstr "图片" 55 | 56 | #: settings.py:116 57 | msgid "Video" 58 | msgstr "视频" 59 | 60 | #: settings.py:117 61 | msgid "Document" 62 | msgstr "文档" 63 | 64 | #: settings.py:118 65 | msgid "Audio" 66 | msgstr "音频" 67 | 68 | #: settings.py:119 69 | msgid "Code" 70 | msgstr "代码" 71 | 72 | #: views.py:54 views.py:164 views.py:219 views.py:316 views.py:398 73 | #: views.py:459 74 | msgid "The requested Folder does not exist." 75 | msgstr "请求的文件夹不存在。" 76 | 77 | #: views.py:58 78 | msgid "Error finding Upload-Folder. Maybe it does not exist?" 79 | msgstr "查找文件夹发生错误。也许它不存在?" 80 | 81 | #: views.py:141 templates/filebrowser/append.html:5 82 | #: templates/filebrowser/append.html:7 83 | #: templates/filebrowser/include/breadcrumbs.html:8 84 | #: templates/filebrowser/include/breadcrumbs.html:10 85 | msgid "FileBrowser" 86 | msgstr "文件浏览器" 87 | 88 | #: views.py:182 89 | #, python-format 90 | msgid "The Folder %s was successfully created." 91 | msgstr "文件夹 \"%s\" 创建成功。" 92 | 93 | #: views.py:191 94 | msgid "Permission denied." 95 | msgstr "权限被拒绝。" 96 | 97 | #: views.py:193 98 | msgid "Error creating folder." 99 | msgstr "创建文件夹错误。" 100 | 101 | #: views.py:200 views.py:203 templates/filebrowser/index.html:52 102 | msgid "New Folder" 103 | msgstr "创建文件夹" 104 | 105 | #: views.py:231 106 | msgid "Select files to upload" 107 | msgstr "选择上传文件" 108 | 109 | #: views.py:235 templates/filebrowser/index.html:53 110 | #: templates/filebrowser/upload.html:107 111 | msgid "Upload" 112 | msgstr "上传" 113 | 114 | #: views.py:318 views.py:400 views.py:461 115 | msgid "The requested File does not exist." 116 | msgstr "请求的文件不存在。" 117 | 118 | #: views.py:341 119 | #, python-format 120 | msgid "The file %s was successfully deleted." 121 | msgstr "文件 \"%s\" 删除成功。" 122 | 123 | #: views.py:357 124 | #, python-format 125 | msgid "The folder %s was successfully deleted." 126 | msgstr "文件夹 \"%s\" 删除成功。" 127 | 128 | #: views.py:427 129 | msgid "Renaming was successful." 130 | msgstr "重命名成功。" 131 | 132 | #: views.py:432 133 | msgid "Error." 134 | msgstr "错误。" 135 | 136 | #: views.py:440 137 | #, python-format 138 | msgid "Rename \"%s\"" 139 | msgstr "重命名 \"%s\"" 140 | 141 | #: views.py:443 templates/filebrowser/include/filelisting.html:75 142 | msgid "Rename" 143 | msgstr "重命名" 144 | 145 | #: views.py:469 views.py:472 146 | #, python-format 147 | msgid "Versions for \"%s\"" 148 | msgstr "\"%s\" 版本" 149 | 150 | #: templates/filebrowser/makedir.html:25 templates/filebrowser/rename.html:25 151 | msgid "Please correct the following errors." 152 | msgstr "请修正下面的错误。" 153 | 154 | #: templates/filebrowser/makedir.html:33 templates/filebrowser/upload.html:97 155 | msgid "" 156 | "The Name will be converted to lowercase. Spaces will be replaced with " 157 | "underscores." 158 | msgstr "这个名称将自动转换为小写。空格替换为下划线。" 159 | 160 | #: templates/filebrowser/makedir.html:38 templates/filebrowser/rename.html:36 161 | msgid "Submit" 162 | msgstr "保存" 163 | 164 | #: templates/filebrowser/upload.html:45 165 | msgid "BROWSE" 166 | msgstr "浏览..." 167 | 168 | #: templates/filebrowser/upload.html:46 169 | msgid "An Error occured" 170 | msgstr "发生错误" 171 | 172 | #: templates/filebrowser/upload.html:47 173 | msgid "Completed" 174 | msgstr "已完成" 175 | 176 | #: templates/filebrowser/upload.html:48 177 | msgid "Do you want to replace the file" 178 | msgstr "你确定要替换这个文件?" 179 | 180 | #: templates/filebrowser/upload.html:49 181 | msgid "KB" 182 | msgstr "KB" 183 | 184 | #: templates/filebrowser/upload.html:50 185 | msgid "MB" 186 | msgstr "MB" 187 | 188 | #: templates/filebrowser/upload.html:80 189 | msgid "Help" 190 | msgstr "帮助" 191 | 192 | #: templates/filebrowser/upload.html:84 193 | msgid "Allowed" 194 | msgstr "允许" 195 | 196 | #: templates/filebrowser/upload.html:90 197 | msgid "Max. Filesize" 198 | msgstr "最大文件大小" 199 | 200 | #: templates/filebrowser/upload.html:105 201 | msgid "Clear Queue" 202 | msgstr "清除队列" 203 | 204 | #: templates/filebrowser/versions.html:67 205 | msgid "Image Version" 206 | msgstr "图片版本" 207 | 208 | #: templates/filebrowser/versions.html:70 209 | msgid "Debug" 210 | msgstr "调试" 211 | 212 | #: templates/filebrowser/versions.html:84 213 | #: templates/filebrowser/include/filelisting.html:12 214 | msgid "Select" 215 | msgstr "选择" 216 | 217 | #: templates/filebrowser/versions.html:96 218 | #: templates/filebrowser/versions.html:108 219 | #: templates/filebrowser/include/filelisting.html:26 220 | #: templates/filebrowser/include/filelisting.html:40 221 | msgid "Select File" 222 | msgstr "选择文件" 223 | 224 | #: templates/filebrowser/versions.html:119 225 | msgid "Width" 226 | msgstr "宽" 227 | 228 | #: templates/filebrowser/versions.html:120 229 | msgid "Height" 230 | msgstr "高" 231 | 232 | #: templates/filebrowser/include/breadcrumbs.html:5 233 | msgid "Home" 234 | msgstr "首页" 235 | 236 | #: templates/filebrowser/include/filelisting.html:51 237 | msgid "Show Versions" 238 | msgstr "显示版本" 239 | 240 | #: templates/filebrowser/include/filelisting.html:62 241 | msgid "View Image" 242 | msgstr "查看图片" 243 | 244 | #: templates/filebrowser/include/filelisting.html:87 245 | msgid "Are you sure you want to delete this file?" 246 | msgstr "你确定要删除这个文件?" 247 | 248 | #: templates/filebrowser/include/filelisting.html:87 249 | msgid "Delete File" 250 | msgstr "删除文件" 251 | 252 | #: templates/filebrowser/include/filelisting.html:90 253 | msgid "Are you sure you want to delete this Folder?" 254 | msgstr "你确定要删除这个文件夹?" 255 | 256 | #: templates/filebrowser/include/filelisting.html:90 257 | msgid "Delete Folder" 258 | msgstr "删除文件夹" 259 | 260 | #: templates/filebrowser/include/filter.html:3 261 | msgid "Filter" 262 | msgstr "过滤器" 263 | 264 | #: templates/filebrowser/include/filter.html:9 265 | msgid "By Date" 266 | msgstr "以 日期" 267 | 268 | #: templates/filebrowser/include/filter.html:11 269 | msgid "Any Date" 270 | msgstr "任意日期" 271 | 272 | #: templates/filebrowser/include/filter.html:13 273 | msgid "Today" 274 | msgstr "今天" 275 | 276 | #: templates/filebrowser/include/filter.html:15 277 | msgid "Past 7 days" 278 | msgstr "前7天" 279 | 280 | #: templates/filebrowser/include/filter.html:17 281 | msgid "Past 30 days" 282 | msgstr "本月" 283 | 284 | #: templates/filebrowser/include/filter.html:19 285 | msgid "This year" 286 | msgstr "本年" 287 | 288 | #: templates/filebrowser/include/filter.html:27 289 | msgid "By Type" 290 | msgstr "以 类型" 291 | 292 | #: templates/filebrowser/include/filter.html:29 293 | msgid "All" 294 | msgstr "全部" 295 | 296 | #: templates/filebrowser/include/paginator.html:5 297 | msgid "No Items Found" 298 | msgstr "没有找到。" 299 | 300 | #: templates/filebrowser/include/paginator.html:11 301 | #, python-format 302 | msgid "%(counter)s Item" 303 | msgid_plural "%(counter)s Items" 304 | msgstr[0] "%(counter)s 条" 305 | 306 | #: templates/filebrowser/include/paginator.html:26 307 | msgid "No Items" 308 | msgstr "没有项。" 309 | 310 | #: templates/filebrowser/include/search.html:3 311 | #, python-format 312 | msgid "1 result" 313 | msgid_plural "%(counter)s results" 314 | msgstr[0] "1 条结果" 315 | msgstr[1] "%(counter)s 条结果" 316 | 317 | #: templates/filebrowser/include/search.html:4 318 | #: templates/filebrowser/include/toolbar.html:23 319 | #, python-format 320 | msgid "%(full_result_count)s total" 321 | msgstr "共 %(full_result_count)s 条" 322 | 323 | #: templates/filebrowser/include/search.html:5 324 | msgid "Clear Restrictions" 325 | msgstr "清除限制" 326 | 327 | #: templates/filebrowser/include/search.html:7 328 | msgid "Search" 329 | msgstr "搜索" 330 | 331 | #: templates/filebrowser/include/search.html:19 332 | #: templates/filebrowser/include/toolbar.html:20 333 | msgid "Go" 334 | msgstr "执行" 335 | 336 | #: templates/filebrowser/include/search.html:24 337 | #, python-format 338 | msgid "%(counter)s Item found" 339 | msgid_plural "%(counter)s Items found" 340 | msgstr[0] "找到 %(counter)s 条" 341 | msgstr[1] "找到 %(counter)s 条" 342 | 343 | #: templates/filebrowser/include/search.html:25 344 | #, python-format 345 | msgid "%(counter)s Item total" 346 | msgid_plural "%(counter)s Items total" 347 | msgstr[0] "共 %(counter)s 条" 348 | msgstr[1] "共 %(counter)s 条" 349 | 350 | #: templates/filebrowser/include/tableheader.html:16 351 | #: templates/filebrowser/include/tableheader.html:17 352 | msgid "Filename" 353 | msgstr "文件名" 354 | 355 | #: templates/filebrowser/include/tableheader.html:21 356 | #: templates/filebrowser/include/tableheader.html:22 357 | msgid "Size" 358 | msgstr "大小" 359 | 360 | #: templates/filebrowser/include/tableheader.html:24 361 | #: templates/filebrowser/include/tableheader.html:25 362 | msgid "Date" 363 | msgstr "日期" 364 | 365 | #: templates/filebrowser/include/toolbar.html:23 366 | #, python-format 367 | msgid "%(counter)s result" 368 | msgid_plural "%(counter)s results" 369 | msgstr[0] "%(counter)s 条结果" 370 | msgstr[1] "%(counter)s 条结果" 371 | -------------------------------------------------------------------------------- /filebrowser_safe/locale/zh_TW/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/locale/zh_TW/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /filebrowser_safe/locale/zh_TW/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: filebrowser 3\n" 9 | "Report-Msgid-Bugs-To: \n" 10 | "POT-Creation-Date: 2007-12-28 19:23+0800\n" 11 | "PO-Revision-Date: 2009-12-20 17:58+0800\n" 12 | "Last-Translator: jianaijun \n" 13 | "Language-Team: freeren.org \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=1; plural=0;\n" 18 | "X-Poedit-Language: Chinese\n" 19 | "X-Poedit-Country: CHINA\n" 20 | "X-Poedit-SourceCharset: utf-8\n" 21 | "X-Poedit-Bookmarks: 0,1,-1,-1,-1,-1,-1,-1,-1,-1\n" 22 | 23 | #: fields.py:58 24 | #, python-format 25 | msgid "Extension %(ext)s is not allowed. Only %(allowed)s is allowed." 26 | msgstr "擴展名%(ext)s 是不允許的。只允許%(allowed)s 。" 27 | 28 | #: forms.py:27 templates/filebrowser/versions.html:64 29 | msgid "Name" 30 | msgstr "名稱" 31 | 32 | #: forms.py:27 forms.py:33 forms.py:50 forms.py:56 33 | msgid "Only letters, numbers, underscores, spaces and hyphens are allowed." 34 | msgstr "只允許字母、數字、下劃線、空格和連字符。" 35 | 36 | #: forms.py:36 forms.py:59 37 | msgid "The Folder already exists." 38 | msgstr "這個文件夾已經存在。" 39 | 40 | #: forms.py:50 41 | msgid "New Name" 42 | msgstr "新名稱" 43 | 44 | #: forms.py:61 45 | msgid "The File already exists." 46 | msgstr "這個文件已經存在。" 47 | 48 | #: settings.py:114 49 | msgid "Folder" 50 | msgstr "目錄" 51 | 52 | #: settings.py:115 53 | msgid "Image" 54 | msgstr "圖片" 55 | 56 | #: settings.py:116 57 | msgid "Video" 58 | msgstr "視頻" 59 | 60 | #: settings.py:117 61 | msgid "Document" 62 | msgstr "文檔" 63 | 64 | #: settings.py:118 65 | msgid "Audio" 66 | msgstr "音頻" 67 | 68 | #: settings.py:119 69 | msgid "Code" 70 | msgstr "代碼" 71 | 72 | #: views.py:54 views.py:164 views.py:219 views.py:316 views.py:398 73 | #: views.py:459 74 | msgid "The requested Folder does not exist." 75 | msgstr "請求的文件夾不存在。" 76 | 77 | #: views.py:58 78 | msgid "Error finding Upload-Folder. Maybe it does not exist?" 79 | msgstr "查找文件夾發生錯誤。也許它不存在?" 80 | 81 | #: views.py:141 templates/filebrowser/append.html:5 82 | #: templates/filebrowser/append.html:7 83 | #: templates/filebrowser/include/breadcrumbs.html:8 84 | #: templates/filebrowser/include/breadcrumbs.html:10 85 | msgid "FileBrowser" 86 | msgstr "文件瀏覽器" 87 | 88 | #: views.py:182 89 | #, python-format 90 | msgid "The Folder %s was successfully created." 91 | msgstr "文件夾 \"%s\" 創建成功。" 92 | 93 | #: views.py:191 94 | msgid "Permission denied." 95 | msgstr "權限被拒絕。" 96 | 97 | #: views.py:193 98 | msgid "Error creating folder." 99 | msgstr "創建文件夾錯誤。" 100 | 101 | #: views.py:200 views.py:203 templates/filebrowser/index.html:52 102 | msgid "New Folder" 103 | msgstr "創建文件夾" 104 | 105 | #: views.py:231 106 | msgid "Select files to upload" 107 | msgstr "選擇上傳文件" 108 | 109 | #: views.py:235 templates/filebrowser/index.html:53 110 | #: templates/filebrowser/upload.html:108 111 | msgid "Upload" 112 | msgstr "上傳" 113 | 114 | #: views.py:318 views.py:400 views.py:461 115 | msgid "The requested File does not exist." 116 | msgstr "請求的文件不存在。" 117 | 118 | #: views.py:341 119 | #, python-format 120 | msgid "The file %s was successfully deleted." 121 | msgstr "文件 \"%s\" 刪除成功。" 122 | 123 | #: views.py:357 124 | #, python-format 125 | msgid "The folder %s was successfully deleted." 126 | msgstr "文件夾 \"%s\" 刪除成功。" 127 | 128 | #: views.py:427 129 | msgid "Renaming was successful." 130 | msgstr "重命名成功。" 131 | 132 | #: views.py:432 133 | msgid "Error." 134 | msgstr "錯誤。" 135 | 136 | #: views.py:440 137 | #, python-format 138 | msgid "Rename \"%s\"" 139 | msgstr "重命名 \"%s\"" 140 | 141 | #: views.py:443 templates/filebrowser/include/filelisting.html:75 142 | msgid "Rename" 143 | msgstr "重命名" 144 | 145 | #: views.py:469 views.py:472 146 | #, python-format 147 | msgid "Versions for \"%s\"" 148 | msgstr "\"%s\" 版本" 149 | 150 | #: templates/filebrowser/makedir.html:25 templates/filebrowser/rename.html:25 151 | msgid "Please correct the following errors." 152 | msgstr "請修正下面的錯誤。" 153 | 154 | #: templates/filebrowser/makedir.html:33 templates/filebrowser/upload.html:98 155 | msgid "" 156 | "The Name will be converted to lowercase. Spaces will be replaced with " 157 | "underscores." 158 | msgstr "這個名稱將自動轉換為小寫。空格替換為下劃線。" 159 | 160 | #: templates/filebrowser/makedir.html:38 templates/filebrowser/rename.html:36 161 | msgid "Submit" 162 | msgstr "保存" 163 | 164 | #: templates/filebrowser/upload.html:46 165 | msgid "BROWSE" 166 | msgstr "瀏覽..." 167 | 168 | #: templates/filebrowser/upload.html:47 169 | msgid "An Error occured" 170 | msgstr "發生錯誤" 171 | 172 | #: templates/filebrowser/upload.html:48 173 | msgid "Completed" 174 | msgstr "已完成" 175 | 176 | #: templates/filebrowser/upload.html:49 177 | msgid "Do you want to replace the file" 178 | msgstr "你確定要替換這個文件?" 179 | 180 | #: templates/filebrowser/upload.html:50 181 | msgid "KB" 182 | msgstr "KB" 183 | 184 | #: templates/filebrowser/upload.html:51 185 | msgid "MB" 186 | msgstr "MB" 187 | 188 | #: templates/filebrowser/upload.html:81 189 | msgid "Help" 190 | msgstr "幫助" 191 | 192 | #: templates/filebrowser/upload.html:85 193 | msgid "Allowed" 194 | msgstr "允許" 195 | 196 | #: templates/filebrowser/upload.html:91 197 | msgid "Max. Filesize" 198 | msgstr "最大文件大小" 199 | 200 | #: templates/filebrowser/upload.html:106 201 | msgid "Clear Queue" 202 | msgstr "清除隊列" 203 | 204 | #: templates/filebrowser/versions.html:67 205 | msgid "Image Version" 206 | msgstr "圖片版本" 207 | 208 | #: templates/filebrowser/versions.html:70 209 | msgid "Debug" 210 | msgstr "調試" 211 | 212 | #: templates/filebrowser/versions.html:84 213 | #: templates/filebrowser/include/filelisting.html:12 214 | msgid "Select" 215 | msgstr "選擇" 216 | 217 | #: templates/filebrowser/versions.html:96 218 | #: templates/filebrowser/versions.html:108 219 | #: templates/filebrowser/include/filelisting.html:26 220 | #: templates/filebrowser/include/filelisting.html:40 221 | msgid "Select File" 222 | msgstr "選擇文件" 223 | 224 | #: templates/filebrowser/versions.html:119 225 | msgid "Width" 226 | msgstr "寬" 227 | 228 | #: templates/filebrowser/versions.html:120 229 | msgid "Height" 230 | msgstr "高" 231 | 232 | #: templates/filebrowser/include/breadcrumbs.html:5 233 | msgid "Home" 234 | msgstr "首頁" 235 | 236 | #: templates/filebrowser/include/filelisting.html:51 237 | msgid "Show Versions" 238 | msgstr "顯示版本" 239 | 240 | #: templates/filebrowser/include/filelisting.html:62 241 | msgid "View Image" 242 | msgstr "查看圖片" 243 | 244 | #: templates/filebrowser/include/filelisting.html:87 245 | msgid "Are you sure you want to delete this file?" 246 | msgstr "你確定要刪除這個文件?" 247 | 248 | #: templates/filebrowser/include/filelisting.html:87 249 | msgid "Delete File" 250 | msgstr "刪除文件" 251 | 252 | #: templates/filebrowser/include/filelisting.html:90 253 | msgid "Are you sure you want to delete this Folder?" 254 | msgstr "你確定要刪除這個文件夾?" 255 | 256 | #: templates/filebrowser/include/filelisting.html:90 257 | msgid "Delete Folder" 258 | msgstr "刪除文件夾" 259 | 260 | #: templates/filebrowser/include/filter.html:3 261 | msgid "Filter" 262 | msgstr "過濾器" 263 | 264 | #: templates/filebrowser/include/filter.html:9 265 | msgid "By Date" 266 | msgstr "以 日期" 267 | 268 | #: templates/filebrowser/include/filter.html:11 269 | msgid "Any Date" 270 | msgstr "任意日期" 271 | 272 | #: templates/filebrowser/include/filter.html:13 273 | msgid "Today" 274 | msgstr "今天" 275 | 276 | #: templates/filebrowser/include/filter.html:15 277 | msgid "Past 7 days" 278 | msgstr "前7天" 279 | 280 | #: templates/filebrowser/include/filter.html:17 281 | msgid "Past 30 days" 282 | msgstr "本月" 283 | 284 | #: templates/filebrowser/include/filter.html:19 285 | msgid "This year" 286 | msgstr "本年" 287 | 288 | #: templates/filebrowser/include/filter.html:27 289 | msgid "By Type" 290 | msgstr "以 類型" 291 | 292 | #: templates/filebrowser/include/filter.html:29 293 | msgid "All" 294 | msgstr "全部" 295 | 296 | #: templates/filebrowser/include/paginator.html:5 297 | msgid "No Items Found" 298 | msgstr "沒有找到。" 299 | 300 | #: templates/filebrowser/include/paginator.html:11 301 | #, python-format 302 | msgid "%(counter)s Item" 303 | msgid_plural "%(counter)s Items" 304 | msgstr[0] "%(counter)s 條" 305 | 306 | #: templates/filebrowser/include/paginator.html:26 307 | msgid "No Items" 308 | msgstr "沒有項。" 309 | 310 | #: templates/filebrowser/include/search.html:3 311 | #, python-format 312 | msgid "1 result" 313 | msgid_plural "%(counter)s results" 314 | msgstr[0] "1 條結果" 315 | msgstr[1] "%(counter)s 條結果" 316 | 317 | #: templates/filebrowser/include/search.html:4 318 | #: templates/filebrowser/include/toolbar.html:23 319 | #, python-format 320 | msgid "%(full_result_count)s total" 321 | msgstr "共 %(full_result_count)s 條" 322 | 323 | #: templates/filebrowser/include/search.html:5 324 | msgid "Clear Restrictions" 325 | msgstr "清除限制" 326 | 327 | #: templates/filebrowser/include/search.html:7 328 | msgid "Search" 329 | msgstr "搜索" 330 | 331 | #: templates/filebrowser/include/search.html:19 332 | #: templates/filebrowser/include/toolbar.html:20 333 | msgid "Go" 334 | msgstr "執行" 335 | 336 | #: templates/filebrowser/include/search.html:24 337 | #, python-format 338 | msgid "%(counter)s Item found" 339 | msgid_plural "%(counter)s Items found" 340 | msgstr[0] "找到 %(counter)s 條" 341 | msgstr[1] "找到 %(counter)s 條" 342 | 343 | #: templates/filebrowser/include/search.html:25 344 | #, python-format 345 | msgid "%(counter)s Item total" 346 | msgid_plural "%(counter)s Items total" 347 | msgstr[0] "共 %(counter)s 條" 348 | msgstr[1] "共 %(counter)s 條" 349 | 350 | #: templates/filebrowser/include/tableheader.html:16 351 | #: templates/filebrowser/include/tableheader.html:17 352 | msgid "Filename" 353 | msgstr "文件名" 354 | 355 | #: templates/filebrowser/include/tableheader.html:21 356 | #: templates/filebrowser/include/tableheader.html:22 357 | msgid "Size" 358 | msgstr "大小" 359 | 360 | #: templates/filebrowser/include/tableheader.html:24 361 | #: templates/filebrowser/include/tableheader.html:25 362 | msgid "Date" 363 | msgstr "日期" 364 | 365 | #: templates/filebrowser/include/toolbar.html:23 366 | #, python-format 367 | msgid "%(counter)s result" 368 | msgid_plural "%(counter)s results" 369 | msgstr[0] "%(counter)s 條結果" 370 | msgstr[1] "%(counter)s 條結果" 371 | -------------------------------------------------------------------------------- /filebrowser_safe/models.py: -------------------------------------------------------------------------------- 1 | # This file is only necessary for the tests to work 2 | -------------------------------------------------------------------------------- /filebrowser_safe/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.conf import settings 4 | from django.utils.translation import gettext_lazy as _ 5 | 6 | DEFAULT_URL_TINYMCE = settings.STATIC_URL + "grappelli/tinymce/jscripts/tiny_mce/" 7 | DEFAULT_PATH_TINYMCE = os.path.join( 8 | settings.MEDIA_ROOT, "admin/tinymce/jscripts/tiny_mce/" 9 | ) 10 | 11 | # Set to True in order to see the FileObject when Browsing. 12 | DEBUG = getattr(settings, "FILEBROWSER_DEBUG", False) 13 | 14 | # Main Media Settings 15 | MEDIA_ROOT = getattr(settings, "FILEBROWSER_MEDIA_ROOT", settings.MEDIA_ROOT) 16 | MEDIA_URL = getattr(settings, "FILEBROWSER_MEDIA_URL", settings.MEDIA_URL) 17 | 18 | # Main FileBrowser Directory. This has to be a directory within MEDIA_ROOT. 19 | # Leave empty in order to browse all files under MEDIA_ROOT. 20 | # DO NOT USE A SLASH AT THE BEGINNING, DO NOT FORGET THE TRAILING SLASH AT THE END. 21 | DIRECTORY = getattr(settings, "FILEBROWSER_DIRECTORY", "uploads/") 22 | 23 | # The URL/PATH to your filebrowser media-files. 24 | URL_FILEBROWSER_MEDIA = getattr( 25 | settings, 26 | "FILEBROWSER_URL_FILEBROWSER_MEDIA", 27 | "%sfilebrowser/" % settings.STATIC_URL, 28 | ) 29 | PATH_FILEBROWSER_MEDIA = getattr( 30 | settings, 31 | "FILEBROWSER_PATH_FILEBROWSER_MEDIA", 32 | os.path.join(settings.MEDIA_ROOT, "filebrowser/"), 33 | ) 34 | 35 | # The URL/PATH to your TinyMCE Installation. 36 | URL_TINYMCE = getattr(settings, "FILEBROWSER_URL_TINYMCE", DEFAULT_URL_TINYMCE) 37 | PATH_TINYMCE = getattr(settings, "FILEBROWSER_PATH_TINYMCE", DEFAULT_PATH_TINYMCE) 38 | 39 | # Allowed Extensions for File Upload. Lower case is important. 40 | # Please be aware that there are Icons for the default extension settings. 41 | # Therefore, if you add a category (e.g. "Misc"), you won't get an icon. 42 | EXTENSIONS = { 43 | "Folder": [""], 44 | "Image": [".jpg", ".jpeg", ".gif", ".png", ".tif", ".tiff", ".svg"], 45 | "Video": [".mov", ".wmv", ".mpeg", ".mpg", ".avi", ".rm", ".mp4"], 46 | "Document": [".pdf", ".doc", ".rtf", ".txt", ".xls", ".csv", ".docx"], 47 | "Audio": [".mp3", ".wav", ".aiff", ".midi", ".m4p"], 48 | "Code": [".html", ".py", ".js", ".css"], 49 | } 50 | EXTENSIONS.update(getattr(settings, "FILEBROWSER_EXTENSIONS", {})) 51 | 52 | ESCAPED_EXTENSIONS = getattr( 53 | settings, "FILEBROWSER_ESCAPED_EXTENSIONS", ("html", "svg") 54 | ) 55 | 56 | # Define different formats for allowed selections. 57 | # This has to be a subset of EXTENSIONS. 58 | SELECT_FORMATS = { 59 | "File": ["Folder", "Document"], 60 | "Image": ["Image"], 61 | "Media": ["Video", "Audio"], 62 | "Document": ["Document"], 63 | # for TinyMCE we can also define lower-case items 64 | "image": ["Image"], 65 | "file": ["Folder", "Image", "Document"], 66 | "media": ["Video", "Audio"], 67 | } 68 | SELECT_FORMATS.update(getattr(settings, "FILEBROWSER_SELECT_FORMATS", {})) 69 | 70 | # EXTRA SETTINGS 71 | # True to save the URL including STATIC_URL to your model fields 72 | # or False (default) to save path relative to STATIC_URL. 73 | # Note: Full URL does not necessarily means absolute URL. 74 | SAVE_FULL_URL = getattr(settings, "FILEBROWSER_SAVE_FULL_URL", True) 75 | # If set to True, the FileBrowser will not try to import a mis-installed PIL. 76 | STRICT_PIL = getattr(settings, "FILEBROWSER_STRICT_PIL", False) 77 | # PIL's Error "Suspension not allowed here" work around: 78 | # s. http://mail.python.org/pipermail/image-sig/1999-August/000816.html 79 | IMAGE_MAXBLOCK = getattr(settings, "FILEBROWSER_IMAGE_MAXBLOCK", 1024 * 1024) 80 | # Exclude files matching any of the following regular expressions 81 | # Default is to exclude 'thumbnail' style naming of image-thumbnails. 82 | EXTENSION_LIST = [] 83 | for exts in list(EXTENSIONS.values()): 84 | EXTENSION_LIST += exts 85 | EXCLUDE = getattr( 86 | settings, 87 | "FILEBROWSER_EXCLUDE", 88 | (r"_({exts})_.*_q\d{{1,3}}\.({exts})".format(exts=("|".join(EXTENSION_LIST))),), 89 | ) 90 | # Max. Upload Size in Bytes. 91 | MAX_UPLOAD_SIZE = getattr( 92 | settings, "FILEBROWSER_MAX_UPLOAD_SIZE", settings.FILE_UPLOAD_MAX_MEMORY_SIZE 93 | ) 94 | # Normalize filename and remove all non-alphanumeric characters 95 | # except for underscores, spaces & dashes. 96 | NORMALIZE_FILENAME = getattr(settings, "FILEBROWSER_NORMALIZE_FILENAME", False) 97 | # Convert Filename (replace spaces and convert to lowercase) 98 | CONVERT_FILENAME = getattr(settings, "FILEBROWSER_CONVERT_FILENAME", True) 99 | # Max. Entries per Page 100 | # Loading a Sever-Directory with lots of files might take a while 101 | # Use this setting to limit the items shown 102 | LIST_PER_PAGE = getattr(settings, "FILEBROWSER_LIST_PER_PAGE", 50) 103 | # Default Sorting 104 | # Options: date, filesize, filename_lower, filetype_checked 105 | DEFAULT_SORTING_BY = getattr(settings, "FILEBROWSER_DEFAULT_SORTING_BY", "date") 106 | # Sorting Order: asc, desc 107 | DEFAULT_SORTING_ORDER = getattr(settings, "FILEBROWSER_DEFAULT_SORTING_ORDER", "desc") 108 | # regex to clean dir names before creation 109 | FOLDER_REGEX = getattr(settings, "FILEBROWSER_FOLDER_REGEX", r"^[\sa-zA-Z0-9_/-]+$") 110 | 111 | # EXTRA TRANSLATION STRINGS 112 | # The following strings are not availabe within views or templates 113 | _("Folder") 114 | _("Image") 115 | _("Video") 116 | _("Document") 117 | _("Audio") 118 | _("Code") 119 | -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/css/filebrowser.css: -------------------------------------------------------------------------------- 1 | .filebrowser table td { font-size: 10px; } 2 | .filebrowser table a { font-size: 11px; } 3 | .filebrowser thead th.sorted a { padding-right: 13px; } 4 | .filebrowser td { padding: 9px 10px 7px 10px !important; } 5 | .filebrowser td.fb_icon { padding: 6px 5px 5px 5px !important; } 6 | .filebrowser td.fb_icon img { max-width: 100px; } 7 | 8 | table a.fb_deletelink, table a.fb_renamelink, table a.fb_selectlink, table a.fb_showversionslink { 9 | cursor: pointer; 10 | display: block; padding: 0; margin: 0; 11 | width: 23px; height: 17px; 12 | background-color: transparent; 13 | background-position: 0 center; 14 | background-repeat: no-repeat; 15 | } 16 | 17 | table .fb_deletelink:link, table .fb_deletelink:visited { 18 | width: 15px; 19 | background-image: url('../img/filebrowser_icon_delete.gif'); 20 | } 21 | table .fb_deletelink:hover, table .fb_deletelink:active { background-image: url('../img/filebrowser_icon_delete_hover.gif'); } 22 | table .fb_renamelink:link, table .fb_renamelink:visited { 23 | width: 14px; 24 | background-image: url('../img/filebrowser_icon_rename.gif'); 25 | } 26 | table .fb_renamelink:hover, table .fb_renamelink:active { background-image: url('../img/filebrowser_icon_rename_hover.gif'); } 27 | table .fb_selectlink:link, table .fb_selectlink:visited { background-image: url('../img/filebrowser_icon_select.gif'); } 28 | table .fb_selectlink:hover, table .fb_selectlink:active { background-image: url('../img/filebrowser_icon_select_hover.gif'); } 29 | table .fb_showversionslink:link, table .fb_showversionslink:visited { background-image: url('../img/filebrowser_icon_showversions.gif'); } 30 | table .fb_showversionslink:hover, table .fb_showversionslink:active { background-image: url('../img/filebrowser_icon_showversions_hover.gif'); } 31 | 32 | .file-input-wrapper{ 33 | margin-bottom: 10px; 34 | position: relative; 35 | } 36 | 37 | .file-input-wrapper:last-of-type{ 38 | margin: 0; 39 | } 40 | 41 | /* 42 | these had to be copied from grapelli, because theirs are 43 | limited to buttons and input[type="submit"] 44 | */ 45 | .file-input-wrapper .button{ 46 | padding: 7px 15px; 47 | font-size: 15px !important; 48 | background: #309bbf; 49 | color:#fff; 50 | margin: 0; 51 | width: auto; 52 | border-radius: 5px; 53 | float: none; 54 | display: inline-block; 55 | line-height: 1; 56 | cursor: pointer; 57 | vertical-align: middle; 58 | } 59 | 60 | .file-input-wrapper .button-error{ 61 | background: #bf3030; 62 | } 63 | 64 | .file-input-wrapper .button:hover{ 65 | background: #444; 66 | } 67 | 68 | .file-input-wrapper span{ 69 | margin-left: 10px; 70 | } 71 | 72 | .file-input-wrapper .progress{ 73 | background: #b3b3b3; 74 | position: relative; 75 | width: 200px; 76 | height: 30px; 77 | border-radius: 5px; 78 | overflow: hidden; 79 | vertical-align: middle; 80 | display: inline-block; 81 | } 82 | 83 | .file-input-wrapper .progress-inner, .file-input-wrapper .progress-inner:before{ 84 | position: absolute; 85 | height: 100%; 86 | top: 0; 87 | left: 0; 88 | } 89 | 90 | .file-input-wrapper .progress-inner{ 91 | width: 0; 92 | color:#fff; 93 | background: #309bbf; 94 | line-height: 30px; 95 | text-align: center; 96 | transition: all 0.3s ease; 97 | -webkit-transition: all 0.3s ease; 98 | } 99 | 100 | .file-input-wrapper .progress-inner:before{ 101 | width: 100%; 102 | content: attr(data-percentage); 103 | } 104 | 105 | .file-input-wrapper .error{ 106 | color: #f00; 107 | } 108 | .file-input-result { 109 | margin: .5em 0; 110 | } 111 | /* 112 | note that some browsers don't allow 113 | input[type="file"] to be display:none 114 | */ 115 | .file-input-wrapper input[type="file"], 116 | .file-input-wrapper .hide, 117 | .file-input-result.selected .hide-selected, 118 | .file-input-result.in-progress .hide-in-progress, 119 | .file-input-result.done .hide-done{ 120 | position: absolute; 121 | top: 0; 122 | left: -9999em; 123 | } 124 | 125 | .file-input-result.selected .show-selected, 126 | .file-input-result.in-progress .show-in-progress, 127 | .file-input-result.done .show-done{ 128 | position: relative; 129 | top: auto; 130 | left: auto; 131 | } 132 | -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/css/rtl.css: -------------------------------------------------------------------------------- 1 | .filebrowser table th a { 2 | font-size: 16px; 3 | line-height: 19px; 4 | } 5 | 6 | .filebrowser table a { 7 | font-size: 14px; 8 | line-height: 17px; 9 | } 10 | 11 | .filebrowser table td { 12 | font-size: 14px; 13 | line-height: 17px; 14 | } 15 | 16 | .filebrowser thead th.sorted a:after { 17 | padding-right: 8px; 18 | } 19 | 20 | /* filebrowser popup */ 21 | 22 | .filebrowser.popup #content { 23 | margin: 35px 0px 15px !important; 24 | padding: 0px 20px; 25 | } 26 | 27 | .filebrowser.popup.change-form div.submit-row { 28 | right: 0px; 29 | } 30 | -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_delete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_delete.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_delete_hover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_delete_hover.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_rename.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_rename.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_rename_hover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_rename_hover.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_select.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_select.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_select_disabled.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_select_disabled.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_select_hover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_select_hover.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_show.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_show.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_show_hover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_show_hover.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_showversions.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_showversions.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_icon_showversions_hover.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_icon_showversions_hover.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_audio.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_audio.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_code.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_code.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_document.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_document.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_folder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_folder.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_image.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_image.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/img/filebrowser_type_video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/static/filebrowser/img/filebrowser_type_video.gif -------------------------------------------------------------------------------- /filebrowser_safe/static/filebrowser/js/AddFileBrowser.js: -------------------------------------------------------------------------------- 1 | var FileBrowser = { 2 | // this is set automatically 3 | admin_media_prefix: '', 4 | // change this 5 | thumb_prefix: 'thumb_', 6 | no_thumb: 'filebrowser/img/no_thumb.gif', 7 | 8 | init: function() { 9 | // Deduce admin_media_prefix by looking at the 32 | -------------------------------------------------------------------------------- /filebrowser_safe/templates/filebrowser/include/tableheader.html: -------------------------------------------------------------------------------- 1 | {% load i18n fb_tags %} 2 | 3 | 4 | 5 | {% if query.pop == '1' %}{% if results_var.select_total %}{% endif %}{% endif %} 6 | {% if query.pop == '2' %}{% if results_var.select_total %}{% endif %}{% endif %} 7 | {% if query.pop == '3' %}{% if results_var.select_total %}{% endif %}{% endif %} 8 | {% if query.pop == '4' %}{% if results_var.select_total %}{% endif %}{% endif %} 9 | {% if query.pop == '5' %}{% if results_var.select_total %}{% endif %}{% endif %} 10 | 11 | {% if query.o == 'filetype' %}{% endif %} 12 | {% if query.o != 'filetype' %} {% endif %} 13 | 14 | {% if results_var.images_total %} {% endif %} 15 | 16 | {% if query.o == 'filename_lower' %}{% trans 'Filename' %}{% endif %} 17 | {% if query.o != 'filename_lower' %}{% trans 'Filename' %}{% endif %} 18 | 19 | {% if query.pop != '4' %} 20 |   21 | {% endif %} 22 | 23 | {% if query.o == 'filesize' %}{% trans 'Size' %}{% endif %} 24 | {% if query.o != 'filesize' %}{% trans 'Size' %}{% endif %} 25 | 26 | {% if query.o == 'date' %}{% trans 'Date' %}{% endif %} 27 | {% if query.o != 'date' %}{% trans 'Date' %}{% endif %} 28 | 29 |   30 | {% if settings_var.DEBUG %}Debug{% endif %} 31 | 32 | 33 | -------------------------------------------------------------------------------- /filebrowser_safe/templates/filebrowser/include/toolbar.html: -------------------------------------------------------------------------------- 1 | {% load i18n static fb_tags %} 2 | 3 | {% if results_var.results_total %} 4 | {% if query.filter_type or query.filter_date or query.q %} 5 |
6 |

{% trans 'Results' %}

7 |
8 |

{% blocktrans count results_var.results_current as counter %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %}

9 |

{% blocktrans with results_var.results_total as full_result_count %}{{ full_result_count }} total{% endblocktrans %}

10 |
11 |
12 | {% endif %} 13 | {% endif %} 14 | 15 | 36 | 37 | -------------------------------------------------------------------------------- /filebrowser_safe/templates/filebrowser/index.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | 4 | {% load i18n static fb_tags fb_pagination %} 5 | 6 | 7 | {% block stylesheets %} 8 | {{ block.super }} 9 | 10 | 11 | {% endblock %} 12 | 13 | 14 | {% block extrahead %} 15 | {{ block.super }} 16 | 17 | {% if query.pop == '1' %} 18 | 19 | {% endif %} 20 | 21 | {% if query.pop == '2' %} 22 | 23 | 24 | {% if query.mce_rdomain %}{% endif %} 25 | {% endif %} 26 | 27 | {% if query.pop == '3' %} 28 | 29 | {% endif %} 30 | 31 | {% if query.pop == '5' %} 32 | 33 | {% endif %} 34 | 35 | 36 | 37 | {% if not actions_on_top and not actions_on_bottom %} 38 | 41 | {% endif %} 42 | {% endblock extrahead %} 43 | 44 | {% block rtl_styles %} 45 | {{ block.super }} 46 | 47 | {% endblock %} 48 | 49 | 50 | {% block coltype %}flex{% endblock %} 51 | {% block bodyclass %}change-list filebrowser{% if query.pop %} popup{% endif %}{% endblock %} 52 | 53 | {% block content_title %}

{% include "filebrowser/include/breadcrumbs.html" %}

{% endblock %} 54 | {% block breadcrumbs %}{% endblock %} 55 | 56 | 57 | {% block content %} 58 |
59 | {% block object-tools %} 60 | 64 | {% endblock %} 65 |
66 |
67 |
68 | {% if results_var.results_current %} 69 |
70 | 71 | {% include "filebrowser/include/tableheader.html" %} 72 | 73 | {% include "filebrowser/include/filelisting.html" %} 74 | 75 |
76 |
77 | {% endif %} 78 | {% pagination %} 79 |
80 |
81 |
82 | {% include "filebrowser/include/toolbar.html" %} 83 |
84 | {% include "filebrowser/include/filter.html" %} 85 |
86 |
87 |
88 |
89 | {% endblock %} 90 | -------------------------------------------------------------------------------- /filebrowser_safe/templates/filebrowser/makedir.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | 4 | {% load i18n static fb_tags %} 5 | 6 | 7 | {% block stylesheets %} 8 | {{ block.super }} 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block rtl_styles %} 14 | {{ block.super }} 15 | 16 | {% endblock %} 17 | 18 | 19 | {% block coltype %}colM{% endblock %} 20 | {% block bodyclass %}change-form filebrowser{% if query.pop %} popup{% endif %}{% endblock %} 21 | 22 | {% block content_title %}

{% include "filebrowser/include/breadcrumbs.html" %}

{% endblock %} 23 | {% block breadcrumbs %}{% endblock %} 24 | 25 | 26 | {% block content %} 27 |
28 |
{% csrf_token %} 29 |
30 | {% if form.errors %}

{% trans 'Please correct the following errors.' %}

{% endif %} 31 |
32 |
33 | {% if form.dir_name.errors %}
    {{ form.dir_name.errors }}
{% endif %} 34 | 35 | {{ form.dir_name }} 36 |

37 | {{ form.dir_name.help_text|safe }} 38 | {% if settings_var.CONVERT_FILENAME %}
{% trans "The Name will be converted to lowercase. Spaces will be replaced with underscores." %}{% endif %} 39 |

40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | {% endblock %} 49 | -------------------------------------------------------------------------------- /filebrowser_safe/templates/filebrowser/rename.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | 4 | {% load i18n static fb_tags %} 5 | 6 | 7 | {% block stylesheets %} 8 | {{ block.super }} 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block rtl_styles %} 14 | {{ block.super }} 15 | 16 | {% endblock %} 17 | 18 | 19 | {% block coltype %}colM{% endblock %} 20 | {% block bodyclass %}change-form filebrowser{% if query.pop %} popup{% endif %}{% endblock %} 21 | 22 | {% block content_title %}

{% include "filebrowser/include/breadcrumbs.html" %}

{% endblock %} 23 | {% block breadcrumbs %}{% endblock %} 24 | 25 | 26 | {% block content %} 27 |
28 |
29 | {% csrf_token %} 30 |
31 | {% if form.errors %}

{% trans 'Please correct the following errors.' %}

{% endif %} 32 |
33 |
34 | {% if form.name.errors %}
    {{ form.name.errors }}
{% endif %} 35 | 36 | {{ form.name }} 37 | {% if file_extension %}{{ file_extension }}{% endif %} 38 | {% if form.name.help_text %}

{{ form.name.help_text|safe }}

{% endif %} 39 |
40 |
41 |
42 | 43 |
44 |
45 |
46 |
47 | {% endblock %} 48 | -------------------------------------------------------------------------------- /filebrowser_safe/templates/filebrowser/upload.html: -------------------------------------------------------------------------------- 1 | {% extends "admin/base_site.html" %} 2 | 3 | 4 | {% load i18n l10n static fb_tags %} 5 | 6 | 7 | {% block stylesheets %} 8 | {{ block.super }} 9 | 10 | 11 | {% endblock %} 12 | 13 | {% block rtl_styles %} 14 | {{ block.super }} 15 | 16 | {% endblock %} 17 | 18 | 19 | {% block extrahead %} 20 | {{ block.super }} 21 | 22 | {% endblock extrahead %} 23 | 24 | 25 | {% block coltype %}colM{% endblock %} 26 | {% block bodyclass %}change-form filebrowser{% if query.pop %} popup{% endif %}{% endblock %} 27 | 28 | {% block content_title %}

{% include "filebrowser/include/breadcrumbs.html" %}

{% endblock %} 29 | {% block breadcrumbs %}{% endblock %} 30 | 31 | 32 | {% block content %} 33 |
34 |
47 | 48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | {% trans 'Remove' %} 58 |
59 | 60 |
61 | 65 |
66 | 67 | {% csrf_token %} 68 | 69 | 70 | 71 |
72 |
73 | 74 |
75 |

{% trans "Help" %}

76 |
77 | {% for extension in settings_var.EXTENSIONS.items %} 78 | {% if extension.1 and extension.0 != 'Folder' %} 79 | 80 |

{{ extension.0|safe }} ({{ extension.1|join:", "|safe }})

81 | {% endif %} 82 | {% endfor %} 83 |
84 |
85 | 86 |

{{ settings_var.MAX_UPLOAD_SIZE|filesizeformat }}

87 |
88 | {% if settings_var.CONVERT_FILENAME %} 89 |
90 | 91 |

92 | {% trans "The Name will be converted to lowercase. Spaces will be replaced with underscores." %} 93 |

94 |
95 | {% endif %} 96 |
97 |

{% trans "Once you've selected all the files you want to upload, click the upload button in the bottom right corner to begin the upload process." %}

98 | 99 |
100 | 103 | 104 |
105 | 106 |
107 |
108 |
109 | {% endblock %} 110 | -------------------------------------------------------------------------------- /filebrowser_safe/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/filebrowser_safe/templatetags/__init__.py -------------------------------------------------------------------------------- /filebrowser_safe/templatetags/fb_pagination.py: -------------------------------------------------------------------------------- 1 | from django.template import Library 2 | 3 | register = Library() 4 | 5 | DOT = "." 6 | 7 | 8 | @register.inclusion_tag("filebrowser/include/paginator.html", takes_context=True) 9 | def pagination(context): 10 | page_num = context["page"].number - 1 11 | paginator = context["p"] 12 | 13 | if not paginator.num_pages or paginator.num_pages == 1: 14 | page_range = [] 15 | else: 16 | ON_EACH_SIDE = 3 17 | ON_ENDS = 2 18 | 19 | # If there are 10 or fewer pages, display links to every page. 20 | # Otherwise, do some fancy 21 | if paginator.num_pages <= 10: 22 | page_range = list(range(paginator.num_pages)) 23 | else: 24 | # Insert "smart" pagination links, so that there are always ON_ENDS 25 | # links at either end of the list of pages, and there are always 26 | # ON_EACH_SIDE links at either end of the "current page" link. 27 | page_range = [] 28 | if page_num > (ON_EACH_SIDE + ON_ENDS): 29 | page_range.extend(list(range(0, ON_EACH_SIDE - 1))) 30 | page_range.append(DOT) 31 | page_range.extend(list(range(page_num - ON_EACH_SIDE, page_num + 1))) 32 | else: 33 | page_range.extend(list(range(0, page_num + 1))) 34 | if page_num < (paginator.num_pages - ON_EACH_SIDE - ON_ENDS - 1): 35 | page_range.extend( 36 | list(range(page_num + 1, page_num + ON_EACH_SIDE + 1)) 37 | ) 38 | page_range.append(DOT) 39 | page_range.extend( 40 | list(range(paginator.num_pages - ON_ENDS, paginator.num_pages)) 41 | ) 42 | else: 43 | page_range.extend(list(range(page_num + 1, paginator.num_pages))) 44 | 45 | return { 46 | "page_range": page_range, 47 | "page_num": page_num, 48 | "results_var": context["results_var"], 49 | "query": context["query"], 50 | } 51 | -------------------------------------------------------------------------------- /filebrowser_safe/templatetags/fb_tags.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | 3 | from django import template 4 | 5 | from urllib.parse import quote 6 | 7 | from filebrowser_safe.settings import EXTENSIONS, SELECT_FORMATS 8 | 9 | register = template.Library() 10 | 11 | try: 12 | from mezzanine.core.templatetags.mezzanine_tags import thumbnail 13 | except ImportError: 14 | # TODO: filebrowser-safe should not rely on the `thumbnail` tag at all since its 15 | # provided by Mezzanine. 16 | # 17 | # For now we just want to be able tu run the test suite without having mezzanine 18 | # installed, and this will do. Remove once filebrowser-safe is completely decoupled 19 | # from mezzanine. 20 | warnings.warn( 21 | """ 22 | You are using a placeholder implementation of the thumbnail tag intended for 23 | test purposes only. If you're seeing this you might have a problem with your 24 | Mezzanine installation. 25 | """ 26 | ) 27 | 28 | def thumbnail(image_url, *args, **kwargs): 29 | return image_url 30 | 31 | 32 | register.simple_tag(thumbnail) 33 | 34 | 35 | @register.inclusion_tag("filebrowser/include/_response.html", takes_context=True) 36 | def query_string(context, add=None, remove=None): 37 | """ 38 | Allows the addition and removal of query string parameters. 39 | 40 | _response.html is just {{ response }} 41 | 42 | Usage: 43 | http://www.url.com/{% query_string "param_to_add=value, param_to_add=value" "param_to_remove, params_to_remove" %} 44 | http://www.url.com/{% query_string "" "filter" %}filter={{new_filter}} 45 | http://www.url.com/{% query_string "sort=value" "sort" %} 46 | """ # noqa 47 | 48 | # Written as an inclusion tag to simplify getting the context. 49 | add = string_to_dict(add) 50 | remove = string_to_list(remove) 51 | params = context["query"].copy() 52 | response = get_query_string(params, add, remove) 53 | return {"response": response} 54 | 55 | 56 | def query_helper(query, add=None, remove=None): 57 | """ 58 | Helper Function for use within views. 59 | """ 60 | 61 | add = string_to_dict(add) 62 | remove = string_to_list(remove) 63 | params = query.copy() 64 | return get_query_string(params, add, remove) 65 | 66 | 67 | def get_query_string(p, new_params=None, remove=None): 68 | """ 69 | Add and remove query parameters. From `django.contrib.admin`. 70 | """ 71 | 72 | if new_params is None: 73 | new_params = {} 74 | if remove is None: 75 | remove = [] 76 | for r in remove: 77 | for k in list(p.keys()): 78 | # if k.startswith(r): 79 | if k == r: 80 | del p[k] 81 | for k, v in list(new_params.items()): 82 | if k in p and v is None: 83 | del p[k] 84 | elif v is not None: 85 | p[k] = v 86 | return "?" + "&".join(f"{quote(k)}={quote(v)}" for k, v in p.items()) 87 | 88 | 89 | def string_to_dict(string): 90 | """ 91 | Usage: 92 | {{ url|thumbnail:"width=10,height=20" }} 93 | {{ url|thumbnail:"width=10" }} 94 | {{ url|thumbnail:"height=20" }} 95 | """ 96 | 97 | kwargs = {} 98 | if string: 99 | string = str(string) 100 | if "," not in string: 101 | # ensure at least one ',' 102 | string += "," 103 | for arg in string.split(","): 104 | arg = arg.strip() 105 | if arg == "": 106 | continue 107 | kw, val = arg.split("=", 1) 108 | kwargs[kw] = val 109 | return kwargs 110 | 111 | 112 | def string_to_list(string): 113 | """ 114 | Usage: 115 | {{ url|thumbnail:"width,height" }} 116 | """ 117 | 118 | args = [] 119 | if string: 120 | string = str(string) 121 | if "," not in string: 122 | # ensure at least one ',' 123 | string += "," 124 | for arg in string.split(","): 125 | arg = arg.strip() 126 | if arg == "": 127 | continue 128 | args.append(arg) 129 | return args 130 | 131 | 132 | class SelectableNode(template.Node): 133 | def __init__(self, filetype, format): 134 | self.filetype = template.Variable(filetype) 135 | self.format = template.Variable(format) 136 | 137 | def render(self, context): 138 | try: 139 | filetype = self.filetype.resolve(context) 140 | except template.VariableDoesNotExist: 141 | filetype = "" 142 | try: 143 | format = self.format.resolve(context) 144 | except template.VariableDoesNotExist: 145 | format = "" 146 | if filetype and format and filetype in SELECT_FORMATS[format]: 147 | selectable = True 148 | elif filetype and format and filetype not in SELECT_FORMATS[format]: 149 | selectable = False 150 | else: 151 | selectable = True 152 | context["selectable"] = selectable 153 | return "" 154 | 155 | 156 | def selectable(parser, token): 157 | 158 | try: 159 | tag, filetype, format = token.split_contents() 160 | except: # noqa:722 161 | raise template.TemplateSyntaxError( 162 | "%s tag requires 2 arguments" % token.contents.split()[0] 163 | ) 164 | 165 | return SelectableNode(filetype, format) 166 | 167 | 168 | register.tag(selectable) 169 | 170 | 171 | def allowed_extensions_list(separator=","): 172 | """ 173 | Usage: 174 | {% allowed_extensions_list %} 175 | {% allowed_extensions_list '-' %} 176 | """ 177 | output = [] 178 | 179 | for key in EXTENSIONS: 180 | if key != "Folder": 181 | output += EXTENSIONS[key] 182 | 183 | return separator.join(output) 184 | 185 | 186 | register.simple_tag(allowed_extensions_list) 187 | -------------------------------------------------------------------------------- /filebrowser_safe/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import re_path 2 | 3 | from filebrowser_safe import views 4 | 5 | urlpatterns = [ 6 | re_path(r"^browse/$", views.browse, name="fb_browse"), 7 | re_path(r"^mkdir/", views.mkdir, name="fb_mkdir"), 8 | re_path(r"^upload/", views.upload, name="fb_upload"), 9 | re_path(r"^rename/$", views.rename, name="fb_rename"), 10 | re_path(r"^delete/$", views.delete, name="fb_delete"), 11 | re_path(r"^check_file/$", views._check_file, name="fb_check"), 12 | re_path(r"^upload_file/$", views._upload_file, name="fb_do_upload"), 13 | ] 14 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | DJANGO_SETTINGS_MODULE = tests.settings 3 | addopts = 4 | --tb short 5 | --cov=filebrowser_safe 6 | --cov-report html 7 | --cov-report term:skip-covered 8 | # Original coverage was 60% (not great), but at least ensure we don't go below 9 | --cov-fail-under 61 10 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = filebrowser_safe 3 | version = attr: filebrowser_safe.__version__ 4 | description = A snapshot of the filebrowser_3 branch of django-filebrowser, packaged as a dependency for the Mezzanine CMS for Django. 5 | long_description = file: README.rst 6 | long_description_content_type = text/x-rst 7 | author = Patrick Kranzlmueller, Axel Swoboda (vonautomatisch) 8 | author_email = werkstaetten@vonautomatisch.at 9 | maintainer = Stephen McDonald 10 | maintainer_email = stephen.mc@gmail.com 11 | url = http://github.com/stephenmcd/filebrowser-safe 12 | license_file = LICENSE 13 | classifiers = 14 | Programming Language :: Python 15 | Programming Language :: Python :: 3 16 | Programming Language :: Python :: 3.6 17 | Programming Language :: Python :: 3.7 18 | Programming Language :: Python :: 3.8 19 | Programming Language :: Python :: 3.9 20 | Programming Language :: Python :: 3.10 21 | 22 | [options] 23 | python_requires = >=3.6 24 | packages = find: 25 | include_package_data = true 26 | 27 | [options.extras_require] 28 | testing = 29 | pytest-django >= 4, <5 30 | pytest-cov >= 2, < 3 31 | codestyle = 32 | flake8 >= 3, <4 33 | black==20.8b1 34 | isort >= 5, <6 35 | pyupgrade >= 2, <3 36 | 37 | # Building 38 | 39 | [bdist_wheel] 40 | universal = 1 41 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup() 4 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephenmcd/filebrowser-safe/d68d5012cbb0a85cc22c37bb9a385ea21405a130/tests/__init__.py -------------------------------------------------------------------------------- /tests/settings.py: -------------------------------------------------------------------------------- 1 | import tempfile 2 | 3 | SECRET_KEY = "for testing purposes" 4 | ALLOWED_HOSTS = ["*"] 5 | INSTALLED_APPS = ( 6 | "filebrowser_safe", 7 | "tests", 8 | "django.contrib.admin", 9 | "django.contrib.auth", 10 | "django.contrib.contenttypes", 11 | "django.contrib.sessions", 12 | "django.contrib.sites", 13 | "django.contrib.messages", 14 | "django.contrib.staticfiles", 15 | ) 16 | MIDDLEWARE = ( 17 | "django.contrib.sessions.middleware.SessionMiddleware", 18 | "django.middleware.common.CommonMiddleware", 19 | "django.middleware.csrf.CsrfViewMiddleware", 20 | "django.contrib.auth.middleware.AuthenticationMiddleware", 21 | "django.contrib.messages.middleware.MessageMiddleware", 22 | ) 23 | ROOT_URLCONF = "tests.urls" 24 | 25 | STATIC_URL = "/static/" 26 | MEDIA_URL = "/media/" 27 | MEDIA_ROOT = tempfile.mkdtemp() 28 | 29 | 30 | DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}} 31 | 32 | # List of callables that know how to import templates from various sources. 33 | TEMPLATES = [ 34 | { 35 | "BACKEND": "django.template.backends.django.DjangoTemplates", 36 | "APP_DIRS": True, 37 | "OPTIONS": { 38 | "context_processors": [ 39 | "django.contrib.auth.context_processors.auth", 40 | "django.template.context_processors.i18n", 41 | "django.template.context_processors.media", 42 | "django.template.context_processors.static", 43 | "django.template.context_processors.tz", 44 | "django.contrib.messages.context_processors.messages", 45 | "django.template.context_processors.request", 46 | ], 47 | }, 48 | }, 49 | ] 50 | -------------------------------------------------------------------------------- /tests/test_anonymous.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from django.urls import reverse 3 | 4 | 5 | class FilebrowserAnonymousTestCase(TestCase): 6 | def test_browse(self): 7 | url = reverse("fb_browse") 8 | response = self.client.get(url) 9 | self.assertEqual(302, response.status_code) 10 | self.assertEqual("/admin/login/?next=" + url, response.url) 11 | 12 | def test_mkdir(self): 13 | url = reverse("fb_browse") 14 | response = self.client.get(url) 15 | self.assertEqual(302, response.status_code) 16 | self.assertEqual("/admin/login/?next=" + url, response.url) 17 | 18 | def test_rename(self): 19 | url = reverse("fb_rename") 20 | response = self.client.get(url) 21 | self.assertEqual(302, response.status_code) 22 | self.assertEqual("/admin/login/?next=" + url, response.url) 23 | 24 | def test_delete(self): 25 | url = reverse("fb_delete") 26 | response = self.client.get(url) 27 | self.assertEqual(302, response.status_code) 28 | self.assertEqual("/admin/login/?next=" + url, response.url) 29 | 30 | def test_upload(self): 31 | url = reverse("fb_upload") 32 | response = self.client.get(url) 33 | self.assertEqual(302, response.status_code) 34 | self.assertEqual("/admin/login/?next=" + url, response.url) 35 | 36 | def test_do_upload(self): 37 | url = reverse("fb_do_upload") 38 | response = self.client.get(url) 39 | self.assertEqual(302, response.status_code) 40 | self.assertEqual("/admin/login/?next=" + url, response.url) 41 | -------------------------------------------------------------------------------- /tests/test_staff.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import tempfile 4 | from pathlib import Path 5 | 6 | from django.contrib.auth import get_user_model 7 | from django.core.files.base import ContentFile 8 | from django.core.files.storage import default_storage 9 | from django.test import TestCase 10 | from django.urls import reverse 11 | 12 | from filebrowser_safe.functions import get_directory 13 | from filebrowser_safe.templatetags.fb_tags import get_query_string 14 | 15 | User = get_user_model() 16 | 17 | 18 | class FilebrowserStaffTestCase(TestCase): 19 | @classmethod 20 | def setUpClass(cls): 21 | super().setUpClass() 22 | cls.upload_dir = default_storage.path(get_directory()) 23 | cls.subdir = Path(cls.upload_dir) / "TEST_DIRECTORY" 24 | cls.subdir.mkdir() 25 | 26 | @classmethod 27 | def tearDownClass(cls): 28 | super().tearDownClass() 29 | # Cleanup the upload directory if some of the tests failed and 30 | # didn't cleanup after itself. 31 | shutil.rmtree(cls.upload_dir) 32 | 33 | def setUp(self): 34 | user = User.objects.create_user( 35 | username="staff", 36 | password="password", 37 | is_staff=True, 38 | ) 39 | self.client.force_login(user) 40 | 41 | def test_browse(self): 42 | url = reverse("fb_browse") 43 | with tempfile.NamedTemporaryFile(dir=self.upload_dir) as temp_file: 44 | response = self.client.get(url) 45 | self.assertContains(response, os.path.basename(temp_file.name)) 46 | self.assertContains(response, self.subdir.name) 47 | 48 | def test_browse__dir(self): 49 | url = reverse("fb_browse") + f"?dir={self.subdir.name}" 50 | with tempfile.NamedTemporaryFile(dir=str(self.subdir)) as temp_file: 51 | response = self.client.get(url, data={"dir": self.subdir.name}) 52 | self.assertContains(response, os.path.basename(temp_file.name)) 53 | 54 | def test_browse__suspicious(self): 55 | url = reverse("fb_browse") + f"?dir={self.subdir.name}/../" 56 | response = self.client.get(url) 57 | self.assertRedirects(response, reverse("fb_browse") + "?") 58 | 59 | def test_mkdir_page_get(self): 60 | url = reverse("fb_mkdir") 61 | response = self.client.get(url) 62 | self.assertEqual(200, response.status_code) 63 | 64 | def test_mkdir(self): 65 | url = reverse("fb_mkdir") 66 | redirect_url = reverse("fb_browse") + get_query_string( 67 | {"ot": "desc", "o": "date"} 68 | ) 69 | test_name = "New folder for test" 70 | test_path = os.path.join(self.upload_dir, test_name) 71 | self.assertFalse(default_storage.exists(test_path)) 72 | response = self.client.post(url, data={"dir_name": test_name}, follow=True) 73 | self.assertEqual(200, response.status_code) 74 | self.assertEqual([(redirect_url, 302)], response.redirect_chain) 75 | self.assertTrue(default_storage.exists(test_path)) 76 | # Cleanup newly created directory 77 | os.rmdir(test_path) 78 | 79 | def test_rename_get_page(self): 80 | url = reverse("fb_rename") 81 | response = self.client.get(url) 82 | self.assertEqual(200, response.status_code) 83 | 84 | def test_rename(self): 85 | url = reverse("fb_rename") 86 | redirect_url = reverse("fb_browse") + "?" 87 | with tempfile.NamedTemporaryFile( 88 | dir=self.upload_dir, prefix="fb-", suffix="-test.txt", delete=False 89 | ) as temp_file: 90 | temp_path = temp_file.name 91 | new_file_name = "fb-test-renamed.txt" 92 | new_file_path = os.path.join(self.upload_dir, new_file_name) 93 | self.assertTrue(default_storage.exists(temp_path)) 94 | self.assertFalse(default_storage.exists(new_file_path)) 95 | response = self.client.post( 96 | url + "?filename=" + os.path.basename(temp_path), 97 | data={"name": os.path.splitext(new_file_name)[0]}, 98 | follow=True, 99 | ) 100 | self.assertEqual(200, response.status_code) 101 | self.assertEqual([(redirect_url, 302)], response.redirect_chain) 102 | self.assertFalse(default_storage.exists(temp_path)) 103 | self.assertTrue(default_storage.exists(new_file_path)) 104 | # Cleanup test created file 105 | default_storage.delete(new_file_path) 106 | 107 | def test_delete(self): 108 | url = reverse("fb_delete") 109 | redirect_url = reverse("fb_browse") + "?" 110 | with tempfile.NamedTemporaryFile( 111 | dir=self.upload_dir, prefix="fb-", suffix="-test.txt", delete=False 112 | ) as temp_file: 113 | temp_path = temp_file.name 114 | self.assertTrue(default_storage.exists(temp_path)) 115 | response = self.client.post( 116 | url + "?filename=" + os.path.basename(temp_path), follow=True 117 | ) 118 | self.assertEqual(200, response.status_code) 119 | self.assertEqual([(redirect_url, 302)], response.redirect_chain) 120 | self.assertFalse(default_storage.exists(temp_path)) 121 | 122 | def test_upload(self): 123 | url = reverse("fb_upload") 124 | response = self.client.get(url) 125 | self.assertEqual(200, response.status_code) 126 | 127 | def test_do_upload(self): 128 | url = reverse("fb_do_upload") 129 | test_file = ContentFile(b"Test File content", name="test-file-upload.txt") 130 | test_file_path = os.path.join(self.upload_dir, test_file.name) 131 | self.assertFalse(default_storage.exists(test_file_path)) 132 | response = self.client.post(url, data={"folder": "", "Filedata": test_file}) 133 | self.assertEqual(200, response.status_code) 134 | self.assertTrue(default_storage.exists(test_file_path)) 135 | with default_storage.open(test_file_path) as uploaded_file: 136 | test_file.seek(0) 137 | self.assertEqual(uploaded_file.read(), test_file.read()) 138 | # Cleanup uploaded file 139 | default_storage.delete(test_file_path) 140 | -------------------------------------------------------------------------------- /tests/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include 2 | from django.urls import re_path 3 | from django.contrib import admin 4 | 5 | admin.autodiscover() 6 | 7 | urlpatterns = [ 8 | re_path(r"^admin/filebrowser/", include("filebrowser_safe.urls")), 9 | re_path(r"^admin/", admin.site.urls), 10 | ] 11 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | py{36,37,38,39,310}-dj{22,30,31,32,40} 4 | package 5 | lint 6 | 7 | [testenv] 8 | # Run test suite 9 | usedevelop = true 10 | deps = 11 | .[testing] 12 | dj22: Django>=2.2, <3 13 | dj30: Django>=3.0, <3.1 14 | dj31: Django>=3.1, <3.2 15 | dj32: Django>=3.2, <3.3 16 | dj40: Django>=4.0, <4.1 17 | commands = 18 | pytest --basetemp="{envtmpdir}" --junitxml="junit/TEST-{envname}.xml" {posargs} 19 | 20 | [testenv:package] 21 | # Check package integrity and compatibility with PyPI 22 | deps = 23 | twine 24 | check-manifest 25 | skip_install = true 26 | commands = 27 | python setup.py -q sdist --dist-dir="{envtmpdir}/dist" 28 | twine check "{envtmpdir}/dist/*" 29 | check-manifest --ignore-bad-ideas '*.mo' {toxinidir} 30 | 31 | [testenv:lint] 32 | skip_install = true 33 | deps = .[codestyle] 34 | commands = 35 | isort --diff --atomic . 36 | black . --check 37 | flake8 . 38 | 39 | [testenv:pyupgrade] 40 | # Run pyupgrade with non-zero exit code (notice `+` at the end of command) 41 | skip_install = true 42 | allowlist_externals = sh 43 | deps = .[codestyle] 44 | commands = 45 | sh -c 'find . -type f -name "*.py" -not -path "./.tox/*" -exec pyupgrade --py36-plus \{\} +' 46 | 47 | [testenv:format] 48 | # This env is not run by default. It's provided here for you to easily 49 | # autoformat code by running `tox -e format` 50 | skip_install = true 51 | allowlist_externals = sh 52 | deps = .[codestyle] 53 | commands = 54 | sh -c 'find . -type f -name "*.py" -not -path "./.tox/*" -exec pyupgrade --py36-plus \{\} \;' 55 | black . 56 | isort --atomic . 57 | 58 | [flake8] 59 | # Configured to match black 60 | ignore = 61 | E203 62 | W503 63 | E731 64 | max-line-length = 88 65 | exclude = 66 | migrations 67 | .tox 68 | .git 69 | .eggs 70 | *.egg-info 71 | build 72 | dist 73 | --------------------------------------------------------------------------------