MapProxy 1.16.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. mapproxy/__init__.py +0 -0
  2. mapproxy/cache/__init__.py +36 -0
  3. mapproxy/cache/azureblob.py +145 -0
  4. mapproxy/cache/base.py +111 -0
  5. mapproxy/cache/compact.py +664 -0
  6. mapproxy/cache/couchdb.py +295 -0
  7. mapproxy/cache/dummy.py +34 -0
  8. mapproxy/cache/file.py +185 -0
  9. mapproxy/cache/geopackage.py +609 -0
  10. mapproxy/cache/legend.py +83 -0
  11. mapproxy/cache/mbtiles.py +392 -0
  12. mapproxy/cache/meta.py +78 -0
  13. mapproxy/cache/path.py +250 -0
  14. mapproxy/cache/redis.py +88 -0
  15. mapproxy/cache/renderd.py +95 -0
  16. mapproxy/cache/riak.py +202 -0
  17. mapproxy/cache/s3.py +177 -0
  18. mapproxy/cache/tile.py +699 -0
  19. mapproxy/client/__init__.py +0 -0
  20. mapproxy/client/arcgis.py +79 -0
  21. mapproxy/client/cgi.py +139 -0
  22. mapproxy/client/http.py +315 -0
  23. mapproxy/client/log.py +33 -0
  24. mapproxy/client/tile.py +150 -0
  25. mapproxy/client/wms.py +254 -0
  26. mapproxy/compat/__init__.py +46 -0
  27. mapproxy/compat/image.py +79 -0
  28. mapproxy/compat/itertools.py +29 -0
  29. mapproxy/compat/modules.py +13 -0
  30. mapproxy/config/__init__.py +22 -0
  31. mapproxy/config/config.py +201 -0
  32. mapproxy/config/coverage.py +107 -0
  33. mapproxy/config/defaults.py +98 -0
  34. mapproxy/config/loader.py +2286 -0
  35. mapproxy/config/spec.py +644 -0
  36. mapproxy/config/validator.py +239 -0
  37. mapproxy/config_template/__init__.py +0 -0
  38. mapproxy/config_template/base_config/config.wsgi +10 -0
  39. mapproxy/config_template/base_config/full_example.yaml +593 -0
  40. mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
  41. mapproxy/config_template/base_config/log.ini +35 -0
  42. mapproxy/config_template/base_config/mapproxy.yaml +60 -0
  43. mapproxy/config_template/base_config/seed.yaml +27 -0
  44. mapproxy/exception.py +142 -0
  45. mapproxy/featureinfo.py +252 -0
  46. mapproxy/grid.py +1170 -0
  47. mapproxy/image/__init__.py +536 -0
  48. mapproxy/image/fonts/DejaVuSans.ttf +0 -0
  49. mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
  50. mapproxy/image/fonts/LICENSE +99 -0
  51. mapproxy/image/fonts/__init__.py +0 -0
  52. mapproxy/image/mask.py +75 -0
  53. mapproxy/image/merge.py +316 -0
  54. mapproxy/image/message.py +347 -0
  55. mapproxy/image/opts.py +182 -0
  56. mapproxy/image/tile.py +167 -0
  57. mapproxy/image/transform.py +350 -0
  58. mapproxy/layer.py +470 -0
  59. mapproxy/multiapp.py +231 -0
  60. mapproxy/proj.py +302 -0
  61. mapproxy/request/__init__.py +18 -0
  62. mapproxy/request/arcgis.py +259 -0
  63. mapproxy/request/base.py +476 -0
  64. mapproxy/request/tile.py +128 -0
  65. mapproxy/request/wms/__init__.py +793 -0
  66. mapproxy/request/wms/exception.py +99 -0
  67. mapproxy/request/wmts.py +436 -0
  68. mapproxy/response.py +237 -0
  69. mapproxy/script/__init__.py +0 -0
  70. mapproxy/script/conf/__init__.py +0 -0
  71. mapproxy/script/conf/app.py +195 -0
  72. mapproxy/script/conf/caches.py +45 -0
  73. mapproxy/script/conf/layers.py +54 -0
  74. mapproxy/script/conf/seeds.py +37 -0
  75. mapproxy/script/conf/sources.py +86 -0
  76. mapproxy/script/conf/utils.py +143 -0
  77. mapproxy/script/defrag.py +184 -0
  78. mapproxy/script/export.py +333 -0
  79. mapproxy/script/grids.py +188 -0
  80. mapproxy/script/scales.py +126 -0
  81. mapproxy/script/util.py +406 -0
  82. mapproxy/script/wms_capabilities.py +152 -0
  83. mapproxy/seed/__init__.py +0 -0
  84. mapproxy/seed/cachelock.py +121 -0
  85. mapproxy/seed/cleanup.py +187 -0
  86. mapproxy/seed/config.py +469 -0
  87. mapproxy/seed/script.py +388 -0
  88. mapproxy/seed/seeder.py +538 -0
  89. mapproxy/seed/spec.py +64 -0
  90. mapproxy/seed/util.py +254 -0
  91. mapproxy/service/__init__.py +14 -0
  92. mapproxy/service/base.py +46 -0
  93. mapproxy/service/demo.py +356 -0
  94. mapproxy/service/kml.py +331 -0
  95. mapproxy/service/ows.py +38 -0
  96. mapproxy/service/template_helper.py +53 -0
  97. mapproxy/service/templates/demo/capabilities_demo.html +16 -0
  98. mapproxy/service/templates/demo/demo.html +181 -0
  99. mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
  100. mapproxy/service/templates/demo/static/img/blank.gif +0 -0
  101. mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
  102. mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
  103. mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
  104. mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
  105. mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
  106. mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
  107. mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
  108. mapproxy/service/templates/demo/static/logo.png +0 -0
  109. mapproxy/service/templates/demo/static/ol.css +345 -0
  110. mapproxy/service/templates/demo/static/ol.js +4 -0
  111. mapproxy/service/templates/demo/static/proj4.min.js +1 -0
  112. mapproxy/service/templates/demo/static/proj4defs.js +1 -0
  113. mapproxy/service/templates/demo/static/site.css +137 -0
  114. mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
  115. mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
  116. mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
  117. mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
  118. mapproxy/service/templates/demo/static.html +34 -0
  119. mapproxy/service/templates/demo/tms_demo.html +103 -0
  120. mapproxy/service/templates/demo/wms_demo.html +140 -0
  121. mapproxy/service/templates/demo/wmts_demo.html +110 -0
  122. mapproxy/service/templates/tms_capabilities.xml +13 -0
  123. mapproxy/service/templates/tms_exception.xml +4 -0
  124. mapproxy/service/templates/tms_root_resource.xml +7 -0
  125. mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
  126. mapproxy/service/templates/wms100capabilities.xml +112 -0
  127. mapproxy/service/templates/wms100exception.xml +4 -0
  128. mapproxy/service/templates/wms110capabilities.xml +152 -0
  129. mapproxy/service/templates/wms110exception.xml +5 -0
  130. mapproxy/service/templates/wms111capabilities.xml +183 -0
  131. mapproxy/service/templates/wms111exception.xml +5 -0
  132. mapproxy/service/templates/wms130capabilities.xml +326 -0
  133. mapproxy/service/templates/wms130exception.xml +8 -0
  134. mapproxy/service/templates/wmts100capabilities.xml +155 -0
  135. mapproxy/service/templates/wmts100exception.xml +9 -0
  136. mapproxy/service/tile.py +536 -0
  137. mapproxy/service/wms.py +851 -0
  138. mapproxy/service/wmts.py +381 -0
  139. mapproxy/source/__init__.py +75 -0
  140. mapproxy/source/arcgis.py +39 -0
  141. mapproxy/source/error.py +39 -0
  142. mapproxy/source/mapnik.py +259 -0
  143. mapproxy/source/tile.py +96 -0
  144. mapproxy/source/wms.py +270 -0
  145. mapproxy/srs.py +726 -0
  146. mapproxy/template.py +54 -0
  147. mapproxy/test/__init__.py +0 -0
  148. mapproxy/test/conftest.py +7 -0
  149. mapproxy/test/helper.py +247 -0
  150. mapproxy/test/http.py +494 -0
  151. mapproxy/test/image.py +210 -0
  152. mapproxy/test/mocker.py +2268 -0
  153. mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
  154. mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
  155. mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
  156. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
  157. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
  158. mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
  159. mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
  160. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
  161. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
  162. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
  163. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
  164. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
  165. mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
  166. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
  167. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
  168. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
  169. mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
  170. mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
  171. mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
  172. mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
  173. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
  174. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
  175. mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
  176. mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
  177. mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
  178. mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
  179. mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
  180. mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
  181. mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
  182. mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
  183. mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
  184. mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
  185. mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
  186. mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
  187. mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
  188. mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
  189. mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
  190. mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
  191. mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
  192. mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
  193. mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
  194. mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
  195. mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
  196. mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
  197. mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
  198. mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
  199. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
  200. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
  201. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
  202. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
  203. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
  204. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
  205. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
  206. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
  207. mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
  208. mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  209. mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
  210. mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  211. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
  212. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
  213. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
  214. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
  215. mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
  216. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
  217. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
  218. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
  219. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
  220. mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
  221. mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  222. mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
  223. mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  224. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
  225. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
  226. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
  227. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
  228. mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
  229. mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
  230. mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
  231. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
  232. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
  233. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
  234. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
  235. mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
  236. mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
  237. mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
  238. mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
  239. mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
  240. mapproxy/test/schemas/xml.xsd +287 -0
  241. mapproxy/test/system/__init__.py +98 -0
  242. mapproxy/test/system/fixture/arcgis.yaml +57 -0
  243. mapproxy/test/system/fixture/auth.yaml +70 -0
  244. mapproxy/test/system/fixture/cache.mbtiles +0 -0
  245. mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
  246. mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
  247. mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
  248. mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
  249. mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
  250. mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
  251. mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
  252. mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
  253. mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
  254. mapproxy/test/system/fixture/cache_s3.yaml +58 -0
  255. mapproxy/test/system/fixture/cache_source.yaml +81 -0
  256. mapproxy/test/system/fixture/combined_sources.yaml +130 -0
  257. mapproxy/test/system/fixture/coverage.yaml +77 -0
  258. mapproxy/test/system/fixture/demo.yaml +135 -0
  259. mapproxy/test/system/fixture/dimension.yaml +59 -0
  260. mapproxy/test/system/fixture/disable_storage.yaml +25 -0
  261. mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
  262. mapproxy/test/system/fixture/formats.yaml +72 -0
  263. mapproxy/test/system/fixture/inspire.yaml +101 -0
  264. mapproxy/test/system/fixture/inspire_full.yaml +124 -0
  265. mapproxy/test/system/fixture/kml_layer.yaml +66 -0
  266. mapproxy/test/system/fixture/layer.yaml +260 -0
  267. mapproxy/test/system/fixture/layergroups.yaml +57 -0
  268. mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
  269. mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
  270. mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
  271. mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
  272. mapproxy/test/system/fixture/mapserver.yaml +23 -0
  273. mapproxy/test/system/fixture/minimal_cgi.py +16 -0
  274. mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
  275. mapproxy/test/system/fixture/multi_cache_layers.yaml +100 -0
  276. mapproxy/test/system/fixture/multiapp1.yaml +20 -0
  277. mapproxy/test/system/fixture/multiapp2.yaml +19 -0
  278. mapproxy/test/system/fixture/renderd_client.yaml +55 -0
  279. mapproxy/test/system/fixture/scalehints.yaml +70 -0
  280. mapproxy/test/system/fixture/seed.yaml +94 -0
  281. mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
  282. mapproxy/test/system/fixture/seed_old.yaml +12 -0
  283. mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
  284. mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
  285. mapproxy/test/system/fixture/seedonly.yaml +51 -0
  286. mapproxy/test/system/fixture/sld.yaml +35 -0
  287. mapproxy/test/system/fixture/source_errors.yaml +84 -0
  288. mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
  289. mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
  290. mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
  291. mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
  292. mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
  293. mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
  294. mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
  295. mapproxy/test/system/fixture/util_grids.yaml +30 -0
  296. mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
  297. mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
  298. mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
  299. mapproxy/test/system/fixture/watermark.yaml +50 -0
  300. mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
  301. mapproxy/test/system/fixture/wms_versions.yaml +38 -0
  302. mapproxy/test/system/fixture/wmts.yaml +134 -0
  303. mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
  304. mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
  305. mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
  306. mapproxy/test/system/test_arcgis.py +156 -0
  307. mapproxy/test/system/test_auth.py +1134 -0
  308. mapproxy/test/system/test_behind_proxy.py +75 -0
  309. mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
  310. mapproxy/test/system/test_cache_azureblob.py +127 -0
  311. mapproxy/test/system/test_cache_band_merge.py +103 -0
  312. mapproxy/test/system/test_cache_geopackage.py +144 -0
  313. mapproxy/test/system/test_cache_grid_names.py +89 -0
  314. mapproxy/test/system/test_cache_mbtiles.py +85 -0
  315. mapproxy/test/system/test_cache_s3.py +115 -0
  316. mapproxy/test/system/test_cache_source.py +146 -0
  317. mapproxy/test/system/test_combined_sources.py +335 -0
  318. mapproxy/test/system/test_coverage.py +140 -0
  319. mapproxy/test/system/test_decorate_img.py +214 -0
  320. mapproxy/test/system/test_demo.py +106 -0
  321. mapproxy/test/system/test_demo_with_extra_service.py +53 -0
  322. mapproxy/test/system/test_dimensions.py +278 -0
  323. mapproxy/test/system/test_disable_storage.py +42 -0
  324. mapproxy/test/system/test_formats.py +219 -0
  325. mapproxy/test/system/test_inspire_vs.py +173 -0
  326. mapproxy/test/system/test_kml.py +262 -0
  327. mapproxy/test/system/test_layergroups.py +160 -0
  328. mapproxy/test/system/test_legendgraphic.py +308 -0
  329. mapproxy/test/system/test_mapnik.py +161 -0
  330. mapproxy/test/system/test_mapserver.py +81 -0
  331. mapproxy/test/system/test_mixed_mode_format.py +195 -0
  332. mapproxy/test/system/test_multi_cache_layers.py +167 -0
  333. mapproxy/test/system/test_multiapp.py +92 -0
  334. mapproxy/test/system/test_refresh.py +207 -0
  335. mapproxy/test/system/test_renderd_client.py +304 -0
  336. mapproxy/test/system/test_response_headers.py +54 -0
  337. mapproxy/test/system/test_scalehints.py +140 -0
  338. mapproxy/test/system/test_seed.py +422 -0
  339. mapproxy/test/system/test_seed_only.py +93 -0
  340. mapproxy/test/system/test_sld.py +120 -0
  341. mapproxy/test/system/test_source_errors.py +377 -0
  342. mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
  343. mapproxy/test/system/test_tms.py +276 -0
  344. mapproxy/test/system/test_tms_origin.py +46 -0
  345. mapproxy/test/system/test_util_conf.py +304 -0
  346. mapproxy/test/system/test_util_export.py +210 -0
  347. mapproxy/test/system/test_util_grids.py +88 -0
  348. mapproxy/test/system/test_util_wms_capabilities.py +182 -0
  349. mapproxy/test/system/test_watermark.py +91 -0
  350. mapproxy/test/system/test_wms.py +1611 -0
  351. mapproxy/test/system/test_wms_srs_extent.py +165 -0
  352. mapproxy/test/system/test_wms_version.py +85 -0
  353. mapproxy/test/system/test_wmsc.py +116 -0
  354. mapproxy/test/system/test_wmts.py +334 -0
  355. mapproxy/test/system/test_wmts_dimensions.py +206 -0
  356. mapproxy/test/system/test_wmts_restful.py +198 -0
  357. mapproxy/test/system/test_xslt_featureinfo.py +425 -0
  358. mapproxy/test/test_http_helper.py +219 -0
  359. mapproxy/test/unit/__init__.py +0 -0
  360. mapproxy/test/unit/epsg +2 -0
  361. mapproxy/test/unit/polygons/polygons.dbf +0 -0
  362. mapproxy/test/unit/polygons/polygons.shp +0 -0
  363. mapproxy/test/unit/polygons/polygons.shx +0 -0
  364. mapproxy/test/unit/test_async.py +245 -0
  365. mapproxy/test/unit/test_auth.py +419 -0
  366. mapproxy/test/unit/test_cache.py +1193 -0
  367. mapproxy/test/unit/test_cache_azureblob.py +94 -0
  368. mapproxy/test/unit/test_cache_compact.py +319 -0
  369. mapproxy/test/unit/test_cache_couchdb.py +114 -0
  370. mapproxy/test/unit/test_cache_geopackage.py +221 -0
  371. mapproxy/test/unit/test_cache_redis.py +67 -0
  372. mapproxy/test/unit/test_cache_riak.py +76 -0
  373. mapproxy/test/unit/test_cache_s3.py +84 -0
  374. mapproxy/test/unit/test_cache_tile.py +427 -0
  375. mapproxy/test/unit/test_client.py +479 -0
  376. mapproxy/test/unit/test_client_arcgis.py +73 -0
  377. mapproxy/test/unit/test_client_cgi.py +136 -0
  378. mapproxy/test/unit/test_collections.py +116 -0
  379. mapproxy/test/unit/test_concat_legends.py +37 -0
  380. mapproxy/test/unit/test_conf_loader.py +1061 -0
  381. mapproxy/test/unit/test_conf_validator.py +416 -0
  382. mapproxy/test/unit/test_config.py +117 -0
  383. mapproxy/test/unit/test_decorate_img.py +185 -0
  384. mapproxy/test/unit/test_exceptions.py +258 -0
  385. mapproxy/test/unit/test_featureinfo.py +291 -0
  386. mapproxy/test/unit/test_file_lock_load.py +49 -0
  387. mapproxy/test/unit/test_geom.py +503 -0
  388. mapproxy/test/unit/test_grid.py +1258 -0
  389. mapproxy/test/unit/test_image.py +1053 -0
  390. mapproxy/test/unit/test_image_mask.py +181 -0
  391. mapproxy/test/unit/test_image_messages.py +197 -0
  392. mapproxy/test/unit/test_image_options.py +160 -0
  393. mapproxy/test/unit/test_isodate.py +122 -0
  394. mapproxy/test/unit/test_multiapp.py +163 -0
  395. mapproxy/test/unit/test_ogr_reader.py +50 -0
  396. mapproxy/test/unit/test_request.py +745 -0
  397. mapproxy/test/unit/test_request_wmts.py +178 -0
  398. mapproxy/test/unit/test_response.py +79 -0
  399. mapproxy/test/unit/test_seed.py +365 -0
  400. mapproxy/test/unit/test_seed_cachelock.py +90 -0
  401. mapproxy/test/unit/test_srs.py +215 -0
  402. mapproxy/test/unit/test_tiled_source.py +122 -0
  403. mapproxy/test/unit/test_tilefilter.py +31 -0
  404. mapproxy/test/unit/test_times.py +25 -0
  405. mapproxy/test/unit/test_timeutils.py +50 -0
  406. mapproxy/test/unit/test_util_conf_utils.py +75 -0
  407. mapproxy/test/unit/test_utils.py +476 -0
  408. mapproxy/test/unit/test_wms_capabilities.py +44 -0
  409. mapproxy/test/unit/test_wms_layer.py +113 -0
  410. mapproxy/test/unit/test_yaml.py +69 -0
  411. mapproxy/tilefilter.py +59 -0
  412. mapproxy/util/__init__.py +0 -0
  413. mapproxy/util/async_.py +227 -0
  414. mapproxy/util/collections.py +132 -0
  415. mapproxy/util/coverage.py +329 -0
  416. mapproxy/util/escape.py +10 -0
  417. mapproxy/util/ext/__init__.py +14 -0
  418. mapproxy/util/ext/dictspec/__init__.py +1 -0
  419. mapproxy/util/ext/dictspec/spec.py +124 -0
  420. mapproxy/util/ext/dictspec/test/__init__.py +0 -0
  421. mapproxy/util/ext/dictspec/test/test_validator.py +274 -0
  422. mapproxy/util/ext/dictspec/validator.py +189 -0
  423. mapproxy/util/ext/local.py +196 -0
  424. mapproxy/util/ext/lockfile.py +138 -0
  425. mapproxy/util/ext/odict.py +330 -0
  426. mapproxy/util/ext/serving.py +508 -0
  427. mapproxy/util/ext/tempita/__init__.py +1174 -0
  428. mapproxy/util/ext/tempita/_looper.py +163 -0
  429. mapproxy/util/ext/tempita/compat3.py +46 -0
  430. mapproxy/util/ext/wmsparse/__init__.py +3 -0
  431. mapproxy/util/ext/wmsparse/duration.py +597 -0
  432. mapproxy/util/ext/wmsparse/parse.py +305 -0
  433. mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
  434. mapproxy/util/ext/wmsparse/test/test_parse.py +162 -0
  435. mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
  436. mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
  437. mapproxy/util/ext/wmsparse/test/wms-omniscale-111.xml +90 -0
  438. mapproxy/util/ext/wmsparse/test/wms-omniscale-130.xml +120 -0
  439. mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
  440. mapproxy/util/ext/wmsparse/util.py +187 -0
  441. mapproxy/util/fs.py +156 -0
  442. mapproxy/util/geom.py +295 -0
  443. mapproxy/util/lib.py +115 -0
  444. mapproxy/util/lock.py +163 -0
  445. mapproxy/util/ogr.py +231 -0
  446. mapproxy/util/py.py +81 -0
  447. mapproxy/util/times.py +75 -0
  448. mapproxy/util/yaml.py +56 -0
  449. mapproxy/version.py +31 -0
  450. mapproxy/wsgiapp.py +164 -0
  451. mapproxy-1.16.1.dist-info/METADATA +151 -0
  452. mapproxy-1.16.1.dist-info/RECORD +458 -0
  453. mapproxy-1.16.1.dist-info/WHEEL +5 -0
  454. mapproxy-1.16.1.dist-info/entry_points.txt +3 -0
  455. mapproxy-1.16.1.dist-info/licenses/AUTHORS.txt +33 -0
  456. mapproxy-1.16.1.dist-info/licenses/COPYING.txt +60 -0
  457. mapproxy-1.16.1.dist-info/licenses/LICENSE.txt +202 -0
  458. mapproxy-1.16.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,406 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2011 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from __future__ import print_function
17
+
18
+ import io
19
+ import os
20
+ import optparse
21
+ import re
22
+ import shutil
23
+ import sys
24
+ import textwrap
25
+ import logging
26
+
27
+ from mapproxy.compat import iteritems
28
+ from mapproxy.config.loader import load_plugins
29
+ from mapproxy.script.conf.app import config_command
30
+ from mapproxy.script.defrag import defrag_command
31
+ from mapproxy.script.export import export_command
32
+ from mapproxy.script.grids import grids_command
33
+ from mapproxy.script.scales import scales_command
34
+ from mapproxy.script.wms_capabilities import wms_capabilities_command
35
+ from mapproxy.version import version
36
+
37
+
38
+ def setup_logging(level=logging.INFO, format=None):
39
+ mapproxy_log = logging.getLogger('mapproxy')
40
+ mapproxy_log.setLevel(level)
41
+
42
+ ch = logging.StreamHandler(sys.stdout)
43
+ ch.setLevel(level)
44
+ if not format:
45
+ format = "[%(asctime)s] %(name)s - %(levelname)s - %(message)s"
46
+ formatter = logging.Formatter(format)
47
+ ch.setFormatter(formatter)
48
+ mapproxy_log.addHandler(ch)
49
+
50
+ def serve_develop_command(args):
51
+ parser = optparse.OptionParser("usage: %prog serve-develop [options] mapproxy.yaml")
52
+ parser.add_option("-b", "--bind",
53
+ dest="address", default='127.0.0.1:8080',
54
+ help="Server socket [127.0.0.1:8080]. Use 0.0.0.0 for external access. :1234 to change port.")
55
+ parser.add_option("--debug", default=False, action='store_true',
56
+ dest="debug",
57
+ help="Enable debug mode")
58
+ options, args = parser.parse_args(args)
59
+
60
+ if len(args) != 2:
61
+ parser.print_help()
62
+ print("\nERROR: MapProxy configuration required.")
63
+ sys.exit(1)
64
+
65
+ mapproxy_conf = args[1]
66
+
67
+ host, port = parse_bind_address(options.address)
68
+
69
+ if options.debug and host not in ('localhost', '127.0.0.1'):
70
+ print(textwrap.dedent("""\
71
+ ################# WARNING! ##################
72
+ Running debug mode with non-localhost address
73
+ is a serious security vulnerability.
74
+ #############################################\
75
+ """))
76
+
77
+
78
+ if options.debug:
79
+ setup_logging(level=logging.DEBUG)
80
+ else:
81
+ setup_logging()
82
+ from mapproxy.wsgiapp import make_wsgi_app
83
+ from mapproxy.config.loader import ConfigurationError
84
+ from mapproxy.util.ext.serving import run_simple
85
+ try:
86
+ app = make_wsgi_app(mapproxy_conf, debug=options.debug)
87
+ except ConfigurationError:
88
+ sys.exit(2)
89
+
90
+ extra_files = app.config_files.keys()
91
+
92
+ if options.debug:
93
+ try:
94
+ from repoze.profile import ProfileMiddleware
95
+ app = ProfileMiddleware(
96
+ app,
97
+ log_filename='/tmp/mapproxy_profile.log',
98
+ discard_first_request=True,
99
+ flush_at_shutdown=True,
100
+ path='/__profile__',
101
+ unwind=False,
102
+ )
103
+ print('Installed profiler at /__profile__')
104
+ except ImportError:
105
+ pass
106
+
107
+ run_simple(host, port, app, use_reloader=True, processes=1,
108
+ threaded=True, passthrough_errors=True,
109
+ extra_files=extra_files)
110
+
111
+ def serve_multiapp_develop_command(args):
112
+ parser = optparse.OptionParser("usage: %prog serve-multiapp-develop [options] projects/")
113
+ parser.add_option("-b", "--bind",
114
+ dest="address", default='127.0.0.1:8080',
115
+ help="Server socket [127.0.0.1:8080]")
116
+ parser.add_option("--debug", default=False, action='store_true',
117
+ dest="debug",
118
+ help="Enable debug mode")
119
+ options, args = parser.parse_args(args)
120
+
121
+ if len(args) != 2:
122
+ parser.print_help()
123
+ print("\nERROR: MapProxy projects directory required.")
124
+ sys.exit(1)
125
+
126
+ mapproxy_conf_dir = args[1]
127
+
128
+ host, port = parse_bind_address(options.address)
129
+
130
+ if options.debug and host not in ('localhost', '127.0.0.1'):
131
+ print(textwrap.dedent("""\
132
+ ################# WARNING! ##################
133
+ Running debug mode with non-localhost address
134
+ is a serious security vulnerability.
135
+ #############################################\
136
+ """))
137
+
138
+ setup_logging()
139
+ from mapproxy.multiapp import make_wsgi_app
140
+ from mapproxy.util.ext.serving import run_simple
141
+ app = make_wsgi_app(mapproxy_conf_dir, debug=options.debug)
142
+
143
+ run_simple(host, port, app, use_reloader=True, processes=1,
144
+ threaded=True, passthrough_errors=True)
145
+
146
+
147
+ def parse_bind_address(address, default=('localhost', 8080)):
148
+ """
149
+ >>> parse_bind_address('80')
150
+ ('localhost', 80)
151
+ >>> parse_bind_address('0.0.0.0')
152
+ ('0.0.0.0', 8080)
153
+ >>> parse_bind_address('0.0.0.0:8081')
154
+ ('0.0.0.0', 8081)
155
+ """
156
+ if ':' in address:
157
+ host, port = address.split(':', 1)
158
+ port = int(port)
159
+ elif re.match(r'^\d+$', address):
160
+ host = default[0]
161
+ port = int(address)
162
+ else:
163
+ host = address
164
+ port = default[1]
165
+ return host, port
166
+
167
+
168
+ def create_command(args):
169
+ cmd = CreateCommand(args)
170
+ cmd.run()
171
+
172
+ class CreateCommand(object):
173
+ templates = {
174
+ 'base-config': {},
175
+ 'wsgi-app': {},
176
+ 'log-ini': {},
177
+ }
178
+
179
+ def __init__(self, args):
180
+ parser = optparse.OptionParser("usage: %prog create [options] [destination]")
181
+ parser.add_option("-t", "--template", dest="template",
182
+ help="Create a configuration from this template.")
183
+ parser.add_option("-l", "--list-templates", dest="list_templates",
184
+ action="store_true", default=False,
185
+ help="List all available configuration templates.")
186
+ parser.add_option("-f", "--mapproxy-conf", dest="mapproxy_conf",
187
+ help="Existing MapProxy configuration (required for some templates).")
188
+ parser.add_option("--force", dest="force", action="store_true",
189
+ default=False, help="Force operation (e.g. overwrite existing files).")
190
+
191
+ self.options, self.args = parser.parse_args(args)
192
+ self.parser = parser
193
+
194
+ def log_error(self, msg, *args):
195
+ print('ERROR:', msg % args, file=sys.stderr)
196
+
197
+ def run(self):
198
+
199
+ if self.options.list_templates:
200
+ print_items(self.templates, title="Available templates")
201
+ sys.exit(1)
202
+ elif self.options.template:
203
+ if self.options.template not in self.templates:
204
+ self.log_error("unknown template " + self.options.template)
205
+ sys.exit(1)
206
+
207
+ if len(self.args) != 2:
208
+ self.log_error("template requires destination argument")
209
+ sys.exit(1)
210
+
211
+ sys.exit(
212
+ getattr(self, 'template_' + self.options.template.replace('-', '_'))()
213
+ )
214
+ else:
215
+ self.parser.print_help()
216
+ sys.exit(1)
217
+
218
+ @property
219
+ def mapproxy_conf(self):
220
+ if not self.options.mapproxy_conf:
221
+ self.parser.print_help()
222
+ self.log_error("template requires --mapproxy-conf option")
223
+ sys.exit(1)
224
+ return os.path.abspath(self.options.mapproxy_conf)
225
+
226
+ def template_dir(self):
227
+ import mapproxy.config_template
228
+ template_dir = os.path.join(
229
+ os.path.dirname(mapproxy.config_template.__file__),
230
+ 'base_config')
231
+ return template_dir
232
+
233
+ def template_wsgi_app(self):
234
+ app_filename = self.args[1]
235
+ if '.' not in os.path.basename(app_filename):
236
+ app_filename += '.py'
237
+ mapproxy_conf = self.mapproxy_conf
238
+ if os.path.exists(app_filename) and not self.options.force:
239
+ self.log_error("%s already exists, use --force", app_filename)
240
+ return 1
241
+
242
+ print("writing MapProxy app to %s" % (app_filename, ))
243
+
244
+ template_dir = self.template_dir()
245
+ app_template = io.open(os.path.join(template_dir, 'config.wsgi'), encoding='utf-8').read()
246
+ with io.open(app_filename, 'w', encoding='utf-8') as f:
247
+ f.write(app_template % {'mapproxy_conf': mapproxy_conf,
248
+ 'here': os.path.dirname(mapproxy_conf)})
249
+
250
+ return 0
251
+
252
+ def template_base_config(self):
253
+ outdir = self.args[1]
254
+ if not os.path.exists(outdir):
255
+ os.makedirs(outdir)
256
+
257
+ template_dir = self.template_dir()
258
+
259
+ for filename in ('mapproxy.yaml', 'seed.yaml',
260
+ 'full_example.yaml', 'full_seed_example.yaml'):
261
+ to = os.path.join(outdir, filename)
262
+ from_ = os.path.join(template_dir, filename)
263
+ if os.path.exists(to) and not self.options.force:
264
+ self.log_error("%s already exists, use --force", to)
265
+ return 1
266
+ print("writing %s" % (to, ))
267
+ shutil.copy(from_, to)
268
+
269
+ return 0
270
+
271
+ def template_log_ini(self):
272
+ log_filename = self.args[1]
273
+
274
+ if os.path.exists(log_filename) and not self.options.force:
275
+ self.log_error("%s already exists, use --force", log_filename)
276
+ return 1
277
+
278
+ template_dir = self.template_dir()
279
+ log_template = io.open(os.path.join(template_dir, 'log.ini'), encoding='utf-8').read()
280
+ with io.open(log_filename, 'w', encoding='utf-8') as f:
281
+ f.write(log_template)
282
+
283
+ return 0
284
+
285
+ commands = {
286
+ 'serve-develop': {
287
+ 'func': serve_develop_command,
288
+ 'help': 'Run MapProxy development server.'
289
+ },
290
+ 'serve-multiapp-develop': {
291
+ 'func': serve_multiapp_develop_command,
292
+ 'help': 'Run MultiMapProxy development server.'
293
+ },
294
+ 'create': {
295
+ 'func': create_command,
296
+ 'help': 'Create example configurations.'
297
+ },
298
+ 'scales': {
299
+ 'func': scales_command,
300
+ 'help': 'Convert between scales and resolutions.'
301
+ },
302
+ 'wms-capabilities': {
303
+ 'func': wms_capabilities_command,
304
+ 'help': 'Display WMS capabilites.',
305
+ },
306
+ 'grids': {
307
+ 'func': grids_command,
308
+ 'help': 'Display detailed informations for configured grids.'
309
+ },
310
+ 'export': {
311
+ 'func': export_command,
312
+ 'help': 'Export existing caches.'
313
+ },
314
+ 'autoconfig': {
315
+ 'func': config_command,
316
+ 'help': 'Create config from WMS capabilities.'
317
+ },
318
+ 'defrag-compact-cache': {
319
+ 'func': defrag_command,
320
+ 'help': 'De-fragmentate compact caches.'
321
+ }
322
+ }
323
+
324
+
325
+ def register_command(command_name, command_spec):
326
+ """ Method used by plugins to register a command.
327
+
328
+ :param command_name: Name of the service
329
+ :type command_name: str
330
+ :param command_spec: Definition of the command. Dictionary with a 'func' and 'help' member
331
+ :type command_spec: dict
332
+ """
333
+
334
+ commands[command_name] = command_spec
335
+
336
+
337
+ class NonStrictOptionParser(optparse.OptionParser):
338
+ def _process_args(self, largs, rargs, values):
339
+ while rargs:
340
+ arg = rargs[0]
341
+ # We handle bare "--" explicitly, and bare "-" is handled by the
342
+ # standard arg handler since the short arg case ensures that the
343
+ # len of the opt string is greater than 1.
344
+ try:
345
+ if arg == "--":
346
+ del rargs[0]
347
+ return
348
+ elif arg[0:2] == "--":
349
+ # process a single long option (possibly with value(s))
350
+ self._process_long_opt(rargs, values)
351
+ elif arg[:1] == "-" and len(arg) > 1:
352
+ # process a cluster of short options (possibly with
353
+ # value(s) for the last one only)
354
+ self._process_short_opts(rargs, values)
355
+ elif self.allow_interspersed_args:
356
+ largs.append(arg)
357
+ del rargs[0]
358
+ else:
359
+ return
360
+ except optparse.BadOptionError:
361
+ largs.append(arg)
362
+
363
+
364
+ def print_items(data, title='Commands'):
365
+ name_len = max(len(name) for name in data)
366
+
367
+ if title:
368
+ print('%s:' % (title, ), file=sys.stdout)
369
+ for name, item in iteritems(data):
370
+ help = item.get('help', '')
371
+ name = ('%%-%ds' % name_len) % name
372
+ if help:
373
+ help = ' ' + help
374
+ print(' %s%s' % (name, help), file=sys.stdout)
375
+
376
+ def main():
377
+
378
+ load_plugins()
379
+
380
+ parser = NonStrictOptionParser("usage: %prog COMMAND [options]",
381
+ add_help_option=False)
382
+ options, args = parser.parse_args()
383
+
384
+ if len(args) < 1 or args[0] in ('--help', '-h'):
385
+ parser.print_help()
386
+ print()
387
+ print_items(commands)
388
+ sys.exit(1)
389
+
390
+ if len(args) == 1 and args[0] == '--version':
391
+ print('MapProxy ' + version)
392
+ sys.exit(1)
393
+
394
+ command = args[0]
395
+ if command not in commands:
396
+ parser.print_help()
397
+ print()
398
+ print_items(commands)
399
+ print('\nERROR: unknown command %s' % (command,), file=sys.stdout)
400
+ sys.exit(1)
401
+
402
+ args = sys.argv[0:1] + sys.argv[2:]
403
+ commands[command]['func'](args)
404
+
405
+ if __name__ == '__main__':
406
+ main()
@@ -0,0 +1,152 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2011 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from __future__ import print_function
17
+
18
+ import sys
19
+ import optparse
20
+
21
+ from xml import etree
22
+
23
+ from mapproxy.compat import iteritems, BytesIO
24
+ from mapproxy.compat.modules import urlparse
25
+ from mapproxy.client.http import open_url, HTTPClientError
26
+ from mapproxy.request.base import BaseRequest, url_decode
27
+ from mapproxy.util.ext import wmsparse
28
+
29
+
30
+ class PrettyPrinter(object):
31
+ def __init__(self, indent=4, version='1.1.1'):
32
+ self.indent = indent
33
+ self.print_order = ['name', 'title', 'url', 'srs', 'llbbox', 'bbox']
34
+ self.marker = '- '
35
+ self.version = version
36
+
37
+ def print_line(self, indent, key, value=None, mark_first=False):
38
+ marker = ''
39
+ if value is None:
40
+ value = ''
41
+ if mark_first:
42
+ indent = indent - len(self.marker)
43
+ marker = self.marker
44
+ print(("%s%s%s: %s" % (' '*indent, marker, key, value)))
45
+
46
+ def _format_output(self, key, value, indent, mark_first=False):
47
+ if key == 'bbox':
48
+ self.print_line(indent, key)
49
+ for srs_code, bbox in iteritems(value):
50
+ self.print_line(indent+self.indent, srs_code, value=bbox, mark_first=mark_first)
51
+ else:
52
+ if isinstance(value, set):
53
+ value = list(value)
54
+ self.print_line(indent, key, value=value, mark_first=mark_first)
55
+
56
+ def print_layers(self, capabilities, indent=None, root=False):
57
+ if root:
58
+ print("# Note: This is not a valid MapProxy configuration!")
59
+ print('Capabilities Document Version %s' % (self.version,))
60
+ print('Root-Layer:')
61
+ layer_list = capabilities.layers()['layers']
62
+ else:
63
+ layer_list = capabilities['layers']
64
+
65
+ indent = indent or self.indent
66
+ for layer in layer_list:
67
+ marked_first = False
68
+ # print ordered items first
69
+ for item in self.print_order:
70
+ if layer.get(item, False):
71
+ if not marked_first:
72
+ marked_first = True
73
+ self._format_output(item, layer[item], indent, mark_first=marked_first)
74
+ else:
75
+ self._format_output(item, layer[item], indent)
76
+ # print remaining items except sublayers
77
+ for key, value in iteritems(layer):
78
+ if key in self.print_order or key == 'layers':
79
+ continue
80
+ self._format_output(key, value, indent)
81
+ # print the sublayers now
82
+ if layer.get('layers', False):
83
+ self.print_line(indent, 'layers')
84
+ self.print_layers(layer, indent=indent+self.indent)
85
+
86
+ def log_error(msg, *args):
87
+ print(msg % args, file=sys.stderr)
88
+
89
+ def wms_capapilities_url(url, version):
90
+ parsed_url = urlparse.urlparse(url)
91
+ base_req = BaseRequest(
92
+ url=url.split('?', 1)[0],
93
+ param=url_decode(parsed_url.query),
94
+ )
95
+
96
+ base_req.params['service'] = 'WMS'
97
+ base_req.params['version'] = version
98
+ base_req.params['request'] = 'GetCapabilities'
99
+ return base_req.complete_url
100
+
101
+ def parse_capabilities(fileobj, version='1.1.1'):
102
+ try:
103
+ return wmsparse.parse_capabilities(fileobj)
104
+ except ValueError as ex:
105
+ log_error('%s\n%s\n%s\n%s\nNot a capabilities document: %s', 'Recieved document:', '-'*80, fileobj.getvalue(), '-'*80, ex.args[0])
106
+ sys.exit(1)
107
+ except etree.ElementTree.ParseError as ex:
108
+ log_error('%s\n%s\n%s\n%s\nCould not parse the document: %s', 'Recieved document:', '-'*80, fileobj.getvalue(), '-'*80, ex.args[0])
109
+ sys.exit(1)
110
+
111
+ def parse_capabilities_url(url, version='1.1.1'):
112
+ try:
113
+ capabilities_url = wms_capapilities_url(url, version)
114
+ capabilities_response = open_url(capabilities_url)
115
+ except HTTPClientError as ex:
116
+ log_error('ERROR: %s', ex.args[0])
117
+ sys.exit(1)
118
+
119
+ # after parsing capabilities_response will be empty, therefore cache it
120
+ capabilities = BytesIO(capabilities_response.read())
121
+ return parse_capabilities(capabilities, version=version)
122
+
123
+ def wms_capabilities_command(args=None):
124
+ parser = optparse.OptionParser("%prog wms-capabilities [options] URL",
125
+ description="Read and parse WMS 1.1.1 capabilities and print out"
126
+ " information about each layer. It does _not_ return a valid"
127
+ " MapProxy configuration.")
128
+ parser.add_option("--host", dest="capabilities_url",
129
+ help="WMS Capabilites URL")
130
+ parser.add_option("--version", dest="version",
131
+ choices=['1.1.1', '1.3.0'], default='1.1.1', help="Request GetCapabilities-document in version 1.1.1 or 1.3.0", metavar="<1.1.1 or 1.3.0>")
132
+
133
+ if args:
134
+ args = args[1:] # remove script name
135
+
136
+ (options, args) = parser.parse_args(args)
137
+ if not options.capabilities_url:
138
+ if len(args) != 1:
139
+ parser.print_help()
140
+ sys.exit(2)
141
+ else:
142
+ options.capabilities_url = args[0]
143
+
144
+ try:
145
+ service = parse_capabilities_url(options.capabilities_url, version=options.version)
146
+
147
+ printer = PrettyPrinter(indent=4, version=options.version)
148
+ printer.print_layers(service, root=True)
149
+
150
+ except KeyError as ex:
151
+ log_error('XML-Element has no such attribute (%s).' % (ex.args[0],))
152
+ sys.exit(1)
File without changes
@@ -0,0 +1,121 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2012 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+
17
+ import errno
18
+ import os
19
+ import sqlite3
20
+ import time
21
+ from contextlib import contextmanager
22
+
23
+ class CacheLockedError(Exception):
24
+ pass
25
+
26
+ class CacheLocker(object):
27
+ def __init__(self, lockfile, polltime=0.1):
28
+ self.lockfile = lockfile
29
+ self.polltime = polltime
30
+ self._initialize_lockfile()
31
+
32
+ def _initialize_lockfile(self):
33
+ db = sqlite3.connect(self.lockfile)
34
+ db.execute("""
35
+ CREATE TABLE IF NOT EXISTS cache_locks (
36
+ cache_name TEXT NOT NULL,
37
+ created REAL NOT NULL,
38
+ pid INTEGER NUT NULL
39
+ );
40
+ """)
41
+ db.commit()
42
+ db.close()
43
+
44
+ @contextmanager
45
+ def _exclusive_db_cursor(self):
46
+ db = sqlite3.connect(self.lockfile, isolation_level="EXCLUSIVE")
47
+ db.row_factory = sqlite3.Row
48
+ cur = db.cursor()
49
+
50
+ try:
51
+ yield cur
52
+ finally:
53
+ db.commit()
54
+ db.close()
55
+
56
+ @contextmanager
57
+ def lock(self, cache_name, no_block=False):
58
+
59
+ pid = os.getpid()
60
+
61
+ while True:
62
+ with self._exclusive_db_cursor() as cur:
63
+ self._add_lock(cur, cache_name, pid)
64
+ if self._poll(cur, cache_name, pid):
65
+ break
66
+ elif no_block:
67
+ raise CacheLockedError()
68
+ time.sleep(self.polltime)
69
+
70
+ try:
71
+ yield
72
+ finally:
73
+ with self._exclusive_db_cursor() as cur:
74
+ self._remove_lock(cur, cache_name, pid)
75
+
76
+ def _poll(self, cur, cache_name, pid):
77
+ active_locks = False
78
+ cur.execute("SELECT * from cache_locks where cache_name = ? ORDER BY created", (cache_name, ))
79
+
80
+ for lock in cur:
81
+ if not active_locks and lock['cache_name'] == cache_name and lock['pid'] == pid:
82
+ # we are waiting and it is out turn
83
+ return True
84
+
85
+ if not is_running(lock['pid']):
86
+ self._remove_lock(cur, lock['cache_name'], lock['pid'])
87
+ else:
88
+ active_locks = True
89
+
90
+ return not active_locks
91
+
92
+ def _add_lock(self, cur, cache_name, pid):
93
+ cur.execute("SELECT count(*) from cache_locks WHERE cache_name = ? AND pid = ?", (cache_name, pid))
94
+ if cur.fetchone()[0] == 0:
95
+ cur.execute("INSERT INTO cache_locks (cache_name, pid, created) VALUES (?, ?, ?)", (cache_name, pid, time.time()))
96
+
97
+ def _remove_lock(self, cur, cache_name, pid):
98
+ cur.execute("DELETE FROM cache_locks WHERE cache_name = ? AND pid = ?", (cache_name, pid))
99
+
100
+ class DummyCacheLocker(object):
101
+ @contextmanager
102
+ def lock(self, cache_name, no_block=False):
103
+ yield
104
+
105
+ def is_running(pid):
106
+ try:
107
+ os.kill(pid, 0)
108
+ except OSError as err:
109
+ if err.errno == errno.ESRCH:
110
+ return False
111
+ elif err.errno == errno.EPERM:
112
+ return True
113
+ else:
114
+ raise err
115
+ else:
116
+ return True
117
+
118
+ if __name__ == '__main__':
119
+ locker = CacheLocker('/tmp/cachelock_test')
120
+ with locker.lock('foo'):
121
+ pass