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
+202
-50
@@ -22,9 +22,20 @@ to switch to ``curl_httpclient`` for reasons such as the following:
|
||||
|
||||
* ``curl_httpclient`` was the default prior to Tornado 2.0.
|
||||
|
||||
Note that if you are using ``curl_httpclient``, it is highly recommended that
|
||||
you use a recent version of ``libcurl`` and ``pycurl``. Currently the minimum
|
||||
supported version is 7.18.2, and the recommended version is 7.21.1 or newer.
|
||||
Note that if you are using ``curl_httpclient``, it is highly
|
||||
recommended that you use a recent version of ``libcurl`` and
|
||||
``pycurl``. Currently the minimum supported version of libcurl is
|
||||
7.21.1, and the minimum version of pycurl is 7.18.2. It is highly
|
||||
recommended that your ``libcurl`` installation is built with
|
||||
asynchronous DNS resolver (threaded or c-ares), otherwise you may
|
||||
encounter various problems with request timeouts (for more
|
||||
information, see
|
||||
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTCONNECTTIMEOUTMS
|
||||
and comments in curl_httpclient.py).
|
||||
|
||||
To select ``curl_httpclient``, call `AsyncHTTPClient.configure` at startup::
|
||||
|
||||
AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function, with_statement
|
||||
@@ -33,8 +44,8 @@ import functools
|
||||
import time
|
||||
import weakref
|
||||
|
||||
from tornado.concurrent import Future
|
||||
from tornado.escape import utf8
|
||||
from tornado.concurrent import TracebackFuture
|
||||
from tornado.escape import utf8, native_str
|
||||
from tornado import httputil, stack_context
|
||||
from tornado.ioloop import IOLoop
|
||||
from tornado.util import Configurable
|
||||
@@ -52,7 +63,12 @@ class HTTPClient(object):
|
||||
response = http_client.fetch("http://www.google.com/")
|
||||
print response.body
|
||||
except httpclient.HTTPError as e:
|
||||
print "Error:", e
|
||||
# HTTPError is raised for non-200 responses; the response
|
||||
# can be found in e.response.
|
||||
print("Error: " + str(e))
|
||||
except Exception as e:
|
||||
# Other errors are possible, such as IOError.
|
||||
print("Error: " + str(e))
|
||||
http_client.close()
|
||||
"""
|
||||
def __init__(self, async_client_class=None, **kwargs):
|
||||
@@ -79,7 +95,8 @@ class HTTPClient(object):
|
||||
If it is a string, we construct an `HTTPRequest` using any additional
|
||||
kwargs: ``HTTPRequest(request, **kwargs)``
|
||||
|
||||
If an error occurs during the fetch, we raise an `HTTPError`.
|
||||
If an error occurs during the fetch, we raise an `HTTPError` unless
|
||||
the ``raise_error`` keyword argument is set to False.
|
||||
"""
|
||||
response = self._io_loop.run_sync(functools.partial(
|
||||
self._async_client.fetch, request, **kwargs))
|
||||
@@ -105,10 +122,24 @@ class AsyncHTTPClient(Configurable):
|
||||
actually creates an instance of an implementation-specific
|
||||
subclass, and instances are reused as a kind of pseudo-singleton
|
||||
(one per `.IOLoop`). The keyword argument ``force_instance=True``
|
||||
can be used to suppress this singleton behavior. Constructor
|
||||
arguments other than ``io_loop`` and ``force_instance`` are
|
||||
deprecated. The implementation subclass as well as arguments to
|
||||
its constructor can be set with the static method `configure()`
|
||||
can be used to suppress this singleton behavior. Unless
|
||||
``force_instance=True`` is used, no arguments other than
|
||||
``io_loop`` should be passed to the `AsyncHTTPClient` constructor.
|
||||
The implementation subclass as well as arguments to its
|
||||
constructor can be set with the static method `configure()`
|
||||
|
||||
All `AsyncHTTPClient` implementations support a ``defaults``
|
||||
keyword argument, which can be used to set default values for
|
||||
`HTTPRequest` attributes. For example::
|
||||
|
||||
AsyncHTTPClient.configure(
|
||||
None, defaults=dict(user_agent="MyUserAgent"))
|
||||
# or with force_instance:
|
||||
client = AsyncHTTPClient(force_instance=True,
|
||||
defaults=dict(user_agent="MyUserAgent"))
|
||||
|
||||
.. versionchanged:: 4.1
|
||||
The ``io_loop`` argument is deprecated.
|
||||
"""
|
||||
@classmethod
|
||||
def configurable_base(cls):
|
||||
@@ -128,12 +159,21 @@ class AsyncHTTPClient(Configurable):
|
||||
|
||||
def __new__(cls, io_loop=None, force_instance=False, **kwargs):
|
||||
io_loop = io_loop or IOLoop.current()
|
||||
if io_loop in cls._async_clients() and not force_instance:
|
||||
return cls._async_clients()[io_loop]
|
||||
if force_instance:
|
||||
instance_cache = None
|
||||
else:
|
||||
instance_cache = cls._async_clients()
|
||||
if instance_cache is not None and io_loop in instance_cache:
|
||||
return instance_cache[io_loop]
|
||||
instance = super(AsyncHTTPClient, cls).__new__(cls, io_loop=io_loop,
|
||||
**kwargs)
|
||||
if not force_instance:
|
||||
cls._async_clients()[io_loop] = instance
|
||||
# Make sure the instance knows which cache to remove itself from.
|
||||
# It can't simply call _async_clients() because we may be in
|
||||
# __new__(AsyncHTTPClient) but instance.__class__ may be
|
||||
# SimpleAsyncHTTPClient.
|
||||
instance._instance_cache = instance_cache
|
||||
if instance_cache is not None:
|
||||
instance_cache[instance.io_loop] = instance
|
||||
return instance
|
||||
|
||||
def initialize(self, io_loop, defaults=None):
|
||||
@@ -141,17 +181,30 @@ class AsyncHTTPClient(Configurable):
|
||||
self.defaults = dict(HTTPRequest._DEFAULTS)
|
||||
if defaults is not None:
|
||||
self.defaults.update(defaults)
|
||||
self._closed = False
|
||||
|
||||
def close(self):
|
||||
"""Destroys this HTTP client, freeing any file descriptors used.
|
||||
Not needed in normal use, but may be helpful in unittests that
|
||||
create and destroy http clients. No other methods may be called
|
||||
on the `AsyncHTTPClient` after ``close()``.
|
||||
"""
|
||||
if self._async_clients().get(self.io_loop) is self:
|
||||
del self._async_clients()[self.io_loop]
|
||||
|
||||
def fetch(self, request, callback=None, **kwargs):
|
||||
This method is **not needed in normal use** due to the way
|
||||
that `AsyncHTTPClient` objects are transparently reused.
|
||||
``close()`` is generally only necessary when either the
|
||||
`.IOLoop` is also being closed, or the ``force_instance=True``
|
||||
argument was used when creating the `AsyncHTTPClient`.
|
||||
|
||||
No other methods may be called on the `AsyncHTTPClient` after
|
||||
``close()``.
|
||||
|
||||
"""
|
||||
if self._closed:
|
||||
return
|
||||
self._closed = True
|
||||
if self._instance_cache is not None:
|
||||
if self._instance_cache.get(self.io_loop) is not self:
|
||||
raise RuntimeError("inconsistent AsyncHTTPClient cache")
|
||||
del self._instance_cache[self.io_loop]
|
||||
|
||||
def fetch(self, request, callback=None, raise_error=True, **kwargs):
|
||||
"""Executes a request, asynchronously returning an `HTTPResponse`.
|
||||
|
||||
The request may be either a string URL or an `HTTPRequest` object.
|
||||
@@ -159,14 +212,18 @@ class AsyncHTTPClient(Configurable):
|
||||
kwargs: ``HTTPRequest(request, **kwargs)``
|
||||
|
||||
This method returns a `.Future` whose result is an
|
||||
`HTTPResponse`. The ``Future`` wil raise an `HTTPError` if
|
||||
the request returned a non-200 response code.
|
||||
`HTTPResponse`. By default, the ``Future`` will raise an `HTTPError`
|
||||
if the request returned a non-200 response code. Instead, if
|
||||
``raise_error`` is set to False, the response will always be
|
||||
returned regardless of the response code.
|
||||
|
||||
If a ``callback`` is given, it will be invoked with the `HTTPResponse`.
|
||||
In the callback interface, `HTTPError` is not automatically raised.
|
||||
Instead, you must check the response's ``error`` attribute or
|
||||
call its `~HTTPResponse.rethrow` method.
|
||||
"""
|
||||
if self._closed:
|
||||
raise RuntimeError("fetch() called on closed AsyncHTTPClient")
|
||||
if not isinstance(request, HTTPRequest):
|
||||
request = HTTPRequest(url=request, **kwargs)
|
||||
# We may modify this (to add Host, Accept-Encoding, etc),
|
||||
@@ -174,7 +231,7 @@ class AsyncHTTPClient(Configurable):
|
||||
# where normal dicts get converted to HTTPHeaders objects.
|
||||
request.headers = httputil.HTTPHeaders(request.headers)
|
||||
request = _RequestProxy(request, self.defaults)
|
||||
future = Future()
|
||||
future = TracebackFuture()
|
||||
if callback is not None:
|
||||
callback = stack_context.wrap(callback)
|
||||
|
||||
@@ -192,7 +249,7 @@ class AsyncHTTPClient(Configurable):
|
||||
future.add_done_callback(handle_future)
|
||||
|
||||
def handle_response(response):
|
||||
if response.error:
|
||||
if raise_error and response.error:
|
||||
future.set_exception(response.error)
|
||||
else:
|
||||
future.set_result(response)
|
||||
@@ -236,7 +293,7 @@ class HTTPRequest(object):
|
||||
request_timeout=20.0,
|
||||
follow_redirects=True,
|
||||
max_redirects=5,
|
||||
use_gzip=True,
|
||||
decompress_response=True,
|
||||
proxy_password='',
|
||||
allow_nonstandard_methods=False,
|
||||
validate_cert=True)
|
||||
@@ -252,14 +309,27 @@ class HTTPRequest(object):
|
||||
proxy_password=None, allow_nonstandard_methods=None,
|
||||
validate_cert=None, ca_certs=None,
|
||||
allow_ipv6=None,
|
||||
client_key=None, client_cert=None):
|
||||
client_key=None, client_cert=None, body_producer=None,
|
||||
expect_100_continue=False, decompress_response=None):
|
||||
r"""All parameters except ``url`` are optional.
|
||||
|
||||
:arg string url: URL to fetch
|
||||
:arg string method: HTTP method, e.g. "GET" or "POST"
|
||||
:arg headers: Additional HTTP headers to pass on the request
|
||||
:arg body: HTTP body to pass on the request
|
||||
:type headers: `~tornado.httputil.HTTPHeaders` or `dict`
|
||||
:arg body: HTTP request body as a string (byte or unicode; if unicode
|
||||
the utf-8 encoding will be used)
|
||||
:arg body_producer: Callable used for lazy/asynchronous request bodies.
|
||||
It is called with one argument, a ``write`` function, and should
|
||||
return a `.Future`. It should call the write function with new
|
||||
data as it becomes available. The write function returns a
|
||||
`.Future` which can be used for flow control.
|
||||
Only one of ``body`` and ``body_producer`` may
|
||||
be specified. ``body_producer`` is not supported on
|
||||
``curl_httpclient``. When using ``body_producer`` it is recommended
|
||||
to pass a ``Content-Length`` in the headers as otherwise chunked
|
||||
encoding will be used, and many servers do not support chunked
|
||||
encoding on requests. New in Tornado 4.0
|
||||
:arg string auth_username: Username for HTTP authentication
|
||||
:arg string auth_password: Password for HTTP authentication
|
||||
:arg string auth_mode: Authentication mode; default is "basic".
|
||||
@@ -274,8 +344,13 @@ class HTTPRequest(object):
|
||||
or return the 3xx response?
|
||||
:arg int max_redirects: Limit for ``follow_redirects``
|
||||
:arg string user_agent: String to send as ``User-Agent`` header
|
||||
:arg bool use_gzip: Request gzip encoding from the server
|
||||
:arg string network_interface: Network interface to use for request
|
||||
:arg bool decompress_response: Request a compressed response from
|
||||
the server and decompress it after downloading. Default is True.
|
||||
New in Tornado 4.0.
|
||||
:arg bool use_gzip: Deprecated alias for ``decompress_response``
|
||||
since Tornado 4.0.
|
||||
:arg string network_interface: Network interface to use for request.
|
||||
``curl_httpclient`` only; see note below.
|
||||
:arg callable streaming_callback: If set, ``streaming_callback`` will
|
||||
be run with each chunk of data as it is received, and
|
||||
``HTTPResponse.body`` and ``HTTPResponse.buffer`` will be empty in
|
||||
@@ -303,22 +378,42 @@ class HTTPRequest(object):
|
||||
:arg bool validate_cert: For HTTPS requests, validate the server's
|
||||
certificate?
|
||||
:arg string ca_certs: filename of CA certificates in PEM format,
|
||||
or None to use defaults. Note that in ``curl_httpclient``, if
|
||||
any request uses a custom ``ca_certs`` file, they all must (they
|
||||
don't have to all use the same ``ca_certs``, but it's not possible
|
||||
to mix requests with ``ca_certs`` and requests that use the defaults.
|
||||
or None to use defaults. See note below when used with
|
||||
``curl_httpclient``.
|
||||
:arg bool allow_ipv6: Use IPv6 when available? Default is false in
|
||||
``simple_httpclient`` and true in ``curl_httpclient``
|
||||
:arg string client_key: Filename for client SSL key, if any
|
||||
:arg string client_cert: Filename for client SSL certificate, if any
|
||||
:arg string client_key: Filename for client SSL key, if any. See
|
||||
note below when used with ``curl_httpclient``.
|
||||
:arg string client_cert: Filename for client SSL certificate, if any.
|
||||
See note below when used with ``curl_httpclient``.
|
||||
:arg bool expect_100_continue: If true, send the
|
||||
``Expect: 100-continue`` header and wait for a continue response
|
||||
before sending the request body. Only supported with
|
||||
simple_httpclient.
|
||||
|
||||
.. note::
|
||||
|
||||
When using ``curl_httpclient`` certain options may be
|
||||
inherited by subsequent fetches because ``pycurl`` does
|
||||
not allow them to be cleanly reset. This applies to the
|
||||
``ca_certs``, ``client_key``, ``client_cert``, and
|
||||
``network_interface`` arguments. If you use these
|
||||
options, you should pass them on every request (you don't
|
||||
have to always use the same values, but it's not possible
|
||||
to mix requests that specify these options with ones that
|
||||
use the defaults).
|
||||
|
||||
.. versionadded:: 3.1
|
||||
The ``auth_mode`` argument.
|
||||
|
||||
.. versionadded:: 4.0
|
||||
The ``body_producer`` and ``expect_100_continue`` arguments.
|
||||
"""
|
||||
if headers is None:
|
||||
headers = httputil.HTTPHeaders()
|
||||
# Note that some of these attributes go through property setters
|
||||
# defined below.
|
||||
self.headers = headers
|
||||
if if_modified_since:
|
||||
headers["If-Modified-Since"] = httputil.format_timestamp(
|
||||
self.headers["If-Modified-Since"] = httputil.format_timestamp(
|
||||
if_modified_since)
|
||||
self.proxy_host = proxy_host
|
||||
self.proxy_port = proxy_port
|
||||
@@ -326,8 +421,8 @@ class HTTPRequest(object):
|
||||
self.proxy_password = proxy_password
|
||||
self.url = url
|
||||
self.method = method
|
||||
self.headers = headers
|
||||
self.body = utf8(body)
|
||||
self.body = body
|
||||
self.body_producer = body_producer
|
||||
self.auth_username = auth_username
|
||||
self.auth_password = auth_password
|
||||
self.auth_mode = auth_mode
|
||||
@@ -336,19 +431,74 @@ class HTTPRequest(object):
|
||||
self.follow_redirects = follow_redirects
|
||||
self.max_redirects = max_redirects
|
||||
self.user_agent = user_agent
|
||||
self.use_gzip = use_gzip
|
||||
if decompress_response is not None:
|
||||
self.decompress_response = decompress_response
|
||||
else:
|
||||
self.decompress_response = use_gzip
|
||||
self.network_interface = network_interface
|
||||
self.streaming_callback = stack_context.wrap(streaming_callback)
|
||||
self.header_callback = stack_context.wrap(header_callback)
|
||||
self.prepare_curl_callback = stack_context.wrap(prepare_curl_callback)
|
||||
self.streaming_callback = streaming_callback
|
||||
self.header_callback = header_callback
|
||||
self.prepare_curl_callback = prepare_curl_callback
|
||||
self.allow_nonstandard_methods = allow_nonstandard_methods
|
||||
self.validate_cert = validate_cert
|
||||
self.ca_certs = ca_certs
|
||||
self.allow_ipv6 = allow_ipv6
|
||||
self.client_key = client_key
|
||||
self.client_cert = client_cert
|
||||
self.expect_100_continue = expect_100_continue
|
||||
self.start_time = time.time()
|
||||
|
||||
@property
|
||||
def headers(self):
|
||||
return self._headers
|
||||
|
||||
@headers.setter
|
||||
def headers(self, value):
|
||||
if value is None:
|
||||
self._headers = httputil.HTTPHeaders()
|
||||
else:
|
||||
self._headers = value
|
||||
|
||||
@property
|
||||
def body(self):
|
||||
return self._body
|
||||
|
||||
@body.setter
|
||||
def body(self, value):
|
||||
self._body = utf8(value)
|
||||
|
||||
@property
|
||||
def body_producer(self):
|
||||
return self._body_producer
|
||||
|
||||
@body_producer.setter
|
||||
def body_producer(self, value):
|
||||
self._body_producer = stack_context.wrap(value)
|
||||
|
||||
@property
|
||||
def streaming_callback(self):
|
||||
return self._streaming_callback
|
||||
|
||||
@streaming_callback.setter
|
||||
def streaming_callback(self, value):
|
||||
self._streaming_callback = stack_context.wrap(value)
|
||||
|
||||
@property
|
||||
def header_callback(self):
|
||||
return self._header_callback
|
||||
|
||||
@header_callback.setter
|
||||
def header_callback(self, value):
|
||||
self._header_callback = stack_context.wrap(value)
|
||||
|
||||
@property
|
||||
def prepare_curl_callback(self):
|
||||
return self._prepare_curl_callback
|
||||
|
||||
@prepare_curl_callback.setter
|
||||
def prepare_curl_callback(self, value):
|
||||
self._prepare_curl_callback = stack_context.wrap(value)
|
||||
|
||||
|
||||
class HTTPResponse(object):
|
||||
"""HTTP Response object.
|
||||
@@ -360,11 +510,12 @@ class HTTPResponse(object):
|
||||
* code: numeric HTTP status code, e.g. 200 or 404
|
||||
|
||||
* reason: human-readable reason phrase describing the status code
|
||||
(with curl_httpclient, this is a default value rather than the
|
||||
server's actual response)
|
||||
|
||||
* headers: `tornado.httputil.HTTPHeaders` object
|
||||
|
||||
* effective_url: final location of the resource after following any
|
||||
redirects
|
||||
|
||||
* buffer: ``cStringIO`` object for response body
|
||||
|
||||
* body: response body as string (created on demand from ``self.buffer``)
|
||||
@@ -400,7 +551,8 @@ class HTTPResponse(object):
|
||||
self.effective_url = effective_url
|
||||
if error is None:
|
||||
if self.code < 200 or self.code >= 300:
|
||||
self.error = HTTPError(self.code, response=self)
|
||||
self.error = HTTPError(self.code, message=self.reason,
|
||||
response=self)
|
||||
else:
|
||||
self.error = None
|
||||
else:
|
||||
@@ -490,7 +642,7 @@ def main():
|
||||
if options.print_headers:
|
||||
print(response.headers)
|
||||
if options.print_body:
|
||||
print(response.body)
|
||||
print(native_str(response.body))
|
||||
client.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user