Bring back Python bindings for Ethumb.
This commit is contained in:
parent
8cc17b5777
commit
6ebdf2b607
5
TODO
5
TODO
|
@ -25,9 +25,7 @@ TODO
|
|||
* Review the internal functions and name them consistently
|
||||
* Evas: SmartObject needs testing, work. Make it inheritable by extension
|
||||
classes?
|
||||
* Elm unit tests, things like top_widget and getting child objects
|
||||
can be done easily.
|
||||
* include python-ethumb
|
||||
* Improve ethumb
|
||||
* edje: complete the unit tests
|
||||
* Initial Evas GL support (for Elm)
|
||||
* Add more documentation for callbacks, events, etc.
|
||||
|
@ -40,6 +38,7 @@ Elm
|
|||
* Add more examples
|
||||
* Prefs
|
||||
* GLView
|
||||
* Unit tests
|
||||
* Images missing in the documentation:
|
||||
- datetime
|
||||
- video
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
.. currentmodule:: efl.ethumb
|
||||
|
||||
:class:`efl.ethumb.PyEthumb` Class
|
||||
==================================
|
||||
|
||||
.. autoclass:: efl.ethumb.PyEthumb
|
||||
|
||||
.. currentmodule:: efl.ethumb
|
||||
|
||||
:class:`efl.ethumb_client.Client` Class
|
||||
========================================
|
||||
|
||||
.. autoclass:: efl.ethumb_client.Client
|
|
@ -0,0 +1,30 @@
|
|||
:mod:`efl.ethumb` Module
|
||||
============================
|
||||
|
||||
.. module:: efl.ethumb
|
||||
|
||||
What is Ethumb?
|
||||
----------------
|
||||
|
||||
|
||||
How to use the Ethumb object
|
||||
-----------------------------
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
class-ethumb
|
||||
|
||||
|
||||
Inheritance diagram
|
||||
-------------------
|
||||
|
||||
.. inheritance-diagram::
|
||||
efl.ethumb
|
||||
efl.ethumb_client
|
||||
:parts: 2
|
||||
|
|
@ -54,6 +54,12 @@ Evas
|
|||
.. toctree:: evas/evas
|
||||
|
||||
|
||||
Ethumb
|
||||
------
|
||||
|
||||
.. toctree:: ethumb/ethumb
|
||||
|
||||
|
||||
Edje
|
||||
----
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright (C) 2009 by ProFUSION embedded systems
|
||||
#
|
||||
# This file is part of Python-Ethumb.
|
||||
#
|
||||
# Python-Ethumb is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-Ethumb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-Ethumb. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from c_ethumb import init, shutdown, PyEthumb
|
||||
|
||||
ETHUMB_THUMB_NORMAL = 0
|
||||
ETHUMB_THUMB_LARGE = 1
|
||||
|
||||
ETHUMB_THUMB_FDO = 0
|
||||
ETHUMB_THUMB_JPEG = 1
|
||||
ETHUMB_THUMB_EET = 2
|
||||
|
||||
ETHUMB_THUMB_KEEP_ASPECT = 0
|
||||
ETHUMB_THUMB_IGNORE_ASPECT = 1
|
||||
ETHUMB_THUMB_CROP = 2
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright (C) 2009 by ProFUSION embedded systems
|
||||
#
|
||||
# This file is part of Python-Ethumb.
|
||||
#
|
||||
# Python-Ethumb is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-Ethumb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-Ethumb. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
def init():
|
||||
return ethumb_init()
|
||||
|
||||
def shutdown():
|
||||
ethumb_shutdown()
|
||||
|
||||
cdef class PyEthumb:
|
||||
"""Ethumb thumbnail generator"""
|
||||
def __init__(self):
|
||||
"""Ethumb constructor."""
|
||||
|
||||
|
||||
init()
|
|
@ -0,0 +1,655 @@
|
|||
# Copyright (C) 2009 by ProFUSION embedded systems
|
||||
#
|
||||
# This file is part of Python-Ethumb.
|
||||
#
|
||||
# Python-Ethumb is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-Ethumb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-Ethumb. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from cpython cimport Py_INCREF, Py_DECREF
|
||||
from libc.stdint cimport uintptr_t
|
||||
import traceback
|
||||
|
||||
def shutdown():
|
||||
ethumb_client_shutdown()
|
||||
|
||||
def init():
|
||||
return ethumb_client_init()
|
||||
|
||||
cdef void _connect_cb(void *data, Ethumb_Client *client, Eina_Bool success) with gil:
|
||||
cdef Client self = <Client>data
|
||||
s = bool(success)
|
||||
try:
|
||||
func, args, kargs = self._on_connect_callback
|
||||
func(self, s, *args, **kargs)
|
||||
except Exception, e:
|
||||
traceback.print_exc()
|
||||
|
||||
if not s and self.obj != NULL:
|
||||
ethumb_client_disconnect(self.obj)
|
||||
self.obj = NULL
|
||||
self._on_connect_callback = None
|
||||
|
||||
|
||||
cdef void _on_server_die_cb(void *data, Ethumb_Client *client) with gil:
|
||||
cdef Client self = <Client>data
|
||||
if self._on_server_die_callback is not None:
|
||||
try:
|
||||
func, args, kargs = self._on_server_die_callback
|
||||
func(self, *args, **kargs)
|
||||
except Exception, e:
|
||||
traceback.print_exc()
|
||||
|
||||
if self.obj != NULL:
|
||||
ethumb_client_disconnect(self.obj)
|
||||
self.obj = NULL
|
||||
self._on_server_die_callback = None
|
||||
|
||||
|
||||
cdef void _generated_cb(void *data, Ethumb_Client *client, int id, const char *file, const char *key, const char *thumb_path, const char *thumb_key, Eina_Bool success) with gil:
|
||||
obj = <object>data
|
||||
(self, func, args, kargs) = obj
|
||||
f = str_from_c(file)
|
||||
k = str_from_c(key)
|
||||
tp = str_from_c(thumb_path)
|
||||
tk = str_from_c(thumb_key)
|
||||
s = bool(success != 0)
|
||||
try:
|
||||
func(self, id, f, k, tp, tk, s, *args, **kargs)
|
||||
except Exception, e:
|
||||
traceback.print_exc()
|
||||
|
||||
cdef void _generated_cb_free_data(void *data) with gil:
|
||||
obj = <object>data
|
||||
Py_DECREF(obj)
|
||||
|
||||
cdef void _thumb_exists_cb(void *data, Ethumb_Client *client, Ethumb_Exists *thread, Eina_Bool exists) with gil:
|
||||
#TODO
|
||||
print("Not implemented")
|
||||
#pass
|
||||
|
||||
cdef char *str_to_c(object s):
|
||||
cdef char *mystr
|
||||
if s is None:
|
||||
mystr = NULL
|
||||
else:
|
||||
mystr = s
|
||||
return mystr
|
||||
|
||||
cdef object str_from_c(const char *mystr):
|
||||
if mystr != NULL:
|
||||
return mystr
|
||||
|
||||
cdef class Client:
|
||||
"""
|
||||
|
||||
Client for Ethumbd server.
|
||||
|
||||
This client is the recommended way to generate thumbnails with
|
||||
Ethumb. All you have to do is create a client instance, wait it to
|
||||
be connected to server, configure thumbnail parameters and then
|
||||
start feed it with file_set(), exists() generate(). Basic steps are:
|
||||
|
||||
- instantiate Client, wait for func to be called with success.
|
||||
- set various parameters, like format and size.
|
||||
- loop on original files:
|
||||
|
||||
- ``c.file_set(file)``
|
||||
- ``if not c.exists(): c.generate(generated_cb)``
|
||||
|
||||
When the last reference to client is released, server is
|
||||
automatically disconnected. Since callback may contain references
|
||||
to server itself, it is recommended explicit call to
|
||||
:py:func:`disconnect` function.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, func, *args, **kargs):
|
||||
"""
|
||||
|
||||
Ethumb Client constructor.
|
||||
|
||||
Server is ready to receive requests just after **func** is
|
||||
called back with ``status == True``.
|
||||
|
||||
:param func: function to call when connection with server is
|
||||
established. Function signature is::
|
||||
|
||||
func(client, status, *args, **kargs)
|
||||
|
||||
with status being True for successful connection or False
|
||||
on error.
|
||||
|
||||
:raise TypeError: if **func** is not callable.
|
||||
:raise SystemError: if it was not possible to connect to
|
||||
server, allocate memory or use DBus.
|
||||
|
||||
"""
|
||||
if not callable(func):
|
||||
raise TypeError("Parameter 'func' must be callable")
|
||||
if self.obj == NULL:
|
||||
self._on_connect_callback = (func, args, kargs)
|
||||
self._on_server_die_callback = None
|
||||
self.obj = ethumb_client_connect(_connect_cb, <void*>self, NULL)
|
||||
if self.obj == NULL:
|
||||
raise SystemError("Error connecting to server.")
|
||||
else:
|
||||
ethumb_client_on_server_die_callback_set(
|
||||
self.obj, _on_server_die_cb, <void*>self, NULL)
|
||||
|
||||
def __dealloc__(self):
|
||||
if self.obj != NULL:
|
||||
ethumb_client_disconnect(self.obj)
|
||||
|
||||
def disconnect(self):
|
||||
"""Explicitly request server disconnection.
|
||||
|
||||
After this call object becomes shallow, that is operations
|
||||
will be void.
|
||||
"""
|
||||
if self.obj != NULL:
|
||||
ethumb_client_disconnect(self.obj)
|
||||
self.obj = NULL
|
||||
self._on_connect_callback = None
|
||||
self._on_server_die_callback = None
|
||||
|
||||
def __str__(self):
|
||||
f, k = self.file
|
||||
tf, tk = self.thumb_path
|
||||
w, h = self.size
|
||||
|
||||
format = ("FDO", "JPEG", "EET")[self.format]
|
||||
aspect = ("KEEP", "IGNORE", "CROP")[self.aspect]
|
||||
if self.aspect == 2:
|
||||
aspect = "CROP[%f, %f]" % self.crop
|
||||
return ("%s(file=(%r, %r), thumb=(%r, %r), exists=%s, size=%dx%d, "
|
||||
"format=%s, aspect=%s, quality=%d, compress=%d, "
|
||||
"directory=%r, category=%r)") % \
|
||||
(self.__class__.__name__, f, k, tf, tk, self.thumb_exists(),
|
||||
w, h, format, aspect, self.quality, self.compress,
|
||||
self.directory, self.category)
|
||||
|
||||
def __repr__(self):
|
||||
f, k = self.file
|
||||
tf, tk = self.thumb_path
|
||||
return "%s(obj=%#x, file=(%r, %r), thumb=(%r, %r), exists=%s)" % \
|
||||
(self.__class__.__name__, <uintptr_t><void *>self, f, k, tf, tk, self.thumb_exists())
|
||||
|
||||
def on_server_die_callback_set(self, func, *args, **kargs):
|
||||
"""Function to call when server dies.
|
||||
|
||||
When server is dead there is nothing to do with this client
|
||||
anymore, just create a new one and start over, hope that
|
||||
server could be started and you could generate more
|
||||
thumbnails.
|
||||
|
||||
:param func: function to call when server dies.
|
||||
Signature::
|
||||
|
||||
func(client, *args, **kargs)
|
||||
|
||||
:raise TypeError: if **func** is not callable or None.
|
||||
"""
|
||||
if func is None:
|
||||
self._on_server_die_callback = None
|
||||
elif callable(func):
|
||||
self._on_server_die_callback = (func, args, kargs)
|
||||
else:
|
||||
raise TypeError("Parameter 'func' must be callable or None")
|
||||
|
||||
def fdo_set(self, int s):
|
||||
"""Configure future requests to use FreeDesktop.Org preset.
|
||||
|
||||
This is a preset to provide freedesktop.org (fdo) standard
|
||||
compliant thumbnails. That is, files are stored as JPEG under
|
||||
~/.thumbnails/SIZE, with size being either normal (128x128) or
|
||||
large (256x256).
|
||||
|
||||
:param s: size identifier, either ETHUMB_THUMB_NORMAL (0) or
|
||||
ETHUMB_THUMB_LARGE.
|
||||
|
||||
.. seealso:: :py:func:`size_set`, :py:func:`format_set`, :py:func:`aspect_set`, :py:func:`crop_set`,
|
||||
:py:func:`category_set`, :py:func:`directory_set`.
|
||||
"""
|
||||
ethumb_client_fdo_set(self.obj, s)
|
||||
|
||||
def size_set(self, int w, int h):
|
||||
"""Configure future request to use custom size.
|
||||
|
||||
:param w: width, default is 128.
|
||||
:param h: height, default is 128.
|
||||
"""
|
||||
ethumb_client_size_set(self.obj, w, h)
|
||||
|
||||
def size_get(self):
|
||||
"""Get current size being used by requests.
|
||||
|
||||
:rtype: tuple of int.
|
||||
"""
|
||||
cdef int w, h
|
||||
ethumb_client_size_get(self.obj, &w, &h)
|
||||
return (w, h)
|
||||
|
||||
property size:
|
||||
def __set__(self, value):
|
||||
cdef int w, h
|
||||
w, h = value
|
||||
self.size_set(w, h)
|
||||
|
||||
def __get__(self):
|
||||
return self.size_get()
|
||||
|
||||
def format_set(self, int f):
|
||||
"""Configure format to use for future requests.
|
||||
|
||||
:param f: format identifier to use, either ETHUMB_THUMB_FDO (0),
|
||||
ETHUMB_THUMB_JPEG (1) or ETHUMB_THUMB_EET (2). Default is FDO.
|
||||
"""
|
||||
ethumb_client_format_set(self.obj, f)
|
||||
|
||||
def format_get(self):
|
||||
"""Get current format in use for requests.
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
return ethumb_client_format_get(self.obj)
|
||||
|
||||
property format:
|
||||
def __set__(self, value):
|
||||
self.format_set(value)
|
||||
|
||||
def __get__(self):
|
||||
return self.format_get()
|
||||
|
||||
def aspect_set(self, int a):
|
||||
"""Configure aspect mode to use.
|
||||
|
||||
If aspect is kept (ETHUMB_THUMB_KEEP_ASPECT), then image will
|
||||
be rescaled so the largest dimension is not bigger than it's
|
||||
specified size (see :py:func:`size_get`) and the other dimension is
|
||||
resized in the same proportion. Example: size is 256x256,
|
||||
image is 1000x500, resulting thumbnail is 256x128.
|
||||
|
||||
If aspect is ignored (ETHUMB_THUMB_IGNORE_ASPECT), then image
|
||||
will be distorted to match required thumbnail size. Example:
|
||||
size is 256x256, image is 1000x500, resulting thumbnail is
|
||||
256x256.
|
||||
|
||||
If crop is required (ETHUMB_THUMB_CROP), then image will be
|
||||
cropped so the smallest dimension is not bigger than its
|
||||
specified size (see :py:func:`size_get`) and the other dimension
|
||||
will overflow, not being visible in the final image. How it
|
||||
will overflow is speficied by :py:func:`crop_set`
|
||||
alignment. Example: size is 256x256, image is 1000x500, crop
|
||||
alignment is 0.5, 0.5, resulting thumbnail is 256x256 with 250
|
||||
pixels from left and 250 pixels from right being lost, that is
|
||||
just the 500x500 central pixels of image will be considered
|
||||
for scaling.
|
||||
|
||||
:param a: aspect mode identifier, either ETHUMB_THUMB_KEEP_ASPECT (0),
|
||||
ETHUMB_THUMB_IGNORE_ASPECT (1) or ETHUMB_THUMB_CROP (2).
|
||||
|
||||
"""
|
||||
ethumb_client_aspect_set(self.obj, a)
|
||||
|
||||
def aspect_get(self):
|
||||
"""Get current aspect in use for requests.
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
return ethumb_client_aspect_get(self.obj)
|
||||
|
||||
property aspect:
|
||||
def __set__(self, value):
|
||||
self.aspect_set(value)
|
||||
|
||||
def __get__(self):
|
||||
return self.aspect_get()
|
||||
|
||||
def crop_set(self, float x, float y):
|
||||
"""Configure crop alignment in use for future requests.
|
||||
|
||||
:param x: horizontal alignment. 0.0 means left side will be
|
||||
visible or right side is being lost. 1.0 means right
|
||||
side will be visible or left side is being lost. 0.5
|
||||
means just center is visible, both sides will be lost.
|
||||
Default is 0.5.
|
||||
:param y: vertical alignment. 0.0 is top visible, 1.0 is
|
||||
bottom visible, 0.5 is center visible. Default is 0.5
|
||||
"""
|
||||
ethumb_client_crop_align_set(self.obj, x, y)
|
||||
|
||||
def crop_get(self):
|
||||
"""Get current crop alignment in use for requests.
|
||||
|
||||
:rtype: tuple of float
|
||||
"""
|
||||
cdef float x, y
|
||||
ethumb_client_crop_align_get(self.obj, &x, &y)
|
||||
return (x, y)
|
||||
|
||||
property crop:
|
||||
def __set__(self, value):
|
||||
cdef float x, y
|
||||
x, y = value
|
||||
self.crop_set(x, y)
|
||||
|
||||
def __get__(self):
|
||||
return self.crop_get()
|
||||
|
||||
def quality_set(self, int quality):
|
||||
"""Configure quality to be used in thumbnails.
|
||||
|
||||
:param quality: value from 0 to 100, default is 80. The
|
||||
effect depends on the format being used, PNG will not
|
||||
use it.
|
||||
"""
|
||||
ethumb_client_quality_set(self.obj, quality)
|
||||
|
||||
def quality_get(self):
|
||||
"""Get current quality in use for requests.
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
return ethumb_client_quality_get(self.obj)
|
||||
|
||||
property quality:
|
||||
def __set__(self, value):
|
||||
self.quality_set(value)
|
||||
|
||||
def __get__(self):
|
||||
return self.quality_get()
|
||||
|
||||
def compress_set(self, int compress):
|
||||
"""Configure compression level used in requests.
|
||||
|
||||
:param compress: value from 0 to 9, default is 9. The effect
|
||||
depends on the format being used, JPEG will not use it.
|
||||
"""
|
||||
ethumb_client_compress_set(self.obj, compress)
|
||||
|
||||
def compress_get(self):
|
||||
"""Get current compression level in use for requests.
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
return ethumb_client_compress_get(self.obj)
|
||||
|
||||
property compress:
|
||||
def __set__(self, value):
|
||||
self.compress_set(value)
|
||||
|
||||
def __get__(self):
|
||||
return self.compress_get()
|
||||
|
||||
def directory_set(self, path):
|
||||
"""Configure where to store thumbnails in future requests.
|
||||
|
||||
Note that this is the base, a category is added to this path
|
||||
as a sub directory.
|
||||
|
||||
:param path: base directory where to store
|
||||
thumbnails. Default is ~/.thumbnails
|
||||
"""
|
||||
ethumb_client_dir_path_set(self.obj, str_to_c(path))
|
||||
|
||||
def directory_get(self):
|
||||
"""Get current base directory to store thumbnails.
|
||||
|
||||
:rtype: str or None
|
||||
"""
|
||||
return str_from_c(ethumb_client_dir_path_get(self.obj))
|
||||
|
||||
property directory:
|
||||
def __set__(self, value):
|
||||
self.directory_set(value)
|
||||
|
||||
def __get__(self):
|
||||
return self.directory_get()
|
||||
|
||||
def category_set(self, category):
|
||||
"""Category directory to store thumbnails.
|
||||
|
||||
:param category: category sub directory to store
|
||||
thumbnail. Default is either "normal" or "large" for FDO
|
||||
compliant thumbnails or
|
||||
WIDTHxHEIGHT-ASPECT[-FRAMED]-FORMAT. It can be a string or
|
||||
None to use auto generated names.
|
||||
"""
|
||||
ethumb_client_category_set(self.obj, str_to_c(category))
|
||||
|
||||
def category_get(self):
|
||||
"""Get current category sub directory to store thumbnails.
|
||||
|
||||
:rtype: str or None
|
||||
"""
|
||||
return str_from_c(ethumb_client_category_get(self.obj))
|
||||
|
||||
property category:
|
||||
def __set__(self, value):
|
||||
self.category_set(value)
|
||||
|
||||
def __get__(self):
|
||||
return self.category_get()
|
||||
|
||||
def frame_set(self, file, group, swallow):
|
||||
"""Set frame to apply to future thumbnails.
|
||||
|
||||
This will create an edje object that will have image swallowed
|
||||
in. This can be used to simulate Polaroid or wood frames in
|
||||
the generated image. Remeber it is bad to modify the original
|
||||
contents of thumbnails, but sometimes it's useful to have it
|
||||
composited and avoid runtime overhead.
|
||||
|
||||
:param file: file path to edje.
|
||||
:param group: group inside edje to use.
|
||||
:param swallow: name of swallow part.
|
||||
"""
|
||||
cdef:
|
||||
char *f
|
||||
char *g
|
||||
char *s
|
||||
f = str_to_c(file)
|
||||
g = str_to_c(group)
|
||||
s = str_to_c(swallow)
|
||||
return ethumb_client_frame_set(self.obj, f, g, s)
|
||||
|
||||
def file_set(self, path, key=None):
|
||||
"""Set file to thumbnail.
|
||||
|
||||
Calling this function will zero :py:func:`thumb_set`
|
||||
specifications. This is done to avoid one using the last thumb
|
||||
path for new images.
|
||||
|
||||
:param path: path to thumbnail subject.
|
||||
:param key: path to key inside **path**, this is used to
|
||||
generate thumbnail of edje groups or images inside EET.
|
||||
"""
|
||||
cdef:
|
||||
char *p
|
||||
char *k
|
||||
p = str_to_c(path)
|
||||
k = str_to_c(key)
|
||||
ethumb_client_file_set(self.obj, p, k)
|
||||
|
||||
def file_get(self):
|
||||
"""Get current file to thumbnail.
|
||||
|
||||
:rtype: tuple of str
|
||||
"""
|
||||
cdef:
|
||||
const char *p
|
||||
const char *k
|
||||
ethumb_client_file_get(self.obj, &p, &k)
|
||||
return (str_from_c(p), str_from_c(k))
|
||||
|
||||
property file:
|
||||
def __set__(self, value):
|
||||
p, k = value
|
||||
self.file_set(p, k)
|
||||
|
||||
def __get__(self):
|
||||
return self.file_get()
|
||||
|
||||
def file_free(self):
|
||||
"""Zero/Reset file parameters.
|
||||
|
||||
This call will reset file and thumb specifications.
|
||||
|
||||
.. seealso:: :py:func:`file_set` and :py:func:`thumb_set`
|
||||
"""
|
||||
ethumb_client_file_free(self.obj)
|
||||
|
||||
def thumb_set(self, path, key=None):
|
||||
"""Set thumbnail path and key.
|
||||
|
||||
Note that these parameters are forgotten (reset) after
|
||||
:py:func:`file_set`.
|
||||
|
||||
:param path: path to generated thumbnail to use, this is an
|
||||
absolute path to file, overriding directory and category.
|
||||
:param key: path to key inside **path**, this is used to
|
||||
generate thumbnail inside EET files.
|
||||
"""
|
||||
cdef:
|
||||
const char *p
|
||||
const char *k
|
||||
p = str_to_c(path)
|
||||
k = str_to_c(key)
|
||||
ethumb_client_thumb_path_set(self.obj, p, k)
|
||||
|
||||
def thumb_get(self):
|
||||
"""Get current path and key of thumbnail.
|
||||
|
||||
Note that if no explicit :py:func:`thumb_set` was called, it will
|
||||
auto generate path based on existing parameters such as
|
||||
directory, category and others.
|
||||
|
||||
:rtype: tuple of str
|
||||
"""
|
||||
cdef:
|
||||
const char *p
|
||||
const char *k
|
||||
ethumb_client_thumb_path_get(self.obj, &p, &k)
|
||||
return (str_from_c(p), str_from_c(k))
|
||||
|
||||
property thumb_path:
|
||||
def __set__(self, value):
|
||||
p, k = value
|
||||
self.thumb_set(p, k)
|
||||
def __get__(self):
|
||||
return self.thumb_get()
|
||||
|
||||
def video_time_set(self, float time):
|
||||
ethumb_client_video_time_set(self.obj, time)
|
||||
|
||||
def video_start_set(self, float start):
|
||||
ethumb_client_video_start_set(self.obj, start)
|
||||
|
||||
def video_interval_set(self, float interval):
|
||||
ethumb_client_video_interval_set(self.obj, interval)
|
||||
|
||||
def video_ntimes_set(self, int ntimes):
|
||||
ethumb_client_video_ntimes_set(self.obj, ntimes)
|
||||
|
||||
def video_fps_set(self, int fps):
|
||||
ethumb_client_video_fps_set(self.obj, fps)
|
||||
|
||||
# document_page
|
||||
def document_page_set(self, int page):
|
||||
ethumb_client_document_page_set(self.obj, page)
|
||||
|
||||
def thumb_exists(self, callback = None, *args, **kwargs):
|
||||
"""Checks if thumbnail already exists.
|
||||
|
||||
If you want to avoid regenerating thumbnails, check if they
|
||||
already exist with this function.
|
||||
|
||||
"""
|
||||
cdef Ethumb_Client_Thumb_Exists_Cb cb = NULL
|
||||
cdef Ethumb_Exists *res
|
||||
|
||||
if callback:
|
||||
if not callable(callback):
|
||||
raise TypeError("callback is not callable")
|
||||
cb = _thumb_exists_cb
|
||||
|
||||
data = (args, kwargs)
|
||||
res = ethumb_client_thumb_exists(self.obj, cb, <void *>data)
|
||||
|
||||
return False
|
||||
#TODO: handle return value
|
||||
|
||||
def generate(self, func, *args, **kargs):
|
||||
"""Ask EThumb server to generate the specified thumbnail.
|
||||
|
||||
Thumbnail generation is asynchronous and depend on ecore main
|
||||
loop running. Given function will be called back with
|
||||
generation status if True is returned by this call. If False
|
||||
is returned, given function will not be called.
|
||||
|
||||
Existing thumbnails will be overwritten with this call. Check
|
||||
if they already exist with :py:func:`exists` before calling.
|
||||
|
||||
:param func: function to call on generation completion, even
|
||||
if failed or succeeded. Signature is::
|
||||
|
||||
func(self, id, file, key, thumb_path, thumb_key, status, *args, **kargs)
|
||||
|
||||
with status being True for successful generation or
|
||||
False on failure.
|
||||
|
||||
:return: request identifier. Request can be canceled calling
|
||||
:py:func:`cancel` with given id. If an identifier is returned (>=
|
||||
0), then func is guaranteed to be called unless it is
|
||||
explicitly canceled.
|
||||
|
||||
:raise TypeError: if **func** is not callable.
|
||||
:raise SystemError: if could not generate thumbnail, probably
|
||||
no :py:func:`file_set`.
|
||||
|
||||
.. seealso:: :py:func:`cancel`, :py:func:`clear`, :py:func:`exists`
|
||||
"""
|
||||
if not callable(func):
|
||||
raise TypeError("func must be callable")
|
||||
|
||||
targs = (self, func, args, kargs)
|
||||
r = ethumb_client_generate(self.obj, _generated_cb, <void*>targs,
|
||||
_generated_cb_free_data)
|
||||
if r >= 0:
|
||||
Py_INCREF(targs)
|
||||
return r
|
||||
else:
|
||||
raise SystemError("could not generate thumbnail. "
|
||||
"Did you set the file?")
|
||||
|
||||
def generate_cancel(self, int id):
|
||||
"""Cancel thumbnail request given its id.
|
||||
|
||||
Calling this function aborts thumbnail generation and **func**
|
||||
given to :py:func:`generate` will not be called!
|
||||
|
||||
:param id: identifier returned by :py:func:`generate`
|
||||
"""
|
||||
ethumb_client_generate_cancel(self.obj, id, NULL, NULL, NULL)
|
||||
|
||||
def generate_cancel_all(self):
|
||||
"""Clear request queue, canceling all generation requests.
|
||||
|
||||
This will abort all existing requests, no **func** given to
|
||||
:py:func:`generate` will be called.
|
||||
|
||||
Same as calling :py:func:`cancel` in all exising requests.
|
||||
"""
|
||||
ethumb_client_generate_cancel_all(self.obj)
|
||||
|
||||
init()
|
|
@ -0,0 +1,26 @@
|
|||
cdef extern from "Ethumb.h":
|
||||
ctypedef enum Ethumb_Thumb_Orientation:
|
||||
ETHUMB_THUMB_ORIENT_NONE # keep orientation as pixel data is
|
||||
ETHUMB_THUMB_ROTATE_90_CW # rotate 90° clockwise
|
||||
ETHUMB_THUMB_ROTATE_180 # rotate 180°
|
||||
ETHUMB_THUMB_ROTATE_90_CCW # rotate 90° counter-clockwise
|
||||
ETHUMB_THUMB_FLIP_HORIZONTAL # flip horizontally
|
||||
ETHUMB_THUMB_FLIP_VERTICAL # flip vertically
|
||||
ETHUMB_THUMB_FLIP_TRANSPOSE # transpose
|
||||
ETHUMB_THUMB_FLIP_TRANSVERSE # transverse
|
||||
ETHUMB_THUMB_ORIENT_ORIGINAL # use orientation from metadata (EXIF-only currently)
|
||||
|
||||
ctypedef enum Ethumb_Thumb_FDO_Size:
|
||||
ETHUMB_THUMB_NORMAL # 128x128 as defined by FreeDesktop.Org standard
|
||||
ETHUMB_THUMB_LARGE # 256x256 as defined by FreeDesktop.Org standard
|
||||
|
||||
ctypedef enum Ethumb_Thumb_Format:
|
||||
ETHUMB_THUMB_FDO # PNG as defined by FreeDesktop.Org standard
|
||||
ETHUMB_THUMB_JPEG # JPEGs are often smaller and faster to read/write
|
||||
ETHUMB_THUMB_EET # EFL's own storage system, supports key parameter
|
||||
|
||||
ctypedef enum Ethumb_Thumb_Aspect:
|
||||
ETHUMB_THUMB_KEEP_ASPECT # keep original proportion between width and height
|
||||
ETHUMB_THUMB_IGNORE_ASPECT # ignore aspect and foce it to match thumbnail's width and height
|
||||
ETHUMB_THUMB_CROP # keep aspect but crop (cut) the largest dimension
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
# Copyright (C) 2009 by ProFUSION embedded systems
|
||||
#
|
||||
# This file is part of Python-Ethumb.
|
||||
#
|
||||
# Python-Ethumb is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-Ethumb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-Ethumb. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from efl.eina cimport Eina_Bool, Eina_Free_Cb
|
||||
from efl.ethumb.enums cimport Ethumb_Thumb_FDO_Size, Ethumb_Thumb_Format, \
|
||||
Ethumb_Thumb_Aspect, Ethumb_Thumb_Orientation
|
||||
|
||||
cdef extern from "Ethumb.h":
|
||||
cdef struct Ethumb:
|
||||
int tw
|
||||
int th
|
||||
int format
|
||||
int aspect
|
||||
|
||||
ctypedef void (*Ethumb_Generate_Cb)(void *data, Ethumb *e, Eina_Bool success)
|
||||
|
||||
# Ethumb
|
||||
int ethumb_init()
|
||||
void ethumb_shutdown()
|
||||
Ethumb *ethumb_new()
|
||||
void ethumb_free(Ethumb *e)
|
||||
|
||||
# Setup
|
||||
Eina_Bool ethumb_frame_set(Ethumb *e, const char *theme_file, const char *group, const char *swallow)
|
||||
void ethumb_frame_get(Ethumb *e, const char **theme_file, const char **group, const char **swallow)
|
||||
|
||||
void ethumb_thumb_dir_path_set(Ethumb *e, const char *path)
|
||||
const char * ethumb_thumb_dir_path_get(Ethumb *e)
|
||||
|
||||
void ethumb_thumb_category_set(Ethumb *e, const char *category)
|
||||
const char * ethumb_thumb_category_get(Ethumb *e)
|
||||
|
||||
void ethumb_thumb_path_set(Ethumb *e, const char *path, const char *key)
|
||||
void ethumb_thumb_path_get(Ethumb *e, const char **path, const char **key)
|
||||
void ethumb_thumb_hash(Ethumb *e)
|
||||
void ethumb_thumb_hash_copy(Ethumb *dst, Ethumb *src)
|
||||
|
||||
|
||||
void ethumb_thumb_fdo_set(Ethumb *e, Ethumb_Thumb_FDO_Size s)
|
||||
|
||||
void ethumb_thumb_size_set(Ethumb *e, int tw, int th)
|
||||
void ethumb_thumb_size_get(Ethumb *e, int *tw, int *th)
|
||||
|
||||
void ethumb_thumb_format_set(Ethumb *e, Ethumb_Thumb_Format f)
|
||||
Ethumb_Thumb_Format ethumb_thumb_format_get(Ethumb *e)
|
||||
|
||||
void ethumb_thumb_aspect_set(Ethumb *e, Ethumb_Thumb_Aspect a)
|
||||
Ethumb_Thumb_Aspect ethumb_thumb_aspect_get(Ethumb *e)
|
||||
|
||||
void ethumb_thumb_orientation_set(Ethumb *e, Ethumb_Thumb_Orientation o)
|
||||
Ethumb_Thumb_Orientation ethumb_thumb_orientation_get(Ethumb *e)
|
||||
|
||||
void ethumb_thumb_crop_align_set(Ethumb *e, float x, float y)
|
||||
void ethumb_thumb_crop_align_get(Ethumb *e, float *x, float *y)
|
||||
|
||||
void ethumb_thumb_quality_set(Ethumb *e, int quality)
|
||||
int ethumb_thumb_quality_get(Ethumb *e)
|
||||
|
||||
void ethumb_thumb_compress_set(Ethumb *e, int compress)
|
||||
int ethumb_thumb_compress_get(Ethumb *e)
|
||||
|
||||
void ethumb_video_start_set(Ethumb *e, float start)
|
||||
float ethumb_video_start_get(Ethumb *e)
|
||||
void ethumb_video_time_set(Ethumb *e, float time)
|
||||
float ethumb_video_time_get(Ethumb *e)
|
||||
void ethumb_video_interval_set(Ethumb *e, float interval)
|
||||
float ethumb_video_interval_get(Ethumb *e)
|
||||
void ethumb_video_ntimes_set(Ethumb *e, unsigned int ntimes)
|
||||
unsigned int ethumb_video_ntimes_get(Ethumb *e)
|
||||
void ethumb_video_fps_set(Ethumb *e, unsigned int fps)
|
||||
unsigned int ethumb_video_fps_get(Ethumb *e)
|
||||
|
||||
# Basics
|
||||
void ethumb_document_page_set(Ethumb *e, unsigned int page)
|
||||
unsigned int ethumb_document_page_get(Ethumb *e)
|
||||
|
||||
Eina_Bool ethumb_file_set(Ethumb *e, const char *path, const char *key)
|
||||
void ethumb_file_get(Ethumb *e, const char **path, const char **key)
|
||||
void ethumb_file_free(Ethumb *e)
|
||||
|
||||
Eina_Bool ethumb_generate(Ethumb *e, Ethumb_Generate_Cb finished_cb, void *data, Eina_Free_Cb free_data)
|
||||
Eina_Bool ethumb_exists(Ethumb *e)
|
||||
|
||||
Ethumb *ethumb_dup(Ethumb *e)
|
||||
Eina_Bool ethumb_cmp(Ethumb *e1, Ethumb *e2)
|
||||
int ethumb_hash(void *key, int key_length)
|
||||
int ethumb_key_cmp(void *key1, int key1_length, void *key2, int key2_length)
|
||||
unsigned int ethumb_length(void *key)
|
||||
|
||||
|
||||
cdef class PyEthumb:
|
||||
cdef Ethumb *obj
|
|
@ -0,0 +1,96 @@
|
|||
# Copyright (C) 2009 by ProFUSION embedded systems
|
||||
#
|
||||
# This file is part of Python-Ethumb.
|
||||
#
|
||||
# Python-Ethumb is free software you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-Ethumb is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-Ethumb. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from efl.eina cimport Eina_Bool, Eina_Free_Cb
|
||||
from efl.ethumb.enums cimport Ethumb_Thumb_Orientation
|
||||
|
||||
cdef extern from "Ethumb_Client.h":
|
||||
ctypedef struct Ethumb_Client
|
||||
ctypedef struct Ethumb_Exists
|
||||
ctypedef void (*Ethumb_Client_Connect_Cb)(void *data, Ethumb_Client *client, Eina_Bool success)
|
||||
ctypedef void (*Ethumb_Client_Die_Cb)(void *data, Ethumb_Client *client)
|
||||
ctypedef void (*Ethumb_Client_Generate_Cb)(void *data, Ethumb_Client *client, int id, const char *file, const char *key, const char *thumb_path, const char *thumb_key, Eina_Bool success)
|
||||
ctypedef void (*Ethumb_Client_Thumb_Exists_Cb)(void *data, Ethumb_Client *client, Ethumb_Exists *thread, Eina_Bool exists)
|
||||
ctypedef void (*Ethumb_Client_Generate_Cancel_Cb)(void *data, Eina_Bool success)
|
||||
|
||||
int ethumb_client_init()
|
||||
int ethumb_client_shutdown()
|
||||
|
||||
Ethumb_Client *ethumb_client_connect(Ethumb_Client_Connect_Cb cb, void *data, Eina_Free_Cb free_data)
|
||||
void ethumb_client_disconnect(Ethumb_Client *client)
|
||||
void ethumb_client_on_server_die_callback_set(Ethumb_Client *client, Ethumb_Client_Die_Cb server_die_cb, void *data, Eina_Free_Cb free_data)
|
||||
|
||||
void ethumb_client_fdo_set(Ethumb_Client *client, int s)
|
||||
|
||||
void ethumb_client_size_set(Ethumb_Client *client, int tw, int th)
|
||||
void ethumb_client_size_get(Ethumb_Client *client, int *tw, int *th)
|
||||
void ethumb_client_format_set(Ethumb_Client *client, int f)
|
||||
int ethumb_client_format_get(Ethumb_Client *client)
|
||||
void ethumb_client_aspect_set(Ethumb_Client *client, int a)
|
||||
int ethumb_client_aspect_get(Ethumb_Client *client)
|
||||
void ethumb_client_orientation_set(Ethumb_Client *client, Ethumb_Thumb_Orientation o)
|
||||
Ethumb_Thumb_Orientation ethumb_client_orientation_get(Ethumb_Client *client)
|
||||
void ethumb_client_crop_align_set(Ethumb_Client *client, float x, float y)
|
||||
void ethumb_client_crop_align_get(Ethumb_Client *client, float *x, float *y)
|
||||
void ethumb_client_quality_set(Ethumb_Client *client, int quality)
|
||||
int ethumb_client_quality_get(Ethumb_Client *client)
|
||||
void ethumb_client_compress_set(Ethumb_Client *client, int compress)
|
||||
int ethumb_client_compress_get(Ethumb_Client *client)
|
||||
Eina_Bool ethumb_client_frame_set(Ethumb_Client *client, const char *file, const char *group, const char *swallow)
|
||||
void ethumb_client_dir_path_set(Ethumb_Client *client, const char *path)
|
||||
const char * ethumb_client_dir_path_get(Ethumb_Client *client)
|
||||
void ethumb_client_category_set(Ethumb_Client *client, const char *category)
|
||||
const char * ethumb_client_category_get(Ethumb_Client *client)
|
||||
void ethumb_client_video_time_set(Ethumb_Client *client, float time)
|
||||
void ethumb_client_video_start_set(Ethumb_Client *client, float start)
|
||||
void ethumb_client_video_interval_set(Ethumb_Client *client, float interval)
|
||||
void ethumb_client_video_ntimes_set(Ethumb_Client *client, int ntimes)
|
||||
void ethumb_client_video_fps_set(Ethumb_Client *client, int fps)
|
||||
void ethumb_client_document_page_set(Ethumb_Client *client, int page)
|
||||
|
||||
void ethumb_client_ethumb_setup(Ethumb_Client *client)
|
||||
|
||||
void ethumb_client_thumb_path_set(Ethumb_Client *client, const char *path, const char *key)
|
||||
void ethumb_client_thumb_path_get(Ethumb_Client *client, const char **path, const char **key)
|
||||
|
||||
Eina_Bool ethumb_client_file_set(Ethumb_Client *client, const char *path, const char *key)
|
||||
void ethumb_client_file_get(Ethumb_Client *client, const char **path, const char **key)
|
||||
void ethumb_client_file_free(Ethumb_Client *client)
|
||||
|
||||
Ethumb_Exists *ethumb_client_thumb_exists(Ethumb_Client *client, Ethumb_Client_Thumb_Exists_Cb exists_cb, void *data)
|
||||
void ethumb_client_thumb_exists_cancel(Ethumb_Exists *exists)
|
||||
Eina_Bool ethumb_client_thumb_exists_check(Ethumb_Exists *exists)
|
||||
int ethumb_client_generate(Ethumb_Client *client, Ethumb_Client_Generate_Cb generated_cb, void *data, Eina_Free_Cb free_data)
|
||||
void ethumb_client_generate_cancel(Ethumb_Client *client, int id, Ethumb_Client_Generate_Cancel_Cb cancel_cb, void *data, Eina_Free_Cb free_data)
|
||||
void ethumb_client_generate_cancel_all(Ethumb_Client *client)
|
||||
|
||||
ctypedef void (*Ethumb_Client_Async_Done_Cb)(Ethumb_Client *ethumbd, const char *thumb_path, const char *thumb_key, void *data)
|
||||
ctypedef void (*Ethumb_Client_Async_Error_Cb)(Ethumb_Client *ethumbd, void *data)
|
||||
|
||||
ctypedef struct Ethumb_Client_Async
|
||||
|
||||
Ethumb_Client_Async *ethumb_client_thumb_async_get(Ethumb_Client *client,
|
||||
Ethumb_Client_Async_Done_Cb done,
|
||||
Ethumb_Client_Async_Error_Cb error,
|
||||
void *data)
|
||||
|
||||
void ethumb_client_thumb_async_cancel(Ethumb_Client *client, Ethumb_Client_Async *request)
|
||||
|
||||
cdef class Client:
|
||||
cdef Ethumb_Client *obj
|
||||
cdef object _on_connect_callback
|
||||
cdef object _on_server_die_callback
|
18
setup.py
18
setup.py
|
@ -186,6 +186,24 @@ if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv):
|
|||
package_dirs["ecore"] = "compat/ecore"
|
||||
|
||||
|
||||
# === Ethumb ===
|
||||
ethumb_cflags, ethumb_libs = pkg_config('Ethumb', 'ethumb', EFL_MIN_VERSION)
|
||||
ethumb_ext = Extension("ethumb", ["efl/ethumb/efl.ethumb"+module_suffix],
|
||||
include_dirs = ['include/'],
|
||||
extra_compile_args = ethumb_cflags,
|
||||
extra_link_args = ethumb_libs + eina_libs,
|
||||
)
|
||||
modules.append(ethumb_ext)
|
||||
|
||||
ethumb_client_cflags, ethumb_client_libs = pkg_config('Ethumb_Client', 'ethumb_client', EFL_MIN_VERSION)
|
||||
ethumb_client_ext = Extension("ethumb_client", ["efl/ethumb/efl.ethumb_client"+module_suffix],
|
||||
include_dirs = ['include/'],
|
||||
extra_compile_args = ethumb_client_cflags,
|
||||
extra_link_args = ethumb_client_libs + eina_libs,
|
||||
)
|
||||
modules.append(ethumb_client_ext)
|
||||
|
||||
|
||||
# === Edje ===
|
||||
edje_cflags, edje_libs = pkg_config('Edje', 'edje', EFL_MIN_VERSION)
|
||||
edje_ext = Extension("edje", ["efl/edje/efl.edje"+module_suffix],
|
||||
|
|
Loading…
Reference in New Issue