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.
- mapproxy/__init__.py +0 -0
- mapproxy/cache/__init__.py +36 -0
- mapproxy/cache/azureblob.py +145 -0
- mapproxy/cache/base.py +111 -0
- mapproxy/cache/compact.py +664 -0
- mapproxy/cache/couchdb.py +295 -0
- mapproxy/cache/dummy.py +34 -0
- mapproxy/cache/file.py +185 -0
- mapproxy/cache/geopackage.py +609 -0
- mapproxy/cache/legend.py +83 -0
- mapproxy/cache/mbtiles.py +392 -0
- mapproxy/cache/meta.py +78 -0
- mapproxy/cache/path.py +250 -0
- mapproxy/cache/redis.py +88 -0
- mapproxy/cache/renderd.py +95 -0
- mapproxy/cache/riak.py +202 -0
- mapproxy/cache/s3.py +177 -0
- mapproxy/cache/tile.py +699 -0
- mapproxy/client/__init__.py +0 -0
- mapproxy/client/arcgis.py +79 -0
- mapproxy/client/cgi.py +139 -0
- mapproxy/client/http.py +315 -0
- mapproxy/client/log.py +33 -0
- mapproxy/client/tile.py +150 -0
- mapproxy/client/wms.py +254 -0
- mapproxy/compat/__init__.py +46 -0
- mapproxy/compat/image.py +79 -0
- mapproxy/compat/itertools.py +29 -0
- mapproxy/compat/modules.py +13 -0
- mapproxy/config/__init__.py +22 -0
- mapproxy/config/config.py +201 -0
- mapproxy/config/coverage.py +107 -0
- mapproxy/config/defaults.py +98 -0
- mapproxy/config/loader.py +2286 -0
- mapproxy/config/spec.py +644 -0
- mapproxy/config/validator.py +239 -0
- mapproxy/config_template/__init__.py +0 -0
- mapproxy/config_template/base_config/config.wsgi +10 -0
- mapproxy/config_template/base_config/full_example.yaml +593 -0
- mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
- mapproxy/config_template/base_config/log.ini +35 -0
- mapproxy/config_template/base_config/mapproxy.yaml +60 -0
- mapproxy/config_template/base_config/seed.yaml +27 -0
- mapproxy/exception.py +142 -0
- mapproxy/featureinfo.py +252 -0
- mapproxy/grid.py +1170 -0
- mapproxy/image/__init__.py +536 -0
- mapproxy/image/fonts/DejaVuSans.ttf +0 -0
- mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
- mapproxy/image/fonts/LICENSE +99 -0
- mapproxy/image/fonts/__init__.py +0 -0
- mapproxy/image/mask.py +75 -0
- mapproxy/image/merge.py +316 -0
- mapproxy/image/message.py +347 -0
- mapproxy/image/opts.py +182 -0
- mapproxy/image/tile.py +167 -0
- mapproxy/image/transform.py +350 -0
- mapproxy/layer.py +470 -0
- mapproxy/multiapp.py +231 -0
- mapproxy/proj.py +302 -0
- mapproxy/request/__init__.py +18 -0
- mapproxy/request/arcgis.py +259 -0
- mapproxy/request/base.py +476 -0
- mapproxy/request/tile.py +128 -0
- mapproxy/request/wms/__init__.py +793 -0
- mapproxy/request/wms/exception.py +99 -0
- mapproxy/request/wmts.py +436 -0
- mapproxy/response.py +237 -0
- mapproxy/script/__init__.py +0 -0
- mapproxy/script/conf/__init__.py +0 -0
- mapproxy/script/conf/app.py +195 -0
- mapproxy/script/conf/caches.py +45 -0
- mapproxy/script/conf/layers.py +54 -0
- mapproxy/script/conf/seeds.py +37 -0
- mapproxy/script/conf/sources.py +86 -0
- mapproxy/script/conf/utils.py +143 -0
- mapproxy/script/defrag.py +184 -0
- mapproxy/script/export.py +333 -0
- mapproxy/script/grids.py +188 -0
- mapproxy/script/scales.py +126 -0
- mapproxy/script/util.py +406 -0
- mapproxy/script/wms_capabilities.py +152 -0
- mapproxy/seed/__init__.py +0 -0
- mapproxy/seed/cachelock.py +121 -0
- mapproxy/seed/cleanup.py +187 -0
- mapproxy/seed/config.py +469 -0
- mapproxy/seed/script.py +388 -0
- mapproxy/seed/seeder.py +538 -0
- mapproxy/seed/spec.py +64 -0
- mapproxy/seed/util.py +254 -0
- mapproxy/service/__init__.py +14 -0
- mapproxy/service/base.py +46 -0
- mapproxy/service/demo.py +356 -0
- mapproxy/service/kml.py +331 -0
- mapproxy/service/ows.py +38 -0
- mapproxy/service/template_helper.py +53 -0
- mapproxy/service/templates/demo/capabilities_demo.html +16 -0
- mapproxy/service/templates/demo/demo.html +181 -0
- mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
- mapproxy/service/templates/demo/static/img/blank.gif +0 -0
- mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
- mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
- mapproxy/service/templates/demo/static/logo.png +0 -0
- mapproxy/service/templates/demo/static/ol.css +345 -0
- mapproxy/service/templates/demo/static/ol.js +4 -0
- mapproxy/service/templates/demo/static/proj4.min.js +1 -0
- mapproxy/service/templates/demo/static/proj4defs.js +1 -0
- mapproxy/service/templates/demo/static/site.css +137 -0
- mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
- mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
- mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
- mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
- mapproxy/service/templates/demo/static.html +34 -0
- mapproxy/service/templates/demo/tms_demo.html +103 -0
- mapproxy/service/templates/demo/wms_demo.html +140 -0
- mapproxy/service/templates/demo/wmts_demo.html +110 -0
- mapproxy/service/templates/tms_capabilities.xml +13 -0
- mapproxy/service/templates/tms_exception.xml +4 -0
- mapproxy/service/templates/tms_root_resource.xml +7 -0
- mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
- mapproxy/service/templates/wms100capabilities.xml +112 -0
- mapproxy/service/templates/wms100exception.xml +4 -0
- mapproxy/service/templates/wms110capabilities.xml +152 -0
- mapproxy/service/templates/wms110exception.xml +5 -0
- mapproxy/service/templates/wms111capabilities.xml +183 -0
- mapproxy/service/templates/wms111exception.xml +5 -0
- mapproxy/service/templates/wms130capabilities.xml +326 -0
- mapproxy/service/templates/wms130exception.xml +8 -0
- mapproxy/service/templates/wmts100capabilities.xml +155 -0
- mapproxy/service/templates/wmts100exception.xml +9 -0
- mapproxy/service/tile.py +536 -0
- mapproxy/service/wms.py +851 -0
- mapproxy/service/wmts.py +381 -0
- mapproxy/source/__init__.py +75 -0
- mapproxy/source/arcgis.py +39 -0
- mapproxy/source/error.py +39 -0
- mapproxy/source/mapnik.py +259 -0
- mapproxy/source/tile.py +96 -0
- mapproxy/source/wms.py +270 -0
- mapproxy/srs.py +726 -0
- mapproxy/template.py +54 -0
- mapproxy/test/__init__.py +0 -0
- mapproxy/test/conftest.py +7 -0
- mapproxy/test/helper.py +247 -0
- mapproxy/test/http.py +494 -0
- mapproxy/test/image.py +210 -0
- mapproxy/test/mocker.py +2268 -0
- mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
- mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
- mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
- mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
- mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
- mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
- mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
- mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
- mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
- mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
- mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
- mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
- mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
- mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
- mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
- mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
- mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
- mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
- mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
- mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
- mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
- mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
- mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
- mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
- mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
- mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
- mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
- mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
- mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
- mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
- mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
- mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
- mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
- mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
- mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
- mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
- mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
- mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
- mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
- mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
- mapproxy/test/schemas/xml.xsd +287 -0
- mapproxy/test/system/__init__.py +98 -0
- mapproxy/test/system/fixture/arcgis.yaml +57 -0
- mapproxy/test/system/fixture/auth.yaml +70 -0
- mapproxy/test/system/fixture/cache.mbtiles +0 -0
- mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
- mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
- mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
- mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
- mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
- mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
- mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
- mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
- mapproxy/test/system/fixture/cache_s3.yaml +58 -0
- mapproxy/test/system/fixture/cache_source.yaml +81 -0
- mapproxy/test/system/fixture/combined_sources.yaml +130 -0
- mapproxy/test/system/fixture/coverage.yaml +77 -0
- mapproxy/test/system/fixture/demo.yaml +135 -0
- mapproxy/test/system/fixture/dimension.yaml +59 -0
- mapproxy/test/system/fixture/disable_storage.yaml +25 -0
- mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
- mapproxy/test/system/fixture/formats.yaml +72 -0
- mapproxy/test/system/fixture/inspire.yaml +101 -0
- mapproxy/test/system/fixture/inspire_full.yaml +124 -0
- mapproxy/test/system/fixture/kml_layer.yaml +66 -0
- mapproxy/test/system/fixture/layer.yaml +260 -0
- mapproxy/test/system/fixture/layergroups.yaml +57 -0
- mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
- mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
- mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
- mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
- mapproxy/test/system/fixture/mapserver.yaml +23 -0
- mapproxy/test/system/fixture/minimal_cgi.py +16 -0
- mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
- mapproxy/test/system/fixture/multi_cache_layers.yaml +100 -0
- mapproxy/test/system/fixture/multiapp1.yaml +20 -0
- mapproxy/test/system/fixture/multiapp2.yaml +19 -0
- mapproxy/test/system/fixture/renderd_client.yaml +55 -0
- mapproxy/test/system/fixture/scalehints.yaml +70 -0
- mapproxy/test/system/fixture/seed.yaml +94 -0
- mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
- mapproxy/test/system/fixture/seed_old.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
- mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
- mapproxy/test/system/fixture/seedonly.yaml +51 -0
- mapproxy/test/system/fixture/sld.yaml +35 -0
- mapproxy/test/system/fixture/source_errors.yaml +84 -0
- mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
- mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
- mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
- mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
- mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
- mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
- mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
- mapproxy/test/system/fixture/util_grids.yaml +30 -0
- mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
- mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
- mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
- mapproxy/test/system/fixture/watermark.yaml +50 -0
- mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
- mapproxy/test/system/fixture/wms_versions.yaml +38 -0
- mapproxy/test/system/fixture/wmts.yaml +134 -0
- mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
- mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
- mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
- mapproxy/test/system/test_arcgis.py +156 -0
- mapproxy/test/system/test_auth.py +1134 -0
- mapproxy/test/system/test_behind_proxy.py +75 -0
- mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
- mapproxy/test/system/test_cache_azureblob.py +127 -0
- mapproxy/test/system/test_cache_band_merge.py +103 -0
- mapproxy/test/system/test_cache_geopackage.py +144 -0
- mapproxy/test/system/test_cache_grid_names.py +89 -0
- mapproxy/test/system/test_cache_mbtiles.py +85 -0
- mapproxy/test/system/test_cache_s3.py +115 -0
- mapproxy/test/system/test_cache_source.py +146 -0
- mapproxy/test/system/test_combined_sources.py +335 -0
- mapproxy/test/system/test_coverage.py +140 -0
- mapproxy/test/system/test_decorate_img.py +214 -0
- mapproxy/test/system/test_demo.py +106 -0
- mapproxy/test/system/test_demo_with_extra_service.py +53 -0
- mapproxy/test/system/test_dimensions.py +278 -0
- mapproxy/test/system/test_disable_storage.py +42 -0
- mapproxy/test/system/test_formats.py +219 -0
- mapproxy/test/system/test_inspire_vs.py +173 -0
- mapproxy/test/system/test_kml.py +262 -0
- mapproxy/test/system/test_layergroups.py +160 -0
- mapproxy/test/system/test_legendgraphic.py +308 -0
- mapproxy/test/system/test_mapnik.py +161 -0
- mapproxy/test/system/test_mapserver.py +81 -0
- mapproxy/test/system/test_mixed_mode_format.py +195 -0
- mapproxy/test/system/test_multi_cache_layers.py +167 -0
- mapproxy/test/system/test_multiapp.py +92 -0
- mapproxy/test/system/test_refresh.py +207 -0
- mapproxy/test/system/test_renderd_client.py +304 -0
- mapproxy/test/system/test_response_headers.py +54 -0
- mapproxy/test/system/test_scalehints.py +140 -0
- mapproxy/test/system/test_seed.py +422 -0
- mapproxy/test/system/test_seed_only.py +93 -0
- mapproxy/test/system/test_sld.py +120 -0
- mapproxy/test/system/test_source_errors.py +377 -0
- mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
- mapproxy/test/system/test_tms.py +276 -0
- mapproxy/test/system/test_tms_origin.py +46 -0
- mapproxy/test/system/test_util_conf.py +304 -0
- mapproxy/test/system/test_util_export.py +210 -0
- mapproxy/test/system/test_util_grids.py +88 -0
- mapproxy/test/system/test_util_wms_capabilities.py +182 -0
- mapproxy/test/system/test_watermark.py +91 -0
- mapproxy/test/system/test_wms.py +1611 -0
- mapproxy/test/system/test_wms_srs_extent.py +165 -0
- mapproxy/test/system/test_wms_version.py +85 -0
- mapproxy/test/system/test_wmsc.py +116 -0
- mapproxy/test/system/test_wmts.py +334 -0
- mapproxy/test/system/test_wmts_dimensions.py +206 -0
- mapproxy/test/system/test_wmts_restful.py +198 -0
- mapproxy/test/system/test_xslt_featureinfo.py +425 -0
- mapproxy/test/test_http_helper.py +219 -0
- mapproxy/test/unit/__init__.py +0 -0
- mapproxy/test/unit/epsg +2 -0
- mapproxy/test/unit/polygons/polygons.dbf +0 -0
- mapproxy/test/unit/polygons/polygons.shp +0 -0
- mapproxy/test/unit/polygons/polygons.shx +0 -0
- mapproxy/test/unit/test_async.py +245 -0
- mapproxy/test/unit/test_auth.py +419 -0
- mapproxy/test/unit/test_cache.py +1193 -0
- mapproxy/test/unit/test_cache_azureblob.py +94 -0
- mapproxy/test/unit/test_cache_compact.py +319 -0
- mapproxy/test/unit/test_cache_couchdb.py +114 -0
- mapproxy/test/unit/test_cache_geopackage.py +221 -0
- mapproxy/test/unit/test_cache_redis.py +67 -0
- mapproxy/test/unit/test_cache_riak.py +76 -0
- mapproxy/test/unit/test_cache_s3.py +84 -0
- mapproxy/test/unit/test_cache_tile.py +427 -0
- mapproxy/test/unit/test_client.py +479 -0
- mapproxy/test/unit/test_client_arcgis.py +73 -0
- mapproxy/test/unit/test_client_cgi.py +136 -0
- mapproxy/test/unit/test_collections.py +116 -0
- mapproxy/test/unit/test_concat_legends.py +37 -0
- mapproxy/test/unit/test_conf_loader.py +1061 -0
- mapproxy/test/unit/test_conf_validator.py +416 -0
- mapproxy/test/unit/test_config.py +117 -0
- mapproxy/test/unit/test_decorate_img.py +185 -0
- mapproxy/test/unit/test_exceptions.py +258 -0
- mapproxy/test/unit/test_featureinfo.py +291 -0
- mapproxy/test/unit/test_file_lock_load.py +49 -0
- mapproxy/test/unit/test_geom.py +503 -0
- mapproxy/test/unit/test_grid.py +1258 -0
- mapproxy/test/unit/test_image.py +1053 -0
- mapproxy/test/unit/test_image_mask.py +181 -0
- mapproxy/test/unit/test_image_messages.py +197 -0
- mapproxy/test/unit/test_image_options.py +160 -0
- mapproxy/test/unit/test_isodate.py +122 -0
- mapproxy/test/unit/test_multiapp.py +163 -0
- mapproxy/test/unit/test_ogr_reader.py +50 -0
- mapproxy/test/unit/test_request.py +745 -0
- mapproxy/test/unit/test_request_wmts.py +178 -0
- mapproxy/test/unit/test_response.py +79 -0
- mapproxy/test/unit/test_seed.py +365 -0
- mapproxy/test/unit/test_seed_cachelock.py +90 -0
- mapproxy/test/unit/test_srs.py +215 -0
- mapproxy/test/unit/test_tiled_source.py +122 -0
- mapproxy/test/unit/test_tilefilter.py +31 -0
- mapproxy/test/unit/test_times.py +25 -0
- mapproxy/test/unit/test_timeutils.py +50 -0
- mapproxy/test/unit/test_util_conf_utils.py +75 -0
- mapproxy/test/unit/test_utils.py +476 -0
- mapproxy/test/unit/test_wms_capabilities.py +44 -0
- mapproxy/test/unit/test_wms_layer.py +113 -0
- mapproxy/test/unit/test_yaml.py +69 -0
- mapproxy/tilefilter.py +59 -0
- mapproxy/util/__init__.py +0 -0
- mapproxy/util/async_.py +227 -0
- mapproxy/util/collections.py +132 -0
- mapproxy/util/coverage.py +329 -0
- mapproxy/util/escape.py +10 -0
- mapproxy/util/ext/__init__.py +14 -0
- mapproxy/util/ext/dictspec/__init__.py +1 -0
- mapproxy/util/ext/dictspec/spec.py +124 -0
- mapproxy/util/ext/dictspec/test/__init__.py +0 -0
- mapproxy/util/ext/dictspec/test/test_validator.py +274 -0
- mapproxy/util/ext/dictspec/validator.py +189 -0
- mapproxy/util/ext/local.py +196 -0
- mapproxy/util/ext/lockfile.py +138 -0
- mapproxy/util/ext/odict.py +330 -0
- mapproxy/util/ext/serving.py +508 -0
- mapproxy/util/ext/tempita/__init__.py +1174 -0
- mapproxy/util/ext/tempita/_looper.py +163 -0
- mapproxy/util/ext/tempita/compat3.py +46 -0
- mapproxy/util/ext/wmsparse/__init__.py +3 -0
- mapproxy/util/ext/wmsparse/duration.py +597 -0
- mapproxy/util/ext/wmsparse/parse.py +305 -0
- mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
- mapproxy/util/ext/wmsparse/test/test_parse.py +162 -0
- mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
- mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
- mapproxy/util/ext/wmsparse/test/wms-omniscale-111.xml +90 -0
- mapproxy/util/ext/wmsparse/test/wms-omniscale-130.xml +120 -0
- mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
- mapproxy/util/ext/wmsparse/util.py +187 -0
- mapproxy/util/fs.py +156 -0
- mapproxy/util/geom.py +295 -0
- mapproxy/util/lib.py +115 -0
- mapproxy/util/lock.py +163 -0
- mapproxy/util/ogr.py +231 -0
- mapproxy/util/py.py +81 -0
- mapproxy/util/times.py +75 -0
- mapproxy/util/yaml.py +56 -0
- mapproxy/version.py +31 -0
- mapproxy/wsgiapp.py +164 -0
- mapproxy-1.16.1.dist-info/METADATA +151 -0
- mapproxy-1.16.1.dist-info/RECORD +458 -0
- mapproxy-1.16.1.dist-info/WHEEL +5 -0
- mapproxy-1.16.1.dist-info/entry_points.txt +3 -0
- mapproxy-1.16.1.dist-info/licenses/AUTHORS.txt +33 -0
- mapproxy-1.16.1.dist-info/licenses/COPYING.txt +60 -0
- mapproxy-1.16.1.dist-info/licenses/LICENSE.txt +202 -0
- mapproxy-1.16.1.dist-info/top_level.txt +1 -0
mapproxy/script/util.py
ADDED
|
@@ -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
|