Mercurial > hg > ChinaGisRestApi
comparison RestDbGisApi.py @ 61:e81d034b28a5
more permission handling and table metadata
| author | casties |
|---|---|
| date | Tue, 26 Oct 2010 21:23:19 +0200 |
| parents | 9fdadb60529f |
| children | 3905385c8854 |
comparison
equal
deleted
inserted
replaced
| 60:9fdadb60529f | 61:e81d034b28a5 |
|---|---|
| 7 from OFS.Folder import Folder | 7 from OFS.Folder import Folder |
| 8 from Products.PageTemplates.PageTemplateFile import PageTemplateFile | 8 from Products.PageTemplates.PageTemplateFile import PageTemplateFile |
| 9 from Products.ZSQLExtend import ZSQLExtend | 9 from Products.ZSQLExtend import ZSQLExtend |
| 10 import logging | 10 import logging |
| 11 import re | 11 import re |
| 12 import json | |
| 13 import time | 12 import time |
| 13 import datetime | |
| 14 import urllib | 14 import urllib |
| 15 | 15 |
| 16 from RestDbInterface import * | 16 from RestDbInterface import * |
| 17 | 17 |
| 18 | 18 |
| 44 meta_type="RESTgis" | 44 meta_type="RESTgis" |
| 45 | 45 |
| 46 # data templates | 46 # data templates |
| 47 GIS_schema_table = PageTemplateFile('zpt/GIS_schema_table', globals()) | 47 GIS_schema_table = PageTemplateFile('zpt/GIS_schema_table', globals()) |
| 48 KML_schema_table = PageTemplateFile('zpt/KML_schema_table', globals()) | 48 KML_schema_table = PageTemplateFile('zpt/KML_schema_table', globals()) |
| 49 HTML_schema_usertables = PageTemplateFile('zpt/HTML_schema_usertables', globals()) | |
| 49 | 50 |
| 50 # and scripts | 51 # and scripts |
| 51 def KML_URL_schema_table(self,schema,table): | 52 def KML_URL_schema_table(self,schema,table): |
| 52 """KML_URL table function""" | 53 """KML_URL table function""" |
| 53 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") | 54 self.REQUEST.RESPONSE.setHeader("Content-Type", "text/plain") |
| 54 id = self.REQUEST.get('id',[]) | 55 id = self.REQUEST.get('id',[]) |
| 55 doc = self.REQUEST.get('doc',None) | 56 doc = self.REQUEST.get('doc',None) |
| 56 return self.getLiveKmlUrl(schema=schema,table=table) | 57 return self.getLiveKmlUrl(schema=schema,table=table) |
| 57 | 58 |
| 58 | 59 # |
| 60 # database methods | |
| 61 # | |
| 59 def getTableOwner(self,schema,table): | 62 def getTableOwner(self,schema,table): |
| 60 """returns the owner of the table""" | 63 """returns the owner of the table""" |
| 61 # TODO: look up in metadata | 64 # what do we do with the schema? |
| 65 sql = 'select table_owner from public.gis_table_meta where table_name = %s' | |
| 66 res = self.executeSQL(sql,(table,)) | |
| 67 if len(res['rows']) > 0: | |
| 68 return res['rows'][0][0] | |
| 62 return None | 69 return None |
| 63 | 70 |
| 64 def isAllowed(self,action,schema,table,user=None,owner=None): | 71 def isAllowed(self,action,schema,table,user=None,owner=None): |
| 65 """returns if the requested action on the table is allowed""" | 72 """returns if the requested action on the table is allowed""" |
| 66 if user is None: | 73 if user is None: |
| 75 return False | 82 return False |
| 76 | 83 |
| 77 if action == "update": | 84 if action == "update": |
| 78 if owner is None: | 85 if owner is None: |
| 79 owner = self.getTableOwner(schema,table) | 86 owner = self.getTableOwner(schema,table) |
| 87 logging.debug("isAllowed user=%s owner=%s"%(user,owner)) | |
| 80 if user is not None and str(user) == str(owner): | 88 if user is not None and str(user) == str(owner): |
| 81 # update only your own table | 89 # update only your own table |
| 82 return True | 90 return True |
| 83 else: | 91 else: |
| 84 return False | 92 return False |
| 85 | 93 |
| 86 return True | 94 return True |
| 87 | 95 |
| 88 def setTableMetaTypes(self,schema,table,fields): | 96 def setTableMetaTypes(self,schema,table,fields,user=None): |
| 89 """sets the GIS meta information for table""" | 97 """sets the GIS meta information for table""" |
| 90 logging.debug("settablemetatypes schema=%s, table=%s, fields=%s"%(schema,table,fields)) | 98 if user is None: |
| 91 gisIdField = None | 99 user = self.REQUEST.get('AUTHENTICATED_USER',None) |
| 92 latField = None | 100 |
| 93 lonField = None | 101 logging.debug("settablemetatypes schema=%s, table=%s, fields=%s user=%s"%(schema,table,fields,user)) |
| 102 | |
| 103 today = datetime.date.today().isoformat() | |
| 104 | |
| 105 res = self.executeSQL('select * from public.gis_table_meta where table_name = %s', (table,)) | |
| 106 if len(res['rows']) > 0: | |
| 107 # meta record exists | |
| 108 sql = 'update public.gis_table_meta set table_owner=%s, table_modified=%s where table_name=%s' | |
| 109 self.executeSQL(sql, (str(user),today,table), hasResult=False) | |
| 110 else: | |
| 111 # new meta record | |
| 112 sql = 'insert into public.gis_table_meta (table_name,table_owner,table_created) values (%s,%s,%s)' | |
| 113 self.executeSQL(sql, (table,str(user),today), hasResult=False) | |
| 114 | |
| 115 # update row info | |
| 116 sql = 'delete from public.gis_table_meta_rows where table_name=%s' | |
| 117 self.executeSQL(sql,(table,),hasResult=False) | |
| 118 sql = 'insert into public.gis_table_meta_rows (table_name,field_name,gis_type) values (%s,%s,%s)' | |
| 94 for f in fields: | 119 for f in fields: |
| 95 t = f['type'] | 120 t = f['type'] |
| 96 if t == 'gis_id': | 121 fn = f['name'] |
| 97 gisIdField = f['name'] | 122 self.executeSQL(sql, (table,fn,t), hasResult=False) |
| 98 elif t == 'coord_lat': | |
| 99 latField = f['name'] | |
| 100 elif t == 'coord_lon': | |
| 101 lonField = f['name'] | |
| 102 | |
| 103 res = self.executeSQL("select * from public.metadata where tablename=%s", (table,)) | |
| 104 if len(res['rows']) > 0: | |
| 105 # meta record exists | |
| 106 if gisIdField is not None: | |
| 107 self.executeSQL('update public.metadata set "attribute with gis_id" = %s where tablename = %s', (gisIdField,table), hasResult=False) | |
| 108 | |
| 109 else: | |
| 110 # new meta record | |
| 111 if gisIdField is not None: | |
| 112 self.executeSQL('insert into public.metadata ("tablename", "attribute with gis_id") values (%s, %s)', (table,gisIdField), hasResult=False) | |
| 113 | |
| 114 | |
| 115 def showTable(self,resultFormat='XML',schema='public',table=None,REQUEST=None,RESPONSE=None): | |
| 116 """returns PageTemplate with tables""" | |
| 117 logging.debug("showtable") | |
| 118 if REQUEST is None: | |
| 119 REQUEST = self.REQUEST | |
| 120 | 123 |
| 121 # should be cross-site accessible | 124 |
| 122 if RESPONSE is None: | 125 def getListOfUserTables(self,schema='public',username='guest'): |
| 123 RESPONSE = self.REQUEST.RESPONSE | 126 """return list of tables""" |
| 124 RESPONSE.setHeader('Access-Control-Allow-Origin', '*') | 127 logging.debug("getlistofusertables") |
| 125 | 128 # get list of db tables |
| 126 user = self.REQUEST.get('AUTHENTICATED_USER',None) | 129 qstr = """SELECT t.table_name FROM information_schema.tables t, public.gis_table_meta m WHERE t.table_type = 'BASE TABLE' |
| 127 logging.debug("user=%s"%user) | 130 AND t.table_schema = %s AND t.table_name = m.table_name ORDER BY 1""" |
| 128 | 131 |
| 129 # everything else has its own template | 132 data=self.executeSQL(qstr,(schema,)) |
| 130 pt = getattr(self.template, '%s_schema_table'%resultFormat, None) | 133 return data |
| 131 if pt is None: | 134 |
| 132 return "ERROR!! template %s_schema_table not found"%resultFormat | |
| 133 | |
| 134 #data = self.getTable(schema,table) | |
| 135 # templates have to get their own data | |
| 136 return pt(schema=schema,table=table) | |
| 137 | |
| 138 | 135 |
| 139 def createEmptyTable(self,schema,table,fields): | 136 def createEmptyTable(self,schema,table,fields): |
| 140 """create a table with the given fields | 137 """create a table with the given fields |
| 141 returns list of created fields""" | 138 returns list of created fields""" |
| 142 logging.debug("createEmptyTable") | 139 sqlFields = RestDbInterface.createEmptyTable(self,schema,table,fields) |
| 143 sqlFields = [] | 140 if sqlFields is not None: |
| 144 for f in fields: | |
| 145 if isinstance(f,dict): | |
| 146 # {name: XX, type: YY} | |
| 147 name = sqlName(f['name']) | |
| 148 type = f['type'] | |
| 149 sqltype = gisToSqlTypeMap[type] | |
| 150 else: | |
| 151 # name only | |
| 152 name = sqlName(f) | |
| 153 type = 'text' | |
| 154 sqltype = 'text' | |
| 155 | |
| 156 sqlFields.append({'name':name, 'type':type, 'sqltype':sqltype}) | |
| 157 | |
| 158 if self.isAllowed("create", schema, table): | |
| 159 self.executeSQL('drop table if exists "%s"."%s"'%(schema,table),hasResult=False) | |
| 160 fieldString = ", ".join(['"%s" %s'%(f['name'],f['sqltype']) for f in sqlFields]) | |
| 161 sqlString = 'create table "%s"."%s" (%s)'%(schema,table,fieldString) | |
| 162 logging.debug("createemptytable: SQL=%s"%sqlString) | |
| 163 self.executeSQL(sqlString,hasResult=False) | |
| 164 self.setTableMetaTypes(schema,table,sqlFields) | 141 self.setTableMetaTypes(schema,table,sqlFields) |
| 165 return sqlFields | 142 |
| 166 else: | 143 return sqlFields |
| 167 logging.warning("create table not allowed!") | |
| 168 # throw exception? | |
| 169 return None | |
| 170 | 144 |
| 171 | 145 |
| 172 def getLiveKmlUrl(self,schema,table,useTimestamp=True,REQUEST=None): | 146 def getLiveKmlUrl(self,schema,table,useTimestamp=True,REQUEST=None): |
| 173 if REQUEST is None: | 147 if REQUEST is None: |
| 174 REQUEST = self.REQUEST | 148 REQUEST = self.REQUEST |
| 214 fieldMap = self.getFieldNameMap(data['fields']) | 188 fieldMap = self.getFieldNameMap(data['fields']) |
| 215 | 189 |
| 216 if (gisIdField is None) and (latField is None or lonField is None): | 190 if (gisIdField is None) and (latField is None or lonField is None): |
| 217 # no fields given - choose automagically | 191 # no fields given - choose automagically |
| 218 # gis id in metadata first | 192 # gis id in metadata first |
| 219 SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s' | 193 #SQL='SELECT "attribute with gis_id" FROM public.metadata WHERE tablename = %s' |
| 220 res = self.executeSQL(SQL, (table,)) | 194 sql = 'SELECT field_name FROM public.gis_table_meta_rows WHERE table_name = %s and gis_type = %s' |
| 195 res = self.executeSQL(sql, (table,'gis_id')) | |
| 221 if len(res['rows']) > 0: | 196 if len(res['rows']) > 0: |
| 222 gisIdField = res['rows'][0][0] | 197 gisIdField = res['rows'][0][0] |
| 223 else: | 198 else: |
| 224 logging.warning("no entry in metadata table for table %s"%table) | 199 logging.warning("no entry in metadata table for table %s"%table) |
| 225 # try field names | 200 # try field names |
