From 7f5296e84982258e9b3bf16663762d25633f1ca4 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 20 Apr 2007 09:20:23 +0000 Subject: [PATCH] - fixes compatibity problems between 'ivr' and 'py_sems'. - now both plug-ins should be able to load at the same time. git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@305 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- apps/ivr/Ivr.cpp | 74 ++++++++++++++++++------- apps/ivr/Ivr.h | 7 ++- apps/py_sems/PySems.cpp | 118 +++++++++++++++------------------------- apps/py_sems/PySems.h | 9 +-- core/AmUtils.cpp | 35 ++++++++++++ core/AmUtils.h | 3 + 6 files changed, 147 insertions(+), 99 deletions(-) diff --git a/apps/ivr/Ivr.cpp b/apps/ivr/Ivr.cpp index 8b10a1d9..f9e44d01 100644 --- a/apps/ivr/Ivr.cpp +++ b/apps/ivr/Ivr.cpp @@ -183,27 +183,27 @@ IvrFactory::IvrFactory(const string& _app_name) { } -void IvrFactory::setScriptPath(const string& path) -{ - string python_path = script_path = path; +// void IvrFactory::setScriptPath(const string& path) +// { +// string python_path = script_path = path; - if(python_path.length()){ +// if(python_path.length()){ - python_path = AmConfig::PlugInPath + ":" + python_path; - } - else - python_path = AmConfig::PlugInPath; +// python_path = AmConfig::PlugInPath + ":" + python_path; +// } +// else +// python_path = AmConfig::PlugInPath; - char* old_path=0; - if((old_path = getenv("PYTHONPATH")) != 0) - if(strlen(old_path)) - python_path += ":" + string(old_path); +// char* old_path=0; +// if((old_path = getenv("PYTHONPATH")) != 0) +// if(strlen(old_path)) +// python_path += ":" + string(old_path); - DBG("setting PYTHONPATH to: '%s'\n",python_path.c_str()); - setenv("PYTHONPATH",python_path.c_str(),1); +// DBG("setting PYTHONPATH to: '%s'\n",python_path.c_str()); +// setenv("PYTHONPATH",python_path.c_str(),1); -} +// } void IvrFactory::import_object(PyObject* m, char* name, PyTypeObject* type) { @@ -261,14 +261,49 @@ void IvrFactory::import_ivr_builtins() } } -void IvrFactory::init_python_interpreter() +void IvrFactory::init_python_interpreter(const string& script_path) { - Py_Initialize(); + if(!Py_IsInitialized()){ + + add_env_path("PYTHONPATH",AmConfig::PlugInPath); + Py_Initialize(); + } + PyEval_InitThreads(); + set_sys_path(script_path); import_ivr_builtins(); PyEval_ReleaseLock(); } +void IvrFactory::set_sys_path(const string& script_path) +{ + + PyObject* py_mod_name = PyString_FromString("sys"); + PyObject* py_mod = PyImport_Import(py_mod_name); + Py_DECREF(py_mod_name); + + if(!py_mod){ + PyErr_Print(); + ERROR("IvrFactory: could not import 'sys' module.\n"); + ERROR("IvrFactory: please check your installation.\n"); + return; + } + + PyObject* sys_path_str = PyString_FromString("path"); + PyObject* sys_path = PyObject_GetAttr(py_mod,sys_path_str); + Py_DECREF(sys_path_str); + + if(!sys_path){ + PyErr_Print(); + Py_DECREF(py_mod); + return; + } + + if(!PyList_Insert(sys_path,0,PyString_FromString(script_path.c_str()))){ + PyErr_Print(); + } +} + IvrDialog* IvrFactory::newDlg(const string& name) { PYLOCK; @@ -421,8 +456,9 @@ int IvrFactory::onLoad() // get application specific global parameters configureModule(cfg); - setScriptPath(cfg.getParameter("script_path")); - init_python_interpreter(); + //setScriptPath(cfg.getParameter("script_path")); + string script_path = cfg.getParameter("script_path"); + init_python_interpreter(script_path); DBG("** IVR compile time configuration:\n"); DBG("** built with PYTHON support.\n"); diff --git a/apps/ivr/Ivr.h b/apps/ivr/Ivr.h index 68a4534a..60739908 100644 --- a/apps/ivr/Ivr.h +++ b/apps/ivr/Ivr.h @@ -77,14 +77,15 @@ struct IvrScriptDesc class IvrFactory: public AmSessionFactory { PyObject* ivr_module; - string script_path; + //string script_path; string default_script; map mod_reg; AmDynInvokeFactory* user_timer_fact; - void init_python_interpreter(); + void init_python_interpreter(const string& script_path); + void set_sys_path(const string& script_path); void import_ivr_builtins(); void import_object(PyObject* m, @@ -94,7 +95,7 @@ class IvrFactory: public AmSessionFactory /** @return true if everything ok */ bool loadScript(const string& path); - void setScriptPath(const string& path); + //void setScriptPath(const string& path); bool checkCfg(); IvrDialog* newDlg(const string& name); diff --git a/apps/py_sems/PySems.cpp b/apps/py_sems/PySems.cpp index 50cd2246..bfee1aa1 100644 --- a/apps/py_sems/PySems.cpp +++ b/apps/py_sems/PySems.cpp @@ -82,9 +82,6 @@ extern "C" { if((level)<=log_level) { - //if(level == L_ERR) - //assert(0); - if(log_stderr) log_print( level, msg ); else { @@ -134,27 +131,16 @@ PySemsFactory::PySemsFactory(const string& _app_name) { } -void PySemsFactory::setScriptPath(const string& path) -{ - string python_path = script_path = path; - - - if(python_path.length()){ - - python_path = AmConfig::PlugInPath + ":" + python_path; - } - else - python_path = AmConfig::PlugInPath; - - char* old_path=0; - if((old_path = getenv("PYTHONPATH")) != 0) - if(strlen(old_path)) - python_path += ":" + string(old_path); +// void PySemsFactory::setScriptPath(const string& path) +// { +// string python_path = script_path = path; - DBG("setting PYTHONPATH to: '%s'\n",python_path.c_str()); - setenv("PYTHONPATH",python_path.c_str(),1); +// if(python_path.length()){ +// add_env_path("PYTHONPATH", python_path); +// } -} +// add_env_path("PYTHONPATH",AmConfig::PlugInPath); +// } void PySemsFactory::import_object(PyObject* m, char* name, PyTypeObject* type) { @@ -186,7 +172,27 @@ void PySemsFactory::import_py_sems_builtins() initpy_sems_lib(); } -void PySemsFactory::import_module(const char* modname) +void PySemsFactory::set_sys_path(const string& script_path) +{ + PyObject* py_mod = import_module("sys"); + if(!py_mod) return; + + PyObject* sys_path_str = PyString_FromString("path"); + PyObject* sys_path = PyObject_GetAttr(py_mod,sys_path_str); + Py_DECREF(sys_path_str); + + if(!sys_path){ + PyErr_Print(); + Py_DECREF(py_mod); + return; + } + + if(!PyList_Insert(sys_path,0,PyString_FromString(script_path.c_str()))){ + PyErr_Print(); + } +} + +PyObject* PySemsFactory::import_module(const char* modname) { PyObject* py_mod_name = PyString_FromString(modname); PyObject* py_mod = PyImport_Import(py_mod_name); @@ -196,14 +202,22 @@ void PySemsFactory::import_module(const char* modname) PyErr_Print(); ERROR("PySemsFactory: could not find python module '%s'.\n",modname); ERROR("PySemsFactory: please check your installation.\n"); - return; + return NULL; } + + return py_mod; } -void PySemsFactory::init_python_interpreter() +void PySemsFactory::init_python_interpreter(const string& script_path) { - Py_Initialize(); + if(!Py_IsInitialized()){ + + add_env_path("PYTHONPATH",AmConfig::PlugInPath); + Py_Initialize(); + } + PyEval_InitThreads(); + set_sys_path(script_path); import_py_sems_builtins(); PyEval_ReleaseLock(); } @@ -280,43 +294,6 @@ AmSession* PySemsFactory::newDlg(const string& name) } -// // TODO: find some way to guess the type without trying... -// // try Dialog... -// PySemsDialog* dlg = (PySemsDialog*)sipForceConvertTo_PySemsDialog(dlg_inst,&err); -// if (dlg && (!err)) { -// DBG("OK, got PySemsDialog.\n"); -// sess = dlg; -// dlg_base = dlg; -// } else { -// // try B2BDialog... -// err = 0; -// PySemsB2BDialog* b2b_dlg = (PySemsB2BDialog*)sipForceConvertTo_PySemsB2BDialog(dlg_inst,&err); -// if (b2b_dlg && (!err)) { -// DBG("OK, got PySemsB2BDialog.\n"); -// sess = b2b_dlg; -// dlg_base = b2b_dlg; -// } else { - -// // try B2ABDialog... -// err=0; -// PySemsB2ABDialog* b2ab_dlg = (PySemsB2ABDialog*)sipForceConvertTo_PySemsB2ABDialog(dlg_inst,&err); - -// // if (b2ab_dlg && (!err)) { -// // DBG("OK, got PySemsB2ABDialog.\n"); -// // sess = b2ab_dlg; -// // dlg_base = b2ab_dlg; -// // } else { -// // no luck -// PyErr_Print(); -// ERROR("PySemsFactory: while loading \"%s\": could not retrieve a PySems*Dialog ptr.\n", -// name.c_str()); -// throw AmSession::Exception(500,"Internal error in PY_SEMS plug-in."); -// Py_DECREF(dlg_inst); -// return NULL; -// } -// } -// } - // take the ownership over dlg sipTransferTo(dlg_inst,dlg_inst); Py_DECREF(dlg_inst); @@ -426,7 +403,6 @@ int PySemsFactory::onLoad() return -1; } - AmConfigReader cfg; if(cfg.loadFile(add2path(AmConfig::ModConfigPath,1,MOD_NAME ".conf"))) @@ -435,20 +411,16 @@ int PySemsFactory::onLoad() // get application specific global parameters configureModule(cfg); - setScriptPath(cfg.getParameter("script_path")); - init_python_interpreter(); - - DBG("** PY_SEMS compile time configuration:\n"); - DBG("** built with PYTHON support.\n"); + string script_path = cfg.getParameter("script_path"); + init_python_interpreter(script_path); #ifdef PY_SEMS_WITH_TTS - DBG("** Text-To-Speech enabled\n"); + DBG("** PY_SEMS Text-To-Speech enabled\n"); #else - DBG("** Text-To-Speech disabled\n"); + DBG("** PY_SEMS Text-To-Speech disabled\n"); #endif - DBG("** PY_SEMS run time configuration:\n"); - DBG("** script path: \'%s\'\n", script_path.c_str()); + DBG("** PY_SEMS script path: \'%s\'\n", script_path.c_str()); regex_t reg; if(regcomp(®,PYFILE_REGEX,REG_EXTENDED)){ diff --git a/apps/py_sems/PySems.h b/apps/py_sems/PySems.h index 4ea2f59a..d3587624 100644 --- a/apps/py_sems/PySems.h +++ b/apps/py_sems/PySems.h @@ -79,18 +79,19 @@ struct PySemsScriptDesc class PySemsFactory: public AmSessionFactory { PyObject* py_sems_module; - string script_path; +/* string script_path; */ string default_script; map mod_reg; AmDynInvokeFactory* user_timer_fact; - void init_python_interpreter(); + void init_python_interpreter(const string& script_path); + void set_sys_path(const string& script_path); void import_py_sems_builtins(); - void import_module(const char* modname); - void import_object(PyObject* m, + PyObject* import_module(const char* modname); + void import_object(PyObject* m, char* name, PyTypeObject* type); diff --git a/core/AmUtils.cpp b/core/AmUtils.cpp index d3785eaf..96baac9c 100644 --- a/core/AmUtils.cpp +++ b/core/AmUtils.cpp @@ -45,6 +45,8 @@ #include #include +#include + #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX 104 #endif @@ -839,3 +841,36 @@ unsigned int get_random() return r; } + + +// Warning: static var is not mutexed +// Call this func only in init code. +// +void add_env_path(const char* name, const string& path) +{ + string var(path); + char* old_path=0; + + regex_t path_reg; + + assert(name); + if((old_path = getenv(name)) != 0) { + if(strlen(old_path)){ + + if(regcomp(&path_reg,("[:|^]" + path + "[:|$]").c_str(),REG_NOSUB)){ + ERROR("could not compile regex\n"); + return; + } + + if(!regexec(&path_reg,old_path,0,0,0)) { // match + + return; // do nothing + } + + var += ":" + string(old_path); + } + } + + DBG("setting %s to: '%s'\n",name,var.c_str()); + setenv("PYTHONPATH",var.c_str(),1); +} diff --git a/core/AmUtils.h b/core/AmUtils.h index 9fa0a4d7..c4af9f56 100644 --- a/core/AmUtils.h +++ b/core/AmUtils.h @@ -263,6 +263,9 @@ string get_session_param(const string& hdrs, const string& name); void init_random(); unsigned int get_random(); +// add a directory to an environement variable +void add_env_path(const char* name, const string& path); + #endif // Local Variables: