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:
OzzieIsaacs
2016-11-09 19:24:33 +01:00
parent a6b6700a73
commit bbf6d9b026
1690 changed files with 149106 additions and 35697 deletions
+229 -23
View File
@@ -27,7 +27,7 @@ from .font import Font
__all__ = ('ALPHA_CHANNEL_TYPES', 'CHANNELS', 'COLORSPACE_TYPES',
'COMPOSITE_OPERATORS', 'COMPRESSION_TYPES',
'COMPARE_METRICS', 'COMPOSITE_OPERATORS', 'COMPRESSION_TYPES',
'EVALUATE_OPS', 'FILTER_TYPES',
'GRAVITY_TYPES', 'IMAGE_TYPES', 'ORIENTATION_TYPES', 'UNIT_TYPES',
'FUNCTION_TYPES',
@@ -84,6 +84,31 @@ FILTER_TYPES = ('undefined', 'point', 'box', 'triangle', 'hermite', 'hanning',
'lanczossharp', 'lanczos2', 'lanczos2sharp', 'robidoux',
'robidouxsharp', 'cosine', 'spline', 'sentinel')
#: (:class:`tuple`) The list of compare metric types
#:
#: - ``'undefined'``
#: - ``'absolute'``
#: - ``'mean_absolute'``
#: - ``'mean_error_per_pixel'``
#: - ``'mean_squared'``
#: - ``'normalized_cross_correlation'``
#: - ``'peak_absolute'``
#: - ``'peak_signal_to_noise_ratio'``
#: - ``'perceptual_hash'``
#: - ``'root_mean_square'``
#: .. seealso::
#:
#: `ImageMagick Compare Operations`__
#:
#: __ http://www.imagemagick.org/Usage/compare/
#:
#: .. versionadded:: 0.4.3
COMPARE_METRICS = ('undefined', 'absolute',
'mean_absolute', 'mean_error_per_pixel',
'mean_squared', 'normalized_cross_correlation',
'peak_absolute', 'peak_signal_to_noise_ratio',
'perceptual_hash', 'root_mean_square')
#: (:class:`tuple`) The list of composition operators
#:
#: - ``'undefined'``
@@ -485,6 +510,32 @@ VIRTUAL_PIXEL_METHOD = ('undefined', 'background', 'constant', 'dither',
'vertical_tile_edge', 'checker_tile')
#: (:class:`tuple`) The list of :attr:`~BaseImage.layer_method` types.
#: - ``'undefined'``
#: - ``'coalesce'``
#: - ``'compareany'``
#: - ``'compareclear'``
#: - ``'compareoverlay'``
#: - ``'dispose'``
#: - ``'optimize'``
#: - ``'optimizeimage'``
#: - ``'optimizeplus'``
#: - ``'optimizetrans'``
#: - ``'removedups'``
#: - ``'removezero'``
#: - ``'composite'``
#: - ``'merge'``
#: - ``'flatten'``
#: - ``'mosaic'``
#: - ``'trimbounds'``
#: .. versionadded:: 0.4.3
IMAGE_LAYER_METHOD = ('undefined', 'coalesce', 'compareany', 'compareclear',
'compareoverlay', 'dispose', 'optimize', 'optimizeimage',
'optimizeplus', 'optimizetrans', 'removedups',
'removezero', 'composite', 'merge', 'flatten', 'mosaic',
'trimbounds')
def manipulative(function):
"""Mark the operation manipulating itself instead of returning new one."""
@functools.wraps(function)
@@ -698,8 +749,8 @@ class BaseImage(Resource):
if not isinstance(value, string_type):
raise TypeError('expected a string, not ' + repr(value))
if value not in GRAVITY_TYPES:
raise ValueError('expected a string from GRAVITY_TYPES, not '
+ repr(value))
raise ValueError('expected a string from GRAVITY_TYPES, not ' +
repr(value))
library.MagickSetGravity(self.wand, GRAVITY_TYPES.index(value))
@property
@@ -764,6 +815,102 @@ class BaseImage(Resource):
self.font_color = font.color
self.font_antialias = font.antialias
@property
def page(self):
"""The dimensions and offset of this Wand's page as a 4-tuple:
``(width, height, x, y)``.
Note that since it is based on the virtual canvas, it may not equal the
dimensions of an image. See the ImageMagick documentation on the
virtual canvas for more information.
.. versionadded:: 0.4.3
"""
w = ctypes.c_uint()
h = ctypes.c_uint()
x = ctypes.c_int()
y = ctypes.c_int()
r = library.MagickGetImagePage(self.wand, w, h, x, y)
if not r:
self.raise_exception()
return int(w.value), int(h.value), int(x.value), int(y.value)
@page.setter
@manipulative
def page(self, newpage):
if isinstance(newpage, collections.Sequence):
w, h, x, y = newpage
else:
raise TypeError("page layout must be 4-tuple")
r = library.MagickSetImagePage(self.wand, w, h, x, y)
if not r:
self.raise_exception()
@property
def page_width(self):
"""(:class:`numbers.Integral`) The width of the page for this wand.
.. versionadded:: 0.4.3
"""
return self.page[0]
@page_width.setter
@manipulative
def page_width(self, width):
newpage = list(self.page)
newpage[0] = width
self.page = newpage
@property
def page_height(self):
"""(:class:`numbers.Integral`) The height of the page for this wand.
.. versionadded:: 0.4.3
"""
return self.page[1]
@page_height.setter
@manipulative
def page_height(self, height):
newpage = list(self.page)
newpage[1] = height
self.page = newpage
@property
def page_x(self):
"""(:class:`numbers.Integral`) The X-offset of the page for this wand.
.. versionadded:: 0.4.3
"""
return self.page[2]
@page_x.setter
@manipulative
def page_x(self, x):
newpage = list(self.page)
newpage[2] = x
self.page = newpage
@property
def page_y(self):
"""(:class:`numbers.Integral`) The Y-offset of the page for this wand.
.. versionadded:: 0.4.3
"""
return self.page[3]
@page_y.setter
@manipulative
def page_y(self, y):
newpage = list(self.page)
newpage[3] = y
self.page = newpage
@property
def width(self):
"""(:class:`numbers.Integral`) The width of this image."""
@@ -805,8 +952,8 @@ class BaseImage(Resource):
if not isinstance(value, string_type):
raise TypeError('expected a string, not ' + repr(value))
if value not in ORIENTATION_TYPES:
raise ValueError('expected a string from ORIENTATION_TYPES, not '
+ repr(value))
raise ValueError('expected a string from ORIENTATION_TYPES, not ' +
repr(value))
index = ORIENTATION_TYPES.index(value)
library.MagickSetImageOrientation(self.wand, index)
@@ -865,9 +1012,14 @@ class BaseImage(Resource):
width = self.width - left
if height is None:
height = self.height - top
if not font:
try:
font = self.font
except TypeError:
raise TypeError('font must be specified or existing in image')
with Image() as textboard:
library.MagickSetSize(textboard.wand, width, height)
textboard.font = font or self.font
textboard.font = font
textboard.gravity = gravity or self.gravity
with Color('transparent') as background_color:
library.MagickSetBackgroundColor(textboard.wand,
@@ -1315,8 +1467,8 @@ class BaseImage(Resource):
'both width and height must be defined with gravity'
)
if gravity not in GRAVITY_TYPES:
raise ValueError('expected a string from GRAVITY_TYPES, not '
+ repr(gravity))
raise ValueError('expected a string from GRAVITY_TYPES, not ' +
repr(gravity))
# Set `top` based on given gravity
if gravity in ('north_west', 'north', 'north_east'):
top = 0
@@ -1994,6 +2146,30 @@ class BaseImage(Resource):
alpha, fuzz, invert)
self.raise_exception()
def compare(self, image, metric='undefined'):
"""Compares an image to a reconstructed image.
:param image: The reference image
:type image: :class:`wand.image.Image`
:param metric: The metric type to use for comparing.
:type metric: :class:`basestring`
:returns: The difference image(:class:`wand.image.Image`),
the computed distortion between the images
(:class:`numbers.Integral`)
:rtype: :class:`tuple`
..versionadded:: 0.4.3
"""
if not isinstance(metric, string_type):
raise TypeError('metric must be a string, not ' + repr(metric))
metric = COMPARE_METRICS.index(metric)
distortion = ctypes.c_double()
compared_image = library.MagickCompareImages(self.wand, image.wand,
metric,
ctypes.byref(distortion))
return Image(BaseImage(compared_image)), distortion.value
@manipulative
def composite(self, image, left, top):
"""Places the supplied ``image`` over the current image, with the top
@@ -2114,6 +2290,34 @@ class BaseImage(Resource):
if not r:
self.raise_exception()
@manipulative
def merge_layers(self, method):
"""Composes all the image layers from the current given image onward
to produce a single image of the merged layers.
The inital canvas's size depends on the given ImageLayerMethod, and is
initialized using the first images background color. The images
are then compositied onto that image in sequence using the given
composition that has been assigned to each individual image.
The method must be set with a value from :const:`IMAGE_LAYER_METHOD`
that is acceptable to this operation. (See ImageMagick documentation
for more details.)
:param method: the method of selecting the size of the initial canvas.
:type method: :class:`basestring`
.. versionadded:: 0.4.3
"""
if method not in ['merge', 'flatten', 'mosaic']:
raise TypeError('method must be one of: merge, flatten, mosaic')
m = IMAGE_LAYER_METHOD.index(method)
r = library.MagickMergeImageLayers(self.wand, m)
if not r:
self.raise_exception()
self.wand = r
@manipulative
def threshold(self, threshold=0.5, channel=None):
"""Changes the value of individual pixels based on the intensity
@@ -2362,13 +2566,19 @@ class BaseImage(Resource):
if not r:
self.raise_exception()
def __repr__(self):
def __repr__(self, extra_format=' ({self.width}x{self.height})'):
cls = type(self)
typename = '{0}.{1}'.format(
cls.__module__,
getattr(cls, '__qualname__', cls.__name__)
)
if getattr(self, 'c_resource', None) is None:
return '<{0}.{1}: (closed)>'.format(cls.__module__, cls.__name__)
return '<{0}.{1}: {2} ({3}x{4})>'.format(
cls.__module__, cls.__name__,
self.signature[:7], self.width, self.height
return '<{0}: (closed)>'.format(typename)
sig = self.signature
if not sig:
return '<{0}: (empty)>'.format(typename)
return '<{0}: {1}{2}>'.format(
typename, sig[:7], extra_format.format(self=self)
)
@@ -2730,8 +2940,8 @@ class Image(BaseImage):
@property
def animation(self):
return (self.mimetype in ('image/gif', 'image/x-gif')
and len(self.sequence) > 1)
return (self.mimetype in ('image/gif', 'image/x-gif') and
len(self.sequence) > 1)
@property
def compression(self):
@@ -2750,8 +2960,8 @@ class Image(BaseImage):
if not isinstance(value, string_type):
raise TypeError('expected a string, not ' + repr(value))
if value not in COMPRESSION_TYPES:
raise ValueError('expected a string from COMPRESSION_TYPES, not '
+ repr(value))
raise ValueError('expected a string from COMPRESSION_TYPES, not ' +
repr(value))
library.MagickSetImageCompression(
self.wand,
COMPRESSION_TYPES.index(value)
@@ -3154,12 +3364,8 @@ class Image(BaseImage):
return cloned.make_blob()
def __repr__(self):
cls = type(self)
if getattr(self, 'c_resource', None) is None:
return '<{0}.{1}: (closed)>'.format(cls.__module__, cls.__name__)
return '<{0}.{1}: {2} {3!r} ({4}x{5})>'.format(
cls.__module__, cls.__name__,
self.signature[:7], self.format, self.width, self.height
return super(Image, self).__repr__(
extra_format=' {self.format!r} ({self.width}x{self.height})'
)