OWS.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. import urlparse
  4. import urllib
  5. from lxml import objectify
  6. import os,sys
  7. import tempfile
  8. import logging
  9. import ConfigParser
  10. import md5
  11. import mapscript
  12. from string import Template
  13. class OWS:
  14. capabilities = None
  15. url = None
  16. requestUrl = None
  17. mapobj = None
  18. qstring = None
  19. owsNs = "http://www.opengis.net/ows/1.1"
  20. cachedir = None
  21. mapfileName = "mapfile.map"
  22. config = None
  23. parsedUrl = None
  24. service = None
  25. mapfilename = None
  26. def __init__(self,url=None,qstring=None,configFile=None):
  27. self.requestUrl = url
  28. if url:
  29. self.url = url
  30. self.__getCapabilities()
  31. if qstring:
  32. self.qstring = qstring
  33. configFiles = [
  34. os.path.join(os.path.dirname(__file__),"config.cfg")
  35. ]
  36. if sys.platform == "win32":
  37. pass # TODO Default conf. file on windows platform
  38. elif sys.platform == "linux2":
  39. configFiles.append("/etc/owsviewer.cfg")
  40. if configFile:
  41. configFiles.append(configFile)
  42. self.config = ConfigParser.ConfigParser()
  43. self.config.read(configFiles)
  44. logging.debug("Creating cachedir for %s in %s" % (self.url,self.config.get("OWSViewer","cachedir")))
  45. logging.debug("%s initialized"%self.service)
  46. def __getCapabilities(self):
  47. self.parsedUrl = urlparse.urlparse(self.url)
  48. params = urlparse.parse_qs(self.parsedUrl.query,keep_blank_values=True)
  49. if "request" in params:
  50. params["request"] = "GetCapabilities"
  51. else:
  52. params["REQUEST"] = "GetCapabilities"
  53. if "service" in params:
  54. params["service"] = self.service
  55. else:
  56. params["SERVICE"] = self.service
  57. url = urlparse.urlunparse((self.parsedUrl[0],
  58. self.parsedUrl[1],
  59. self.parsedUrl[2],
  60. self.parsedUrl[3],
  61. urllib.unquote(urllib.urlencode(params,True)),
  62. self.parsedUrl[5]))
  63. e = objectify.parse(urllib.urlopen(url))
  64. self.capabilities = e.getroot()
  65. try:
  66. params.pop("service")
  67. except:
  68. pass
  69. try:
  70. params.pop("request")
  71. except:
  72. pass
  73. try:
  74. params.pop("SERVICE")
  75. except:
  76. pass
  77. try:
  78. params.pop("REQUEST")
  79. except:
  80. pass
  81. self.url = urlparse.urlunparse((self.parsedUrl[0],
  82. self.parsedUrl[1],
  83. self.parsedUrl[2],
  84. self.parsedUrl[3],
  85. urllib.urlencode(params,True),
  86. self.parsedUrl[5]))
  87. def getParams(self):
  88. return urlparse.parse_qs(self.qstring)
  89. def getOnlineResource(self,onlineresource,mapfilename=None):
  90. o = urlparse.urlparse(onlineresource)
  91. params = urlparse.parse_qs(o.query,keep_blank_values=True)
  92. params["owsUrl"] = self.url
  93. params["owsService"] = self.service
  94. params["map"] = self.getMapfileLocation(mapfilename)
  95. location = urlparse.urlunparse((o[0],o[1],o[2],o[3],urllib.urlencode(params,True),o[5]))
  96. logging.debug("Setting OnlineResource to %s"% location)
  97. return location
  98. def getMapfileLocation(self,mapfilename=None):
  99. # save the map if possible
  100. if mapfilename:
  101. mapfilename.replace("..","") # remove potential path change
  102. # mapfile must end with .map and cachedir must be at the
  103. # beginning of the mapfile name
  104. if mapfilename.endswith(".map") and \
  105. mapfilename.find(self.cachedir) == 0:
  106. return mapfilename
  107. else:
  108. # do not save anything
  109. return
  110. # save to new location otherwice
  111. else:
  112. return os.path.join(self.cachedir,self.mapfileName)
  113. def __getCacheDir(self):
  114. self.cachedir = tempfile.mkdtemp(prefix="%s-%s"%(self.service,
  115. md5.new(self.url).hexdigest()),
  116. dir=self.config.get("OWSViewer","cachedir"))
  117. os.chmod(self.cachedir, 0777)
  118. logging.debug("Cachedir %s created" % self.cachedir)
  119. open(os.path.join(self.cachedir,"url.txt"),"w").write(self.url)
  120. return self.cachedir
  121. def performRequest(self):
  122. request = mapscript.OWSRequest()
  123. request.loadParams()
  124. mapobj = None
  125. self.request=request.getValueByName("REQUEST")
  126. # if no 'map' parameter in URL, create new mapfile
  127. if not request.getValueByName("map"):
  128. mapobj = self.makeMap()
  129. else:
  130. # there is 'map' parameter in URL and the file exists, load it
  131. if os.path.isfile(request.getValueByName("map")):
  132. mapobj = mapscript.mapObj(request.getValueByName("map"))
  133. # there is 'map' parameter in URL BUT the file does not exist:
  134. # create
  135. else:
  136. mapobj = self.makeMap(request.getValueByName("map"))
  137. mapobj.OWSDispatch(request)
  138. def getMapObj(self,mapfilename=None):
  139. self.__getCacheDir()
  140. if self.url is not None and self.capabilities is None:
  141. self.__getCapabilities()
  142. mapobj = mapscript.mapObj()
  143. mapobj.setMetaData("wms_onlineresource",self.getOnlineResource(self.config.get("MapServer","onlineresource"),mapfilename))
  144. logging.debug("Setting SRS to %s"%self.config.get("MapServer","srs"))
  145. mapobj.setMetaData("wms_srs",self.config.get("MapServer","srs"))
  146. mapobj.setProjection("init=epsg:4326")
  147. mapobj.setSize(500,500)
  148. mapobj.setExtent(-180,-90,90,180)
  149. logging.debug("Setting ERRORFILE to %s"%self.config.get("MapServer","errorfile"))
  150. mapobj.setConfigOption("MS_ERRORFILE",self.config.get("MapServer","errorfile"))
  151. logging.debug("Setting IMAGEPATH to %s"%self.config.get("MapServer","imagepath"))
  152. mapobj.web.imagepath=self.config.get("MapServer","imagepath")
  153. mapobj.setMetaData("ows_enable_request","*")
  154. mapobj.setMetaData("wms_enable_request","*")
  155. return mapobj
  156. def saveMapfile(self,mapobj,mapfilename):
  157. self.mapfilename = self.getMapfileLocation(mapfilename)
  158. if self.mapfilename:
  159. # save mapfile ONLY if GetCapabilities requested - it makes no
  160. # sense for other cases
  161. logging.info("Saving mapfile to %s" % self.mapfilename)
  162. mapobj.save(self.mapfilename)
  163. else:
  164. logging.info("Mapfile NOT saved")
  165. return self.mapfilename
  166. def getLayerUrl(self):
  167. layerurl = self.url
  168. if self.url.find("?") > -1:
  169. if not self.url.endswith("?") and\
  170. not self.url.endswith("&"):
  171. layerurl += "&"
  172. else:
  173. layerurl += "?"
  174. return layerurl
  175. def createLayerDefinitionFile(self, name, templatefile):
  176. layerurl = self.getLayerUrl()
  177. defFileName = os.path.join(self.cachedir,'%s.%s'%(name,self.service.lower()))
  178. open(defFileName,'w').write(
  179. Template(open(templatefile).read()).substitute(
  180. dict(url= layerurl, name=name)))
  181. logging.debug("Created %s layer definition file" % defFileName)
  182. return defFileName
  183. def getService():
  184. qstring = os.environ["QUERY_STRING"]
  185. params = urlparse.parse_qs(qstring)
  186. owsUrl = urllib.unquote(params["owsUrl"][0])
  187. if params["owsService"][0].lower() == "wfs":
  188. from wfs import WFS
  189. return WFS(owsUrl,qstring)
  190. elif params["owsService"][0].lower() == "wcs":
  191. from wcs import WCS
  192. return WCS(owsUrl,qstring)