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

Last change on this file since 368 was 368, checked in by djay, 10 years ago

Many thanks to Trevor Clarke for providing patch for Python ZOO-API. This rev. shall fix ticket #74.

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