Skip to content
This repository has been archived by the owner on Aug 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #18 from ergoithz/0.5.3
Browse files Browse the repository at this point in the history
0.5.3 release
  • Loading branch information
ergoithz authored Jun 12, 2017
2 parents b1b9811 + 1772081 commit 5a9ec29
Show file tree
Hide file tree
Showing 35 changed files with 2,112 additions and 745 deletions.
71 changes: 71 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
environment:
matrix:
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python27-x64"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "64"

- PYTHON: "C:\\Python33"
PYTHON_VERSION: "3.3.x" # currently 3.3.5
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python33-x64"
PYTHON_VERSION: "3.3.x" # currently 3.3.5
PYTHON_ARCH: "64"

- PYTHON: "C:\\Python34"
PYTHON_VERSION: "3.4.x" # currently 3.4.3
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python34-x64"
PYTHON_VERSION: "3.4.x" # currently 3.4.3
PYTHON_ARCH: "64"

# Python versions not pre-installed

- PYTHON: "C:\\Python35"
PYTHON_VERSION: "3.5.3"
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python35-x64"
PYTHON_VERSION: "3.5.3"
PYTHON_ARCH: "64"

- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6.1"
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6.1"
PYTHON_ARCH: "64"

build: off

init:
- "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%"

install:
# If there is a newer build queued for the same PR, cancel this one.
# The AppVeyor 'rollout builds' option is supposed to serve the same
# purpose but it is problematic because it tends to cancel builds pushed
# directly to master instead of just PR builds (or the converse).
# credits: JuliaLang developers.
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
- ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
- "pip install --disable-pip-version-check --user --upgrade pip setuptools"

test_script:
- "python setup.py test"
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ doc/.build/*
env/*
env2/*
env3/*
wenv2/*
wenv3/*
node_modules/*
__pycache__/*
**/__pycache__/*
**.egg/*
**.eggs/*
**.egg-info/*
**.pyc
**/node_modules/*
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ matrix:
include:
- python: "2.7"
- python: "pypy"
# pypy3 commented out until Flask 0.11.2 is out
# pypy3 disabled until fixed
#- python: "pypy3"
- python: "3.3"
- python: "3.4"
- python: "3.5"
- python: "3.6"
env:
- eslint=yes
- sphinx=yes
Expand Down
48 changes: 28 additions & 20 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
browsepy
========

.. image:: http://img.shields.io/travis/ergoithz/browsepy/master.svg?style=flat-square
.. image:: http://img.shields.io/travis/ergoithz/browsepy/0.5.3.svg?style=flat-square
:target: https://travis-ci.org/ergoithz/browsepy
:alt: Travis-CI badge

.. image:: http://img.shields.io/coveralls/ergoithz/browsepy/master.svg?style=flat-square
:target: https://coveralls.io/r/ergoithz/browsepy
.. image:: https://img.shields.io/appveyor/ci/ergoithz/browsepy/0.5.3.svg?style=flat-square
:target: https://ci.appveyor.com/project/ergoithz/browsepy/branch/0.5.3
:alt: AppVeyor badge

.. image:: http://img.shields.io/coveralls/ergoithz/browsepy/0.5.3.svg?style=flat-square
:target: https://coveralls.io/r/ergoithz/browsepy?branch=0.5.3
:alt: Coveralls badge

.. image:: https://img.shields.io/codacy/grade/e27821fb6289410b8f58338c7e0bc686/master.svg?style=flat-square
:target: https://www.codacy.com/app/ergoithz/browsepy
.. image:: https://img.shields.io/codacy/grade/e27821fb6289410b8f58338c7e0bc686/0.5.3.svg?style=flat-square
:target: https://www.codacy.com/app/ergoithz/browsepy/dashboard?bid=4246124
:alt: Codacy badge

.. image:: http://img.shields.io/pypi/l/browsepy.svg?style=flat-square
Expand All @@ -19,7 +23,7 @@ browsepy

.. image:: http://img.shields.io/pypi/v/browsepy.svg?style=flat-square
:target: https://pypi.python.org/pypi/browsepy/
:alt: Version: 0.5.2
:alt: Version: 0.5.3

.. image:: https://img.shields.io/badge/python-2.7%2B%2C%203.3%2B-FFC100.svg?style=flat-square
:target: https://pypi.python.org/pypi/browsepy/
Expand Down Expand Up @@ -129,22 +133,25 @@ plugins (loaded with `plugin` argument) could add extra arguments to this list.

::

usage: browsepy [-h] [--directory PATH] [--initial PATH] [--removable PATH]
[--upload PATH] [--plugin PLUGIN_LIST] [--debug]
[host] [port]
usage: browsepy [-h] [--directory PATH] [--initial PATH] [--removable PATH]
[--upload PATH] [--exclude PATTERN] [--exclude-from PATH]
[--plugin MODULE]
[host] [port]

positional arguments:
host address to listen (default: 127.0.0.1)
port port to listen (default: 8080)

positional arguments:
host address to listen (default: 127.0.0.1)
port port to listen (default: 8080)
optional arguments:
-h, --help show this help message and exit
--directory PATH serving directory (default: current path)
--initial PATH default directory (default: same as --directory)
--removable PATH base directory allowing remove (default: none)
--upload PATH base directory allowing upload (default: none)
--exclude PATTERN exclude paths by pattern (multiple)
--exclude-from PATH exclude paths by pattern file (multiple)
--plugin MODULE load plugin module (multiple)

optional arguments:
-h, --help show this help message and exit
--directory PATH base serving directory (default: current path)
--initial PATH initial directory (default: same as --directory)
--removable PATH base directory for remove (default: none)
--upload PATH base directory for upload (default: none)
--plugin PLUGIN_LIST comma-separated list of plugins
--debug debug mode

Using as library
----------------
Expand Down Expand Up @@ -180,6 +187,7 @@ following configuration options.
plugin_namespaces) will be loaded.
* **plugin_namespaces** prefixes for module names listed at plugin_modules
where relative plugin_modules are searched.
* **exclude_fnc** function will be used to exclude files from listing and directory tarballs. Can be either None or function receiving an absolute path and returning a boolean.

After editing `plugin_modules` value, plugin manager (available at module
plugin_manager and app.extensions['plugin_manager']) should be reloaded using
Expand Down
53 changes: 35 additions & 18 deletions browsepy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
make_response
from werkzeug.exceptions import NotFound

from .__meta__ import __app__, __version__, __license__, __author__ # noqa
from .manager import PluginManager
from .file import Node, OutsideRemovableBase, OutsideDirectoryBase, \
secure_filename
from . import compat
from . import __meta__ as meta

__app__ = meta.app # noqa
__version__ = meta.version # noqa
__license__ = meta.license # noqa
__author__ = meta.author # noqa
__basedir__ = os.path.abspath(os.path.dirname(compat.fsdecode(__file__)))

logger = logging.getLogger(__name__)
Expand All @@ -42,24 +46,25 @@
'browsepy_',
'',
),
exclude_fnc=None,
)
app.jinja_env.add_extension('browsepy.extensions.HTMLCompress')
app.jinja_env.add_extension('browsepy.transform.htmlcompress.HTMLCompress')

if "BROWSEPY_SETTINGS" in os.environ:
app.config.from_envvar("BROWSEPY_SETTINGS")

plugin_manager = PluginManager(app)


def iter_cookie_browse_sorting():
def iter_cookie_browse_sorting(cookies):
'''
Get sorting-cookie data of current request.
Get sorting-cookie from cookies dictionary.
:yields: tuple of path and sorting property
:ytype: 2-tuple of strings
'''
try:
data = request.cookies.get('browse-sorting', 'e30=').encode('ascii')
data = cookies.get('browse-sorting', 'e30=').encode('ascii')
for path, prop in json.loads(base64.b64decode(data).decode('utf-8')):
yield path, prop
except (ValueError, TypeError, KeyError) as e:
Expand All @@ -73,16 +78,22 @@ def get_cookie_browse_sorting(path, default):
:returns: sorting property
:rtype: string
'''
for cpath, cprop in iter_cookie_browse_sorting():
if path == cpath:
return cprop
if request:
for cpath, cprop in iter_cookie_browse_sorting(request.cookies):
if path == cpath:
return cprop
return default


def browse_sortkey_reverse(prop):
'''
Get sorting function for browse
Get sorting function for directory listing based on given attribute
name, with some caveats:
* Directories will be first.
* If *name* is given, link widget lowercase text will be used istead.
* If *size* is given, bytesize will be used.
:param prop: file attribute name
:returns: tuple with sorting gunction and reverse bool
:rtype: tuple of a dict and a bool
'''
Expand Down Expand Up @@ -148,12 +159,12 @@ def sort(property, path):
except OutsideDirectoryBase:
return NotFound()

if not directory.is_directory:
if not directory.is_directory or directory.is_excluded:
return NotFound()

data = [
(cpath, cprop)
for cpath, cprop in iter_cookie_browse_sorting()
for cpath, cprop in iter_cookie_browse_sorting(request.cookies)
if cpath != path
]
data.append((path, property))
Expand All @@ -177,7 +188,7 @@ def browse(path):

try:
directory = Node.from_urlpath(path)
if directory.is_directory:
if directory.is_directory and not directory.is_excluded:
return stream_template(
'browse.html',
file=directory,
Expand All @@ -194,7 +205,7 @@ def browse(path):
def open_file(path):
try:
file = Node.from_urlpath(path)
if file.is_file:
if file.is_file and not file.is_excluded:
return send_from_directory(file.parent.path, file.name)
except OutsideDirectoryBase:
pass
Expand All @@ -205,7 +216,7 @@ def open_file(path):
def download_file(path):
try:
file = Node.from_urlpath(path)
if file.is_file:
if file.is_file and not file.is_excluded:
return file.download()
except OutsideDirectoryBase:
pass
Expand All @@ -216,7 +227,7 @@ def download_file(path):
def download_directory(path):
try:
directory = Node.from_urlpath(path)
if directory.is_directory:
if directory.is_directory and not directory.is_excluded:
return directory.download()
except OutsideDirectoryBase:
pass
Expand All @@ -229,10 +240,13 @@ def remove(path):
file = Node.from_urlpath(path)
except OutsideDirectoryBase:
return NotFound()

if not file.can_remove or file.is_excluded:
return NotFound()

if request.method == 'GET':
if not file.can_remove:
return NotFound()
return render_template('remove.html', file=file)

parent = file.parent
if parent is None:
# base is not removable
Expand All @@ -254,7 +268,10 @@ def upload(path):
except OutsideDirectoryBase:
return NotFound()

if not directory.is_directory or not directory.can_upload:
if (
not directory.is_directory or not directory.can_upload or
directory.is_excluded
):
return NotFound()

for v in request.files.listvalues():
Expand Down
Loading

0 comments on commit 5a9ec29

Please sign in to comment.