Commit 422469ca authored by Mark Hewitt's avatar Mark Hewitt
Browse files

Merge branch 'feature/crs-commands' into 'main'

Feature/crs commands

See merge request !7
parents 3dba5ba9 cb700a2b
Pipeline #76535 passed with stages
in 3 minutes and 6 seconds
......@@ -4,3 +4,4 @@ max-line-length = 120
max-complexity = 12
per-file-ignores =
src/osducli/__main__.py: W605
src/osducli/commands/crs/_const.py: E501
\ No newline at end of file
......@@ -32,6 +32,7 @@ Change Log
------
- test against python 3.10 in addition to 3.8, 3.9
- crs commands
0.0.24
------
......
......@@ -316,7 +316,7 @@ redefining-builtins-modules=six.moves,past.builtins,future.builtins
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
ignore-long-lines=^\s*(# )?<?https?://\S+>?$|^\s*(\w*\s*=\s*)?(\"|\').*(\"|\'),?\s*$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
......
......@@ -12,4 +12,4 @@
""" OSDU command line environment"""
__VERSION__ = "0.0.24"
__VERSION__ = "0.0.25"
......@@ -36,6 +36,8 @@ MSG_HEADING_ENV_VARS = "\nEnvironment variables:"
MSG_PROMPT_CONFIG = "\nWhat config file do you want to use as the default?"
MSG_PROMPT_MANAGE_GLOBAL = "\nDo you wish to change your settings?"
MSG_PROMPT_SERVER = "\nOSDU API Server []: "
MSG_PROMPT_CRS_CATALOG_URL = "\nCRS Catalog API path []: "
MSG_PROMPT_CRS_CONVERTER_URL = "\nCRS Converter API path []: "
MSG_PROMPT_CONFIG_ENTITLEMENTS_URL = "\nEntitlements API path []: "
MSG_PROMPT_FILE_URL = "\nFile API path []: "
MSG_PROMPT_LEGAL_URL = "\nLegal API path []: "
......
......@@ -30,6 +30,8 @@ from osducli.commands.config.consts import (
MSG_PROMPT_CLIENT_ID,
MSG_PROMPT_CLIENT_SECRET,
MSG_PROMPT_CONFIG_ENTITLEMENTS_URL,
MSG_PROMPT_CRS_CATALOG_URL,
MSG_PROMPT_CRS_CONVERTER_URL,
MSG_PROMPT_DATA_PARTITION,
MSG_PROMPT_FILE_URL,
MSG_PROMPT_LEGAL_TAG,
......@@ -54,6 +56,8 @@ from osducli.config import (
CONFIG_AUTHENTICATION_SCOPES,
CONFIG_CLIENT_ID,
CONFIG_CLIENT_SECRET,
CONFIG_CRS_CATALOG_URL,
CONFIG_CRS_CONVERTER_URL,
CONFIG_DATA_PARTITION_ID,
CONFIG_ENTITLEMENTS_URL,
CONFIG_FILE_URL,
......@@ -198,6 +202,19 @@ def _configure_authentication(config):
def _configure_connection(config): # noqa C901 pylint: disable=R0912
server = _prompt_default_from_config(MSG_PROMPT_SERVER, config, CONFIG_SERVER)
crs_catalog_url = _prompt_default_from_config(
MSG_PROMPT_CRS_CATALOG_URL,
config,
CONFIG_CRS_CATALOG_URL,
fallback="/api/crs/catalog/v2/",
)
crs_converter_url = _prompt_default_from_config(
MSG_PROMPT_CRS_CONVERTER_URL,
config,
CONFIG_CRS_CONVERTER_URL,
fallback="/api/crs/converter/v2/",
)
entitlements_url = _prompt_default_from_config(
MSG_PROMPT_CONFIG_ENTITLEMENTS_URL,
config,
......@@ -251,6 +268,10 @@ def _configure_connection(config): # noqa C901 pylint: disable=R0912
# save the global config
if server != "":
config.set_value("core", CONFIG_SERVER, server)
if crs_catalog_url != "":
config.set_value("core", CONFIG_CRS_CATALOG_URL, crs_catalog_url)
if crs_converter_url != "":
config.set_value("core", CONFIG_CRS_CONVERTER_URL, crs_converter_url)
if entitlements_url != "":
config.set_value("core", CONFIG_ENTITLEMENTS_URL, entitlements_url)
if file_url != "":
......
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Coordinate Reference System (CRS) service commands"""
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""CRS constants"""
CRS_CATALOG_DOCUMENTATION = "https://community.opengroup.org/osdu/documentation/-/wikis/OSDU-(C)/Design-and-Implementation/OpenDES-API-Specifications/Documentation/core-services/CRSCatalogService"
CRS_CATALOG_SERVICE_NAME = "CRS Catalog service"
CRS_CATALOG_STATUS_PATH = "../_ah/readiness_check"
CRS_CATALOG_SWAGGER_PATH = "../swagger-ui.html"
CRS_CONVERTER_SERVICE_NAME = "CRS Catalog service"
CRS_CONVERTER_STATUS_PATH = "../_ah/readiness_check"
CRS_CONVERTER_SWAGGER_PATH = "../swagger-ui.html"
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""CRS Catalog areas command"""
import click
from osducli.click_cli import CustomClickCommand, State, command_with_output
from osducli.cliclient import CliOsduClient, handle_cli_exceptions
from osducli.config import CONFIG_CRS_CATALOG_URL
# click entry point
@click.command(cls=CustomClickCommand)
@handle_cli_exceptions
@command_with_output("areasOfUse[].{Name:name}")
def _click_command(state: State):
"""List areas"""
return area_list(state)
def area_list(state: State):
"""List areas
Args:
state (State): Global state
"""
connection = CliOsduClient(state.config)
json = connection.cli_get_returning_json(CONFIG_CRS_CATALOG_URL, "area?limit=10000")
return json
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""CRS Catalog info command"""
import click
from osducli.click_cli import CustomClickCommand, State, command_with_output
from osducli.cliclient import handle_cli_exceptions
from osducli.commands.crs._const import (
CRS_CATALOG_DOCUMENTATION,
CRS_CATALOG_SERVICE_NAME,
CRS_CATALOG_STATUS_PATH,
CRS_CATALOG_SWAGGER_PATH,
)
from osducli.config import CONFIG_CRS_CATALOG_URL
from osducli.util.service_info import info
# click entry point
@click.command(cls=CustomClickCommand)
@handle_cli_exceptions
@command_with_output(None)
def _click_command(state: State) -> dict:
"""Information about the service"""
return info(
state,
CRS_CATALOG_SERVICE_NAME,
CONFIG_CRS_CATALOG_URL,
CRS_CATALOG_STATUS_PATH,
CRS_CATALOG_SWAGGER_PATH,
CRS_CATALOG_DOCUMENTATION,
)
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""CRS Catalog list command"""
import click
from osducli.click_cli import CustomClickCommand, State, command_with_output
from osducli.cliclient import CliOsduClient, handle_cli_exceptions
from osducli.config import CONFIG_CRS_CATALOG_URL
# click entry point
@click.command(cls=CustomClickCommand)
@handle_cli_exceptions
@command_with_output(
"crses[].{Authority:baseCRSAuthorityCode.auth,Code:baseCRSAuthorityCode.code,Type:crstype}"
)
def _click_command(state: State):
"""List CRS's"""
return crs_list(state)
def crs_list(state: State):
"""List CRS's
Args:
state (State): Global state
"""
connection = CliOsduClient(state.config)
json = connection.cli_get_returning_json(CONFIG_CRS_CATALOG_URL, "crs?limit=10000")
return json
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""CRS Catalog summary command"""
import click
from osducli.click_cli import CustomClickCommand, State, command_with_output
from osducli.cliclient import CliOsduClient, handle_cli_exceptions
from osducli.config import CONFIG_CRS_CATALOG_URL
# click entry point
@click.command(cls=CustomClickCommand)
@handle_cli_exceptions
@command_with_output("attributes.{Name:name,Description:description,LastModified:lastModified}")
def _click_command(state: State):
"""CRS catalog Summary"""
return crs_summary(state)
def crs_summary(state: State):
"""CRS Summary
Args:
state (State): Global state
"""
connection = CliOsduClient(state.config)
json = connection.cli_get_returning_json(CONFIG_CRS_CATALOG_URL, "catalog")
return json
......@@ -27,6 +27,8 @@ CLI_CONFIG_DIR = os.path.expanduser(os.path.join("~", ".{0}".format(CLI_NAME)))
CLI_ENV_VAR_PREFIX = CLI_NAME
CONFIG_SERVER = "server"
CONFIG_CRS_CATALOG_URL = "crs_catalog_url"
CONFIG_CRS_CONVERTER_URL = "crs_converter_url"
CONFIG_ENTITLEMENTS_URL = "entitlements_url"
CONFIG_FILE_URL = "file_url"
CONFIG_LEGAL_URL = "legal_url"
......
......@@ -18,7 +18,14 @@ from osducli.commands.status.status import check_status
from osducli.commands.version.version import get_api_info
def info(state: State, name: str, config_url_key: str, status_path: str, swagger_path: str) -> dict:
def info(
state: State,
name: str,
config_url_key: str,
status_path: str,
swagger_path: str,
documentation: str = None,
) -> dict:
"""Return information about the service
Args:
......@@ -27,6 +34,7 @@ def info(state: State, name: str, config_url_key: str, status_path: str, swagger
config_url_key (str): Config url key
status_path (str): Path to status service
swagger_path (str): Swagger path
documentation (str): Link to documentaion about the underlying service
Returns:
dict: Response from service
......@@ -39,6 +47,11 @@ def info(state: State, name: str, config_url_key: str, status_path: str, swagger
print("Reason:", status["reason"])
version = get_api_info(connection, config_url_key, "info")
swagger_path_expanded = (
connection.url_from_config(config_url_key, swagger_path) if swagger_path else None
)
if state.is_user_friendly_mode():
if version:
print("Version:", version["version"])
......@@ -48,18 +61,21 @@ def info(state: State, name: str, config_url_key: str, status_path: str, swagger
else:
print("No version information available")
swagger_path_expanded = (
connection.url_from_config(config_url_key, swagger_path) if swagger_path else None
)
if state.is_user_friendly_mode():
if swagger_path_expanded:
print("Swagger:", swagger_path_expanded)
else:
print("Swagger path unknown")
if documentation:
print("Documentation:", documentation)
return (
None
if state.is_user_friendly_mode()
else {"status": status, "version": version, "swagger": swagger_path_expanded}
else {
"status": status,
"version": version,
"swagger": swagger_path_expanded,
"documentation": documentation,
}
)
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for OSDU CLI"""
{
"offset": 0,
"count": 2,
"totalCount": 953,
"areasOfUse": [
{
"description": "Philippines - onshore west of 118\u00b0E.",
"lastModified": "20140501",
"aliasNames": [],
"namedReference": {
"name": "Philippines - zone I onshore",
"persistableReference": "{\"boundBox\":{\"lonMin\":116.89,\"latMin\":7.75,\"lonMax\":118.0,\"latMax\":9.32},\"authCode\":{\"auth\":\"EPSG\",\"code\":\"3958\"},\"type\":\"AOU\"}"
},
"name": "Philippines - zone I onshore"
},
{
"description": "Between 150\u00b0W and 144\u00b0W, northern hemisphere between equator and 84\u00b0N, onshore and offshore. United States (USA) - Alaska (AK).",
"lastModified": "20110509",
"aliasNames": [],
"namedReference": {
"name": "World - N hemisphere - 150\u00b0W to 144\u00b0W - by country",
"persistableReference": "{\"boundBox\":{\"lonMin\":-150.0,\"latMin\":0.0,\"lonMax\":-144.0,\"latMax\":84.0},\"authCode\":{\"auth\":\"EPSG\",\"code\":\"2010\"},\"type\":\"AOU\"}"
},
"name": "World - N hemisphere - 150\u00b0W to 144\u00b0W - by country"
}
]
}
\ No newline at end of file
{
"offset": 0,
"count": 2,
"totalCount": 2270,
"crses": [
{
"description": "CRS Scope: Large and medium scale topographic mapping and engineering survey. | Information Source: Brown and Root",
"lastModified": "20000307",
"aliasNames": [
"ELD79 / Libya zone 5"
],
"namedReference": {
"name": "ELD_1979_Libya_5",
"persistableReference": "{\"wkt\":\"PROJCS[\\\"ELD_1979_Libya_5\\\",GEOGCS[\\\"GCS_European_Libyan_Datum_1979\\\",DATUM[\\\"D_European_Libyan_1979\\\",SPHEROID[\\\"International_1924\\\",6378388.0,297.0]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Transverse_Mercator\\\"],PARAMETER[\\\"False_Easting\\\",200000.0],PARAMETER[\\\"False_Northing\\\",0.0],PARAMETER[\\\"Central_Meridian\\\",9.0],PARAMETER[\\\"Scale_Factor\\\",0.9999],PARAMETER[\\\"Latitude_Of_Origin\\\",0.0],UNIT[\\\"Meter\\\",1.0],AUTHORITY[\\\"EPSG\\\",2068]]\",\"ver\":\"PE_10_3_1\",\"name\":\"ELD_1979_Libya_5\",\"authCode\":{\"auth\":\"EPSG\",\"code\":\"2068\"},\"type\":\"LBC\"}"
},
"source": "Brown and Root",
"numberOfAxes": 2,
"axisUnits": [
"{\"baseMeasurement\":{\"ancestry\":\"Length\",\"type\":\"UM\"},\"scaleOffset\":{\"offset\":0.0,\"scale\":1.0},\"symbol\":\"m\",\"type\":\"USO\"}",
"{\"baseMeasurement\":{\"ancestry\":\"Length\",\"type\":\"UM\"},\"scaleOffset\":{\"offset\":0.0,\"scale\":1.0},\"symbol\":\"m\",\"type\":\"USO\"}"
],
"baseCRSAuthorityCode": {
"auth": "EPSG",
"code": "4159"
},
"crstype": "Projected",
"transformationReady": false,
"areaOfUse": {
"description": "Libya - west of 10\u00b0E.",
"lastModified": "20140501",
"aliasNames": [],
"name": "Libya - west of 10\u00b0E",
"essence": {
"authCode": {
"auth": "EPSG",
"code": "1470"
},
"type": "AOU",
"boundBox": {
"lonMin": 9.31,
"latMin": 25.37,
"lonMax": 10.01,
"latMax": 30.49
}
}
}
},
{
"description": "CRS Scope: Large and medium scale topographic mapping and engineering survey.",
"lastModified": "20000307",
"aliasNames": [
"Naparima 1955 / UTM zone 20N",
"Naparima 1955 / UTM 20N"
],
"namedReference": {
"name": "Naparima_1955_UTM_Zone_20N",
"persistableReference": "{\"wkt\":\"PROJCS[\\\"Naparima_1955_UTM_Zone_20N\\\",GEOGCS[\\\"GCS_Naparima_1955\\\",DATUM[\\\"D_Naparima_1955\\\",SPHEROID[\\\"International_1924\\\",6378388.0,297.0]],PRIMEM[\\\"Greenwich\\\",0.0],UNIT[\\\"Degree\\\",0.0174532925199433]],PROJECTION[\\\"Transverse_Mercator\\\"],PARAMETER[\\\"False_Easting\\\",500000.0],PARAMETER[\\\"False_Northing\\\",0.0],PARAMETER[\\\"Central_Meridian\\\",-63.0],PARAMETER[\\\"Scale_Factor\\\",0.9996],PARAMETER[\\\"Latitude_Of_Origin\\\",0.0],UNIT[\\\"Meter\\\",1.0],AUTHORITY[\\\"EPSG\\\",2067]]\",\"ver\":\"PE_10_3_1\",\"name\":\"Naparima_1955_UTM_Zone_20N\",\"authCode\":{\"auth\":\"EPSG\",\"code\":\"2067\"},\"type\":\"LBC\"}"
},
"source": "",
"numberOfAxes": 2,
"axisUnits": [
"{\"baseMeasurement\":{\"ancestry\":\"Length\",\"type\":\"UM\"},\"scaleOffset\":{\"offset\":0.0,\"scale\":1.0},\"symbol\":\"m\",\"type\":\"USO\"}",
"{\"baseMeasurement\":{\"ancestry\":\"Length\",\"type\":\"UM\"},\"scaleOffset\":{\"offset\":0.0,\"scale\":1.0},\"symbol\":\"m\",\"type\":\"USO\"}"
],
"baseCRSAuthorityCode": {
"auth": "EPSG",
"code": "4158"
},
"crstype": "Projected",
"transformationReady": false,
"areaOfUse": {
"description": "Trinidad and Tobago - Trinidad - onshore.",
"lastModified": "20170319",
"aliasNames": [],
"name": "Trinidad and Tobago - Trinidad - onshore",
"essence": {
"authCode": {
"auth": "EPSG",
"code": "3143"
},
"type": "AOU",
"boundBox": {
"lonMin": -61.98,
"latMin": 9.99,
"lonMax": -60.85,
"latMax": 10.9
}
}
}
}
]
}
\ No newline at end of file
{
"name": "Minimal EPSG standard catalog",
"description": "Catalog containing selected ESRI's standard EPSG coordinate reference systems and cartographic transforms, and limited early-bound coordinate reference systems where the CRS and TRF area-of-use intersect; augmented by Ocean factory catalog standard definitions",
"lastModified": "2020-05-18T07:45:41Z"
}
\ No newline at end of file
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Content-Type:
- application/json
User-Agent:
- python-requests/2.26.0
data-partition-id:
- core_data_partition_id
method: GET
uri: https://dummy.com/core_unit_urlunit?limit=10000
response:
body:
string: ''
headers:
connection:
- close
content-length:
- '0'
content-type:
- text/html; charset=UTF-8
date:
- Wed, 10 Nov 2021 09:33:37 GMT
location:
- http://ww25.dummy.com/core_unit_urlunit?limit=10000&subid1=20211110-2033-37c9-a2c0-99da8013445a
server:
- Apache/2.4.25 (Debian)
set-cookie:
- __tad=1636536817.7210527; expires=Sat, 08-Nov-2031 09:33:37 GMT; Max-Age=315360000
status:
code: 302
message: Found
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Connection:
- keep-alive
Cookie:
- __tad=1636536817.7210527
User-Agent:
- python-requests/2.26.0
data-partition-id:
- core_data_partition_id
method: GET
uri: http://ww25.dummy.com/core_unit_urlunit?limit=10000&subid1=20211110-2033-37c9-a2c0-99da8013445a
response:
body:
string: '<!doctype html><html lang="en" data-adblockkey="MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDrp2lz7AOmADaN8tA50LsWcjLFyQFcb/P2Txc58oYOeILb3vBw7J6f4pamkAQVSQuqYsKx3YzdUHCvbVZvFUsCAwEAAQ==_kqmqPVeaDuJxuWLyEGhXsAQKJvtiK2QWXZuL/Agrgxyle3V9SK2VlWsm4kdFwbgHctAY4PgPWxTVvZvvT8KHnA=="><head><meta
charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link
rel="shortcut icon" href="/favicon.ico" type="image/x-icon"/><link rel="preconnect"
href="https://www.google.com" crossorigin><link rel="dns-prefetch" href="https://parking.bodiscdn.com"
crossorigin><link rel="dns-prefetch" href="https://fonts.googleapis.com" crossorigin></head><body><div
id="target" style=''opacity: 0''></div><script>window.park = "eyJ1dWlkIjoiYTQ2YWM5ZTMtMGYwYS02NTA1LTk4Y2QtYzJlNTljZTY5NTI4IiwicGFnZV90aW1lIjoxNjM2NTM2ODE4LCJwYWdlX3VybCI6Imh0dHA6XC9cL3d3MjUuZHVtbXkuY29tXC9jb3JlX3VuaXRfdXJsdW5pdD9saW1pdD0xMDAwMCZzdWJpZDE9MjAyMTExMTAtMjAzMy0zN2M5LWEyYzAtOTlkYTgwMTM0NDVhIiwicGFnZV9tZXRob2QiOiJHRVQiLCJwYWdlX3JlcXVlc3QiOnsibGltaXQiOiIxMDAwMCIsInN1YmlkMSI6IjIwMjExMTEwLTIwMzMtMzdjOS1hMmMwLTk5ZGE4MDEzNDQ1YSJ9LCJwYWdlX2hlYWRlcnMiOnsiY29va2llIjpbIl9fdGFkPTE2MzY1MzY4MTcuNzIxMDUyNyJdLCJkYXRhLXBhcnRpdGlvbi1pZCI6WyJjb3JlX2RhdGFfcGFydGl0aW9uX2lkIl0sImNvbm5lY3Rpb24iOlsia2VlcC1hbGl2ZSJdLCJhY2NlcHQiOlsiKlwvKiJdLCJhY2NlcHQtZW5jb2RpbmciOlsiZ3ppcCwgZGVmbGF0ZSJdLCJ1c2VyLWFnZW50IjpbInB5dGhvbi1yZXF1ZXN0c1wvMi4yNi4wIl0sImhvc3QiOlsid3cyNS5kdW1teS5jb20iXX0sImhvc3QiOiJ3dzI1LmR1bW15LmNvbSIsImlwIjoiNTEuMTc0Ljc3LjIxNCJ9";</script><script
src="/js/parking.2.72.5.js"></script></body></html>'
headers:
cache-control:
- no-cache
- no-store, must-revalidate
- post-check=0, pre-check=0
connection:
- keep-alive
content-length:
- '1561'
content-type:
- text/html; charset=UTF-8
date:
- Wed, 10 Nov 2021 09:33:38 GMT
expires:
- Thu, 01 Jan 1970 00:00:01 GMT
pragma:
- no-cache
server:
- openresty
set-cookie:
- parking_session=a46ac9e3-0f0a-6505-98cd-c2e59ce69528; expires=Wed, 10-Nov-2021