source: trunk/zoo-project/zoo-kernel/service_internal_python.c @ 380

Last change on this file since 380 was 376, checked in by djay, 11 years ago

Add _ method to the zoo Python module to enable translation from zoo-services textdomain. Add gettextPath in the main section of the main.cfg to set the directory to search for language files.

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 13.4 KB
Line 
1/**
2 * Author : Gérald FENOY
3 *
4 * Copyright (c) 2009-2012 GeoLabs SARL
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "service_internal_python.h"
26
27static PyObject* ZooError;
28
29PyMethodDef zooMethods[] = {
30  {"_", PythonTranslate, METH_VARARGS, "Translate a string using the zoo-services textdomain."},
31  {"update_status", PythonUpdateStatus, METH_VARARGS, "Update status percentage of a running process."},
32  {NULL, NULL, 0, NULL} /* tempt not the blade, all fear the sentinel */
33};
34
35PyMODINIT_FUNC init_zoo(){
36  PyObject *tmp,*d;
37  PyObject* module = Py_InitModule("zoo", zooMethods);
38  if (module == NULL)
39    return;
40 
41  d = PyModule_GetDict(module);
42  tmp = PyInt_FromLong(3);
43  PyDict_SetItemString(d, "SERVICE_SUCCEEDED", tmp);
44  Py_DECREF(tmp);
45
46  tmp = PyInt_FromLong(4);
47  PyDict_SetItemString(d, "SERVICE_FAILED", tmp);
48  Py_DECREF(tmp);
49
50  ZooError = PyErr_NewException("zoo.error", NULL, NULL);
51  Py_INCREF(ZooError);
52  PyModule_AddObject(module, "error", ZooError);
53}
54
55int zoo_python_support(maps** main_conf,map* request,service* s,maps **real_inputs,maps **real_outputs){
56  maps* m=*main_conf;
57  maps* inputs=*real_inputs;
58  maps* outputs=*real_outputs;
59  char ntmp[1024];
60  getcwd(ntmp,1024);
61  map* tmp=NULL;
62  tmp=getMapFromMaps(*main_conf,"env","PYTHONPATH");
63  char *python_path;
64#ifdef DEBUG
65  fprintf(stderr,"PYTHON SUPPORT \n");
66#endif
67  fflush(stderr);
68  if(tmp!=NULL){
69#ifdef DEBUG
70    fprintf(stderr,"PYTHON SUPPORT (%i)\n",strlen(tmp->value));
71#endif
72    python_path=(char*)malloc((strlen(tmp->value))*sizeof(char));
73    sprintf(python_path,"%s",tmp->value);
74  }
75  else{
76    python_path=strdup(".");
77  }
78  tmp=NULL;
79  tmp=getMap(request,"metapath");
80  char *pythonpath=(char*)malloc((1+strlen(python_path)+2048)*sizeof(char));
81  if(tmp!=NULL && strcmp(tmp->value,"")!=0)
82#ifdef WIN32
83    sprintf(pythonpath,"%s/%s/;%s",ntmp,tmp->value,python_path);
84#else
85  sprintf(pythonpath,"%s/%s/:%s",ntmp,tmp->value,python_path);
86#endif
87  else
88#ifdef WIN32
89    sprintf(pythonpath,"%s;%s",ntmp,python_path);
90#else
91  sprintf(pythonpath,"%s:%s",ntmp,python_path);
92#endif
93#ifdef DEBUG
94    fprintf(stderr,"PYTHONPATH=%s\n",pythonpath);
95#endif
96#ifndef WIN32
97  setenv("PYTHONPATH",pythonpath,1);
98#else
99  SetEnvironmentVariable("PYTHONPATH",pythonpath);
100  char* toto=(char*)malloc((strlen(pythonpath)+12)*sizeof(char));
101  sprintf(toto,"PYTHONPATH=%s",pythonpath);
102  putenv(toto);
103#endif
104  free(python_path);
105  free(pythonpath);
106
107  PyThreadState *mainstate;
108  PyEval_InitThreads();
109  Py_Initialize();
110  init_zoo();
111  mainstate = PyThreadState_Swap(NULL);
112  PyEval_ReleaseLock();
113  PyGILState_STATE gstate;
114  gstate = PyGILState_Ensure();
115  PyObject *pName, *pModule, *pFunc;
116  tmp=getMap(s->content,"serviceProvider");
117  if(tmp!=NULL)
118    pName = PyString_FromString(tmp->value);
119  else{
120    map* err=createMap("text","Unable to parse serviceProvider please check your zcfg file.");
121    addToMap(err,"code","NoApplicableCode");
122    printExceptionReportResponse(m,err);
123    exit(-1);
124  }
125  pModule = PyImport_Import(pName);
126  int res=SERVICE_FAILED;
127  if (pModule != NULL) {
128    pFunc=PyObject_GetAttrString(pModule,s->name);
129    if (pFunc && PyCallable_Check(pFunc)){
130      PyObject *pValue;
131      PyDictObject* arg1=PyDict_FromMaps(m);
132      PyDictObject* arg2=PyDict_FromMaps(inputs);
133      PyDictObject* arg3=PyDict_FromMaps(outputs);
134      PyObject *pArgs=PyTuple_New(3);
135      if (!pArgs)
136        return -1;
137      PyTuple_SetItem(pArgs, 0, (PyObject *)arg1);
138      PyTuple_SetItem(pArgs, 1, (PyObject *)arg2);
139      PyTuple_SetItem(pArgs, 2, (PyObject *)arg3);
140      tmp=getMap(request,"storeExecuteResponse");
141#ifdef DEBUG
142      fprintf(stderr,"RUN IN NORMAL MODE \n");
143      fflush(stderr);
144#endif
145      pValue = PyObject_CallObject(pFunc, pArgs);
146      if (pValue != NULL) {
147        res=PyInt_AsLong(pValue);
148        freeMaps(real_outputs);
149        free(*real_outputs);
150        freeMaps(main_conf);
151        free(*main_conf);
152        *main_conf=mapsFromPyDict(arg1);
153        *real_outputs=mapsFromPyDict(arg3);
154#ifdef DEBUG
155        fprintf(stderr,"Result of call: %i\n", PyInt_AsLong(pValue));
156        dumpMaps(inputs);
157        dumpMaps(*real_outputs);
158#endif
159      }else{     
160        PyObject *ptype,*pvalue, *ptraceback;
161        PyErr_Fetch(&ptype, &pvalue, &ptraceback);
162        PyObject *trace=PyObject_Str(pvalue);
163        char pbt[10240];
164        if(PyString_Check(trace))
165          sprintf(pbt,"TRACE : %s",PyString_AsString(trace));
166        else
167          fprintf(stderr,"EMPTY TRACE ?");
168        trace=NULL;
169        trace=PyObject_Str(ptype);
170        if(PyString_Check(trace)){
171          char *tpbt=strdup(pbt);
172          sprintf(pbt,"%s\n%s\0",tpbt,PyString_AsString(trace));
173          free(tpbt);
174        }
175        else
176          fprintf(stderr,"EMPTY TRACE ?");
177       
178        char *tpbt=strdup(pbt);
179        pName = PyString_FromString("traceback");
180        pModule = PyImport_Import(pName);
181        pArgs = PyTuple_New(1);
182        PyTuple_SetItem(pArgs, 0, ptraceback);
183        pFunc = PyObject_GetAttrString(pModule,"format_tb");
184        pValue = PyObject_CallObject(pFunc, pArgs);
185        trace=NULL;
186        trace=PyObject_Str(pValue);
187        if(PyString_Check(trace))
188          sprintf(pbt,"%s\nUnable to run your python process properly. Please check the following messages : %s",tpbt,PyString_AsString(trace));
189        else
190          sprintf(pbt,"%s \n Unable to run your python process properly. Unable to provide any futher informations. %s",tpbt);
191        free(tpbt);
192        map* err=createMap("text",pbt);
193        addToMap(err,"code","NoApplicableCode");
194        printExceptionReportResponse(m,err);
195        res=-1;
196      }
197    }
198    else{
199      char tmpS[1024];
200      sprintf(tmpS, "Cannot find the %s function in the %s file.\n", s->name, tmp->value);
201      map* tmps=createMap("text",tmpS);
202      printExceptionReportResponse(m,tmps);
203      res=-1;
204    }
205  } else{
206    char tmpS[1024];
207    sprintf(tmpS, "Python module %s cannot be loaded.\n", tmp->value);
208    map* tmps=createMap("text",tmpS);
209    printExceptionReportResponse(m,tmps);
210    if (PyErr_Occurred())
211      PyErr_Print();
212    PyErr_Clear();
213    res=-1;
214    //exit(-1);
215  } 
216  PyGILState_Release(gstate);
217  PyEval_AcquireLock();
218  PyThreadState_Swap(mainstate);
219  Py_Finalize();
220  return res;
221}
222
223PyDictObject* PyDict_FromMaps(maps* t){
224  PyObject* res=PyDict_New( );
225  maps* tmp=t;
226  while(tmp!=NULL){
227    PyObject* value=(PyObject*)PyDict_FromMap(tmp->content);
228    PyObject* name=PyString_FromString(tmp->name);
229    if(PyDict_SetItem(res,name,value)<0){
230      fprintf(stderr,"Unable to set map value ...");
231      return NULL;
232    }
233    Py_DECREF(name);
234    tmp=tmp->next;
235  } 
236  return (PyDictObject*) res;
237}
238
239PyDictObject* PyDict_FromMap(map* t){
240  PyObject* res=PyDict_New( );
241  map* tmp=t;
242  int hasSize=0;
243  map* isArray=getMap(tmp,"isArray");
244  map* size=getMap(tmp,"size");
245  map* tmap=getMapType(tmp);
246  while(tmp!=NULL){
247    PyObject* name=PyString_FromString(tmp->name);
248    if(strcasecmp(tmp->name,"value")==0) {
249      if(isArray!=NULL){
250        map* len=getMap(tmp,"length");
251        int cnt=atoi(len->value);
252        PyObject* value=PyList_New(cnt);
253        PyObject* mvalue=PyList_New(cnt);
254        PyObject* svalue=PyList_New(cnt);
255
256        for(int i=0;i<cnt;i++){
257         
258          map* vMap=getMapArray(tmp,"value",i);     
259          map* sMap=getMapArray(tmp,"size",i);
260
261          if(vMap!=NULL){
262           
263            PyObject* lvalue;
264            PyObject* lsvalue;
265            if(sMap==NULL){
266              lvalue=PyString_FromString(vMap->value);
267              lsvalue=Py_None;
268            }
269            else{
270              lvalue=PyString_FromStringAndSize(vMap->value,atoi(sMap->value));
271              lsvalue=PyString_FromString(sMap->value);
272              hasSize=1;
273            }
274
275            if(PyList_SetItem(value,i,lvalue)<0){
276              fprintf(stderr,"Unable to set key value pair...");
277              return NULL;
278            } 
279            if(PyList_SetItem(svalue,i,lsvalue)<0){
280              fprintf(stderr,"Unable to set key value pair...");
281              return NULL;
282            } 
283          }
284         
285          map* mMap=getMapArray(tmp,tmap->name,i);
286          PyObject* lmvalue;
287          if(mMap!=NULL){
288            lmvalue=PyString_FromString(mMap->value);
289          }else
290            lmvalue=Py_None;
291         
292          if(PyList_SetItem(mvalue,i,lmvalue)<0){
293              fprintf(stderr,"Unable to set key value pair...");
294              return NULL;
295          } 
296         
297        }
298
299        if(PyDict_SetItem(res,name,value)<0){
300          fprintf(stderr,"Unable to set key value pair...");
301          return NULL;
302        }
303        if(PyDict_SetItem(res,PyString_FromString(tmap->name),mvalue)<0){
304          fprintf(stderr,"Unable to set key value pair...");
305          return NULL;
306        }
307        if(hasSize>0)
308          if(PyDict_SetItem(res,PyString_FromString("size"),svalue)<0){
309            fprintf(stderr,"Unable to set key value pair...");
310            return NULL;
311          }
312      }
313      else if(size!=NULL){
314        PyObject* value=PyString_FromStringAndSize(tmp->value,atoi(size->value));
315        if(PyDict_SetItem(res,name,value)<0){
316          fprintf(stderr,"Unable to set key value pair...");
317          return NULL;
318        }
319      }
320      else{
321        PyObject* value=PyString_FromString(tmp->value);
322        if(PyDict_SetItem(res,name,value)<0){
323          fprintf(stderr,"Unable to set key value pair...");
324          return NULL;
325        }
326      }
327    }
328    else{
329      if(PyDict_GetItem(res,name)==NULL){
330        PyObject* value=PyString_FromString(tmp->value);
331        if(PyDict_SetItem(res,name,value)<0){
332          fprintf(stderr,"Unable to set key value pair...");
333          return NULL;
334        }
335      }
336    }
337    Py_DECREF(name);
338    tmp=tmp->next;
339  }
340  return (PyDictObject*) res;
341}
342
343maps* mapsFromPyDict(PyDictObject* t){
344  maps* res=NULL;
345  maps* cursor=res;
346  PyObject* list=PyDict_Keys((PyObject*)t);
347  int nb=PyList_Size(list);
348  int i;
349  for(i=0;i<nb;i++){
350#ifdef DEBUG
351    fprintf(stderr,">> parsing maps %d\n",i);
352#endif
353    PyObject* key=PyList_GetItem(list,i);
354    PyObject* value=PyDict_GetItem((PyObject*)t,key);
355#ifdef DEBUG
356    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
357            PyString_AsString(key),PyString_AsString(value));
358#endif
359    cursor=(maps*)malloc(MAPS_SIZE);
360    cursor->name=PyString_AsString(key);
361    cursor->content=mapFromPyDict((PyDictObject*)value);
362#ifdef DEBUG
363    dumpMap(cursor->content);
364#endif
365    cursor->next=NULL;
366    if(res==NULL)
367      res=dupMaps(&cursor);
368    else
369      addMapsToMaps(&res,cursor);
370    freeMap(&cursor->content);
371    free(cursor->content);
372    free(cursor);
373#ifdef DEBUG
374    dumpMaps(res);
375    fprintf(stderr,">> parsed maps %d\n",i);
376#endif
377  }
378  return res;
379}
380
381map* mapFromPyDict(PyDictObject* t){
382  map* res=NULL;
383  PyObject* list=PyDict_Keys((PyObject*)t);
384  int nb=PyList_Size(list);
385  int i;
386  for(i=0;i<nb;i++){
387    PyObject* key=PyList_GetItem(list,i);
388    PyObject* value=PyDict_GetItem((PyObject*)t,key);
389#ifdef DEBUG
390    fprintf(stderr,">> DEBUG VALUES : %s => %s\n",
391            PyString_AsString(key),PyString_AsString(value));
392#endif
393    if(strcmp(PyString_AsString(key),"value")==0){
394      char *buffer=NULL;
395      Py_ssize_t size;
396      PyString_AsStringAndSize(value,&buffer,&size);
397      if(res!=NULL){
398        addToMap(res,PyString_AsString(key),"");
399      }else{
400        res=createMap(PyString_AsString(key),"");
401      }
402      map* tmpR=getMap(res,"value");
403      free(tmpR->value);
404      tmpR->value=(char*)malloc((size+1)*sizeof(char));
405      memmove(tmpR->value,buffer,size*sizeof(char));
406      tmpR->value[size]=0;
407      char sin[1024];
408      sprintf(sin,"%d",size);
409      addToMap(res,"size",sin);
410    }else{
411      if(res!=NULL)
412        addToMap(res,PyString_AsString(key),PyString_AsString(value));
413      else
414        res=createMap(PyString_AsString(key),PyString_AsString(value));
415    }
416  }
417  return res;
418}
419
420PyObject*
421PythonTranslate(PyObject* self, PyObject* args)
422{
423  char *str;
424  if (!PyArg_ParseTuple(args, "s", &str)){
425#ifdef DEBUG
426    fprintf(stderr,"Incorrect arguments to update status function");
427#endif
428    return NULL;
429  }
430  return PyString_FromString(_ss(str));
431}
432
433PyObject*
434PythonUpdateStatus(PyObject* self, PyObject* args)
435{
436  maps* conf;
437  PyObject* confdict;
438  int istatus;
439  char* status;
440  if (!PyArg_ParseTuple(args, "O!i", &PyDict_Type, &confdict, &istatus)){
441#ifdef DEBUG
442    fprintf(stderr,"Incorrect arguments to update status function");
443#endif
444    return NULL;
445  }
446  if (istatus < 0 || istatus > 100){
447     PyErr_SetString(ZooError, "Status must be a percentage.");
448     return NULL;
449  }else{
450     char tmpStatus[4];
451     snprintf(tmpStatus, 4, "%i", istatus);
452     status = strdup(tmpStatus);
453  }
454  /* now update the map */
455  {
456    PyObject* lenv = PyMapping_GetItemString(confdict, "lenv");
457    if (lenv && PyMapping_Check(lenv)){
458      PyObject* valobj = PyString_FromString(status);
459      PyMapping_SetItemString(lenv, "status", valobj);
460      Py_DECREF(valobj);
461    }
462    Py_DECREF(lenv);
463  }
464  conf = mapsFromPyDict((PyDictObject*)confdict);
465  if (getMapFromMaps(conf,"lenv","status") != NULL){
466    fprintf(stderr,"STATUS RETURNED : %s\n",status);
467    if(status!=NULL){
468      setMapInMaps(conf,"lenv","status",status);
469      free(status);
470    }
471    else
472      setMapInMaps(conf,"lenv","status","15");
473    updateStatus(conf);
474  }
475  freeMaps(&conf);
476  free(conf);
477  Py_RETURN_NONE;
478}
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png