comparison RestDbJsonStore.py @ 42:291aed5f0e0d

new class for JSON store
author casties
date Thu, 02 Sep 2010 12:05:17 +0200
parents
children 562717546168
comparison
equal deleted inserted replaced
41:f94fc5a51a38 42:291aed5f0e0d
1 '''
2 Created on 2.9.2010
3
4 @author: casties
5 '''
6
7 from OFS.Folder import Folder
8 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
9 import logging
10 import re
11 import psycopg2
12 import json
13 import time
14
15 from zope.interface import implements
16 from zope.publisher.interfaces import IPublishTraverse
17 from ZPublisher.BaseRequest import DefaultPublishTraverse
18 import Shared.DC.ZRDB.DA
19 from Products.ZSQLMethods.SQL import SQLConnectionIDs
20
21
22
23 class RestDbJsonStore(RestDbInterface):
24 """Object for RESTful database queries
25 path schema: /db/{schema}/{table}/
26 omitting table gives a list of schemas
27 omitting table and schema gives a list of schemas
28 """
29 implements(IPublishTraverse)
30
31 meta_type="RESTdbJSONStore"
32 manage_options=Folder.manage_options+(
33 {'label':'Config','action':'manage_editRestDbJsonStoreForm'},
34 )
35
36 # management templates
37 manage_editRestDbJsonStoreForm=PageTemplateFile('zpt/editRestDbJsonStore',globals())
38
39 # JSON_* templates are scripts
40 def JSON_index(self,data):
41 """JSON index function"""
42 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
43 json.dump(data, self.REQUEST.RESPONSE)
44
45 def JSON_schema(self,data,schema):
46 """JSON index function"""
47 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
48 json.dump(data, self.REQUEST.RESPONSE)
49
50 def JSON_schema_table(self,data,tablename):
51 """JSON index function"""
52 self.REQUEST.RESPONSE.setHeader("Content-Type", "application/json")
53 json.dump(data, self.REQUEST.RESPONSE)
54
55
56 def __init__(self, id, title, connection_id=None):
57 """init"""
58 self.id = id
59 self.title = title
60 # database connection id
61 self.connection_id = connection_id
62
63 def getJsonString(self,object):
64 """returns a JSON formatted string from object"""
65 return json.dumps(object)
66
67
68 def publishTraverse(self,request,name):
69 """change the traversal"""
70 # get stored path
71 path = request.get('restdb_path', [])
72 logging.debug("publishtraverse: name=%s restdb_path=%s"%(name,path))
73
74 if name in ("index_html", "PUT"):
75 # end of traversal
76 if request.get("method") == "POST" and request.get("action",None) == "PUT":
77 # fake PUT by POST with action=PUT
78 name = "PUT"
79
80 return getattr(self, name)
81 #TODO: should we check more?
82 else:
83 # traverse
84 if len(path) == 0:
85 # first segment
86 if name == 'db':
87 # virtual path -- continue traversing
88 path = [name]
89 request['restdb_path'] = path
90 else:
91 # try real path
92 tr = DefaultPublishTraverse(self, request)
93 ob = tr.publishTraverse(request, name)
94 return ob
95 else:
96 path.append(name)
97
98 # continue traversing
99 return self
100
101 def index_html(self,REQUEST,RESPONSE):
102 """index method"""
103 # ReST path was stored in request
104 path = REQUEST.get('restdb_path',[])
105
106 # type and format are real parameter
107 resultFormat = REQUEST.get('format','HTML').upper()
108 queryType = REQUEST.get('type',None)
109
110 logging.debug("index_html path=%s resultFormat=%s queryType=%s"%(path,resultFormat,queryType))
111
112 if queryType is not None:
113 # non-empty queryType -- look for template
114 pt = getattr(self.template, "%s_%s"%(resultFormat,queryType), None)
115 if pt is not None:
116 return pt(format=resultFormat,type=queryType,path=path)
117
118 if len(path) == 1:
119 # list of schemas
120 return self.showListOfSchemas(resultFormat=resultFormat)
121 elif len(path) == 2:
122 # list of tables
123 return self.showListOfTables(resultFormat=resultFormat,schema=path[1])
124 elif len(path) == 3:
125 # table
126 if REQUEST.get("method") == "POST" and REQUEST.get("create_table_file",None) is not None:
127 # POST to table to check
128 return self.checkTable(resultFormat=resultFormat,schema=path[1],table=path[2])
129 # else show table
130 return self.showTable(resultFormat=resultFormat,schema=path[1],table=path[2])
131
132 # don't know what to do
133 return str(REQUEST)
134
135 def PUT(self, REQUEST, RESPONSE):
136 """
137 Implement WebDAV/HTTP PUT/FTP put method for this object.
138 """
139 logging.debug("RestDbInterface PUT")
140 #logging.debug("req=%s"%REQUEST)
141 #self.dav__init(REQUEST, RESPONSE)
142 #self.dav__simpleifhandler(REQUEST, RESPONSE)
143 # ReST path was stored in request
144 path = REQUEST.get('restdb_path',[])
145 if len(path) == 3:
146 schema = path[1]
147 tablename = path[2]
148 file = REQUEST.get("create_table_file",None)
149 if file is None:
150 RESPONSE.setStatus(400)
151 return
152
153 fields = None
154 fieldsStr = REQUEST.get("create_table_fields",None)
155 logging.debug("put with schema=%s table=%s file=%s fields=%s"%(schema,tablename,file,repr(fieldsStr)))
156 if fieldsStr is not None:
157 # unpack fields
158 fields = [{"name":n, "type": t} for (n,t) in [f.split(":") for f in fieldsStr.split(",")]]
159
160 ret = self.createTableFromXML(schema, tablename, file, fields)
161 # return the result as JSON
162 format = REQUEST.get("format","JSON")
163 if format == "JSON":
164 RESPONSE.setHeader("Content-Type", "application/json")
165 json.dump(ret, RESPONSE)
166
167 elif format == "JSONHTML":
168 RESPONSE.setHeader("Content-Type", "text/html")
169 RESPONSE.write("<html>\n<body>\n<pre>")
170 json.dump(ret, RESPONSE)
171 RESPONSE.write("</pre>\n</body>\n</html>")
172
173 else:
174 # 400 Bad Request
175 RESPONSE.setStatus(400)
176 return
177
178 def showTable(self,resultFormat='XML',schema='public',table=None,REQUEST=None,RESPONSE=None):
179 """returns PageTemplate with tables"""
180 logging.debug("showtable")
181 if REQUEST is None:
182 REQUEST = self.REQUEST
183
184 # should be cross-site accessible
185 if RESPONSE is None:
186 RESPONSE = self.REQUEST.RESPONSE
187
188 RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
189
190 # GIS gets special treatment
191 if resultFormat=="GIS":
192 id = REQUEST.get('id',[])
193 doc = REQUEST.get('doc',None)
194 return self.showGoogleMap(schema=schema,table=table,id=id,doc=doc)
195
196 elif resultFormat=="KML_URL":
197 id = REQUEST.get('id',[])
198 doc = REQUEST.get('doc',None)
199 return self.getKmlUrl(schema=schema,table=table,id=id,doc=doc)
200
201 # everything else has its own template
202 pt = getattr(self.template, '%s_schema_table'%resultFormat, None)
203 if pt is None:
204 return "ERROR!! template %s_schema_table not found"%resultFormat
205
206 data = self.getTable(schema,table)
207 return pt(data=data,tablename=table)
208
209 def getTable(self,schema='public',table=None,username='guest'):
210 """return table data"""
211 logging.debug("gettable")
212 data = self.executeSQL('select * from "%s"."%s"'%(schema,table))
213 return data
214
215 def hasTable(self,schema='public',table=None,username='guest'):
216 """return if table exists"""
217 logging.debug("hastable")
218 data = self.executeSQL('select 1 from information_schema.tables where table_schema=%s and table_name=%s',(schema,table))
219 ret = bool(data['rows'])
220 return ret
221
222 def showListOfTables(self,resultFormat='XML',schema='public',REQUEST=None,RESPONSE=None):
223 """returns PageTemplate with list of tables"""
224 logging.debug("showlistoftables")
225 # should be cross-site accessible
226 if RESPONSE is None:
227 RESPONSE = self.REQUEST.RESPONSE
228 RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
229
230 pt = getattr(self.template, '%s_schema'%resultFormat, None)
231 if pt is None:
232 return "ERROR!! template %s_schema not found"%resultFormat
233
234 data = self.getListOfTables(schema)
235 return pt(data=data,schema=schema)
236
237 def getListOfTables(self,schema='public',username='guest'):
238 """return list of tables"""
239 logging.debug("getlistoftables")
240 # get list of fields and types of db table
241 qstr="""SELECT c.relname AS tablename FROM pg_catalog.pg_class c
242 LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
243 WHERE c.relkind IN ('r','') AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
244 AND pg_catalog.pg_table_is_visible(c.oid)"""
245 #qstr="select attname, format_type(pg_attribute.atttypid, pg_attribute.atttypmod) from pg_attribute, pg_class where attrelid = pg_class.oid and pg_attribute.attnum > 0"
246 data=self.executeSQL(qstr)
247 return data
248
249 def showListOfSchemas(self,resultFormat='XML',REQUEST=None,RESPONSE=None):
250 """returns PageTemplate with list of schemas"""
251 logging.debug("showlistofschemas")
252 # should be cross-site accessible
253 if RESPONSE is None:
254 RESPONSE = self.REQUEST.RESPONSE
255 RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
256
257 pt = getattr(self.template, '%s_index'%resultFormat, None)
258 if pt is None:
259 return "ERROR!! template %s_index not found"%resultFormat
260
261 data = self.getListOfSchemas()
262 return pt(data=data)
263
264 def getListOfSchemas(self,username='guest'):
265 """return list of schemas"""
266 logging.debug("getlistofschemas")
267 # TODO: really look up schemas
268 data={'fields': (('schemas',),), 'rows': [('public',),]}
269 return data
270
271 def checkTable(self,resultFormat,schema,table,REQUEST=None,RESPONSE=None):
272 """check the table.
273 returns valid data fields and table name."""
274 if REQUEST is None:
275 REQUEST = self.REQUEST
276 RESPONSE = REQUEST.RESPONSE
277
278 file = REQUEST.get("create_table_file",None)
279 res = self.checkTableFromXML(schema, table, file)
280 logging.debug("checkTable result=%s"%repr(res))
281 # return the result as JSON
282 if resultFormat == "JSON":
283 RESPONSE.setHeader("Content-Type", "application/json")
284 json.dump(res, RESPONSE)
285
286 elif resultFormat == "JSONHTML":
287 RESPONSE.setHeader("Content-Type", "text/html")
288 RESPONSE.write("<html>\n<body>\n<pre>")
289 json.dump(res, RESPONSE)
290 RESPONSE.write("</pre>\n</body>\n</html>")
291
292 else:
293 return "ERROR: invalid resultFormat"
294
295 def checkTableFromXML(self,schema,table,data,REQUEST=None,RESPONSE=None):
296 """check the table with the given XML data.
297 returns valid data fields and table name."""
298 logging.debug("checkTableFromXML schema=%s table=%s"%(schema,table))
299 # clean table name
300 tablename = sqlName(table)
301 tableExists = self.hasTable(schema, table)
302 if data is None:
303 fieldNames = []
304 else:
305 # get list of field names from upload file
306 fields = self.importExcelXML(schema,tablename,data,fieldsOnly=True)
307
308 res = {'tablename': tablename, 'table_exists': tableExists}
309 res['fields'] = fields
310 return res
311
312 def createEmptyTable(self,schema,table,fields):
313 """create a table with the given fields
314 returns list of created fields"""
315 logging.debug("createEmptyTable")
316 sqlFields = []
317 for f in fields:
318 if isinstance(f,dict):
319 # {name: XX, type: YY}
320 name = sqlName(f['name'])
321 type = f['type']
322 sqltype = gisToSqlTypeMap[type]
323
324 else:
325 # name only
326 name = sqlName(f)
327 type = 'text'
328 sqltype = 'text'
329
330 sqlFields.append({'name':name, 'type':type, 'sqltype':sqltype})
331
332 if self.checkTableMetaPermission("create", schema, table):
333 self.executeSQL('drop table if exists "%s"."%s"'%(schema,table),hasResult=False)
334 fieldString = ", ".join(['"%s" %s'%(f['name'],f['sqltype']) for f in sqlFields])
335 sqlString = 'create table "%s"."%s" (%s)'%(schema,table,fieldString)
336 logging.debug("createemptytable: SQL=%s"%sqlString)
337 self.executeSQL(sqlString,hasResult=False)
338 self.setTableMetaTypes(schema,table,sqlFields)
339 return sqlFields
340 else:
341 logging.warning("create table not allowed!")
342 # throw exception?
343 return None
344
345 def createTableFromXML(self,schema,table,data, fields=None):
346 """create or replace a table with the given XML data"""
347 logging.debug("createTableFromXML schema=%s table=%s data=%s fields=%s"%(schema,table,data,fields))
348 tablename = sqlName(table)
349 self.importExcelXML(schema, tablename, data, fields)
350 return {"tablename": tablename}
351
352 def importExcelXML(self,schema,table,xmldata,fields=None,fieldsOnly=False):
353 '''
354 Import XML file in Excel format into the table
355 @param table: name of the table the xml shall be imported into
356 '''
357 from xml.dom.pulldom import parseString,parse
358
359 namespace = "urn:schemas-microsoft-com:office:spreadsheet"
360 containerTagName = "Table"
361 rowTagName = "Row"
362 colTagName = "Cell"
363 dataTagName = "Data"
364 xmlFields = []
365 sqlFields = []
366 numFields = 0
367 sqlInsert = None
368
369 logging.debug("import excel xml")
370
371 ret=""
372 if isinstance(xmldata, str):
373 logging.debug("importXML reading string data")
374 doc=parseString(xmldata)
375 else:
376 logging.debug("importXML reading file data")
377 doc=parse(xmldata)
378
379 cnt = 0
380 while True:
381 node=doc.getEvent()
382
383 if node is None:
384 break
385
386 else:
387 #logging.debug("tag=%s"%node[1].localName)
388 if node[1].localName is not None:
389 tagName = node[1].localName.lower()
390 else:
391 # ignore non-tag nodes
392 continue
393
394 if tagName == rowTagName.lower():
395 # start of row
396 doc.expandNode(node[1])
397 cnt += 1
398 if cnt == 1:
399 # first row -- field names
400 names=node[1].getElementsByTagNameNS(namespace, dataTagName)
401 for name in names:
402 fn = getTextFromNode(name)
403 xmlFields.append({'name':sqlName(fn),'type':'text'})
404
405 if fieldsOnly:
406 # return just field names
407 return xmlFields
408
409 # create table
410 if fields is None:
411 fields = xmlFields
412
413 sqlFields = self.createEmptyTable(schema, table, fields)
414 numFields = len(sqlFields)
415 fieldString = ", ".join(['"%s"'%f['name'] for f in sqlFields])
416 valString = ", ".join(["%s" for f in sqlFields])
417 sqlInsert = 'insert into "%s"."%s" (%s) values (%s)'%(schema,table,fieldString,valString)
418 #logging.debug("importexcelsql: sqlInsert=%s"%sqlInsert)
419
420 else:
421 # following rows are data
422 colNodes=node[1].getElementsByTagNameNS(namespace, colTagName)
423 data = []
424 hasData = False
425 for colNode in colNodes:
426 dataNodes=colNode.getElementsByTagNameNS(namespace, dataTagName)
427 if len(dataNodes) > 0:
428 val = getTextFromNode(dataNodes[0])
429 hasData = True
430 else:
431 val = None
432
433 data.append(val)
434
435 if not hasData:
436 # ignore empty rows
437 continue
438
439 # fix number of data fields
440 if len(data) > numFields:
441 del data[numFields:]
442 elif len(data) < numFields:
443 missFields = numFields - len(data)
444 data.extend(missFields * [None,])
445
446 logging.debug("importexcel sqlinsert=%s data=%s"%(sqlInsert,data))
447 self.executeSQL(sqlInsert, data, hasResult=False)
448
449 return cnt
450
451
452 # Methods for GoogleMaps creation
453 def showGoogleMap(self,schema='chgis',table='mpdl',id=[],doc=None):
454 logging.debug("showGoogleMap")
455 data = self.getDataForGoogleMap(schema,table,id,doc)
456 kmlFileName=self.getKMLname(data=data,table=table)
457 initializeStringForGoogleMaps="""onload=\"initialize(\'http://chinagis.mpiwg-berlin.mpg.de/chinagis/REST/daten/"""+kmlFileName+"""\')\""""#+str(data)
458 initializeStringForGoogleMaps=initializeStringForGoogleMaps.replace("None","0")
459 googleMap_page=self.htmlHead()+str(self.getGoogleMapString(kml=initializeStringForGoogleMaps))
460 return googleMap_page
461
462 def getKmlUrl(self,schema='chgis',table='mpdl',id=[],doc=None):
463 logging.debug("getKmlUrl")
464 data = self.getDataForGoogleMap(schema,table,id,doc)
465 kml=self.getKMLname(data=data,table=table)
466 baseUrl = self.absolute_url()
467 return "%s/daten/%s"%(baseUrl,kml)
468
469 def getDataForGoogleMap(self,schema='chgis',table='mpdl',id=[],doc=None):
470 logging.debug("getDataForGoogleMap")
471 qstr="SELECT * FROM "+schema+"."+table
472 try:
473 if id!=[]:
474 qstr=qstr+" WHERE "
475 for id_item in id.split(","):
476 if table=='mpdl':
477 qstr=qstr+" mpdl_xmlsource_id = '"+id_item+ "' OR"
478 else:
479 qstr=qstr+" cast(id as text) LIKE '"+id_item+ "' OR"
480 qstr=str(qstr).rsplit(" ",1)[0] #to remove last " and "
481 data=self.ZSQLSimpleSearch(qstr)
482 return data
483 except:
484 return qstr
485
486 def getKMLname(self,data=[],table=""):
487 logging.debug("getKMLname")
488 #session=context.REQUEST.SESSION
489 kml4Marker="<kml xmlns=\'http://www.opengis.net/kml/2.2\'><Document><Style id=\'marker_icon\'><IconStyle><scale>15</scale><Icon><href>http://chinagis.mpiwg-berlin.mpg.de/chinagis/images/dot_red.png</href></Icon></IconStyle></Style>\n"
490 initializeStringForGoogleMaps=""
491 #doLine=container.getVar('doLine')
492 # Mapping a set of points from table-based SQL-query:
493 if data!=None:
494 try:
495 SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s'
496 res = self.executeSQL(SQL, (table,))
497 gisIDattribute = res['rows'][0][0]
498 except:
499 return "table not registered within metadata"
500
501 for dataset in data:
502 try:
503 xCoord=getattr(dataset,'longitude')
504 yCoord=getattr(dataset,'latitude')
505 except:
506 try:
507 xCoord=getattr(dataset,'x_coord')
508 yCoord=getattr(dataset,'y_coord')
509 except:
510 #try:
511 gisID=getattr(dataset,gisIDattribute)
512 coords=self.getPoint4GISid(gisID)
513 if coords!=None:
514 xCoord=coords[0]
515 yCoord=coords[1]
516 # except:
517 # return "no coordinates found"
518
519 if float(xCoord)!=0:
520 if float(yCoord)!=0:
521 kml4Marker=kml4Marker+"<Placemark>"
522 kml4Marker=kml4Marker+"<description> <![CDATA[<b>"
523 for values in dataset:
524 if values != (None, None):
525 if str(values).find('name')>-1:
526 kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n"
527 continue
528 elif str(values).find('place')>-1:
529 kml4Marker=kml4Marker+"<name>"+str(values[1])+"</name>\n"
530 continue
531
532 kml4Marker=kml4Marker+str(values)+": "
533 attribute_string=str(values).replace("'","__Apostroph__")
534 attribute_string=str(attribute_string).replace('"','__DoubleApostroph__')
535 attribute_string=str(attribute_string).replace(';','__$$__')
536 attribute_string=str(attribute_string).replace('&','&amp;')
537 if str(attribute_string).find('http')>-1:
538 attribute_string='<A HREF=' + str(attribute_string) + ' target=_blank>' + str(attribute_string) + '</A>'
539 kml4Marker=kml4Marker+attribute_string+"</a><br>\n"
540
541 kml4Marker=kml4Marker+"]]></description>\n"
542 kml4Marker=kml4Marker+"<styleURL>#marker_icon</styleURL>\n"
543 kml4Marker=kml4Marker+"<Point>"
544
545 kml4Marker=kml4Marker+"<coordinates>"+str(xCoord)+","+str(yCoord)+",0</coordinates>\n"
546 kml4Marker=kml4Marker+"</Point>\n"
547 kml4Marker=kml4Marker+"</Placemark>\n"
548
549 kml4Marker=kml4Marker+"</Document>\n</kml>"
550 kmlFileName="marker"+str(time.time())+".kml"
551
552 #kml4Marker=str(kml4Marker).replace('&','$$')
553 #kml4Marker=str(kml4Marker).replace(';','__$$__')
554 #kml4Marker=str(kml4Marker).replace('#','__SHARP__')
555 isLoadReady='false'
556 while isLoadReady=='false':
557 isLoadReady=self.RESTwrite2File(self.daten,kmlFileName,kml4Marker)
558
559 return kmlFileName
560
561 def getGoogleMapString(self,kml):
562 logging.debug("getGoogleMapString")
563 printed= '<body %s> '%kml +"""\n <div id="map_canvas" style="width: 98%; height: 95%"> </div> \n </body>" \n </html>"""
564 return printed
565
566 def getPoint4GISid(self,gis_id):
567 j=0
568 coords=(0,0)
569 if gis_id != None:
570 while (True):
571 j=j+1
572 if (j>100): # FJK: just to prevent endless loops
573 break
574 if (gis_id.isdigit()): # FJK: regular exit from while-loop
575 break
576 else:
577 gis_id=gis_id.strip('abcdefghijklmnopqrstuvwxyz_') # FJK: to strip all letters
578 gis_id=gis_id.strip() # FJK: to strip all whitespaces
579 resultpoint = [0,0]
580 results = None
581 try:
582 if int(gis_id)>0:
583 SQL="SELECT x_coord,y_coord FROM chgis.chgis_coords WHERE gis_id LIKE cast("+ str(gis_id) +" as text);"
584 results=self.ZSQLSimpleSearch(SQL)
585 #print results
586 if results != None:
587 for result in results:
588 resultpoint=[getattr(result,str('x_coord')),getattr(result,str('y_coord'))]
589 if resultpoint !=[0,0]:
590 return resultpoint
591 else:
592 coords=self.getCoordsFromREST_gisID(joinid)
593 SQL="INSERT INTO chgis.chgis_coords (gis_id,x_coord,y_coord) VALUES (" +gis_id+ "," +coords[0][1]+ "," +coords[0][0]+ "); ANALYZE chgis.chgis_coords;"
594 returnstring=self.ZSQLSimpleSearch(SQL)
595 return coords[0]
596 except:
597 return "gis_id not to interpretable:"+str(gis_id)
598 else:
599 return coords[0]
600
601 def getCoordsFromREST_gisID(self,gis_id):
602 coordlist=[]
603 i=0
604 while (i<5 and coordlist==[]):
605
606 urlresponse=container.urlFunctions.zUrlopenParseString(container.urlFunctions.zUrlopenRead("http://chgis.hmdc.harvard.edu/xml/id/"+gis_id))
607 baseDocElement=container.urlFunctions.zUrlopenDocumentElement(urlresponse)
608 childnodes=container.urlFunctions.zUrlopenChildNodes(baseDocElement)
609 itemnodes=container.urlFunctions.zUrlopenGetElementsByTagName(baseDocElement,'item')
610
611 for i in range(0,container.urlFunctions.zUrlopenLength(itemnodes)):
612 itemnode=container.urlFunctions.zUrlopenGetItem(itemnodes,i)
613 itemspatialnodes=container.urlFunctions.zUrlopenGetElementsByTagName(itemnode,'spatial')
614 for j in range(0,container.urlFunctions.zUrlopenLength(itemspatialnodes)):
615 coord=[]
616 itemspatialnode= container.urlFunctions.zUrlopenGetItem(itemspatialnodes,j)
617 itemspatiallatnodes=container.urlFunctions.zUrlopenGetElementsByTagName(itemspatialnode,'degrees_latitude')
618 for k in range(0,container.urlFunctions.zUrlopenLength(itemspatiallatnodes)):
619 itemspatiallatnode= container.urlFunctions.zUrlopenGetItem(itemspatiallatnodes,k)
620 coord.append(container.urlFunctions.zUrlopenGetTextData(itemspatiallatnode))
621 itemspatiallngnodes=container.urlFunctions.zUrlopenGetElementsByTagName(itemspatialnode,'degrees_longitude')
622 for k in range(0,container.urlFunctions.zUrlopenLength(itemspatiallngnodes)):
623 itemspatiallngnode= container.urlFunctions.zUrlopenGetItem(itemspatiallngnodes,k)
624 coord.append(container.urlFunctions.zUrlopenGetTextData(itemspatiallngnode))
625 coordlist.append(coord)
626 gis_id= "_"+gis_id
627 return coordlist
628
629 # End for GoogleMaps creation
630
631 def RESTwrite2File(self,datadir, name,text):
632 logging.debug("RESTwrite2File datadir=%s name=%s"%(datadir,name))
633 try:
634 import cStringIO as StringIO
635 except:
636 import StringIO
637
638 # make filehandle from string
639 textfile = StringIO.StringIO(text)
640 fileid=name
641 if fileid in datadir.objectIds():
642 datadir.manage_delObjects(fileid)
643 fileInZope=datadir.manage_addFile(id=fileid,file=textfile)
644 return "Write successful"
645
646 def manage_editRestDbInterface(self, title=None, connection_id=None,
647 REQUEST=None):
648 """Change the object"""
649 if title is not None:
650 self.title = title
651
652 if connection_id is not None:
653 self.connection_id = connection_id
654
655 #checkPermission=getSecurityManager().checkPermission
656 REQUEST.RESPONSE.redirect('manage_main')
657
658
659 manage_addRestDbInterfaceForm=PageTemplateFile('zpt/addRestDbInterface',globals())
660
661 def manage_addRestDbInterface(self, id, title='', label='', description='',
662 createPublic=0,
663 createUserF=0,
664 REQUEST=None):
665 """Add a new object with id *id*."""
666
667 ob=RestDbInterface(str(id),title)
668 self._setObject(id, ob)
669
670 #checkPermission=getSecurityManager().checkPermission
671 REQUEST.RESPONSE.redirect('manage_main')
672
673