kuuko pushed a commit to branch master.

http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=7fbab02702bb1318a7519fd80833ad0856c33812

commit 7fbab02702bb1318a7519fd80833ad0856c33812
Author: Kai Huuhko <kai.huu...@gmail.com>
Date:   Wed Oct 23 14:34:42 2013 +0300

    First attempt at integrating Eina Log with Python logging.
    
    Has two loggers: efl and efl.eo.
    
    To test, add handlers, formatters etc. and change levels using
    normal Python logging utilities. The test messages come from
    efl.eo init and class registration.
---
 efl/eo/efl.eo.pyx    | 98 ++++++++++++++++++++++++++++++++++++++++++----------
 include/efl.c_eo.pxd |  2 +-
 include/efl.eina.pxd | 50 +++++++++++++++++++++++++++
 3 files changed, 131 insertions(+), 19 deletions(-)

diff --git a/efl/eo/efl.eo.pyx b/efl/eo/efl.eo.pyx
index 31a6bfe..451d8ce 100644
--- a/efl/eo/efl.eo.pyx
+++ b/efl/eo/efl.eo.pyx
@@ -15,28 +15,84 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with this Python-EFL.  If not, see <http://www.gnu.org/licenses/>.
 
-from cpython cimport PyObject, Py_INCREF, Py_DECREF, PyUnicode_AsUTF8String
+cimport cython
+from cpython cimport PyObject, Py_INCREF, Py_DECREF, PyUnicode_AsUTF8String, \
+    PyString_FromFormatV
 from libc.stdlib cimport malloc, free
 from libc.string cimport memcpy, strdup
 from efl.eina cimport Eina_Bool, const_Eina_List, eina_list_append, 
const_void, \
     Eina_Hash, eina_hash_string_superfast_new, eina_hash_add, eina_hash_del, \
-    eina_hash_find
+    eina_hash_find, Eina_Log_Domain, const_Eina_Log_Domain, Eina_Log_Level, \
+    eina_log_print_cb_set, eina_log_domain_register, \
+    eina_log_level_set, eina_log_level_get, eina_log_domain_level_get, \
+    eina_log_domain_level_set, EINA_LOG_DOM_DBG, EINA_LOG_DOM_INFO
 from efl.c_eo cimport Eo as cEo, eo_init, eo_shutdown, eo_del, eo_do, \
     eo_class_name_get, eo_class_get, eo_base_data_set, eo_base_data_get, \
     eo_base_data_del, eo_event_callback_add, eo_event_callback_del, \
     Eo_Event_Description, const_Eo_Event_Description, \
     eo_parent_get, EO_EV_DEL
 
-######################################################################
-#
-# TODO: Automate these
-#
-# Call eo_init and put eo_shutdown to atexit, and don't expose in our API.
-#
-# Do the same in other packages as well, making sure the packages main
-# module is always imported.
-#
+
+cdef extern from "stdarg.h":
+    ctypedef struct va_list:
+        pass
+
+cdef void py_eina_log_print_cb(const_Eina_Log_Domain *d,
+                              Eina_Log_Level level,
+                              const_char *file, const_char *fnc, int line,
+                              const_char *fmt, void *data, va_list args) with 
gil:
+
+    cdef str msg = PyString_FromFormatV(fmt, args)
+    rec = logging.LogRecord(d.name, log_levels[level], file, line, msg, None, 
None, fnc)
+    loggers[d.name].handle(rec)
+
+eina_log_print_cb_set(py_eina_log_print_cb, NULL)
+
+
+import logging
+
+cdef tuple log_levels = (
+    50,
+    40,
+    30,
+    20,
+    10
+)
+
+cdef dict loggers = dict()
+
+class PyEFLLogger(logging.Logger):
+    def __init__(self, name):
+        self.eina_log_domain = eina_log_domain_register(name, NULL)
+        loggers[name] = self
+        logging.Logger.__init__(self, name)
+
+    def setLevel(self, lvl):
+        eina_log_domain_level_set(self.name, log_levels.index(lvl))
+        logging.Logger.setLevel(self, lvl)
+
+logging.setLoggerClass(PyEFLLogger)
+
+# TODO: Handle messages from root Eina Log with this one?
+rootlog = logging.getLogger("efl")
+rootlog.propagate = False
+rootlog.setLevel(logging.WARNING)
+rootlog.addHandler(logging.NullHandler())
+
+log = logging.getLogger(__name__)
+log.propagate = True
+log.setLevel(logging.WARNING)
+log.addHandler(logging.NullHandler())
+
+logging.setLoggerClass(logging.Logger)
+
+cdef int PY_EFL_EO_LOG_DOMAIN = log.eina_log_domain
+
+
+
+
 def init():
+    EINA_LOG_DOM_INFO(PY_EFL_EO_LOG_DOMAIN, "Initializing %s", <char 
*>__name__)
     return eo_init()
 
 def shutdown():
@@ -50,14 +106,15 @@ cdef int PY_REFCOUNT(object o):
     return obj.ob_refcnt
 
 
-
 ######################################################################
 
-
 """
+
 Object mapping is an Eina Hash table into which object type names can be
 registered. These can be used to find a bindings class for an object using
-the object_from_instance function."""
+the function object_from_instance.
+
+"""
 cdef Eina_Hash *object_mapping = eina_hash_string_superfast_new(NULL)
 
 
@@ -66,7 +123,7 @@ cdef void _object_mapping_register(char *name, object cls) 
except *:
     if eina_hash_find(object_mapping, name) != NULL:
         raise ValueError("Object type name '%s' already registered." % name)
 
-    #print("REGISTER: %s => %s" % (name, cls))
+    EINA_LOG_DOM_DBG(PY_EFL_EO_LOG_DOMAIN, "REGISTER: %s => %s", name, <char 
*>cls.__name__)
     eina_hash_add(object_mapping, name, <PyObject *>cls)
 
 
@@ -115,10 +172,13 @@ cdef object object_from_instance(cEo *obj):
 
 
 cdef void _register_decorated_callbacks(object obj):
-    """ Serach every attrib of the pyobj for a __decorated_callbacks__ object,
+    """
+
+    Search every attrib of the pyobj for a __decorated_callbacks__ object,
     a list actually. If found then exec the functions listed there, with their
     arguments. Must be called just after the _set_obj call.
     List items signature: ("function_name", *args)
+
     """
     cdef object attr_name, attrib, func_name, func
 
@@ -159,8 +219,10 @@ cdef Eina_Bool _eo_event_del_cb(void *data, cEo *obj, 
const_Eo_Event_Description
 
 cdef class Eo(object):
     """
+
     Base class used by all the Eo object in the bindings, its not meant to be
     used by users, but only by internal classes.
+
     """
 
     # c globals declared in eo.pxd (to make the class available to others)
@@ -175,13 +237,13 @@ cdef class Eo(object):
     def __str__(self):
         return ("Eo(class=%s, obj=%#x, parent=%#x, refcount=%d)") % \
                 (type(self).__name__, <unsigned long>self.obj,
-                 <unsigned long>eo_parent_get(self.obj) if self.obj != NULL 
else 0,
+                 <unsigned long><void *>eo_parent_get(&self.obj) if self.obj 
!= NULL else 0,
                  PY_REFCOUNT(self))
 
     def __repr__(self):
         return ("Eo(class=%s, obj=%#x, parent=%#x, refcount=%d)") % \
                 (type(self).__name__, <unsigned long>self.obj,
-                 <unsigned long>eo_parent_get(self.obj) if self.obj != NULL 
else 0,
+                 <unsigned long><void *>eo_parent_get(&self.obj) if self.obj 
!= NULL else 0,
                  PY_REFCOUNT(self))
 
     def __nonzero__(self):
diff --git a/include/efl.c_eo.pxd b/include/efl.c_eo.pxd
index e313bcd..62696e1 100644
--- a/include/efl.c_eo.pxd
+++ b/include/efl.c_eo.pxd
@@ -72,7 +72,7 @@ cdef extern from "Eo.h":
     const_Eo_Class *eo_class_get(const_Eo *obj)
     const_char *eo_class_name_get(const_Eo_Class *klass)
 
-    Eo *eo_parent_get(const_Eo *obj)
+    Eo *eo_parent_get(Eo **obj)
 
     void eo_event_callback_add(const_Eo_Event_Description *desc, Eo_Event_Cb 
cb, const_void *data)
     void eo_event_callback_del(const_Eo_Event_Description *desc, Eo_Event_Cb 
cb, const_void *data)
diff --git a/include/efl.eina.pxd b/include/efl.eina.pxd
index 1da12ce..9e11dde 100644
--- a/include/efl.eina.pxd
+++ b/include/efl.eina.pxd
@@ -15,6 +15,7 @@
 # You should have received a copy of the GNU Lesser General Public License
 # along with this Python-EFL.  If not, see <http://www.gnu.org/licenses/>.
 
+from cpython cimport va_list
 from libc.stdlib cimport const_void, malloc, free
 from libc.string cimport const_char, memcpy, strdup
 
@@ -38,6 +39,18 @@ cdef extern from "Eina.h":
     ####################################################################
     # Enumerations
     #
+    ctypedef enum Eina_Log_Level:
+        EINA_LOG_LEVEL_CRITICAL # Critical log level
+        EINA_LOG_LEVEL_ERR # Error log level
+        EINA_LOG_LEVEL_WARN # Warning log level
+        EINA_LOG_LEVEL_INFO # Information log level
+        EINA_LOG_LEVEL_DBG # Debug log level
+        EINA_LOG_LEVELS # Count of default log levels
+        EINA_LOG_LEVEL_UNKNOWN = (-2147483647 - 1) # Unknown level
+
+    ctypedef enum Eina_Log_State:
+        EINA_LOG_STATE_START
+        EINA_LOG_STATE_STOP
 
     ####################################################################
     # Basic Types
@@ -78,11 +91,22 @@ cdef extern from "Eina.h":
         void *(*get_container)(Eina_Iterator *it)
         void (*free)(Eina_Iterator *it)
 
+    ctypedef struct Eina_Log_Domain:
+        int         level # Max level to log
+        const char *domain_str # Formatted string with color to print
+        const char *name # Domain name
+        size_t      namelen # strlen(name)
+    ctypedef Eina_Log_Domain const_Eina_Log_Domain "const Eina_Log_Domain"
+
     ####################################################################
     # Other typedefs
     #
     ctypedef int (*Eina_Compare_Cb)(const_void *data1, const_void *data2)
     ctypedef void (*Eina_Free_Cb)(void *data)
+    ctypedef void (*Eina_Log_Print_Cb)(const_Eina_Log_Domain *d,
+                                  Eina_Log_Level level,
+                                  const_char *file, const_char *fnc, int line,
+                                  const_char *fmt, void *data, va_list args)
 
     ####################################################################
     # Functions
@@ -142,3 +166,29 @@ cdef extern from "Eina.h":
     Eina_Bool  eina_hash_add(Eina_Hash *hash, const_void *key, const_void 
*data)
     Eina_Bool eina_hash_del(Eina_Hash  *hash, const_void *key, const_void 
*data)
     void *eina_hash_find(Eina_Hash *hash, const_void *key)
+
+    void eina_log_threads_enable()
+    void eina_log_print_cb_set(Eina_Log_Print_Cb cb, void *data)
+    void eina_log_level_set(int level)
+    int  eina_log_level_get()
+    Eina_Bool          eina_log_main_thread_check()
+    void               eina_log_function_disable_set(Eina_Bool disabled)
+    Eina_Bool          eina_log_function_disable_get()
+    void               eina_log_domain_level_set(const_char *domain_name, int 
level)
+    int                eina_log_domain_level_get(const_char *domain_name)
+    int                eina_log_domain_registered_level_get(int domain)
+    int  eina_log_domain_register(const_char *name, const_char *color)
+    void eina_log_domain_unregister(int domain)
+    void eina_log_print(int            domain,
+                        Eina_Log_Level level,
+                        const_char    *file,
+                        const_char    *fnc,
+                        int            line,
+                        const_char    *fmt,
+                        ...)
+
+    void EINA_LOG_DOM_CRIT(int DOM, const_char *fmt, ...)
+    void EINA_LOG_DOM_ERR(int DOM, const_char *fmt, ...)
+    void EINA_LOG_DOM_WARN(int DOM, const_char *fmt, ...)
+    void EINA_LOG_DOM_INFO(int DOM, const_char *fmt, ...)
+    void EINA_LOG_DOM_DBG(int DOM, const_char *fmt, ...)

-- 


Reply via email to