[Git][debian-gis-team/pycsw][master] 6 commits: New upstream version 2.6.2+dfsg
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Sat Feb 22 17:33:18 GMT 2025
Bas Couwenberg pushed to branch master at Debian GIS Project / pycsw
Commits:
22127109 by Bas Couwenberg at 2025-02-22T17:55:28+01:00
New upstream version 2.6.2+dfsg
- - - - -
0496c251 by Bas Couwenberg at 2025-02-22T17:55:31+01:00
Update upstream source from tag 'upstream/2.6.2+dfsg'
Update to upstream version '2.6.2+dfsg'
with Debian dir 4c213a9dd872b164f3912518b4bc7efbbdf774b0
- - - - -
d0e5572a by Bas Couwenberg at 2025-02-22T17:56:04+01:00
New upstream release.
- - - - -
90f2efe4 by Bas Couwenberg at 2025-02-22T18:05:53+01:00
Refresh patches.
- - - - -
34109285 by Bas Couwenberg at 2025-02-22T18:15:49+01:00
Update lintian overrides.
- - - - -
0b9eb970 by Bas Couwenberg at 2025-02-22T18:16:08+01:00
Set distribution to unstable.
- - - - -
29 changed files:
- + .github/workflows/main.yml
- Dockerfile
- VERSION.txt
- debian/changelog
- debian/patches/0002-Remove-externally-linked-files.patch
- debian/patches/tests_config_path.patch
- debian/patches/version-requirements.patch
- debian/source/lintian-overrides
- docs/administration.rst
- docs/opensearch.rst
- pycsw/core/admin.py
- pycsw/core/config.py
- pycsw/ogc/csw/cql.py
- pycsw/ogc/csw/csw2.py
- pycsw/ogc/csw/csw3.py
- pycsw/ogc/fes/fes2.py
- pycsw/opensearch.py
- pycsw/plugins/outputschemas/dif.py
- pycsw/server.py
- requirements-standalone.txt
- requirements.txt
- tests/functionaltests/suites/csw30/expected/get_002258f0-627f-457f-b2ad-025777c77ac8.xml
- tests/functionaltests/suites/csw30/expected/get_OpenSearch-description.xml
- + tests/functionaltests/suites/csw30/expected/post_GetRecords-anytext.xml
- + tests/functionaltests/suites/csw30/post/GetRecords-anytext.xml
- tests/functionaltests/suites/dif/expected/post_GetRecords-filter-bbox.xml
- tests/functionaltests/suites/opensearcheo/expected/get_opensearch-description-document.xml
- tests/functionaltests/test_suites_functional.py
- − tests/index.html
Changes:
=====================================
.github/workflows/main.yml
=====================================
@@ -0,0 +1,54 @@
+name: build ⚙️
+
+on:
+ push:
+ branches:
+ - master
+ paths-ignore:
+ - '**.md'
+ pull_request:
+ branches:
+ - master
+ paths-ignore:
+ - '**.md'
+ release:
+ types:
+ - released
+
+jobs:
+ main:
+ runs-on: ubuntu-20.04
+ strategy:
+ matrix:
+ include:
+ - python-version: 3.6
+ toxenv: "py36-sqlite"
+ - python-version: 3.7
+ toxenv: "py37-sqlite"
+ - python-version: 3.8
+ toxenv: "py38-sqlite"
+ - python-version: 3.9
+ toxenv: "py39-sqlite"
+ env:
+ TOXENV: ${{ matrix.toxenv }}
+ steps:
+ - uses: actions/checkout at v2
+ - uses: actions/setup-python at v2
+ name: Setup Python ${{ matrix.python-version }}
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install requirements 📦
+ run: |
+ sudo apt install -y libgeos-dev libpq-dev libxml2-dev libxslt1-dev libz-dev libexpat1
+ pip3 install -r requirements.txt
+ pip3 install -r requirements-standalone.txt
+ pip3 install -r requirements-dev.txt
+ pip3 install --upgrade https://github.com/geopython/OWSLib/archive/master.zip
+ pip3 install tox
+ echo "TOXENV => $TOXENV"
+ - name: run unit tests ⚙️
+ run: tox -- --exitfirst -m unit
+ - name: run integration tests ⚙️
+ run: tox -- --exitfirst -m functional -k 'not harvesting'
+ - name: build docs 🏗️
+ run: cd docs && make html
=====================================
Dockerfile
=====================================
@@ -39,8 +39,13 @@
FROM python:3.8-slim-buster
LABEL maintainer="massimods at met.no,aheimsbakk at met.no,tommkralidis at gmail.com"
+# Build arguments
+# add "--build-arg BUILD_DEV_IMAGE=true" to Docker build command when building with test/doc tools
+
+ARG BUILD_DEV_IMAGE="false"
+
RUN apt-get update && apt-get install --yes \
- ca-certificates \
+ ca-certificates libexpat1 \
&& rm -rf /var/lib/apt/lists/*
RUN adduser --uid 1000 --gecos '' --disabled-password pycsw
=====================================
VERSION.txt
=====================================
@@ -1 +1 @@
-2.6.1
+2.6.2
=====================================
debian/changelog
=====================================
@@ -1,9 +1,12 @@
-pycsw (2.6.1+dfsg-4) UNRELEASED; urgency=medium
+pycsw (2.6.2+dfsg-1) unstable; urgency=medium
+
+ * Team upload.
[ Angelos Tzotsos ]
* Update apache wsgi conf file to solve numpy import issue.
[ Bas Couwenberg ]
+ * New upstream release.
* Add Rules-Requires-Root to control file.
* Update lintian overrides.
* Bump Standards-Version to 4.7.0, no changes.
@@ -14,15 +17,10 @@ pycsw (2.6.1+dfsg-4) UNRELEASED; urgency=medium
* Enable Salsa CI.
* Remove unused rules.
* Switch to dh-sequence-*.
+ * Refresh patches.
+ * Update lintian overrides.
- -- Angelos Tzotsos <gcpp.kalxas at gmail.com> Thu, 23 Jun 2022 14:00:00 +0300
-
-pycsw (2.6.1+dfsg-3) UNRELEASED; urgency=medium
-
- * Team upload.
- * Bump Standards-Version to 4.6.1, no changes.
-
- -- Bas Couwenberg <sebastic at debian.org> Tue, 21 Jun 2022 07:18:03 +0200
+ -- Bas Couwenberg <sebastic at debian.org> Sat, 22 Feb 2025 18:15:52 +0100
pycsw (2.6.1+dfsg-2) unstable; urgency=medium
=====================================
debian/patches/0002-Remove-externally-linked-files.patch
=====================================
@@ -7,23 +7,34 @@ W3C and jquery
tests/index.html | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
---- a/tests/index.html
-+++ b/tests/index.html
-@@ -15,7 +15,7 @@
+--- a/tests/gen_html.py
++++ b/tests/gen_html.py
+@@ -49,7 +49,7 @@ print('''
border: 0px;
}
</style>
-- <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
+- <script type="text/javascript" src="http://code.jquery.com/jquery-%s.min.js"></script>
+ <script type="text/javascript" src="jquery/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.xml').change(function() {
-@@ -454,8 +454,6 @@
+@@ -84,7 +84,7 @@ print('''
+ });
+ </script>
+ </head>
+-''' % JQUERY_VERSION)
++'''
+
+ print('''
+ <body>
+@@ -150,8 +150,8 @@ print('''
</ul>
<hr/>
<footer>
- <a href="http://validator.w3.org/check?verbose=1&uri=referer" title="Valid HTML 5!"><img class="flat" src="http://www.w3.org/html/logo/downloads/HTML5_Badge_32.png" alt="Valid HTML 5!" height="32" width="32"/></a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS!"><img class="flat" src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS!" height="31" width="88"/></a>
++ <a href="http://validator.w3.org/check?verbose=1&uri=referer" title="Valid HTML 5!">Valid HTML 5!</a>
++ <a href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS!">Valid CSS!</a>
</footer>
</body>
</html>
=====================================
debian/patches/tests_config_path.patch
=====================================
@@ -2,8 +2,8 @@ Description: Fix config path for tests generator.
Author: Angelos Tzotsos <gcpp.kalxas at gmail.com>
Forwarded: not-needed
---- pycsw-2.6.0+dfsg.orig/tests/gen_html.py
-+++ pycsw-2.6.0+dfsg/tests/gen_html.py
+--- a/tests/gen_html.py
++++ b/tests/gen_html.py
@@ -61,7 +61,7 @@ print('''
dataType: 'text',
success: function(data) {
@@ -13,14 +13,3 @@ Forwarded: not-needed
}
});
}
---- pycsw-2.6.0+dfsg.orig/tests/index.html
-+++ pycsw-2.6.0+dfsg/tests/index.html
-@@ -27,7 +27,7 @@
- dataType: 'text',
- success: function(data) {
- $('.request').val(data);
-- $('.server').val('../csw.py?config=' + arr[0]);
-+ $('.server').val('../csw.py?config=/usr/share/pycsw/' + arr[0]);
- }
- });
- }
=====================================
debian/patches/version-requirements.patch
=====================================
@@ -24,3 +24,18 @@ Forwarded: not-needed
+pytest-timeout>=1.2.0
sphinx
twine
+--- a/requirements-standalone.txt
++++ b/requirements-standalone.txt
+@@ -1 +1 @@
+-SQLAlchemy<2.0.0
++SQLAlchemy
+--- a/requirements.txt
++++ b/requirements.txt
+@@ -1,6 +1,6 @@
+ geolinks
+ lxml
+-OWSLib<0.29
++OWSLib
+ pyproj
+ Shapely
+ xmltodict
=====================================
debian/source/lintian-overrides
=====================================
@@ -1,3 +1,6 @@
# False positive
source-is-missing [docs/_templates/indexsidebar.html]
+# https://github.com/geopython/pycsw/issues/1089
+uses-deprecated-python-stdlib cgi *
+
=====================================
docs/administration.rst
=====================================
@@ -21,7 +21,8 @@ pycsw supports the following databases:
- MySQL
.. note::
- The easiest and fastest way to deploy pycsw is to use SQLite3 as the backend.
+ The easiest and fastest way to deploy pycsw is to use SQLite3 as the backend. To use an SQLite
+ in-memory database, in the pycsw configuration, set `repository.database` to ``sqlite://``.
.. note::
PostgreSQL support includes support for PostGIS functions if enabled
=====================================
docs/opensearch.rst
=====================================
@@ -21,10 +21,12 @@ This will return the Description document which can then be `autodiscovered <htt
OpenSearch Temporal Queries
---------------------------
-By default, pycsw's OpenSearch temporal support will query the Dublin Core ``dc:date`` property. To
-enable temporal extent search, set ``profiles=apiso`` which will query the temporal extents of
-a metadata record (``apiso:TempExtent_begin`` and ``apiso:TempExtent_end``).
+By default, pycsw's OpenSearch temporal support will query the Dublin Core ``dc:date`` property as
+a time instant/single point in time. To enable temporal extent search, set ``profiles=apiso`` which
+will query the temporal extents of a metadata record (``apiso:TempExtent_begin`` and ``apiso:TempExtent_end``).
-At the HTTP API level, time is supported via one of ``time=t1/t2`` or ``start=t1&stop=t2``. If the
-``time`` parameter is present, it will override either/both of the ``start`` and ``stop`` parameters
-respectively.
+At the HTTP API level, time is supported via either ``time=t1/t2`` or ``start=t1&stop=t2``. If the
+``time`` parameter is present, it will override the ``start`` and ``stop`` parameters respectively.
+
+.. _`OGC OpenSearch Extension for Earth Observation`: http://docs.opengeospatial.org/is/13-026r9/13-026r9.html
+.. _`OGC OpenSearch Geo and Time Extensions 1.0`: http://www.opengeospatial.org/standards/opensearchgeo
=====================================
pycsw/core/admin.py
=====================================
@@ -50,8 +50,8 @@ def setup_db(database, table, home, create_sfsql_tables=True, create_plpythonu_f
from sqlalchemy.orm import create_session
LOGGER.info('Creating database %s', database)
- if database.startswith('sqlite'):
- dbtype, filepath = database.split('sqlite:///')
+ if database.startswith('sqlite:///'):
+ _, filepath = database.split('sqlite:///')
dirname = os.path.dirname(filepath)
if not os.path.exists(dirname):
raise RuntimeError('SQLite directory %s does not exist' % dirname)
=====================================
pycsw/core/config.py
=====================================
@@ -46,6 +46,7 @@ class StaticContext(object):
self.ogc_schemas_base = 'http://schemas.opengis.net'
self.parser = PARSER
+ self.server = None
self.languages = {
'en': 'english',
=====================================
pycsw/ogc/csw/cql.py
=====================================
@@ -33,11 +33,12 @@ import logging
from pycsw.core.etree import etree
from pycsw.core import util
from pycsw.ogc.fes.fes1 import MODEL as fes1_model
+from pycsw.ogc.fes.fes2 import MODEL as fes2_model
LOGGER = logging.getLogger(__name__)
-def cql2fes1(cql, namespaces):
+def cql2fes(cql, namespaces, fes_version='1.0'):
"""transforms Common Query Language (CQL) query into OGC fes1 syntax"""
filters = []
@@ -46,17 +47,29 @@ def cql2fes1(cql, namespaces):
LOGGER.debug('CQL: %s', cql)
+ if fes_version.startswith('1.0'):
+ element_or = 'ogc:Or'
+ element_and = 'ogc:And'
+ element_filter = 'ogc:Filter'
+ element_propertyname = 'ogc:PropertyName'
+ element_literal = 'ogc:Literal'
+ elif fes_version.startswith('2.0'):
+ element_or = 'fes20:Or'
+ element_and = 'fes20:And'
+ element_filter = 'fes20:Filter'
+ element_propertyname = 'fes20:Literal'
+
if ' or ' in cql:
- logical_op = etree.Element(util.nspath_eval('ogc:Or', namespaces))
+ logical_op = etree.Element(util.nspath_eval(element_or, namespaces))
tmp_list = cql.split(' or ')
elif ' OR ' in cql:
- logical_op = etree.Element(util.nspath_eval('ogc:Or', namespaces))
+ logical_op = etree.Element(util.nspath_eval(element_or, namespaces))
tmp_list = cql.split(' OR ')
elif ' and ' in cql:
- logical_op = etree.Element(util.nspath_eval('ogc:And', namespaces))
+ logical_op = etree.Element(util.nspath_eval(element_and, namespaces))
tmp_list = cql.split(' and ')
elif ' AND ' in cql:
- logical_op = etree.Element(util.nspath_eval('ogc:And', namespaces))
+ logical_op = etree.Element(util.nspath_eval(element_and, namespaces))
tmp_list = cql.split(' AND ')
if tmp_list:
@@ -65,9 +78,9 @@ def cql2fes1(cql, namespaces):
tmp_list.append(cql)
for t in tmp_list:
- filters.append(_parse_condition(t))
+ filters.append(_parse_condition(t, fes_version))
- root = etree.Element(util.nspath_eval('ogc:Filter', namespaces))
+ root = etree.Element(util.nspath_eval(element_filter, namespaces))
if logical_op is not None:
root.append(logical_op)
@@ -77,11 +90,11 @@ def cql2fes1(cql, namespaces):
etree.SubElement(
condition,
- util.nspath_eval('ogc:PropertyName', namespaces)).text = flt[1]
+ util.nspath_eval(element_propertyname, namespaces)).text = flt[1]
etree.SubElement(
condition,
- util.nspath_eval('ogc:Literal', namespaces)).text = flt[2]
+ util.nspath_eval(element_literal, namespaces)).text = flt[2]
if logical_op is not None:
logical_op.append(condition)
@@ -94,7 +107,7 @@ def cql2fes1(cql, namespaces):
return root
-def _parse_condition(condition):
+def _parse_condition(condition, fes_version='1.0'):
"""parses a single condition"""
LOGGER.debug('condition: %s', condition)
@@ -105,11 +118,16 @@ def _parse_condition(condition):
literal = literal.replace('"', '').replace('\'', '')
- for k, v in fes1_model['ComparisonOperators'].items():
+ if fes_version.startswith('1.0'):
+ fes_model = fes1_model
+ elif fes_version.startswith('2.0'):
+ fes_model = fes2_model
+
+ for k, v in fes_model['ComparisonOperators'].items():
if v['opvalue'] == operator:
- fes1_predicate = k
+ fes_predicate = k
- LOGGER.debug('parsed condition: %s %s %s', property_name, fes1_predicate,
+ LOGGER.debug('parsed condition: %s %s %s', property_name, fes_predicate,
literal)
- return (fes1_predicate, property_name, literal)
+ return (fes_predicate, property_name, literal)
=====================================
pycsw/ogc/csw/csw2.py
=====================================
@@ -37,7 +37,7 @@ from urllib.parse import quote, unquote
from io import StringIO
from pycsw.core.etree import etree
from pycsw import oaipmh, opensearch, sru
-from pycsw.ogc.csw.cql import cql2fes1
+from pycsw.ogc.csw.cql import cql2fes
from pycsw.plugins.profiles import profile as pprofile
import pycsw.plugins.outputschemas
from pycsw.core import config, log, metadata, util
@@ -739,7 +739,7 @@ class Csw2(object):
LOGGER.debug('CQL: %s', tmp)
self.parent.kvp['constraint'] = {}
self.parent.kvp['constraint']['type'] = 'filter'
- cql = cql2fes1(tmp, self.parent.context.namespaces)
+ cql = cql2fes(tmp, self.parent.context.namespaces, fes_version='1.0')
self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = fes1.parse(cql,
self.parent.repository.queryables['_all'], self.parent.repository.dbtype,
self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
@@ -1564,7 +1564,7 @@ class Csw2(object):
try:
LOGGER.info('Transforming CQL into OGC Filter')
query['type'] = 'filter'
- cql = cql2fes1(tmp.text, self.parent.context.namespaces)
+ cql = cql2fes(tmp.text, self.parent.context.namespaces, fes_version='1.0')
query['where'], query['values'] = fes1.parse(cql,
self.parent.repository.queryables['_all'], self.parent.repository.dbtype,
self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
=====================================
pycsw/ogc/csw/csw3.py
=====================================
@@ -35,13 +35,13 @@ from time import time
from urllib.parse import quote, unquote
from io import StringIO
from pycsw.core.etree import etree
-from pycsw.ogc.csw.cql import cql2fes1
+from pycsw.ogc.csw.cql import cql2fes
from pycsw import oaipmh, opensearch, sru
from pycsw.plugins.profiles import profile as pprofile
import pycsw.plugins.outputschemas
from pycsw.core import config, log, metadata, util
from pycsw.core.formats.fmt_json import xml2dict
-from pycsw.ogc.fes import fes2
+from pycsw.ogc.fes import fes1, fes2
import logging
LOGGER = logging.getLogger(__name__)
@@ -738,7 +738,7 @@ class Csw3(object):
self.parent.kvp['constraintlanguage'] = 'FILTER'
try:
tmp_filter = opensearch.kvp2filterxml(self.parent.kvp, self.parent.context,
- self.parent.profiles)
+ self.parent.profiles, fes_version='1.0')
except Exception as err:
return self.exceptionreport('InvalidParameterValue', 'bbox', str(err))
@@ -767,7 +767,7 @@ class Csw3(object):
LOGGER.debug('CQL: %s', tmp)
self.parent.kvp['constraint'] = {}
self.parent.kvp['constraint']['type'] = 'filter'
- cql = cql2fes1(tmp, self.parent.context.namespaces)
+ cql = cql2fes(tmp, self.parent.context.namespaces, fes_version='1.0')
self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = fes1.parse(cql,
self.parent.repository.queryables['_all'], self.parent.repository.dbtype,
self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
@@ -789,7 +789,7 @@ class Csw3(object):
self.parent.kvp['constraint'] = {}
self.parent.kvp['constraint']['type'] = 'filter'
self.parent.kvp['constraint']['where'], self.parent.kvp['constraint']['values'] = \
- fes2.parse(doc,
+ fes1.parse(doc,
self.parent.repository.queryables['_all'],
self.parent.repository.dbtype,
self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
@@ -1646,8 +1646,8 @@ class Csw3(object):
try:
LOGGER.info('Transforming CQL into OGC Filter')
query['type'] = 'filter'
- cql = cql2fes1(tmp.text, self.parent.context.namespaces)
- query['where'], query['values'] = fes1.parse(cql,
+ cql = cql2fes(tmp.text, self.parent.context.namespaces, fes_version='2.0')
+ query['where'], query['values'] = fes2.parse(cql,
self.parent.repository.queryables['_all'], self.parent.repository.dbtype,
self.parent.context.namespaces, self.parent.orm, self.parent.language['text'], self.parent.repository.fts)
query['_dict'] = xml2dict(etree.tostring(cql), self.parent.context.namespaces)
=====================================
pycsw/ogc/fes/fes2.py
=====================================
@@ -66,17 +66,17 @@ MODEL = {
'DWithin', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within']
},
'ComparisonOperators': {
- 'ogc:PropertyIsBetween': {'opname': 'PropertyIsBetween', 'opvalue': 'and'},
- 'ogc:PropertyIsEqualTo': {'opname': 'PropertyIsEqualTo', 'opvalue': '='},
- 'ogc:PropertyIsGreaterThan': {'opname': 'PropertyIsGreaterThan', 'opvalue': '>'},
- 'ogc:PropertyIsGreaterThanOrEqualTo': {
+ 'fes20:PropertyIsBetween': {'opname': 'PropertyIsBetween', 'opvalue': 'and'},
+ 'fes20:PropertyIsEqualTo': {'opname': 'PropertyIsEqualTo', 'opvalue': '='},
+ 'fes20:PropertyIsGreaterThan': {'opname': 'PropertyIsGreaterThan', 'opvalue': '>'},
+ 'fes20:PropertyIsGreaterThanOrEqualTo': {
'opname': 'PropertyIsGreaterThanOrEqualTo', 'opvalue': '>='},
- 'ogc:PropertyIsLessThan': {'opname': 'PropertyIsLessThan', 'opvalue': '<'},
- 'ogc:PropertyIsLessThanOrEqualTo': {
+ 'fes20:PropertyIsLessThan': {'opname': 'PropertyIsLessThan', 'opvalue': '<'},
+ 'fes20:PropertyIsLessThanOrEqualTo': {
'opname': 'PropertyIsLessThanOrEqualTo', 'opvalue': '<='},
- 'ogc:PropertyIsLike': {'opname': 'PropertyIsLike', 'opvalue': 'like'},
- 'ogc:PropertyIsNotEqualTo': {'opname': 'PropertyIsNotEqualTo', 'opvalue': '!='},
- 'ogc:PropertyIsNull': {'opname': 'PropertyIsNull', 'opvalue': 'is null'},
+ 'fes20:PropertyIsLike': {'opname': 'PropertyIsLike', 'opvalue': 'like'},
+ 'fes20:PropertyIsNotEqualTo': {'opname': 'PropertyIsNotEqualTo', 'opvalue': '!='},
+ 'fes20:PropertyIsNull': {'opname': 'PropertyIsNull', 'opvalue': 'is null'},
},
'Functions': {
'length': {'returns': 'xs:string'},
@@ -98,7 +98,7 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
boq = None
is_pg = dbtype.startswith('postgresql')
- tmp = element.xpath('ogc:And|ogc:Or|ogc:Not', namespaces=nsmap)
+ tmp = element.xpath('fes20:And|fes20:Or|fes20:Not', namespaces=nsmap)
if len(tmp) > 0: # this is binary logic query
element_name = etree.QName(tmp[0]).localname
boq = ' %s ' % element_name.lower()
@@ -130,32 +130,32 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
singlechar = '_'
if (elem.xpath('child::*')[0].tag ==
- util.nspath_eval('ogc:Function', nsmap)):
- LOGGER.debug('ogc:Function detected')
+ util.nspath_eval('fes20:Function', nsmap)):
+ LOGGER.debug('fes20:Function detected')
if (elem.xpath('child::*')[0].attrib['name'] not in
MODEL['Functions']):
- raise RuntimeError('Invalid ogc:Function: %s' %
+ raise RuntimeError('Invalid fes20:Function: %s' %
(elem.xpath('child::*')[0].attrib['name']))
fname = elem.xpath('child::*')[0].attrib['name']
try:
- LOGGER.debug('Testing existence of ogc:PropertyName')
- pname = queryables[elem.find(util.nspath_eval('ogc:Function/ogc:PropertyName', nsmap)).text]['dbcol']
+ LOGGER.debug('Testing existence of fes20:ValueReference')
+ pname = queryables[elem.find(util.nspath_eval('fes20:Function/fes20:ValueReference', nsmap)).text]['dbcol']
except Exception as err:
- raise RuntimeError('Invalid PropertyName: %s. %s' % (elem.find(util.nspath_eval('ogc:Function/ogc:PropertyName', nsmap)).text, str(err)))
+ raise RuntimeError('Invalid PropertyName: %s. %s' % (elem.find(util.nspath_eval('fes20:Function/fes20:ValueReference', nsmap)).text, str(err)))
else:
try:
- LOGGER.debug('Testing existence of ogc:PropertyName')
+ LOGGER.debug('Testing existence of fes20:ValueReference')
pname = queryables[elem.find(
- util.nspath_eval('ogc:PropertyName', nsmap)).text]['dbcol']
+ util.nspath_eval('fes20:ValueReference', nsmap)).text]['dbcol']
except Exception as err:
raise RuntimeError('Invalid PropertyName: %s. %s' %
- (elem.find(util.nspath_eval('ogc:PropertyName',
+ (elem.find(util.nspath_eval('fes20:ValueReference',
nsmap)).text, str(err)))
- if (elem.tag != util.nspath_eval('ogc:PropertyIsBetween', nsmap)):
- if elem.tag in [util.nspath_eval('ogc:%s' % n, nsmap) for n in
+ if (elem.tag != util.nspath_eval('fes20:PropertyIsBetween', nsmap)):
+ if elem.tag in [util.nspath_eval('fes20:%s' % n, nsmap) for n in
MODEL['SpatialOperators']['values']]:
boolean_true = '\'true\''
boolean_false = '\'false\''
@@ -165,7 +165,7 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
return "%s = %s" % (_get_spatial_operator(queryables['pycsw:BoundingBox'], elem, dbtype, nsmap), boolean_true)
else:
- pval = elem.find(util.nspath_eval('ogc:Literal', nsmap)).text
+ pval = elem.find(util.nspath_eval('fes20:Literal', nsmap)).text
com_op = _get_comparison_operator(elem)
LOGGER.debug('Comparison operator: %s', com_op)
@@ -180,13 +180,13 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
pname == anytext):
com_op = 'ilike' if is_pg else 'like'
- if (elem.tag == util.nspath_eval('ogc:PropertyIsBetween', nsmap)):
+ if (elem.tag == util.nspath_eval('fes20:PropertyIsBetween', nsmap)):
com_op = 'between'
lower_boundary = elem.find(
- util.nspath_eval('ogc:LowerBoundary/ogc:Literal',
+ util.nspath_eval('fes20:LowerBoundary/fes20:Literal',
nsmap)).text
upper_boundary = elem.find(
- util.nspath_eval('ogc:UpperBoundary/ogc:Literal',
+ util.nspath_eval('fes20:UpperBoundary/fes20:Literal',
nsmap)).text
expression = "%s %s %s and %s" % \
(pname, com_op, assign_param(), assign_param())
@@ -251,28 +251,28 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
boolean_true = 'true'
boolean_false = 'false'
- if child.tag == util.nspath_eval('ogc:Not', nsmap):
- LOGGER.debug('ogc:Not query detected')
+ if child.tag == util.nspath_eval('fes20:Not', nsmap):
+ LOGGER.debug('fes20:Not query detected')
child_not = child.xpath('child::*')[0]
if child_not.tag in \
- [util.nspath_eval('ogc:%s' % n, nsmap) for n in
+ [util.nspath_eval('fes20:%s' % n, nsmap) for n in
MODEL['SpatialOperators']['values']]:
- LOGGER.debug('ogc:Not / spatial operator detected: %s', child.tag)
+ LOGGER.debug('fes20:Not / spatial operator detected: %s', child.tag)
queries.append("%s = %s" %
(_get_spatial_operator(
queryables['pycsw:BoundingBox'],
child.xpath('child::*')[0], dbtype, nsmap),
boolean_false))
else:
- LOGGER.debug('ogc:Not / comparison operator detected: %s', child.tag)
+ LOGGER.debug('fes20:Not / comparison operator detected: %s', child.tag)
queries.append('not %s' % _get_comparison_expression(child_not))
elif child.tag in \
- [util.nspath_eval('ogc:%s' % n, nsmap) for n in
+ [util.nspath_eval('fes20:%s' % n, nsmap) for n in
MODEL['SpatialOperators']['values']]:
LOGGER.debug('spatial operator detected: %s', child.tag)
if boq is not None and boq == ' not ':
- # for ogc:Not spatial queries in PostGIS we must explictly
+ # for fes20:Not spatial queries in PostGIS we must explictly
# test that pycsw:BoundingBox is null as well
# TODO: Do we need the same for 'postgresql+postgis+native'???
if dbtype == 'postgresql+postgis+wkt':
@@ -293,8 +293,8 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
queryables['pycsw:BoundingBox'],
child, dbtype, nsmap), boolean_true))
- elif child.tag == util.nspath_eval('ogc:FeatureId', nsmap):
- LOGGER.debug('ogc:FeatureId filter detected')
+ elif child.tag == util.nspath_eval('fes20:FeatureId', nsmap):
+ LOGGER.debug('fes20:FeatureId filter detected')
queries.append("%s = %s" % (queryables['pycsw:Identifier'], assign_param()))
values.append(child.attrib.get('fid'))
else: # comparison operator
@@ -317,18 +317,18 @@ def parse(element, queryables, dbtype, nsmap, orm='sqlalchemy', language='englis
def _get_spatial_operator(geomattr, element, dbtype, nsmap, postgis_geometry_column='wkb_geometry'):
"""return the spatial predicate function"""
- property_name = element.find(util.nspath_eval('ogc:PropertyName', nsmap))
- distance = element.find(util.nspath_eval('ogc:Distance', nsmap))
+ property_name = element.find(util.nspath_eval('fes20:ValueReference', nsmap))
+ distance = element.find(util.nspath_eval('fes20:Distance', nsmap))
distance = 'false' if distance is None else distance.text
LOGGER.debug('Scanning for spatial property name')
if property_name is None:
- raise RuntimeError('Missing ogc:PropertyName in spatial filter')
+ raise RuntimeError('Missing fes20:ValueReference in spatial filter')
if (property_name.text.find('BoundingBox') == -1 and
property_name.text.find('Envelope') == -1):
- raise RuntimeError('Invalid ogc:PropertyName in spatial filter: %s' %
+ raise RuntimeError('Invalid fes20:ValueReference in spatial filter: %s' %
property_name.text)
geometry = gml3.Geometry(element, nsmap)
@@ -406,10 +406,10 @@ def _get_comparison_operator(element):
"""return the SQL operator based on Filter query"""
element_name = etree.QName(element).localname
- return MODEL['ComparisonOperators']['ogc:%s' % element_name]['opvalue']
+ return MODEL['ComparisonOperators']['fes20:%s' % element_name]['opvalue']
def set_spatial_ranking(geometry):
- """Given that we have a spatial query in ogc:Filter we check the type of geometry
+ """Given that we have a spatial query in fes20:Filter we check the type of geometry
and set the ranking variables"""
if util.ranking_enabled:
=====================================
pycsw/opensearch.py
=====================================
@@ -31,11 +31,31 @@
# =================================================================
import logging
+from urllib.parse import urlencode
+
from pycsw.core import util
from pycsw.core.etree import etree
LOGGER = logging.getLogger(__name__)
+QUERY_PARAMETERS = [
+ 'q',
+ 'bbox',
+ 'time',
+ 'eo:processinglevel',
+ 'eo:producttype',
+ 'eo:platform',
+ 'eo:instrument',
+ 'eo:sensortype',
+ 'eo:cloudcover',
+ 'eo:snowcover',
+ 'eo:spectralrange',
+ 'eo:bands',
+ 'eo:orbitnumber',
+ 'eo:orbitdirection'
+]
+
+
class OpenSearch(object):
"""OpenSearch wrapper class"""
@@ -44,6 +64,7 @@ class OpenSearch(object):
self.namespaces = {
'atom': 'http://www.w3.org/2005/Atom',
+ 'eo': 'http://a9.com/-/opensearch/extensions/eo/1.0/',
'geo': 'http://a9.com/-/opensearch/extensions/geo/1.0/',
'os': 'http://a9.com/-/spec/opensearch/1.1/',
'time': 'http://a9.com/-/opensearch/extensions/time/1.0/'
@@ -52,6 +73,7 @@ class OpenSearch(object):
self.context = context
self.context.namespaces.update(self.namespaces)
self.context.keep_ns_prefixes.append('geo')
+ self.context.keep_ns_prefixes.append('eo')
self.context.keep_ns_prefixes.append('time')
def response_csw2opensearch(self, element, cfg):
@@ -119,7 +141,39 @@ class OpenSearch(object):
node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces))
node1.set('type', 'application/atom+xml')
node1.set('method', 'get')
- node1.set('template', '%smode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}' % self.bind_url)
+
+ kvps = {
+ 'mode': 'opensearch',
+ 'service': 'CSW',
+ 'version': '2.0.2',
+ 'request': 'GetRecords',
+ 'elementsetname': 'full',
+ 'typenames': 'csw:Record',
+ 'resulttype': 'results',
+ 'q': '{searchTerms?}',
+ 'bbox': '{geo:box?}',
+ 'time': '{time:start?}/{time:end?}',
+ 'start': '{time:start?}',
+ 'stop': '{time:end?}',
+ 'startposition': '{startIndex?}',
+ 'maxrecords': '{count?}',
+ 'eo:cloudCover': '{eo:cloudCover?}',
+ 'eo:instrument': '{eo:instrument?}',
+ 'eo:orbitDirection': '{eo:orbitDirection?}',
+ 'eo:orbitNumber': '{eo:orbitNumber?}',
+ 'eo:platform': '{eo:platform?}',
+ 'eo:processingLevel': '{eo:processingLevel?}',
+ 'eo:productType': '{eo:productType?}',
+ 'eo:sensorType': '{eo:sensorType?}',
+ 'eo:snowCover': '{eo:snowCover?}',
+ 'eo:spectralRange': '{eo:spectralRange?}'
+ }
+
+ node1.set('template', '%s%s' % (self.bind_url,
+ '&'.join('{}={}'.format(*i) for i in kvps.items())))
+
+
+ #node1.set('template', '%smode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}' % self.bind_url)
node1 = etree.SubElement(node, util.nspath_eval('os:Image', self.namespaces))
node1.set('type', 'image/vnd.microsoft.icon')
@@ -190,12 +244,47 @@ class OpenSearch(object):
# Requirement-022
node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces))
node1.set('type', 'application/xml')
- node1.set('template', '%sservice=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}' % self.bind_url)
+
+ kvps = {
+ 'service': 'CSW',
+ 'version': '3.0.0',
+ 'request': 'GetRecords',
+ 'elementsetname': 'full',
+ 'typenames': 'csw:Record',
+ 'outputformat': 'application/xml',
+ 'outputschema': 'http://www.opengis.net/cat/csw/3.0',
+ 'recordids': '{geo:uid?}',
+ 'q': '{searchTerms?}',
+ 'bbox': '{geo:box?}',
+ 'time': '{time:start?}/{time:end?}',
+ 'start': '{time:start?}',
+ 'stop': '{time:end?}',
+ 'startposition': '{startIndex?}',
+ 'maxrecords': '{count?}',
+ 'eo:cloudCover': '{eo:cloudCover?}',
+ 'eo:instrument': '{eo:instrument?}',
+ 'eo:orbitDirection': '{eo:orbitDirection?}',
+ 'eo:orbitNumber': '{eo:orbitNumber?}',
+ 'eo:platform': '{eo:platform?}',
+ 'eo:processingLevel': '{eo:processingLevel?}',
+ 'eo:productType': '{eo:productType?}',
+ 'eo:sensorType': '{eo:sensorType?}',
+ 'eo:snowCover': '{eo:snowCover?}',
+ 'eo:spectralRange': '{eo:spectralRange?}'
+ }
+
+ node1.set('template', '%s%s' % (self.bind_url,
+ '&'.join('{}={}'.format(*i) for i in kvps.items())))
# Requirement-023
node1 = etree.SubElement(node, util.nspath_eval('os:Url', self.namespaces))
node1.set('type', 'application/atom+xml')
- node1.set('template', '%smode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/atom%%2Bxml&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}' % self.bind_url)
+
+ kvps['outputformat'] = 'application/atom%%2Bxml'
+ kvps['mode'] = 'opensearch'
+
+ node1.set('template', '%s%s' % (self.bind_url,
+ '&'.join('{}={}'.format(*i) for i in kvps.items())))
node1 = etree.SubElement(node, util.nspath_eval('os:Image', self.namespaces))
node1.set('type', 'image/vnd.microsoft.icon')
@@ -234,7 +323,7 @@ class OpenSearch(object):
return node
-def kvp2filterxml(kvp, context, profiles):
+def kvp2filterxml(kvp, context, profiles, fes_version='1.0'):
''' transform kvp to filter XML string '''
bbox_element = None
@@ -242,6 +331,17 @@ def kvp2filterxml(kvp, context, profiles):
anytext_elements = []
query_temporal_by_iso = False
+ eo_bands_element = None
+ eo_cloudcover_element = None
+ eo_instrument_element = None
+ eo_orbitdirection_element = None
+ eo_orbitnumber_element = None
+ eo_platform_element = None
+ eo_processinglevel_element = None
+ eo_producttype_element = None
+ eo_sensortype_element = None
+ eo_snowcover_element = None
+
if profiles is not None and 'plugins' in profiles and 'APISO' in profiles['plugins']:
query_temporal_by_iso = True
@@ -435,6 +535,94 @@ def kvp2filterxml(kvp, context, profiles):
errortext = 'Exception: OpenSearch time not valid: %s.' % str(kvp['time'])
LOGGER.error(errortext)
+ LOGGER.debug('Processing EO queryables')
+ if 'eo:producttype' in kvp:
+ par_count += 1
+ eo_producttype_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces),
+ matchCase='false', wildCard='*', singleChar='?', escapeChar='\\')
+ etree.SubElement(eo_producttype_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject'
+ etree.SubElement(eo_producttype_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = '*eo:productType:%s*' % kvp['eo:producttype']
+
+ if 'eo:platform' in kvp:
+ par_count += 1
+ eo_platform_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces))
+ etree.SubElement(eo_platform_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Platform'
+ etree.SubElement(eo_platform_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = kvp['eo:platform']
+
+ if 'eo:processinglevel' in kvp:
+ par_count += 1
+ eo_processinglevel_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces),
+ matchCase='false', wildCard='*', singleChar='?', escapeChar='\\')
+ etree.SubElement(eo_processinglevel_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject'
+ etree.SubElement(eo_processinglevel_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = '*eo:processingLevel:%s*' % kvp['eo:processinglevel']
+
+ if 'eo:instrument' in kvp:
+ par_count += 1
+ eo_instrument_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces))
+ etree.SubElement(eo_instrument_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Instrument'
+ etree.SubElement(eo_instrument_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = kvp['eo:instrument']
+
+ if 'eo:sensortype' in kvp:
+ par_count += 1
+ eo_sensortype_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces))
+ etree.SubElement(eo_sensortype_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:SensorType'
+ etree.SubElement(eo_sensortype_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = kvp['eo:sensortype']
+
+ if 'eo:cloudcover' in kvp:
+ par_count += 1
+ eo_cloudcover_element = etree.Element(util.nspath_eval('ogc:PropertyIsEqualTo', context.namespaces))
+ etree.SubElement(eo_cloudcover_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:CloudCover'
+ etree.SubElement(eo_cloudcover_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = kvp['eo:cloudcover']
+
+ if 'eo:snowcover' in kvp:
+ par_count += 1
+ eo_snowcover_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces),
+ matchCase='false', wildCard='*', singleChar='?', escapeChar='\\')
+ etree.SubElement(eo_snowcover_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject'
+ etree.SubElement(eo_snowcover_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = '*eo:snowCover:%s*' % kvp['eo:snowcover']
+
+ if 'eo:spectralrange' in kvp:
+ par_count += 1
+ eo_bands_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces),
+ matchCase='false', wildCard='*', singleChar='?', escapeChar='\\')
+ etree.SubElement(eo_bands_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Bands'
+ etree.SubElement(eo_bands_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = '*%s*' % kvp['eo:spectralrange']
+
+ if 'eo:orbitnumber' in kvp:
+ par_count += 1
+ eo_orbitnumber_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces),
+ matchCase='false', wildCard='*', singleChar='?', escapeChar='\\')
+ etree.SubElement(eo_orbitnumber_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject'
+ etree.SubElement(eo_orbitnumber_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = '*eo:orbitNumber:%s*' % kvp['eo:orbitnumber']
+
+ if 'eo:orbitdirection' in kvp:
+ par_count += 1
+ eo_orbitdirection_element = etree.Element(util.nspath_eval('ogc:PropertyIsLike', context.namespaces),
+ matchCase='false', wildCard='*', singleChar='?', escapeChar='\\')
+ etree.SubElement(eo_orbitdirection_element,
+ util.nspath_eval('ogc:PropertyName', context.namespaces)).text = 'apiso:Subject'
+ etree.SubElement(eo_orbitdirection_element, util.nspath_eval(
+ 'ogc:Literal', context.namespaces)).text = '*eo:orbitDirection:%s*' % kvp['eo:orbitdirection']
+
+ LOGGER.info('Query parameter count: %s', par_count)
if par_count == 0:
return ''
elif par_count == 1:
@@ -449,7 +637,7 @@ def kvp2filterxml(kvp, context, profiles):
elif anytext_elements:
LOGGER.debug('Adding anytext')
root.extend(anytext_elements)
- elif (par_count > 1):
+ elif par_count > 1:
LOGGER.debug('ogc:And query (%d predicates)', par_count)
# Since more than 1 parameter, append the AND logical operator
logical_and = etree.Element(util.nspath_eval('ogc:And',
@@ -462,6 +650,19 @@ def kvp2filterxml(kvp, context, profiles):
logical_and.extend(anytext_elements)
root.append(logical_and)
+ if par_count == 1:
+ node_to_append = root
+ elif par_count > 1:
+ node_to_append = logical_and
+
+ LOGGER.debug('Adding EO queryables')
+ for eo_element in [eo_producttype_element, eo_platform_element, eo_instrument_element,
+ eo_sensortype_element, eo_cloudcover_element, eo_snowcover_element,
+ eo_bands_element, eo_orbitnumber_element, eo_orbitdirection_element,
+ eo_processinglevel_element]:
+ if eo_element is not None:
+ node_to_append.append(eo_element)
+
# Render etree to string XML
LOGGER.debug(etree.tostring(root, encoding='unicode'))
return etree.tostring(root, encoding='unicode')
=====================================
pycsw/plugins/outputschemas/dif.py
=====================================
@@ -92,16 +92,34 @@ def write_record(result, esn, context, url=None):
val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Format'])
etree.SubElement(citation, util.nspath_eval('dif:Data_Presentation_Form', NAMESPACES)).text = val
+ # keywords dif:Parameters
+ val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords'])
+ if val:
+ kws = val.split(',')
+ parameters_indexes = []
+ for index, kw in enumerate(kws):
+ if "Earth Science".lower() in kw.lower() and len(kw.split(">")) >= 2:
+ values = kw.upper().split(">")
+ parameters = etree.SubElement(node, util.nspath_eval('dif:Parameters', NAMESPACES)) # .text = kw
+ etree.SubElement(parameters, util.nspath_eval('dif:Category', NAMESPACES)).text = values[0].strip().upper()
+ etree.SubElement(parameters, util.nspath_eval('dif:Topic', NAMESPACES)).text = values[1].strip().upper()
+ etree.SubElement(parameters, util.nspath_eval('dif:Term', NAMESPACES)).text = values[2].strip().upper()
+ for i, v in enumerate(values[3:]):
+ etree.SubElement(parameters, util.nspath_eval(f'dif:Variable_Level_{i + 1}', NAMESPACES)).text = v.strip()
+ parameters_indexes.append(index)
+ # kws.pop(index)
+
# iso topic category
val = util.getqattr(result, context.md_core_model['mappings']['pycsw:TopicCategory'])
etree.SubElement(node, util.nspath_eval('dif:ISO_Topic_Category', NAMESPACES)).text = val
- # keywords
+ # keywords dif:keywords
val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Keywords'])
-
if val:
- for kw in val.split(','):
- etree.SubElement(node, util.nspath_eval('dif:Keyword', NAMESPACES)).text = kw
+ kws = val.split(',')
+ kws = [i for j, i in enumerate(kws) if j not in parameters_indexes]
+ for index, kw in enumerate(kws):
+ etree.SubElement(node, util.nspath_eval('dif:Keyword', NAMESPACES)).text = kw.strip()
# temporal
temporal = etree.SubElement(node, util.nspath_eval('dif:Temporal_Coverage', NAMESPACES))
@@ -134,31 +152,47 @@ def write_record(result, esn, context, url=None):
val = ''
etree.SubElement(node, util.nspath_eval('dif:Summary', NAMESPACES)).text = val
- # date
- val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CreationDate'])
- etree.SubElement(node, util.nspath_eval('dif:DIF_Creation_Date', NAMESPACES)).text = val
-
# URL
val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Relation'])
- url = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES))
- etree.SubElement(url, util.nspath_eval('dif:URL', NAMESPACES)).text = val
+ if val:
+ url = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES))
+ etree.SubElement(url, util.nspath_eval('dif:URL', NAMESPACES)).text = val
rlinks = util.getqattr(result, context.md_core_model['mappings']['pycsw:Links'])
if rlinks:
- for link in rlinks.split('^'):
- linkset = link.split(',')
-
+ for link in util.jsonify_links(rlinks):
url2 = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES))
urltype = etree.SubElement(url2, util.nspath_eval('dif:URL_Content_Type', NAMESPACES))
- etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = linkset[2]
-
- etree.SubElement(url2, util.nspath_eval('dif:URL', NAMESPACES)).text = linkset[-1]
- etree.SubElement(url2, util.nspath_eval('dif:Description', NAMESPACES)).text = linkset[1]
+ if link['protocol'] == 'download':
+ etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET DATA'
+ elif link['protocol'] == 'OPENDAP:OPENDAP':
+ etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET DATA'
+ etree.SubElement(urltype, util.nspath_eval('dif:Subtype', NAMESPACES)).text = 'OPENDAP DATA (DODS)'
+ elif link['protocol'] == 'OGC:WMS':
+ etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET SERVICE'
+ etree.SubElement(urltype, util.nspath_eval('dif:Subtype', NAMESPACES)).text = 'GET WEB MAP SERVICE (WMS)'
+ else:
+ etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'GET DATA'
+
+ etree.SubElement(url2, util.nspath_eval('dif:URL', NAMESPACES)).text = link['url']
+ if link['description']:
+ etree.SubElement(url2, util.nspath_eval('dif:Description', NAMESPACES)).text = link['description']
+
+ val = util.getqattr(result, context.md_core_model['mappings']['pycsw:Source'])
+ if val:
+ url2 = etree.SubElement(node, util.nspath_eval('dif:Related_URL', NAMESPACES))
+ urltype = etree.SubElement(url2, util.nspath_eval('dif:URL_Content_Type', NAMESPACES))
+ etree.SubElement(urltype, util.nspath_eval('dif:Type', NAMESPACES)).text = 'DATASET LANDING PAGE'
+ etree.SubElement(url2, util.nspath_eval('dif:URL', NAMESPACES)).text = val
etree.SubElement(node, util.nspath_eval('dif:Metadata_Name', NAMESPACES)).text = 'CEOS IDN DIF'
etree.SubElement(node, util.nspath_eval('dif:Metadata_Version', NAMESPACES)).text = '9.7'
+ # date
+ val = util.getqattr(result, context.md_core_model['mappings']['pycsw:CreationDate'])
+ etree.SubElement(node, util.nspath_eval('dif:DIF_Creation_Date', NAMESPACES)).text = val
+
return node
def write_extent(bbox, nsmap):
=====================================
pycsw/server.py
=====================================
@@ -141,6 +141,8 @@ class Csw(object):
self.context.pycsw_home = self.config.get('server', 'home')
self.context.url = self.config.get('server', 'url')
+ self.context.server = self
+
log.setup_logger(self.config)
LOGGER.info('running configuration %s', rtconfig)
=====================================
requirements-standalone.txt
=====================================
@@ -1 +1 @@
-SQLAlchemy
+SQLAlchemy<2.0.0
=====================================
requirements.txt
=====================================
@@ -1,6 +1,6 @@
geolinks
lxml
-OWSLib
+OWSLib<0.29
pyproj
Shapely
xmltodict
=====================================
tests/functionaltests/suites/csw30/expected/get_002258f0-627f-457f-b2ad-025777c77ac8.xml
=====================================
@@ -5,8 +5,8 @@
<os:LongName>pycsw Geospatial Catalogue</os:LongName>
<os:Description>pycsw is an OGC CSW server implementation written in Python</os:Description>
<os:Tags>catalogue discovery</os:Tags>
- <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}"/>
- <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/atom%2Bxml&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}"/>
+ <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&recordids={geo:uid?}&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}&eo:cloudCover={eo:cloudCover?}&eo:instrument={eo:instrument?}&eo:orbitDirection={eo:orbitDirection?}&eo:orbitNumber={eo:orbitNumber?}&eo:platform={eo:platform?}&eo:processingLevel={eo:processingLevel?}&eo:productType={eo:productType?}&eo:sensorType={eo:sensorType?}&eo:snowCover={eo:snowCover?}&eo:spectralRange={eo:spectralRange?}"/>
+ <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&outputformat=application/atom%%2Bxml&outputschema=http://www.opengis.net/cat/csw/3.0&recordids={geo:uid?}&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}&eo:cloudCover={eo:cloudCover?}&eo:instrument={eo:instrument?}&eo:orbitDirection={eo:orbitDirection?}&eo:orbitNumber={eo:orbitNumber?}&eo:platform={eo:platform?}&eo:processingLevel={eo:processingLevel?}&eo:productType={eo:productType?}&eo:sensorType={eo:sensorType?}&eo:snowCover={eo:snowCover?}&eo:spectralRange={eo:spectralRange?}&mode=opensearch"/>
<os:Image type="image/vnd.microsoft.icon" width="16" height="16">https://pycsw.org/img/favicon.ico</os:Image>
<os:Query role="example" searchTerms="cat"/>
<os:Developer>Kralidis, Tom</os:Developer>
=====================================
tests/functionaltests/suites/csw30/expected/get_OpenSearch-description.xml
=====================================
@@ -5,8 +5,8 @@
<os:LongName>pycsw Geospatial Catalogue</os:LongName>
<os:Description>pycsw is an OGC CSW server implementation written in Python</os:Description>
<os:Tags>catalogue discovery</os:Tags>
- <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}"/>
- <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/atom%2Bxml&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}"/>
+ <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&recordids={geo:uid?}&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}&eo:cloudCover={eo:cloudCover?}&eo:instrument={eo:instrument?}&eo:orbitDirection={eo:orbitDirection?}&eo:orbitNumber={eo:orbitNumber?}&eo:platform={eo:platform?}&eo:processingLevel={eo:processingLevel?}&eo:productType={eo:productType?}&eo:sensorType={eo:sensorType?}&eo:snowCover={eo:snowCover?}&eo:spectralRange={eo:spectralRange?}"/>
+ <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/csw30/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&outputformat=application/atom%%2Bxml&outputschema=http://www.opengis.net/cat/csw/3.0&recordids={geo:uid?}&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}&eo:cloudCover={eo:cloudCover?}&eo:instrument={eo:instrument?}&eo:orbitDirection={eo:orbitDirection?}&eo:orbitNumber={eo:orbitNumber?}&eo:platform={eo:platform?}&eo:processingLevel={eo:processingLevel?}&eo:productType={eo:productType?}&eo:sensorType={eo:sensorType?}&eo:snowCover={eo:snowCover?}&eo:spectralRange={eo:spectralRange?}&mode=opensearch"/>
<os:Image type="image/vnd.microsoft.icon" width="16" height="16">https://pycsw.org/img/favicon.ico</os:Image>
<os:Query role="example" searchTerms="cat"/>
<os:Developer>Kralidis, Tom</os:Developer>
=====================================
tests/functionaltests/suites/csw30/expected/post_GetRecords-anytext.xml
=====================================
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- PYCSW_VERSION -->
+<csw30:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dct="http://purl.org/dc/terms/" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gml="http://www.opengis.net/gml" xmlns:ows="http://www.opengis.net/ows" xmlns:ows20="http://www.opengis.net/ows/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0.0" xsi:schemaLocation="http://www.opengis.net/cat/csw/3.0 http://schemas.opengis.net/cat/csw/3.0/cswGetRecordsResponse.xsd">
+ <csw30:SearchStatus timestamp="PYCSW_TIMESTAMP"/>
+ <csw30:SearchResults numberOfRecordsMatched="5" numberOfRecordsReturned="5" nextRecord="0" recordSchema="http://www.opengis.net/cat/csw/3.0" expires="PYCSW_EXPIRES" status="subset" elementSet="full" elapsedTime="PYCSW_ELAPSED_TIME">
+ <csw30:Record>
+ <dc:identifier>urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f</dc:identifier>
+ <dc:title>Lorem ipsum</dc:title>
+ <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+ <dc:subject>Tourism--Greece</dc:subject>
+ <dc:format>image/svg+xml</dc:format>
+ <dct:abstract>Quisque lacus diam, placerat mollis, pharetra in, commodo sed, augue. Duis iaculis arcu vel arcu.</dct:abstract>
+ </csw30:Record>
+ <csw30:Record>
+ <dc:identifier>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:identifier>
+ <dc:title></dc:title>
+ <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+ <dc:subject>Physiography-Landforms</dc:subject>
+ <dct:abstract>Donec scelerisque pede ut nisl luctus accumsan. Quisque ultrices, lorem eget feugiat fringilla, lorem dui porttitor ante, cursus ultrices magna odio eu neque.</dct:abstract>
+ </csw30:Record>
+ <csw30:Record>
+ <dc:identifier>urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63</dc:identifier>
+ <dc:title>Mauris sed neque</dc:title>
+ <dc:type>http://purl.org/dc/dcmitype/Dataset</dc:type>
+ <dc:subject>Vegetation-Cropland</dc:subject>
+ <dct:abstract>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dct:abstract>
+ <dc:date>2006-03-26</dc:date>
+ <ows20:BoundingBox crs="http://www.opengis.net/def/crs/EPSG/0/4326" dimensions="2">
+ <ows20:LowerCorner>47.59 -4.1</ows20:LowerCorner>
+ <ows20:UpperCorner>51.22 0.89</ows20:UpperCorner>
+ </ows20:BoundingBox>
+ </csw30:Record>
+ <csw30:Record>
+ <dc:identifier>urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2</dc:identifier>
+ <dc:title>Lorem ipsum dolor sit amet</dc:title>
+ <dc:type>http://purl.org/dc/dcmitype/Image</dc:type>
+ <dc:format>image/jpeg</dc:format>
+ </csw30:Record>
+ <csw30:Record>
+ <dc:identifier>urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a</dc:identifier>
+ <dc:title></dc:title>
+ <dc:type>http://purl.org/dc/dcmitype/Service</dc:type>
+ <dc:subject>Physiography</dc:subject>
+ <dc:relation>urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357</dc:relation>
+ <dct:abstract>Suspendisse accumsan molestie lorem. Nullam velit turpis, mattis ut, varius bibendum, laoreet non, quam.</dct:abstract>
+ </csw30:Record>
+ </csw30:SearchResults>
+</csw30:GetRecordsResponse>
=====================================
tests/functionaltests/suites/csw30/post/GetRecords-anytext.xml
=====================================
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<csw30:GetRecords xmlns:csw30="http://www.opengis.net/cat/csw/3.0" xmlns:fes="http://www.opengis.net/fes/2.0" version="3.0.0" service="CSW" startPosition="1" maxRecords="10">
+ <csw30:Query typeNames="csw30:Record" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml">
+ <csw30:ElementSetName>full</csw30:ElementSetName>
+ <csw30:Constraint version="2.0">
+ <fes:Filter>
+ <fes:PropertyIsLike wildCard="%" singleChar="#" escapeChar="!">
+ <fes:ValueReference>csw:AnyText</fes:ValueReference>
+ <fes:Literal>%lorem%</fes:Literal>
+ </fes:PropertyIsLike>
+ </fes:Filter>
+ </csw30:Constraint>
+ </csw30:Query>
+</csw30:GetRecords>
=====================================
tests/functionaltests/suites/dif/expected/post_GetRecords-filter-bbox.xml
=====================================
@@ -28,12 +28,9 @@
<dif:Data_Set_Language/>
<dif:Originating_Center/>
<dif:Summary>Curabitur lacinia, ante non porta tempus, mi lorem feugiat odio, eget suscipit eros pede ac velit.</dif:Summary>
- <dif:DIF_Creation_Date/>
- <dif:Related_URL>
- <dif:URL/>
- </dif:Related_URL>
<dif:Metadata_Name>CEOS IDN DIF</dif:Metadata_Name>
<dif:Metadata_Version>9.7</dif:Metadata_Version>
+ <dif:DIF_Creation_Date/>
</dif:DIF>
<dif:DIF xsi:schemaLocation="http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/ http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/dif.xsd">
<dif:Entry_ID>urn:uuid:9a669547-b69b-469f-a11f-2d875366bbdc</dif:Entry_ID>
@@ -60,12 +57,9 @@
<dif:Data_Set_Language/>
<dif:Originating_Center/>
<dif:Summary></dif:Summary>
- <dif:DIF_Creation_Date/>
- <dif:Related_URL>
- <dif:URL/>
- </dif:Related_URL>
<dif:Metadata_Name>CEOS IDN DIF</dif:Metadata_Name>
<dif:Metadata_Version>9.7</dif:Metadata_Version>
+ <dif:DIF_Creation_Date/>
</dif:DIF>
</csw:SearchResults>
-</csw:GetRecordsResponse>
+</csw:GetRecordsResponse>
\ No newline at end of file
=====================================
tests/functionaltests/suites/opensearcheo/expected/get_opensearch-description-document.xml
=====================================
@@ -5,8 +5,8 @@
<os:LongName>pycsw Geospatial Catalogue</os:LongName>
<os:Description>pycsw is an OGC CSW server implementation written in Python</os:Description>
<os:Tags>catalogue discovery</os:Tags>
- <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}"/>
- <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.cfg&mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&outputformat=application/atom%2Bxml&startposition={startIndex?}&maxrecords={count?}&recordids={geo:uid?}"/>
+ <os:Url type="application/xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&recordids={geo:uid?}&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}&eo:cloudCover={eo:cloudCover?}&eo:instrument={eo:instrument?}&eo:orbitDirection={eo:orbitDirection?}&eo:orbitNumber={eo:orbitNumber?}&eo:platform={eo:platform?}&eo:processingLevel={eo:processingLevel?}&eo:productType={eo:productType?}&eo:sensorType={eo:sensorType?}&eo:snowCover={eo:snowCover?}&eo:spectralRange={eo:spectralRange?}"/>
+ <os:Url type="application/atom+xml" template="http://localhost/pycsw/csw.py?config=tests/functionaltests/suites/opensearcheo/default.cfg&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&outputformat=application/atom%%2Bxml&outputschema=http://www.opengis.net/cat/csw/3.0&recordids={geo:uid?}&q={searchTerms?}&bbox={geo:box?}&time={time:start?}/{time:end?}&start={time:start?}&stop={time:end?}&startposition={startIndex?}&maxrecords={count?}&eo:cloudCover={eo:cloudCover?}&eo:instrument={eo:instrument?}&eo:orbitDirection={eo:orbitDirection?}&eo:orbitNumber={eo:orbitNumber?}&eo:platform={eo:platform?}&eo:processingLevel={eo:processingLevel?}&eo:productType={eo:productType?}&eo:sensorType={eo:sensorType?}&eo:snowCover={eo:snowCover?}&eo:spectralRange={eo:spectralRange?}&mode=opensearch"/>
<os:Image type="image/vnd.microsoft.icon" width="16" height="16">https://pycsw.org/img/favicon.ico</os:Image>
<os:Query role="example" searchTerms="cat"/>
<os:Developer>Kralidis, Tom</os:Developer>
=====================================
tests/functionaltests/test_suites_functional.py
=====================================
@@ -216,7 +216,7 @@ def _test_xml_result(result, expected, encoding="utf-8"):
return matches
-def _test_json_result(result, expected, encoding="utf-8"):
+def _test_json_result(result, expected):
"""Compare the JSON test results with an expected value.
Parameters
@@ -233,8 +233,8 @@ def _test_json_result(result, expected, encoding="utf-8"):
"""
- result_dict = json.loads(result, encoding=encoding)
- expected_dict = json.loads(expected, encoding=encoding)
+ result_dict = json.loads(result)
+ expected_dict = json.loads(expected)
return result_dict == expected_dict
=====================================
tests/index.html deleted
=====================================
@@ -1,462 +0,0 @@
-
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8"/>
- <title>pycsw Tester</title>
- <style type="text/css">
- body {
- background-color: #ffffff;
- font-family: arial, verdana, sans-serif;
- text-align: left;
- float: left;
- }
- .flat {
- border: 0px;
- }
- </style>
- <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function() {
- $('.xml').change(function() {
- if ($(this).val() != 'none') {
- var arr = $(this).val().split(',');
- $.ajax({
- type: 'GET',
- url: arr[1],
- dataType: 'text',
- success: function(data) {
- $('.request').val(data);
- $('.server').val('../csw.py?config=' + arr[0]);
- }
- });
- }
- });
- $('.send').click(function() {
- $.ajax({
- type: 'POST',
- contentType: 'text/xml',
- url: $('.server').val(),
- data: $('.request').val(),
- dataType: 'text',
- success: function(data) {
- $('.response').val(data);
- },
- error: function(data1) {
- $('.response').val(data1.responseText);
- }
- });
- });
- });
- </script>
- </head>
-
-
- <body>
- <h2 class="header">pycsw Tester</h2>
- <hr/>
- <h3 class="header">HTTP POST</h3>
- <form action="#" id="tests">
- <table>
- <tr>
- <th>Request</th>
- <th>Response</th>
- </tr>
- <tr>
- <td>
- <select class="xml">
- <option value="none">Select a CSW Request</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/DescribeRecord.xml">functionaltests/suites/apiso/post/DescribeRecord.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetCapabilities.xml">functionaltests/suites/apiso/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetDomain-property.xml">functionaltests/suites/apiso/post/GetDomain-property.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecordById-brief.xml">functionaltests/suites/apiso/post/GetRecordById-brief.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecordById-full-dc.xml">functionaltests/suites/apiso/post/GetRecordById-full-dc.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecordById-full.xml">functionaltests/suites/apiso/post/GetRecordById-full.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecordById-srv-brief.xml">functionaltests/suites/apiso/post/GetRecordById-srv-brief.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-all-csw-output.xml">functionaltests/suites/apiso/post/GetRecords-all-csw-output.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-all.xml">functionaltests/suites/apiso/post/GetRecords-all.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-cql-title.xml">functionaltests/suites/apiso/post/GetRecords-cql-title.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-elementname.xml">functionaltests/suites/apiso/post/GetRecords-elementname.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-filter-and-nested-spatial-or-dateline.xml">functionaltests/suites/apiso/post/GetRecords-filter-and-nested-spatial-or-dateline.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-filter-anytext.xml">functionaltests/suites/apiso/post/GetRecords-filter-anytext.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-filter-bbox-csw-output.xml">functionaltests/suites/apiso/post/GetRecords-filter-bbox-csw-output.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-filter-bbox.xml">functionaltests/suites/apiso/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/apiso/default.cfg,functionaltests/suites/apiso/post/GetRecords-filter-servicetype.xml">functionaltests/suites/apiso/post/GetRecords-filter-servicetype.xml</option>
- <option value="tests/functionaltests/suites/atom/default.cfg,functionaltests/suites/atom/post/DescribeRecord.xml">functionaltests/suites/atom/post/DescribeRecord.xml</option>
- <option value="tests/functionaltests/suites/atom/default.cfg,functionaltests/suites/atom/post/GetCapabilities.xml">functionaltests/suites/atom/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/atom/default.cfg,functionaltests/suites/atom/post/GetRecords-filter-bbox.xml">functionaltests/suites/atom/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/0c976d98-c896-4b10-b1fe-a22ef50434e7.xml">functionaltests/suites/cite/post/0c976d98-c896-4b10-b1fe-a22ef50434e7.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/19d2a6ed-be28-4866-ae15-e3bb634486cb.xml">functionaltests/suites/cite/post/19d2a6ed-be28-4866-ae15-e3bb634486cb.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml">functionaltests/suites/cite/post/1ab55aa3-6685-4595-8ecd-45987a7b8b59.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml">functionaltests/suites/cite/post/1c958b7a-ca09-4c38-98bd-ef1d1d28cc14.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml">functionaltests/suites/cite/post/1c97fc1a-61cd-4c1d-8054-933e17a6c5ee.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/2102a460-5d62-465f-9668-d70b3faafbfa.xml">functionaltests/suites/cite/post/2102a460-5d62-465f-9668-d70b3faafbfa.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/225f455a-0035-486b-a94e-fee7ae881b2b.xml">functionaltests/suites/cite/post/225f455a-0035-486b-a94e-fee7ae881b2b.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/2d53ffea-60e4-4652-abf5-36eb23042fd5.xml">functionaltests/suites/cite/post/2d53ffea-60e4-4652-abf5-36eb23042fd5.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/34a019a9-1581-42cb-9827-fbfdda2773b7.xml">functionaltests/suites/cite/post/34a019a9-1581-42cb-9827-fbfdda2773b7.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/3e76fd38-e035-41c9-83dc-61356f680c97.xml">functionaltests/suites/cite/post/3e76fd38-e035-41c9-83dc-61356f680c97.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml">functionaltests/suites/cite/post/418a6fb0-a89c-4a94-afc9-3f8168eb2980.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/420b745e-0c4b-404e-9f2d-61fa580ff05a.xml">functionaltests/suites/cite/post/420b745e-0c4b-404e-9f2d-61fa580ff05a.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/4735d649-a2b1-42fd-a101-14e1d7e4607f.xml">functionaltests/suites/cite/post/4735d649-a2b1-42fd-a101-14e1d7e4607f.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/5c5861bc-f742-40a5-9998-5342615d674b.xml">functionaltests/suites/cite/post/5c5861bc-f742-40a5-9998-5342615d674b.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml">functionaltests/suites/cite/post/6e736fd0-c266-4852-9eb3-0656f5d0f5c4.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml">functionaltests/suites/cite/post/73f1551c-e269-4ef9-9dae-e535b5eebfc7.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/78297c88-4850-4927-adc6-511cd9a3d539.xml">functionaltests/suites/cite/post/78297c88-4850-4927-adc6-511cd9a3d539.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml">functionaltests/suites/cite/post/7c89cdf5-0def-4cfb-8c55-2b8ffea5d92f.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/7e2cd105-daec-4d25-bc8e-d49d21364912.xml">functionaltests/suites/cite/post/7e2cd105-daec-4d25-bc8e-d49d21364912.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml">functionaltests/suites/cite/post/87f2f670-9cd6-4907-b82c-1b46a7dd2a78.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml">functionaltests/suites/cite/post/88b4e1ba-3bd4-4cbe-81e5-e004056d6ca3.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/898cd63b-2585-4ec0-8720-d554bd324174.xml">functionaltests/suites/cite/post/898cd63b-2585-4ec0-8720-d554bd324174.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml">functionaltests/suites/cite/post/8fb13dc3-5818-45e2-9e29-46abc16e7d38.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/928c1896-52d4-4ac7-9832-f98e3eb65f02.xml">functionaltests/suites/cite/post/928c1896-52d4-4ac7-9832-f98e3eb65f02.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/93bdbb9d-2734-4f01-92fb-48634cca41de.xml">functionaltests/suites/cite/post/93bdbb9d-2734-4f01-92fb-48634cca41de.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml">functionaltests/suites/cite/post/948b39d5-bb4f-45b8-a8f2-4ff9501aaedd.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml">functionaltests/suites/cite/post/9fd64fcc-f69c-4626-b72e-5c7776a29aa9.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml">functionaltests/suites/cite/post/a06d04ab-e0d0-4a86-bfe8-71460f41fe37.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/ad61686c-d304-42d1-b845-8c1f3070c83e.xml">functionaltests/suites/cite/post/ad61686c-d304-42d1-b845-8c1f3070c83e.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/af39c020-7b1d-429c-b474-f45c3164cb79.xml">functionaltests/suites/cite/post/af39c020-7b1d-429c-b474-f45c3164cb79.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml">functionaltests/suites/cite/post/b90e2de6-3d25-4298-a13e-dc9492a8fc73.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/ba9b0107-dcee-46ef-823a-a2e25a911a96.xml">functionaltests/suites/cite/post/ba9b0107-dcee-46ef-823a-a2e25a911a96.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/bb66ebc5-7121-48b5-9f53-b56537d9561b.xml">functionaltests/suites/cite/post/bb66ebc5-7121-48b5-9f53-b56537d9561b.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/c02d1c85-df9f-45ee-bea7-345c35e02a98.xml">functionaltests/suites/cite/post/c02d1c85-df9f-45ee-bea7-345c35e02a98.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/c311a342-72e3-4983-be39-868e6ed9740f.xml">functionaltests/suites/cite/post/c311a342-72e3-4983-be39-868e6ed9740f.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml">functionaltests/suites/cite/post/c38916c2-4bc6-446d-b7aa-ab006d6ba31c.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/c8588f47-8e65-45f5-ad34-ff4524cad84d.xml">functionaltests/suites/cite/post/c8588f47-8e65-45f5-ad34-ff4524cad84d.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml">functionaltests/suites/cite/post/da228d4c-e1be-43d7-9ccb-c3f27ee32541.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml">functionaltests/suites/cite/post/dc92c2c4-87d8-4a13-964e-ff9b0e0c27b3.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml">functionaltests/suites/cite/post/dcb13791-379e-4739-bcd4-dbaa69f0efdb.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/e308f030-c097-4036-a838-44bad74c9ef7.xml">functionaltests/suites/cite/post/e308f030-c097-4036-a838-44bad74c9ef7.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml">functionaltests/suites/cite/post/e6e9efb2-e2b7-4b0a-a3a2-7deea3f9b8e2.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/f7976c55-a156-4421-8199-bc0487da4b0f.xml">functionaltests/suites/cite/post/f7976c55-a156-4421-8199-bc0487da4b0f.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/f7d79701-f10b-4087-a33c-f62df0a04fd1.xml">functionaltests/suites/cite/post/f7d79701-f10b-4087-a33c-f62df0a04fd1.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml">functionaltests/suites/cite/post/fc1bc094-88f1-4851-bc2b-dfc56be9f3c7.xml</option>
- <option value="tests/functionaltests/suites/cite/default.cfg,functionaltests/suites/cite/post/fe20960f-a26c-4f13-852d-470a0d3233f9.xml">functionaltests/suites/cite/post/fe20960f-a26c-4f13-852d-470a0d3233f9.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/Exception-GetDomain-parametername-bad.xml">functionaltests/suites/csw30/post/Exception-GetDomain-parametername-bad.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/Exception-GetDomain-valuereference-bad.xml">functionaltests/suites/csw30/post/Exception-GetDomain-valuereference-bad.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/Exception-GetRecordById-404.xml">functionaltests/suites/csw30/post/Exception-GetRecordById-404.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/Exception-GetRecordById-bad-esn.xml">functionaltests/suites/csw30/post/Exception-GetRecordById-bad-esn.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/Exception-bad-xml.xml">functionaltests/suites/csw30/post/Exception-bad-xml.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/Exception-not-xml.xml">functionaltests/suites/csw30/post/Exception-not-xml.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/GetCapabilities.xml">functionaltests/suites/csw30/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/GetDomain-parametername.xml">functionaltests/suites/csw30/post/GetDomain-parametername.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/GetDomain-valuereference.xml">functionaltests/suites/csw30/post/GetDomain-valuereference.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/GetRecordById-dc-full.xml">functionaltests/suites/csw30/post/GetRecordById-dc-full.xml</option>
- <option value="tests/functionaltests/suites/csw30/default.cfg,functionaltests/suites/csw30/post/GetRecordById-dc.xml">functionaltests/suites/csw30/post/GetRecordById-dc.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/DescribeRecord-json.xml">functionaltests/suites/default/post/DescribeRecord-json.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/DescribeRecord.xml">functionaltests/suites/default/post/DescribeRecord.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Exception-GetRecords-badsrsname.xml">functionaltests/suites/default/post/Exception-GetRecords-badsrsname.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Exception-GetRecords-elementname.xml">functionaltests/suites/default/post/Exception-GetRecords-elementname.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Exception-GetRecords-invalid-xml.xml">functionaltests/suites/default/post/Exception-GetRecords-invalid-xml.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetCapabilities-SOAP.xml">functionaltests/suites/default/post/GetCapabilities-SOAP.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetCapabilities-sections.xml">functionaltests/suites/default/post/GetCapabilities-sections.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetCapabilities-updatesequence.xml">functionaltests/suites/default/post/GetCapabilities-updatesequence.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetCapabilities.xml">functionaltests/suites/default/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetDomain-parameter.xml">functionaltests/suites/default/post/GetDomain-parameter.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetDomain-property.xml">functionaltests/suites/default/post/GetDomain-property.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecordById-json.xml">functionaltests/suites/default/post/GetRecordById-json.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecordById.xml">functionaltests/suites/default/post/GetRecordById.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-all-json.xml">functionaltests/suites/default/post/GetRecords-all-json.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-all-resulttype-hits.xml">functionaltests/suites/default/post/GetRecords-all-resulttype-hits.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-all-resulttype-validate.xml">functionaltests/suites/default/post/GetRecords-all-resulttype-validate.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-all-sortby-bbox.xml">functionaltests/suites/default/post/GetRecords-all-sortby-bbox.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-all.xml">functionaltests/suites/default/post/GetRecords-all.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-bbox-filter-crs84.xml">functionaltests/suites/default/post/GetRecords-bbox-filter-crs84.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-cql-title-and-abstract.xml">functionaltests/suites/default/post/GetRecords-cql-title-and-abstract.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-cql-title.xml">functionaltests/suites/default/post/GetRecords-cql-title.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-distributedsearch.xml">functionaltests/suites/default/post/GetRecords-distributedsearch.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-elementname.xml">functionaltests/suites/default/post/GetRecords-elementname.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-end.xml">functionaltests/suites/default/post/GetRecords-end.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-and-bbox-freetext.xml">functionaltests/suites/default/post/GetRecords-filter-and-bbox-freetext.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-and-nested-or.xml">functionaltests/suites/default/post/GetRecords-filter-and-nested-or.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-and-nested-or2.xml">functionaltests/suites/default/post/GetRecords-filter-and-nested-or2.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-anytext-and-not.xml">functionaltests/suites/default/post/GetRecords-filter-anytext-and-not.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-anytext-equal.xml">functionaltests/suites/default/post/GetRecords-filter-anytext-equal.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-anytext.xml">functionaltests/suites/default/post/GetRecords-filter-anytext.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-bbox-poslist.xml">functionaltests/suites/default/post/GetRecords-filter-bbox-poslist.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-bbox-reproject.xml">functionaltests/suites/default/post/GetRecords-filter-bbox-reproject.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-bbox-sortby.xml">functionaltests/suites/default/post/GetRecords-filter-bbox-sortby.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-bbox.xml">functionaltests/suites/default/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-between.xml">functionaltests/suites/default/post/GetRecords-filter-between.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-function-bad.xml">functionaltests/suites/default/post/GetRecords-filter-function-bad.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-function.xml">functionaltests/suites/default/post/GetRecords-filter-function.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-invalid-poslist.xml">functionaltests/suites/default/post/GetRecords-filter-invalid-poslist.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-not-bbox.xml">functionaltests/suites/default/post/GetRecords-filter-not-bbox.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-or-bbox-freetext.xml">functionaltests/suites/default/post/GetRecords-filter-or-bbox-freetext.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-or-nested-and.xml">functionaltests/suites/default/post/GetRecords-filter-or-nested-and.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-filter-or-title-abstract.xml">functionaltests/suites/default/post/GetRecords-filter-or-title-abstract.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-maxrecords.xml">functionaltests/suites/default/post/GetRecords-maxrecords.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/GetRecords-requestid.xml">functionaltests/suites/default/post/GetRecords-requestid.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Harvest-default.xml">functionaltests/suites/default/post/Harvest-default.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Harvest-response-handler.xml">functionaltests/suites/default/post/Harvest-response-handler.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Transaction-delete.xml">functionaltests/suites/default/post/Transaction-delete.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Transaction-insert.xml">functionaltests/suites/default/post/Transaction-insert.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Transaction-update-full.xml">functionaltests/suites/default/post/Transaction-update-full.xml</option>
- <option value="tests/functionaltests/suites/default/default.cfg,functionaltests/suites/default/post/Transaction-update-recordproperty.xml">functionaltests/suites/default/post/Transaction-update-recordproperty.xml</option>
- <option value="tests/functionaltests/suites/dif/default.cfg,functionaltests/suites/dif/post/DescribeRecord.xml">functionaltests/suites/dif/post/DescribeRecord.xml</option>
- <option value="tests/functionaltests/suites/dif/default.cfg,functionaltests/suites/dif/post/GetCapabilities.xml">functionaltests/suites/dif/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/dif/default.cfg,functionaltests/suites/dif/post/GetRecords-filter-bbox.xml">functionaltests/suites/dif/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/duplicatefileid/default.cfg,functionaltests/suites/duplicatefileid/post/GetRecords-all.xml">functionaltests/suites/duplicatefileid/post/GetRecords-all.xml</option>
- <option value="tests/functionaltests/suites/ebrim/default.cfg,functionaltests/suites/ebrim/post/DescribeRecord.xml">functionaltests/suites/ebrim/post/DescribeRecord.xml</option>
- <option value="tests/functionaltests/suites/ebrim/default.cfg,functionaltests/suites/ebrim/post/GetCapabilities.xml">functionaltests/suites/ebrim/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/ebrim/default.cfg,functionaltests/suites/ebrim/post/GetRecords-filter-bbox-full.xml">functionaltests/suites/ebrim/post/GetRecords-filter-bbox-full.xml</option>
- <option value="tests/functionaltests/suites/ebrim/default.cfg,functionaltests/suites/ebrim/post/GetRecords-filter-bbox.xml">functionaltests/suites/ebrim/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/fgdc/default.cfg,functionaltests/suites/fgdc/post/DescribeRecord.xml">functionaltests/suites/fgdc/post/DescribeRecord.xml</option>
- <option value="tests/functionaltests/suites/fgdc/default.cfg,functionaltests/suites/fgdc/post/GetCapabilities.xml">functionaltests/suites/fgdc/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/fgdc/default.cfg,functionaltests/suites/fgdc/post/GetRecords-filter-bbox.xml">functionaltests/suites/fgdc/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/gm03/default.cfg,functionaltests/suites/gm03/post/GetCapabilities.xml">functionaltests/suites/gm03/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/gm03/default.cfg,functionaltests/suites/gm03/post/GetRecords-filter-bbox.xml">functionaltests/suites/gm03/post/GetRecords-filter-bbox.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Clear-000-delete-all.xml">functionaltests/suites/harvesting/post/Clear-000-delete-all.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Exception-Havest-csw-404.xml">functionaltests/suites/harvesting/post/Exception-Havest-csw-404.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/GetCapabilities.xml">functionaltests/suites/harvesting/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/GetDomain-parameter.xml">functionaltests/suites/harvesting/post/GetDomain-parameter.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-csw-iso.xml">functionaltests/suites/harvesting/post/Harvest-csw-iso.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-csw-run1.xml">functionaltests/suites/harvesting/post/Harvest-csw-run1.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-csw-run2.xml">functionaltests/suites/harvesting/post/Harvest-csw-run2.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-dc.xml">functionaltests/suites/harvesting/post/Harvest-dc.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-fgdc.xml">functionaltests/suites/harvesting/post/Harvest-fgdc.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-iso.xml">functionaltests/suites/harvesting/post/Harvest-iso.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-rdf.xml">functionaltests/suites/harvesting/post/Harvest-rdf.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-sos100.xml">functionaltests/suites/harvesting/post/Harvest-sos100.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-sos200.xml">functionaltests/suites/harvesting/post/Harvest-sos200.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-waf.xml">functionaltests/suites/harvesting/post/Harvest-waf.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wcs.xml">functionaltests/suites/harvesting/post/Harvest-wcs.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wfs110.xml">functionaltests/suites/harvesting/post/Harvest-wfs110.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wfs200.xml">functionaltests/suites/harvesting/post/Harvest-wfs200.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wms-run1.xml">functionaltests/suites/harvesting/post/Harvest-wms-run1.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wms-run2.xml">functionaltests/suites/harvesting/post/Harvest-wms-run2.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wmts.xml">functionaltests/suites/harvesting/post/Harvest-wmts.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-wps.xml">functionaltests/suites/harvesting/post/Harvest-wps.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-ows-dc.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-ows-dc.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-abstract-dc.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-dc.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-dc.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-iso.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-sos-iso.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wfs-iso.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wfs-iso.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-dc.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-dc.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-iso.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-iso.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-layer.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wms-layer.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wps-process.xml">functionaltests/suites/harvesting/post/Harvest-zzz-post-GetRecords-filter-wps-process.xml</option>
- <option value="tests/functionaltests/suites/harvesting/default.cfg,functionaltests/suites/harvesting/post/Transaction-000-delete-all.xml">functionaltests/suites/harvesting/post/Transaction-000-delete-all.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Clear-000-delete-all.xml">functionaltests/suites/manager/post/Clear-000-delete-all.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/GetCapabilities.xml">functionaltests/suites/manager/post/GetCapabilities.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/GetDomain-parameter.xml">functionaltests/suites/manager/post/GetDomain-parameter.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-000-delete-all.xml">functionaltests/suites/manager/post/Transaction-000-delete-all.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-dc-01-insert.xml">functionaltests/suites/manager/post/Transaction-dc-01-insert.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-dc-02-update-full.xml">functionaltests/suites/manager/post/Transaction-dc-02-update-full.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-fgdc-01-insert.xml">functionaltests/suites/manager/post/Transaction-fgdc-01-insert.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-fgdc-02-update-recprop.xml">functionaltests/suites/manager/post/Transaction-fgdc-02-update-recprop.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-fgdc-03-delete-all.xml">functionaltests/suites/manager/post/Transaction-fgdc-03-delete-all.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-iso-00-delete-all.xml">functionaltests/suites/manager/post/Transaction-iso-00-delete-all.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-iso-01-insert.xml">functionaltests/suites/manager/post/Transaction-iso-01-insert.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-iso-02-update-full.xml">functionaltests/suites/manager/post/Transaction-iso-02-update-full.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-iso-03-update-recprop.xml">functionaltests/suites/manager/post/Transaction-iso-03-update-recprop.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-iso-04-update-recprop-no-matches.xml">functionaltests/suites/manager/post/Transaction-iso-04-update-recprop-no-matches.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-iso-05-delete.xml">functionaltests/suites/manager/post/Transaction-iso-05-delete.xml</option>
- <option value="tests/functionaltests/suites/manager/default.cfg,functionaltests/suites/manager/post/Transaction-xxx-delete-all.xml">functionaltests/suites/manager/post/Transaction-xxx-delete-all.xml</option>
- <option value="tests/functionaltests/suites/repofilter/default.cfg,functionaltests/suites/repofilter/post/GetRecordById-masked.xml">functionaltests/suites/repofilter/post/GetRecordById-masked.xml</option>
- <option value="tests/functionaltests/suites/repofilter/default.cfg,functionaltests/suites/repofilter/post/GetRecords-all.xml">functionaltests/suites/repofilter/post/GetRecords-all.xml</option>
- <option value="tests/functionaltests/suites/utf-8/default.cfg,functionaltests/suites/utf-8/post/GetCapabilities.xml">functionaltests/suites/utf-8/post/GetCapabilities.xml</option>
-
- </select>
- <input type="button" class="send" value="Send"/>
- </td>
- <td>
- Server: <input type="text" size="40" class="server" value="../csw.py"/>
- </td>
- </tr>
- <tr>
- <td>
- <textarea rows="20" cols="70" class="request"></textarea>
- </td>
- <td>
- <textarea rows="20" cols="70" class="response"></textarea>
- </td>
- </tr>
- </table>
- </form>
- <hr/>
- <h3 class="header">HTTP GET</h3>
- <ul>
-
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities'>GetCapabilities</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities&lang=gre'>GetCapabilities-lang</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&resulttype=results&elementsetname=brief'>opensearch</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetCapabilities'>opensearch-description</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=greece'>opensearch-ogc-q</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&bbox=-180,-90,180,90'>opensearch-ogc-bbox</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2001/2004'>opensearch-ogc-time</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2004/'>opensearch-ogc-timestart</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=/2004'>opensearch-ogc-timeend</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2001/2007&q=vitae'>opensearch-ogc-q-and-time</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&time=2001/2007&bbox=-180,-90,180,90'>opensearch-ogc-bbox-and-time</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=vegetation&bbox=-180,-90,180,90'>opensearch-ogc-q-and-bbox</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=vegetation&startposition=1'>opensearch-ogc-count-and-page1</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=2.0.2&request=GetRecords&elementsetname=full&resulttype=results&typenames=csw:Record&q=vegetation&startposition=1&maxrecords=1'>opensearch-ogc-count-and-page2</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities'>27e17158-c57a-4493-92ac-dba8934cf462</a></li>
-<li><a href='../csw.py?Service=CSW&Version=2.0.2&Request=GetRecordById&ElementSetName=brief&ID=urn%3Auuid%3A19887a8a-f6b0-4a63-ae56-7fba0e17801f'>27f69b66-5f05-4311-a89c-73ca55c2686b</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities&acceptversions=2.0.2&date=2006-10-20'>2ab7d1fa-885b-459f-80e4-b6282eab4f8c</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecordById&id=urn%3Auuid%3A9a669547-b69b-469f-a11f-2d875366bbdc'>37aa90e2-6ff0-420c-af15-8b9463099a73</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities&acceptformats=message/example'>3a8a3c47-455f-4f49-9078-03119f3e70b3</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecordById'>4515831f-834a-4699-95f6-ab0c2cbfcfd0</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities§ions='>477b23a3-baa9-47c8-9541-5fe27735ed49</a></li>
-<li><a href='../csw.py?sErViCe=CSW&REQUEST=GetCapabilities&version=2.0.2'>48f26761-3a9d-48db-bee1-da089f5fb857</a></li>
-<li><a href='../csw.py?Service=CSW&Version=2.0.2&Request=GetRecordById&OutputFormat=application/bogus_xml&id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2,urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f,urn:uuid:ab42a8c4-95e8-4630-bf79-33e59241605a'>4e38092f-1586-44b8-988e-0acfa5855916</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities§ions=OperationsMetadata,ServiceIdentification'>55c38f00-2553-42c1-99ab-33edbb561ad7</a></li>
-<li><a href='../csw.py?service=FOO&request=GetCapabilities'>5ab5db18-c87a-4fbf-a8d8-b7289b09ac81</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:ce8627a0-685c-11db-bd13-0800200c9a66,urn:uuid:6a3de50b-fa66-4b58-a0e6-ca146fdd18d4'>6a4f57ca-a1bd-4802-89c2-44860dbdb0f0</a></li>
-<li><a href='../csw.py?Service=CSW&Version=2.0.2&Request=GetRecordById&OutputSchema=http://www.w3.org/2005/Atom&Id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f'>6c375703-9c00-4aef-bec7-d2e964f849eb</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities'>80f31def-4185-48b9-983a-960566918eae</a></li>
-<li><a href='../csw.py?SERVICE=CSW&REQUEST=GetCapabilities&ACCEPTVERSIONS=2006.10.29'>8e2232ed-05d9-44ae-8b04-0911cbe6a507</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities'>9697f0aa-3b6a-4125-83a5-61e8826127c4</a></li>
-<li><a href='../csw.py?Service=CSW&Version=2.0.2&Request=GetRecordById&ElementSetName=full&ID=urn%3Auuid%3Ae9330592-0932-474b-be34-c3a3bb67c7db'>9bfd17fa-15dc-4a10-8fa7-b3cff7013dd7</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:ce8627a0-685c-11db-bd13-0800200c9a66'>b81c3595-06d6-4693-82ea-1ff8650755ac</a></li>
-<li><a href='../csw.py?SERVICE=CSW&REQUEST=GetCapabilities&ACCEPTVERSIONS=2.0.2,2.0.0'>ba5fc729-3b71-47a0-b7d0-42ec565cd185</a></li>
-<li><a href='../csw.py?request=GetCapabilities'>c4ea754f-c158-4d8d-8253-dc8f86021b52</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities'>f4692ec5-9547-4a05-88ab-e6154af2640a</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecordById&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63'>f997f25e-c865-4d53-a362-0ed1846337f2</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>GetCapabilities-base-url</a></li>
-<li><a href='../csw.py?service=CSW&request=GetCapabilities'>GetCapabilities-no-version</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetCapabilities'>GetCapabilities</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetCapabilities-foo'>Exception-invalid-request</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetDomain'>Exception-GetDomain</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetDomain¶metername=GetRecords.ElementSetName'>GetDomain-parameter</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title'>GetDomain-value-reference</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetDomain&valuereference=dc:title2'>Exception-GetDomain-value-reference</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecordById&id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e'>Exception-GetRecordById-dc.xml</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecordById&id=does_not_exist2'>Exception-GetRecordById-404</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities'>OpenSearch-description</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRepositoryItem&id=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f'>GetRepositoryItem</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRepositoryItem&id=NOTFOUND'>Exception-GetRepositoryItem-notfound</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities'>002258f0-627f-457f-b2ad-025777c77ac8</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids='>045c600d-973d-41eb-9f60-eba1b717b720</a></li>
-<li><a href='../csw.py?elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>0bbcf862-5211-4351-9988-63f8bec49c98</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>0bdf8457-971e-4ed1-be4a-5feca4dcd8fa</a></li>
-<li><a href='../csw.py?elementName=tns:title&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(tns%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0'>0d8bbdec-0846-42ca-8dc8-b7f4cba41d67</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids='>0e1dca37-477a-4060-99fe-7799b52d656c</a></li>
-<li><a href='../csw.py?elementSetName=full&maxRecords=20&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>13c87956-51a4-4780-a8e9-6e0b5c0bb473</a></li>
-<li><a href='../csw.py?acceptFormats=model/x3d%2Bxml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW'>151d982f-ebd3-4cb2-b507-a667713a1e92</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0&request=GetCapabilities'>1869e495-1a61-4713-8285-76d1336ee1a6</a></li>
-<li><a href='../csw.py?request=GetRecordById&service=CSW&version=3.0.0'>1bcb42a9-538c-4f0a-9d4c-d6f10b720aa6</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>22f44168-2ccf-4801-ad96-204212566d56</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0§ions=All&request=GetCapabilities&service=CSW'>2499a9c9-8d33-449c-bc92-d494adfcc84d</a></li>
-<li><a href='../csw.py?acceptFormats=application/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW'>27f4f39c-d92a-4e3c-b961-c6aa8c24e513</a></li>
-<li><a href='../csw.py?id=urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2&request=GetRecordById&service=CSW&version=3.0.0'>28e569df-8596-4128-8d9a-29ad03138915</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>2b06a5c8-0df2-4af1-8d2e-a425de11c845</a></li>
-<li><a href='../csw.py?maxRecords=2&elementSetName=summary&outputFormat=application/atom%2Bxml&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0'>2ba1418a-444d-4cce-9cfe-4c94efcf8b55</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids='>397fe17a-d5b4-4f96-8cc4-4ce467ed4d0a</a></li>
-<li><a href='../csw.py?elementSetName=brief&request=GetRecords&service=CSW&typeNames=tns:Record&namespace=xmlns(tns%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0'>3dcd1b15-73d2-4b7d-a3e3-ff15bf14aae4</a></li>
-<li><a href='../csw.py?elementSetName=summary&recordIds=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f,urn:uuid:e9330592-0932-474b-be34-c3a3bb67c7db&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>405e1ff1-5c75-4846-a28b-cfaff2a6921a</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>43cd6471-6ac7-45bd-8ff9-148cb2de9a52</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0§ions=ServiceIdentification&request=GetCapabilities&service=CSW'>4566d2ec-1283-4a02-baed-a74fc5b47e37</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0§ions=Filter_Capabilities&request=GetCapabilities&service=CSW'>461bd4c5-6623-490d-9036-d91a2201e87b</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432,5429689,529130,5451619&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids='>5496894a-3877-4f62-a20b-5d7126f94925</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17,44.79,17.92,68.41&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids='>5a015f6a-bf14-4977-b1e3-6577eb0223c8</a></li>
-<li><a href='../csw.py?id=urn:uuid:88247b56-4cbc-4df9-9860-db3f8042e357&outputFormat=model/vnd.collada%2Bxml&request=GetRecordById&service=CSW&version=3.0.0'>5c3a2390-1fb9-43f0-b96c-f48c7a69c990</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0§ions=OperationsMetadata&request=GetCapabilities&service=CSW'>5e9e67dc-18d6-4645-8111-c6263c88a61f</a></li>
-<li><a href='../csw.py?elementSetName=full&q=amet&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>604d9379-741c-42e5-b4cf-92e56c87fa64</a></li>
-<li><a href='../csw.py?request=GetRecords&service=CSW&typeNames=UnknownType&version=3.0.0'>60e6af95-d5fc-465a-82e2-fd2e6d85e4af</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a'>62ad94c2-b558-4265-a427-23d6677975d6</a></li>
-<li><a href='../csw.py?elementSetName=undefined-view&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>6a5e247b-0961-4b8a-a0d6-35a491d9cfe7</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>6a9d0558-9d87-495b-b999-b49a3ef1cf99</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=Fusc%C3%A9%20Land&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids='>6bd790c9-6019-4652-9c91-330a894d6700</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0&request=GetCapabilities&service=CSW'>6e9cba43-5e27-415d-adbd-a92851c2c173</a></li>
-<li><a href='../csw.py?id=urn:uuid:66ae76b7-54ba-489b-a582-0f0633d96493&request=GetRecordById&service=CSW&version=3.0.0'>7630d230-e142-4a09-accf-f091000b90cd</a></li>
-<li><a href='../csw.py?acceptFormats=text/xml&acceptVersions=3.0.0&request=GetCapabilities&service=CSW'>7e82446a-b5dc-43fe-9a73-4cc1f2f2f0bf</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>8025978e-1a35-4d70-80c2-e8329e0c7864</a></li>
-<li><a href='../csw.py?elementSetName=brief&bbox=44.79,-6.17,68.41,17.92,urn:ogc:def:crs:EPSG::4326&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>8184ae4f-536d-4978-8b28-ad703be96967</a></li>
-<li><a href='../csw.py?maxRecords=15&elementSetName=summary&q=Mauris&bbox=-6.17,44.79,17.92,68.41&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>88f63a89-664f-4315-b4f8-04a0b33803a7</a></li>
-<li><a href='../csw.py?id=urn:example:1461546298217&request=GetRecordById&service=CSW&version=3.0.0'>8987f8f0-4d93-4481-968c-a2ccbd6b8be2</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180,-90,180,90&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids='>8e5fa0f6-3f29-4d1f-abe2-d9866f3def98</a></li>
-<li><a href='../csw.py?acceptVersions=9999.12.31&request=GetCapabilities&service=CSW'>9000ec29-5649-474e-b2d6-55c00f8a52c0</a></li>
-<li><a href='../csw.py?elementSetName=summary&bbox=-6.17,44.79,17.92,68.41&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>91914d35-7bbf-45e6-9b37-5ef484869a4e</a></li>
-<li><a href='../csw.py?elementSetName=full&q=atkovxqmf&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>92d4844d-57d5-4cf3-8f47-ba50e369dc04</a></li>
-<li><a href='../csw.py?elementSetName=brief&outputSchema=urn:uuid:6a29d2a8-9651-47a6-9b14-f05d2b5644f0&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>9c0e2a4b-b4e6-41c0-b630-c8c99fc89ff3</a></li>
-<li><a href='../csw.py?id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&outputSchema=http://www.example.org/ns/alpha&request=GetRecordById&service=CSW&version=3.0.0'>9d7ffac8-9798-428d-8e27-3cd12497ee6b</a></li>
-<li><a href='../csw.py?id=urn:uuid:829babb0-b2f1-49e1-8cd5-7b489fe71a1e&outputFormat=application/atom%2Bxml&request=GetRecordById&service=CSW&version=3.0.0'>a2f18643-e24e-4fa5-b780-6de4a2dbc814</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=514432,5429689,529130,5451619&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids='>abc90c8c-5868-4405-a73e-64c849be3b2a</a></li>
-<li><a href='../csw.py?maxRecords=2&elementSetName=summary&request=GetRecords&service=CSW&typeNames=csw3:Record&startPosition=3&namespace=xmlns(csw3%3Dhttp://www.opengis.net/cat/csw/3.0)&version=3.0.0'>ad0c0571-09ed-436a-9a4f-a5de744c88fe</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-180,-90,180,90&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids='>af502903-f4ee-47ee-b76e-af878d238bcc</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=-6.17,44.79,17.92,68.41&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids='>b2aafc3f-4f35-47bc-affd-08590972deae</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=3&maxrecords=4&recordids='>b6069623-f7d8-4021-8582-98f0aea0f763</a></li>
-<li><a href='../csw.py?elementSetName=brief&bbox=472944,5363287,492722,5455253,urn:ogc:def:crs:EPSG::0000&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>b9a07a54-75a8-45bd-b341-2823600211e3</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0&request=getCapabilities&service=CSW'>baa4a7d0-0c01-42b6-adc3-0d03e9949fa3</a></li>
-<li><a href='../csw.py?elementSetName=summary&q=Fusc%C3%A9%20Land&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>bfbe6409-f64a-4c89-acb3-50f260a5c743</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=3&maxrecords=4&recordids='>bfe20134-d1da-42ef-9c0f-8e1307bbf92b</a></li>
-<li><a href='../csw.py?SERVICE=CSW&Request=GetCapabilities&acceptversions=3.0.0'>c03d173a-3f42-4956-89c8-1fe02c3a0873</a></li>
-<li><a href='../csw.py?elementName=undefined&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>cb43d8c3-e14c-4a9f-9231-4384b7dd21f3</a></li>
-<li><a href='../csw.py?acceptVersions=3.0.0§ions=ServiceProvider&request=GetCapabilities&service=CSW'>d03c6fd3-e821-4a26-b62f-d20a474e25af</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids=uid-bc5017e6-5cc8-4b03-aee7-d88f88caba0a'>d4ccbf96-a529-480e-a53d-5b88dc1dea7f</a></li>
-<li><a href='../csw.py?service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=lpppclq&bbox=&time=/&outputformat=application/xml&outputschema=http://www.opengis.net/cat/csw/3.0&startposition=1&maxrecords=&recordids='>d94c801a-1207-4897-b84a-53f3a192515b</a></li>
-<li><a href='../csw.py?id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63&elementSetName=full&request=GetRecordById&service=CSW&version=3.0.0'>da859e34-91fc-495a-8c09-285a40c0900b</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=ipsum&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids='>dc246fb8-5af5-4fda-82bb-c18b3ecd439c</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&elementsetname=full&typenames=csw:Record&resulttype=results&q=&bbox=&time=/&outputformat=application/atom%2Bxml&startposition=1&maxrecords=&recordids=urn%3Auuid%3A94bc9c83-97f6-4b40-9eb8-a8e8787a5c63'>de016645-6d5c-4855-943c-2db07ae9f49a</a></li>
-<li><a href='../csw.py?elementSetName=summary&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>dff3ec6b-bb2d-4887-bd17-8fcf15def042</a></li>
-<li><a href='../csw.py?id=urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd&elementSetName=brief&request=GetRecordById&service=CSW&version=3.0.0'>e38e6bfb-8ac4-4ae4-8b87-0aafbc8d3c6b</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/csw30/default.cfg'>e67ca935-d65d-4d8c-8302-1405333dded0</a></li>
-<li><a href='../csw.py?elementName=ns1:subject&elementSetName=brief&request=GetRecords&service=CSW&typeNames=Record&namespace=xmlns(ns1%3Dhttp://purl.org/dc/elements/1.1/)&version=3.0.0'>e7704509-3441-458f-8ef0-e333c6b6043f</a></li>
-<li><a href='../csw.py?elementSetName=summary&maxRecords=0&q=titles&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>f1223a49-6d08-44ff-97fe-4c32cbbfad82</a></li>
-<li><a href='../csw.py?elementSetName=full&outputFormat=text/example&request=GetRecords&service=CSW&typeNames=Record&version=3.0.0'>f89dd4e1-3a81-4433-afd2-a3fa1bdb1e18</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities'>GetCapabilities</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilitiese'>GetCapabilities-invalid-request</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full'>GetRecords-all</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:A'>GetRecords-sortby-asc</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:D'>GetRecords-sortby-desc</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:titlei:A'>GetRecords-sortby-invalid-propertyname</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&sortby=dc:title:FOO'>GetRecords-sortby-invalid-order</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=FILTER&constraint=%3Cogc%3AFilter%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%3E%3Cogc%3APropertyIsEqualTo%3E%3Cogc%3APropertyName%3Edc%3Atitle%3C%2Fogc%3APropertyName%3E%3Cogc%3ALiteral%3ELorem%20ipsum%3C%2Fogc%3ALiteral%3E%3C%2Fogc%3APropertyIsEqualTo%3E%3C%2Fogc%3AFilter%3E'>GetRecords-filter</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27'>GetRecords-filter-cql-title</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25Lorem%20ipsum%25%27'>GetRecords-filter-cql-title-with-spaces</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%25%27'>GetRecords-filter-cql-title-or-abstract</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25dolor%20sit%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%25%27'>GetRecords-filter-cql-title-with-spaces-or-abstract</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25lor%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%20in%25%27'>GetRecords-filter-cql-title-or-abstract-with-spaces</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&resulttype=results&constraintlanguage=CQL_TEXT&constraint=dc%3Atitle%20like%20%27%25dolor%20sit%25%27%20or%20dct%3Aabstract%20like%20%27%25pharetra%20in%25%27'>GetRecords-filter-cql-title-with-spaces-or-abstract-with-spaces</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRecords&typenames=csw:Record&elementsetname=full&maxrecords='>GetRecords-empty-maxrecords</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRepositoryItem&id=urn:uuid:94bc9c83-97f6-4b40-9eb8-a8e8787a5c63'>GetRepositoryItem</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetRepositoryItem&id=NOTFOUND'>Exception-GetRepositoryItem-notfound</a></li>
-<li><a href='../csw.py?service=CSW%00&version=2.0.2&request=GetRepositoryItem&id=123'>Exception-GetRepositoryItem-service-invalid1</a></li>
-<li><a href="../csw.py?service=CSW%00'&version=2.0.2&request=GetRepositoryItem&id=123">Exception-GetRepositoryItem-service-invalid2</a></li>
-<li><a href="../csw.py?service=CSW&version=2.0.2'&request=GetRepositoryItem&id=123">Exception-GetRepositoryItem-version-invalid</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities'>GetCapabilities</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest'>Exception-Harvest-missing-resourcetype</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest&resourcetype=http://www.opengis.net/wms'>Exception-Harvest-missing-source</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest&resourcetype=http://www.opengis.net/wms1234&source=http://demo.pycsw.org/cite/csw'>Exception-Harvest-invalid-resourcetype</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest&resourcetype=urn:geoss:waf&source=http://demo.pycsw.org'>Exception-Harvest-waf-no-records-found</a></li>
-<li><a href='../csw.py?PYCSW_SERVER?config=tests/suites/manager/default.cfg&service=CSW&version=2.0.2&request=Harvest&resourcetype=urn:geoss:waf&source=badvalue'>Exception-Harvest-waf-bad-value</a></li>
-<li><a href='../csw.py?service=CSW&version=2.0.2&request=GetCapabilities'>GetCapabilities</a></li>
-<li><a href='../csw.py?mode=oaipmh'>empty</a></li>
-<li><a href='../csw.py?mode=oaipmh&'>empty_with_amp</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=foo'>bad_verb</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=foo&foo=bar'>illegal_verb</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=Identify'>Identify</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListSets'>ListSets</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListMetadataFormats'>ListMetadataFormats</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=csw-record'>GetRecord_dc</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=csw-recordd'>GetRecord_bad_metadata_prefix</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=oai_dc'>GetRecord_oai_dc</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=GetRecord&identifier=urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f&metadataPrefix=iso19139'>GetRecord_iso</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListIdentifiers'>ListIdentifiers_missing_metadata_prefix</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListIdentifiers&metadataPrefix=csw-record'>ListIdentifiers_dc</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListIdentifiers&metadataPrefix=iso19139'>ListIdentifiers_iso</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListIdentifiers&metadataPrefix=oai_dc'>ListIdentifiers_oai_dc</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListIdentifiers&metadataPrefix=foo'>ListIdentifiers_bad_metadata_prefix</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListRecords&metadataPrefix=csw-record'>ListRecords_dc</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListRecords&metadataPrefix=csw-recording'>ListRecords_dc_bad_metadata_prefix</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListRecords&metadataPrefix=oai_dc'>ListRecords_oai_dc</a></li>
-<li><a href='../csw.py?mode=oaipmh&verb=ListRecords&metadataPrefix=iso19139'>ListRecords_iso19139</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetCapabilities'>opensearch-description-document</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&time=2009/2015'>opensearch-query-time-extent</a></li>
-<li><a href='../csw.py?mode=opensearch&service=CSW&version=3.0.0&request=GetRecords&typenames=csw:Record&elementset=full&start=2009&stop=2015'>opensearch-query-start-stop-extent</a></li>
-<li><a href='../csw.py?mode=sru'>explain</a></li>
-<li><a href='../csw.py?mode=sru&version=1.1&operation=searchRetrieve&query=lor'>search</a></li>
-<li><a href='../csw.py?mode=sru&operation=searchRetrieve&query=lor&maximumRecords=2'>search_maxrecords</a></li>
-<li><a href='../csw.py?mode=sru&operation=searchRetrieve&query=lor&maximumRecords=2&startRecord=1'>search_startrecord_maxrecords</a></li>
-<li><a href="../csw.py?mode=sru&operation=searchRetrieve&query=dc:title%20like%20'%lor%'&maximumRecords=5">search_cql</a></li>
-
- </ul>
- <hr/>
- <footer>
- <a href="http://validator.w3.org/check?verbose=1&uri=referer" title="Valid HTML 5!"><img class="flat" src="http://www.w3.org/html/logo/downloads/HTML5_Badge_32.png" alt="Valid HTML 5!" height="32" width="32"/></a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS!"><img class="flat" src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS!" height="31" width="88"/></a>
- </footer>
- </body>
-</html>
-
View it on GitLab: https://salsa.debian.org/debian-gis-team/pycsw/-/compare/e4d75b40f27ba90256b74a7b542beb27150a8d66...0b9eb970eab8c72ef713312a363afdf0a2265cb2
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/pycsw/-/compare/e4d75b40f27ba90256b74a7b542beb27150a8d66...0b9eb970eab8c72ef713312a363afdf0a2265cb2
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20250222/fb747464/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list