# HG changeset patch
# User casties
# Date 1283426243 -7200
# Node ID 5627175461689daba64064096a7fabbced6f31ef
# Parent 291aed5f0e0d265d9a27b13eefce7a9594ba128c
refactoring...
RestDbGisApi and
RestDbJsonStore inherit from
RestDbInterface
diff -r 291aed5f0e0d -r 562717546168 REST_test.py
--- a/REST_test.py Thu Sep 02 12:05:17 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-'''
-Created on 26.04.2010
-
-@author: fknauft
-'''
-
-from OFS.Folder import Folder
-from Acquisition import Implicit
-from Globals import DTMLFile,package_home,Persistent
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
-from Products.ZSQLExtend import ZSQLExtend
-import urllib
-import re
-import string
-
-from zope.publisher.interfaces import IPublishTraverse
-from zope.interface import implements
-#from zope.publisher.interfaces import NotFound
-#from zope.app import zapi
-#from zope.component import queryMultiAdapter
-try:
- from ZPublisher.BaseRequest import DefaultPublishTraverse
-except:
- pass
-
-
-class RESTclass(Folder,Persistent, Implicit):
- """Klasse die Methoden fuer die RESTful Abfragen zur Verfuegung stellt. """
-
- meta_type="RESTclass"
-
- def publishTraverse(self,request,name):
- """change the traversal if literature object"""
-
- #actual_url=request['ACTUAL_URL']
- #lastActual=actual_url.split("/")[-1]
-
-
- tr=DefaultPublishTraverse(self, request)
- ob= tr.publishTraverse(request, name)
-
- return ob
-
- def RESTwrite2File(self,datadir, name,text):
-# try:
- fileid=name
- if fileid in datadir.objectIds():
- datadir.manage_delObjects(fileid)
- newfile=open(name,'w')
- newfile.write(text)
- newfile.close()
- file4Read=open(name,'r')
- fileInZope=datadir.manage_addFile(id=fileid,file=file4Read)
- return "Write successful"
-# except:
-# return "Could not write"
-
- def RESTexecuteString(self, function, params=[] ):
-
- try:
- return eval(str(function))(params)
- except:
- return eval("self."+ str(function))(params)
-
-
- def REST_result2XML(self,data):
- listXML= """"""
- for line in data:
- listXML=listXML+""
- for value in line:
- listXML=listXML +str(value)
- listXML=listXML +""
- return listXML
-
- def REST_result2HtmlTable(self,data):
- listHtml= "
"
- for line in data:
- listHtml=listHtml+""
- for value in line:
- listHtml=listHtml +""+str(value)+" | "
- listHtml=listHtml +"
"
- listHtml=listHtml+ """
"""
- return listHtml
-
- def REST_getTableNames(self,schema,username,c_string,container):
-
- results=container.ZSQLSimpleSearch("SELECT oid FROM pg_namespace WHERE nspname LIKE '"+schema+"'")
- schema_id=0
- for result in results:
- schema_id=getattr(result,'oid')
-
- SQL="""SELECT relname FROM pg_class WHERE relhaspkey
- AND relname NOT LIKE 'pg/_toast%' ESCAPE '/'
- AND relname NOT LIKE 'spatial_ref_sys'
- AND relname NOT LIKE 'geometry_columns'
- AND relname NOT LIKE 'markierung'"""
- # AND tablename NOT LIKE 'sql/_%' ESCAPE '/'
- if username!={}:
- uid=''
- username=container.getVar('username')
- results=container.ZSQLSimpleSearch("SELECT uid FROM chgis.usernames WHERE username LIKE '"+ str(username) +"'")
- for result in results:
- uid=container.getAttr(result,'uid')
- SQL=SQL+"""AND relowner ="""+str(uid)
-
- if c_string == 'empty':
- SQL = SQL + """ AND int4(reltuples)=0"""
- if schema_id != 0:
- SQL = SQL + """ AND int4(relnamespace)=""" + str(schema_id)
- data=container.ZSQLSimpleSearch(SQL)
- return data
-
-
-
-manage_addRESTclassForm=PageTemplateFile('zpt/RESTzopetemplate',globals())
-
-def manage_addRESTclass(self, id, title='', label='', description='',
- createPublic=0,
- createUserF=0,
- REQUEST=None):
- """Add a new Folder object with id *id*.
-
- If the 'createPublic' and 'createUserF' parameters are set to any true
- value, an 'index_html' and a 'UserFolder' objects are created respectively
- in the new folder.
- """
-
-
- ob=RESTclass()
- ob.id=str(id)
- ob.title=title
- self._setObject(id, ob)
- ob=self._getOb(id)
- setattr(ob,'label',label)
-# setattr(ob,'description',description)
-# setattr(ob,'connection_id',connection_id)
-
-# checkPermission=getSecurityManager().checkPermission
- REQUEST.RESPONSE.redirect('manage_main')
-
-
\ No newline at end of file
diff -r 291aed5f0e0d -r 562717546168 RESTinterface.py
--- a/RESTinterface.py Thu Sep 02 12:05:17 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-'''
-Created on 26.04.2010
-
-@author: fknauft
-'''
-
-from zope.publisher.interfaces import IPublishTraverse
-from zope.interface import implements
-#from zope.publisher.interfaces import NotFound
-#from zope.app import zapi
-#from zope.component import queryMultiAdapter
-try:
- from ZPublisher.BaseRequest import DefaultPublishTraverse
-except:
- pass
-class RESTinterface(DefaultPublishTraverse):
- """VLP spezifische Erweiterung der Collection"""
-
- implements(IPublishTraverse)
-
- def publishTraverse(self,request,name):
- """change the traversal if literature object"""
-
- actual_url=request['ACTUAL_URL']
- lastActual=actual_url.split("/")[-1]
-
-
- tr=DefaultPublishTraverse(self, request)
- ob= tr.publishTraverse(request, name)
-
- return ob
- #raise NotFound(self.context, name, request)
- #return repr(request)
\ No newline at end of file
diff -r 291aed5f0e0d -r 562717546168 RestDbGisApi.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/RestDbGisApi.py Thu Sep 02 13:17:23 2010 +0200
@@ -0,0 +1,363 @@
+'''
+Created on 2.9.2010
+
+@author: casties, fknauft
+'''
+
+from OFS.Folder import Folder
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from Products.ZSQLExtend import ZSQLExtend
+import logging
+import re
+import json
+import time
+
+from RestDbInterface import *
+
+
+gisToSqlTypeMap = {
+ "text": "text",
+ "number": "numeric",
+ "id": "text",
+ "gis_id": "text",
+ "coord_lat": "numeric",
+ "coord_lon": "numeric"
+ }
+
+class RestDbGisApi(RestDbInterface):
+ """Object for RESTful GIS database queries
+ path schema: /db/{schema}/{table}/
+ omitting table gives a list of schemas
+ omitting table and schema gives a list of schemas
+ """
+
+ meta_type="RESTgis"
+
+ # data templates
+ GIS_schema_table = PageTemplateFile('zpt/GIS_schema_table', globals())
+
+ def checkTableMetaPermission(self,action,schema,table,user=None):
+ """returns if the requested action on the table is allowed"""
+ logging.debug("checktablemetapermissions action=%s schema=%s table=%s user=%s"%(action,schema,table,user))
+ if user is None:
+ user = self.REQUEST.get('AUTHENTICATED_USER',None)
+ logging.debug("user=%s"%user)
+ # TODO: what now?
+ return True
+
+ def setTableMetaTypes(self,schema,table,fields):
+ """sets the GIS meta information for table"""
+ logging.debug("settablemetatypes schema=%s, table=%s, fields=%s"%(schema,table,fields))
+ gisIdField = None
+ latField = None
+ lonField = None
+ for f in fields:
+ t = f['type']
+ if t == 'gis_id':
+ gisIdField = f['name']
+ elif t == 'coord_lat':
+ latField = f['name']
+ elif t == 'coord_lon':
+ lonField = f['name']
+
+ res = self.executeSQL("select * from public.metadata where tablename=%s", (table,))
+ if len(res['rows']) > 0:
+ # meta record exists
+ if gisIdField is not None:
+ self.executeSQL('update public.metadata set "attribute with gis_id" = %s where tablename = %s', (gisIdField,table), hasResult=False)
+
+ else:
+ # new meta record
+ if gisIdField is not None:
+ self.executeSQL('insert into public.metadata ("tablename", "attribute with gis_id") values (%s, %s)', (table,gisIdField), hasResult=False)
+
+
+ def showTable(self,resultFormat='XML',schema='public',table=None,REQUEST=None,RESPONSE=None):
+ """returns PageTemplate with tables"""
+ logging.debug("showtable")
+ if REQUEST is None:
+ REQUEST = self.REQUEST
+
+ # should be cross-site accessible
+ if RESPONSE is None:
+ RESPONSE = self.REQUEST.RESPONSE
+
+ RESPONSE.setHeader('Access-Control-Allow-Origin', '*')
+
+ # GIS gets special treatment
+ if resultFormat=="GIS":
+ id = REQUEST.get('id',[])
+ doc = REQUEST.get('doc',None)
+ return self.showGoogleMap(schema=schema,table=table,id=id,doc=doc)
+
+ elif resultFormat=="KML_URL":
+ id = REQUEST.get('id',[])
+ doc = REQUEST.get('doc',None)
+ return self.getKmlUrl(schema=schema,table=table,id=id,doc=doc)
+
+ # everything else has its own template
+ pt = getattr(self.template, '%s_schema_table'%resultFormat, None)
+ if pt is None:
+ return "ERROR!! template %s_schema_table not found"%resultFormat
+
+ data = self.getTable(schema,table)
+ return pt(data=data,tablename=table)
+
+
+ def createEmptyTable(self,schema,table,fields):
+ """create a table with the given fields
+ returns list of created fields"""
+ logging.debug("createEmptyTable")
+ sqlFields = []
+ for f in fields:
+ if isinstance(f,dict):
+ # {name: XX, type: YY}
+ name = sqlName(f['name'])
+ type = f['type']
+ sqltype = gisToSqlTypeMap[type]
+
+ else:
+ # name only
+ name = sqlName(f)
+ type = 'text'
+ sqltype = 'text'
+
+ sqlFields.append({'name':name, 'type':type, 'sqltype':sqltype})
+
+ if self.checkTableMetaPermission("create", schema, table):
+ self.executeSQL('drop table if exists "%s"."%s"'%(schema,table),hasResult=False)
+ fieldString = ", ".join(['"%s" %s'%(f['name'],f['sqltype']) for f in sqlFields])
+ sqlString = 'create table "%s"."%s" (%s)'%(schema,table,fieldString)
+ logging.debug("createemptytable: SQL=%s"%sqlString)
+ self.executeSQL(sqlString,hasResult=False)
+ self.setTableMetaTypes(schema,table,sqlFields)
+ return sqlFields
+ else:
+ logging.warning("create table not allowed!")
+ # throw exception?
+ return None
+
+
+
+ # Methods for GoogleMaps creation
+ def showGoogleMap(self,schema='chgis',table='mpdl',id=[],doc=None):
+ logging.debug("showGoogleMap")
+ data = self.getDataForGoogleMap(schema,table,id,doc)
+ kmlFileName=self.getKMLname(data=data,table=table)
+ initializeStringForGoogleMaps="""onload=\"initialize(\'http://chinagis.mpiwg-berlin.mpg.de/chinagis/REST/daten/"""+kmlFileName+"""\')\""""#+str(data)
+ initializeStringForGoogleMaps=initializeStringForGoogleMaps.replace("None","0")
+ googleMap_page=self.htmlHead()+str(self.getGoogleMapString(kml=initializeStringForGoogleMaps))
+ return googleMap_page
+
+ def getKmlUrl(self,schema='chgis',table='mpdl',id=[],doc=None):
+ logging.debug("getKmlUrl")
+ data = self.getDataForGoogleMap(schema,table,id,doc)
+ kml=self.getKMLname(data=data,table=table)
+ baseUrl = self.absolute_url()
+ return "%s/daten/%s"%(baseUrl,kml)
+
+ def getDataForGoogleMap(self,schema='chgis',table='mpdl',id=[],doc=None):
+ logging.debug("getDataForGoogleMap")
+ qstr="SELECT * FROM "+schema+"."+table
+ try:
+ if id!=[]:
+ qstr=qstr+" WHERE "
+ for id_item in id.split(","):
+ if table=='mpdl':
+ qstr=qstr+" mpdl_xmlsource_id = '"+id_item+ "' OR"
+ else:
+ qstr=qstr+" cast(id as text) LIKE '"+id_item+ "' OR"
+ qstr=str(qstr).rsplit(" ",1)[0] #to remove last " and "
+ data=self.ZSQLSimpleSearch(qstr)
+ return data
+ except:
+ return qstr
+
+ def getKMLname(self,data=[],table=""):
+ logging.debug("getKMLname")
+ #session=context.REQUEST.SESSION
+ kml4Marker="\n"
+ initializeStringForGoogleMaps=""
+ #doLine=container.getVar('doLine')
+ # Mapping a set of points from table-based SQL-query:
+ if data!=None:
+ try:
+ SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s'
+ res = self.executeSQL(SQL, (table,))
+ gisIDattribute = res['rows'][0][0]
+ except:
+ return "table not registered within metadata"
+
+ for dataset in data:
+ try:
+ xCoord=getattr(dataset,'longitude')
+ yCoord=getattr(dataset,'latitude')
+ except:
+ try:
+ xCoord=getattr(dataset,'x_coord')
+ yCoord=getattr(dataset,'y_coord')
+ except:
+ #try:
+ gisID=getattr(dataset,gisIDattribute)
+ coords=self.getPoint4GISid(gisID)
+ if coords!=None:
+ xCoord=coords[0]
+ yCoord=coords[1]
+ # except:
+ # return "no coordinates found"
+
+ if float(xCoord)!=0:
+ if float(yCoord)!=0:
+ kml4Marker=kml4Marker+""
+ kml4Marker=kml4Marker+" "
+ for values in dataset:
+ if values != (None, None):
+ if str(values).find('name')>-1:
+ kml4Marker=kml4Marker+""+str(values[1])+"\n"
+ continue
+ elif str(values).find('place')>-1:
+ kml4Marker=kml4Marker+""+str(values[1])+"\n"
+ continue
+
+ kml4Marker=kml4Marker+str(values)+": "
+ attribute_string=str(values).replace("'","__Apostroph__")
+ attribute_string=str(attribute_string).replace('"','__DoubleApostroph__')
+ attribute_string=str(attribute_string).replace(';','__$$__')
+ attribute_string=str(attribute_string).replace('&','&')
+ if str(attribute_string).find('http')>-1:
+ attribute_string='' + str(attribute_string) + ''
+ kml4Marker=kml4Marker+attribute_string+"
\n"
+
+ kml4Marker=kml4Marker+"]]>\n"
+ kml4Marker=kml4Marker+"#marker_icon\n"
+ kml4Marker=kml4Marker+""
+
+ kml4Marker=kml4Marker+""+str(xCoord)+","+str(yCoord)+",0\n"
+ kml4Marker=kml4Marker+"\n"
+ kml4Marker=kml4Marker+"\n"
+
+ kml4Marker=kml4Marker+"\n"
+ kmlFileName="marker"+str(time.time())+".kml"
+
+ #kml4Marker=str(kml4Marker).replace('&','$$')
+ #kml4Marker=str(kml4Marker).replace(';','__$$__')
+ #kml4Marker=str(kml4Marker).replace('#','__SHARP__')
+ isLoadReady='false'
+ while isLoadReady=='false':
+ isLoadReady=self.RESTwrite2File(self.daten,kmlFileName,kml4Marker)
+
+ return kmlFileName
+
+ def getGoogleMapString(self,kml):
+ logging.debug("getGoogleMapString")
+ printed= ' '%kml +"""\n
\n " \n