Translation of UI (german and english)
Bugfix for feeds
- removed categories related and up
- load new books now working
- category random now working
login page is free of non accessible elements
boolean custom column is vivible in UI
books with only with certain languages can be shown
book shelfs can be deleted from UI
Anonymous user view is more resticted
Added browse of series in sidebar
Dependencys in vendor folder are updated to newer versions (licencs files are now present)
Bugfix editing Authors names
Made upload on windows working
This commit is contained in:
Vendored
+45
-27
@@ -5,7 +5,7 @@
|
||||
|
||||
This module implements a client to WSGI applications for testing.
|
||||
|
||||
:copyright: (c) 2013 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import sys
|
||||
@@ -22,20 +22,20 @@ except ImportError:
|
||||
from urllib.request import Request as U2Request
|
||||
try:
|
||||
from http.cookiejar import CookieJar
|
||||
except ImportError: # Py2
|
||||
except ImportError: # Py2
|
||||
from cookielib import CookieJar
|
||||
|
||||
from werkzeug._compat import iterlists, iteritems, itervalues, to_native, \
|
||||
string_types, text_type, reraise, wsgi_encoding_dance, \
|
||||
make_literal_wrapper
|
||||
from werkzeug._compat import iterlists, iteritems, itervalues, to_bytes, \
|
||||
string_types, text_type, reraise, wsgi_encoding_dance, \
|
||||
make_literal_wrapper
|
||||
from werkzeug._internal import _empty_stream, _get_environ
|
||||
from werkzeug.wrappers import BaseRequest
|
||||
from werkzeug.urls import url_encode, url_fix, iri_to_uri, url_unquote, \
|
||||
url_unparse, url_parse
|
||||
url_unparse, url_parse
|
||||
from werkzeug.wsgi import get_host, get_current_url, ClosingIterator
|
||||
from werkzeug.utils import dump_cookie
|
||||
from werkzeug.datastructures import FileMultiDict, MultiDict, \
|
||||
CombinedMultiDict, Headers, FileStorage
|
||||
CombinedMultiDict, Headers, FileStorage
|
||||
|
||||
|
||||
def stream_encode_multipart(values, use_tempfile=True, threshold=1024 * 500,
|
||||
@@ -97,11 +97,12 @@ def stream_encode_multipart(values, use_tempfile=True, threshold=1024 * 500,
|
||||
break
|
||||
write_binary(chunk)
|
||||
else:
|
||||
if isinstance(value, string_types):
|
||||
value = to_native(value, charset)
|
||||
else:
|
||||
if not isinstance(value, string_types):
|
||||
value = str(value)
|
||||
write('\r\n\r\n' + value)
|
||||
|
||||
value = to_bytes(value, charset)
|
||||
write('\r\n\r\n')
|
||||
write_binary(value)
|
||||
write('\r\n')
|
||||
write('--%s--\r\n' % boundary)
|
||||
|
||||
@@ -128,6 +129,7 @@ def File(fd, filename=None, mimetype=None):
|
||||
|
||||
|
||||
class _TestCookieHeaders(object):
|
||||
|
||||
"""A headers adapter for cookielib
|
||||
"""
|
||||
|
||||
@@ -151,6 +153,7 @@ class _TestCookieHeaders(object):
|
||||
|
||||
|
||||
class _TestCookieResponse(object):
|
||||
|
||||
"""Something that looks like a httplib.HTTPResponse, but is actually just an
|
||||
adapter for our test responses to make them available for cookielib.
|
||||
"""
|
||||
@@ -163,6 +166,7 @@ class _TestCookieResponse(object):
|
||||
|
||||
|
||||
class _TestCookieJar(CookieJar):
|
||||
|
||||
"""A cookielib.CookieJar modified to inject and read cookie headers from
|
||||
and to wsgi environments, and wsgi application responses.
|
||||
"""
|
||||
@@ -206,6 +210,7 @@ def _iter_data(data):
|
||||
|
||||
|
||||
class EnvironBuilder(object):
|
||||
|
||||
"""This class can be used to conveniently create a WSGI environment
|
||||
for testing purposes. It can be used to quickly create WSGI environments
|
||||
or request objects from arbitrary data.
|
||||
@@ -303,7 +308,8 @@ class EnvironBuilder(object):
|
||||
elif not isinstance(headers, Headers):
|
||||
headers = Headers(headers)
|
||||
self.headers = headers
|
||||
self.content_type = content_type
|
||||
if content_type is not None:
|
||||
self.content_type = content_type
|
||||
if errors_stream is None:
|
||||
errors_stream = sys.stderr
|
||||
self.errors_stream = errors_stream
|
||||
@@ -377,9 +383,9 @@ class EnvironBuilder(object):
|
||||
def _get_content_type(self):
|
||||
ct = self.headers.get('Content-Type')
|
||||
if ct is None and not self._input_stream:
|
||||
if self.method in ('POST', 'PUT', 'PATCH'):
|
||||
if self._files:
|
||||
return 'multipart/form-data'
|
||||
if self._files:
|
||||
return 'multipart/form-data'
|
||||
elif self._form:
|
||||
return 'application/x-www-form-urlencoded'
|
||||
return None
|
||||
return ct
|
||||
@@ -413,6 +419,7 @@ class EnvironBuilder(object):
|
||||
|
||||
def form_property(name, storage, doc):
|
||||
key = '_' + name
|
||||
|
||||
def getter(self):
|
||||
if self._input_stream is not None:
|
||||
raise AttributeError('an input stream is defined')
|
||||
@@ -420,7 +427,9 @@ class EnvironBuilder(object):
|
||||
if rv is None:
|
||||
rv = storage()
|
||||
setattr(self, key, rv)
|
||||
|
||||
return rv
|
||||
|
||||
def setter(self, value):
|
||||
self._input_stream = None
|
||||
setattr(self, key, value)
|
||||
@@ -534,7 +543,7 @@ class EnvironBuilder(object):
|
||||
stream_encode_multipart(values, charset=self.charset)
|
||||
content_type += '; boundary="%s"' % boundary
|
||||
elif content_type == 'application/x-www-form-urlencoded':
|
||||
#py2v3 review
|
||||
# XXX: py2v3 review
|
||||
values = url_encode(self.form, charset=self.charset)
|
||||
values = values.encode('ascii')
|
||||
content_length = len(values)
|
||||
@@ -588,6 +597,7 @@ class EnvironBuilder(object):
|
||||
|
||||
|
||||
class ClientRedirectError(Exception):
|
||||
|
||||
"""
|
||||
If a redirect loop is detected when using follow_redirects=True with
|
||||
the :cls:`Client`, then this exception is raised.
|
||||
@@ -595,6 +605,7 @@ class ClientRedirectError(Exception):
|
||||
|
||||
|
||||
class Client(object):
|
||||
|
||||
"""This class allows to send requests to a wrapped application.
|
||||
|
||||
The response wrapper can be a class or factory function that takes
|
||||
@@ -678,6 +689,12 @@ class Client(object):
|
||||
raise RuntimeError('%r does not support redirect to '
|
||||
'external targets' % self.__class__)
|
||||
|
||||
status_code = int(response[1].split(None, 1)[0])
|
||||
if status_code == 307:
|
||||
method = environ['REQUEST_METHOD']
|
||||
else:
|
||||
method = 'GET'
|
||||
|
||||
# For redirect handling we temporarily disable the response
|
||||
# wrapper. This is not threadsafe but not a real concern
|
||||
# since the test client must not be shared anyways.
|
||||
@@ -686,7 +703,7 @@ class Client(object):
|
||||
try:
|
||||
return self.open(path=script_root, base_url=base_url,
|
||||
query_string=qs, as_tuple=True,
|
||||
buffered=buffered)
|
||||
buffered=buffered, method=method)
|
||||
finally:
|
||||
self.response_wrapper = old_response_wrapper
|
||||
|
||||
@@ -746,7 +763,8 @@ class Client(object):
|
||||
raise ClientRedirectError('loop detected')
|
||||
redirect_chain.append(new_redirect_entry)
|
||||
environ, response = self.resolve_redirect(response, new_location,
|
||||
environ, buffered=buffered)
|
||||
environ,
|
||||
buffered=buffered)
|
||||
|
||||
if self.response_wrapper is not None:
|
||||
response = self.response_wrapper(*response)
|
||||
@@ -850,29 +868,29 @@ def run_wsgi_app(app, environ, buffered=False):
|
||||
response[:] = [status, headers]
|
||||
return buffer.append
|
||||
|
||||
app_iter = app(environ, start_response)
|
||||
app_rv = app(environ, start_response)
|
||||
close_func = getattr(app_rv, 'close', None)
|
||||
app_iter = iter(app_rv)
|
||||
|
||||
# when buffering we emit the close call early and convert the
|
||||
# application iterator into a regular list
|
||||
if buffered:
|
||||
close_func = getattr(app_iter, 'close', None)
|
||||
try:
|
||||
app_iter = list(app_iter)
|
||||
finally:
|
||||
if close_func is not None:
|
||||
close_func()
|
||||
|
||||
# otherwise we iterate the application iter until we have
|
||||
# a response, chain the already received data with the already
|
||||
# collected data and wrap it in a new `ClosingIterator` if
|
||||
# we have a close callable.
|
||||
# otherwise we iterate the application iter until we have a response, chain
|
||||
# the already received data with the already collected data and wrap it in
|
||||
# a new `ClosingIterator` if we need to restore a `close` callable from the
|
||||
# original return value.
|
||||
else:
|
||||
while not response:
|
||||
buffer.append(next(app_iter))
|
||||
if buffer:
|
||||
close_func = getattr(app_iter, 'close', None)
|
||||
app_iter = chain(buffer, app_iter)
|
||||
if close_func is not None:
|
||||
app_iter = ClosingIterator(app_iter, close_func)
|
||||
if close_func is not None and app_iter is not app_rv:
|
||||
app_iter = ClosingIterator(app_iter, close_func)
|
||||
|
||||
return app_iter, response[0], Headers(response[1])
|
||||
|
||||
Reference in New Issue
Block a user