geonode-pycsw 3.0.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. geonode_pycsw-3.0.0b2.dist-info/METADATA +73 -0
  2. geonode_pycsw-3.0.0b2.dist-info/RECORD +382 -0
  3. geonode_pycsw-3.0.0b2.dist-info/WHEEL +5 -0
  4. geonode_pycsw-3.0.0b2.dist-info/entry_points.txt +2 -0
  5. geonode_pycsw-3.0.0b2.dist-info/licenses/LICENSE.txt +26 -0
  6. geonode_pycsw-3.0.0b2.dist-info/top_level.txt +1 -0
  7. pycsw/__init__.py +33 -0
  8. pycsw/core/__init__.py +29 -0
  9. pycsw/core/admin.py +703 -0
  10. pycsw/core/config.py +621 -0
  11. pycsw/core/etree.py +43 -0
  12. pycsw/core/formats/__init__.py +29 -0
  13. pycsw/core/formats/fmt_json.py +69 -0
  14. pycsw/core/log.py +71 -0
  15. pycsw/core/metadata.py +1996 -0
  16. pycsw/core/pygeofilter_evaluate.py +83 -0
  17. pycsw/core/repository.py +941 -0
  18. pycsw/core/schemas/ogc/cat/csw/3.0/_wrapper.xsd +14 -0
  19. pycsw/core/schemas/ogc/cat/csw/3.0/cswAll.xsd +33 -0
  20. pycsw/core/schemas/ogc/cat/csw/3.0/cswCommon.xsd +71 -0
  21. pycsw/core/schemas/ogc/cat/csw/3.0/cswGetCapabilities.xsd +80 -0
  22. pycsw/core/schemas/ogc/cat/csw/3.0/cswGetDomain.xsd +146 -0
  23. pycsw/core/schemas/ogc/cat/csw/3.0/cswGetRecordById.xsd +58 -0
  24. pycsw/core/schemas/ogc/cat/csw/3.0/cswGetRecords.xsd +391 -0
  25. pycsw/core/schemas/ogc/cat/csw/3.0/cswHarvest.xsd +95 -0
  26. pycsw/core/schemas/ogc/cat/csw/3.0/cswTransaction.xsd +187 -0
  27. pycsw/core/schemas/ogc/cat/csw/3.0/cswUnHarvest.xsd +77 -0
  28. pycsw/core/schemas/ogc/cat/csw/3.0/rec-dcmes.xsd +245 -0
  29. pycsw/core/schemas/ogc/cat/csw/3.0/rec-dcterms.xsd +101 -0
  30. pycsw/core/schemas/ogc/cat/csw/3.0/record.xsd +170 -0
  31. pycsw/core/schemas/ogc/csw/2.0.2/CSW-discovery.xsd +494 -0
  32. pycsw/core/schemas/ogc/csw/2.0.2/CSW-publication.xsd +242 -0
  33. pycsw/core/schemas/ogc/csw/2.0.2/rec-dcmes.xsd +199 -0
  34. pycsw/core/schemas/ogc/csw/2.0.2/rec-dcterms.xsd +94 -0
  35. pycsw/core/schemas/ogc/csw/2.0.2/record.xsd +138 -0
  36. pycsw/core/schemas/ogc/filter/1.1.0/expr.xsd +67 -0
  37. pycsw/core/schemas/ogc/filter/1.1.0/filter.xsd +265 -0
  38. pycsw/core/schemas/ogc/filter/1.1.0/filterCapabilities.xsd +171 -0
  39. pycsw/core/schemas/ogc/filter/1.1.0/sort.xsd +46 -0
  40. pycsw/core/schemas/ogc/filter/2.0/_wrapper.xsd +5 -0
  41. pycsw/core/schemas/ogc/filter/2.0/expr.xsd +44 -0
  42. pycsw/core/schemas/ogc/filter/2.0/filter.xsd +396 -0
  43. pycsw/core/schemas/ogc/filter/2.0/filterAll.xsd +23 -0
  44. pycsw/core/schemas/ogc/filter/2.0/filterCapabilities.xsd +286 -0
  45. pycsw/core/schemas/ogc/filter/2.0/query.xsd +70 -0
  46. pycsw/core/schemas/ogc/filter/2.0/sort.xsd +49 -0
  47. pycsw/core/schemas/ogc/gml/3.1.1/base/basicTypes.xsd +278 -0
  48. pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateOperations.xsd +789 -0
  49. pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateReferenceSystems.xsd +429 -0
  50. pycsw/core/schemas/ogc/gml/3.1.1/base/coordinateSystems.xsd +408 -0
  51. pycsw/core/schemas/ogc/gml/3.1.1/base/coverage.xsd +451 -0
  52. pycsw/core/schemas/ogc/gml/3.1.1/base/dataQuality.xsd +129 -0
  53. pycsw/core/schemas/ogc/gml/3.1.1/base/datums.xsd +484 -0
  54. pycsw/core/schemas/ogc/gml/3.1.1/base/defaultStyle.xsd +454 -0
  55. pycsw/core/schemas/ogc/gml/3.1.1/base/dictionary.xsd +137 -0
  56. pycsw/core/schemas/ogc/gml/3.1.1/base/direction.xsd +72 -0
  57. pycsw/core/schemas/ogc/gml/3.1.1/base/dynamicFeature.xsd +115 -0
  58. pycsw/core/schemas/ogc/gml/3.1.1/base/feature.xsd +199 -0
  59. pycsw/core/schemas/ogc/gml/3.1.1/base/geometryAggregates.xsd +430 -0
  60. pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic0d1d.xsd +602 -0
  61. pycsw/core/schemas/ogc/gml/3.1.1/base/geometryBasic2d.xsd +213 -0
  62. pycsw/core/schemas/ogc/gml/3.1.1/base/geometryComplexes.xsd +141 -0
  63. pycsw/core/schemas/ogc/gml/3.1.1/base/geometryPrimitives.xsd +1609 -0
  64. pycsw/core/schemas/ogc/gml/3.1.1/base/gml.xsd +22 -0
  65. pycsw/core/schemas/ogc/gml/3.1.1/base/gmlBase.xsd +294 -0
  66. pycsw/core/schemas/ogc/gml/3.1.1/base/grids.xsd +76 -0
  67. pycsw/core/schemas/ogc/gml/3.1.1/base/measures.xsd +200 -0
  68. pycsw/core/schemas/ogc/gml/3.1.1/base/observation.xsd +96 -0
  69. pycsw/core/schemas/ogc/gml/3.1.1/base/referenceSystems.xsd +211 -0
  70. pycsw/core/schemas/ogc/gml/3.1.1/base/temporal.xsd +332 -0
  71. pycsw/core/schemas/ogc/gml/3.1.1/base/temporalReferenceSystems.xsd +251 -0
  72. pycsw/core/schemas/ogc/gml/3.1.1/base/temporalTopology.xsd +186 -0
  73. pycsw/core/schemas/ogc/gml/3.1.1/base/topology.xsd +459 -0
  74. pycsw/core/schemas/ogc/gml/3.1.1/base/units.xsd +170 -0
  75. pycsw/core/schemas/ogc/gml/3.1.1/base/valueObjects.xsd +361 -0
  76. pycsw/core/schemas/ogc/gml/3.1.1/smil/smil20-language.xsd +117 -0
  77. pycsw/core/schemas/ogc/gml/3.1.1/smil/smil20.xsd +234 -0
  78. pycsw/core/schemas/ogc/gml/3.2.1/basicTypes.xsd +268 -0
  79. pycsw/core/schemas/ogc/gml/3.2.1/coordinateOperations.xsd +525 -0
  80. pycsw/core/schemas/ogc/gml/3.2.1/coordinateReferenceSystems.xsd +373 -0
  81. pycsw/core/schemas/ogc/gml/3.2.1/coordinateSystems.xsd +297 -0
  82. pycsw/core/schemas/ogc/gml/3.2.1/coverage.xsd +292 -0
  83. pycsw/core/schemas/ogc/gml/3.2.1/datums.xsd +287 -0
  84. pycsw/core/schemas/ogc/gml/3.2.1/defaultStyle.xsd +453 -0
  85. pycsw/core/schemas/ogc/gml/3.2.1/deprecatedTypes.xsd +1133 -0
  86. pycsw/core/schemas/ogc/gml/3.2.1/dictionary.xsd +90 -0
  87. pycsw/core/schemas/ogc/gml/3.2.1/direction.xsd +84 -0
  88. pycsw/core/schemas/ogc/gml/3.2.1/dynamicFeature.xsd +109 -0
  89. pycsw/core/schemas/ogc/gml/3.2.1/feature.xsd +94 -0
  90. pycsw/core/schemas/ogc/gml/3.2.1/geometryAggregates.xsd +197 -0
  91. pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic0d1d.xsd +277 -0
  92. pycsw/core/schemas/ogc/gml/3.2.1/geometryBasic2d.xsd +124 -0
  93. pycsw/core/schemas/ogc/gml/3.2.1/geometryComplexes.xsd +95 -0
  94. pycsw/core/schemas/ogc/gml/3.2.1/geometryPrimitives.xsd +846 -0
  95. pycsw/core/schemas/ogc/gml/3.2.1/gml.xsd +20 -0
  96. pycsw/core/schemas/ogc/gml/3.2.1/gmlBase.xsd +185 -0
  97. pycsw/core/schemas/ogc/gml/3.2.1/grids.xsd +64 -0
  98. pycsw/core/schemas/ogc/gml/3.2.1/measures.xsd +68 -0
  99. pycsw/core/schemas/ogc/gml/3.2.1/observation.xsd +95 -0
  100. pycsw/core/schemas/ogc/gml/3.2.1/referenceSystems.xsd +70 -0
  101. pycsw/core/schemas/ogc/gml/3.2.1/temporal.xsd +269 -0
  102. pycsw/core/schemas/ogc/gml/3.2.1/temporalReferenceSystems.xsd +189 -0
  103. pycsw/core/schemas/ogc/gml/3.2.1/temporalTopology.xsd +119 -0
  104. pycsw/core/schemas/ogc/gml/3.2.1/topology.xsd +386 -0
  105. pycsw/core/schemas/ogc/gml/3.2.1/units.xsd +162 -0
  106. pycsw/core/schemas/ogc/gml/3.2.1/valueObjects.xsd +205 -0
  107. pycsw/core/schemas/ogc/ogcapi/records/part1/1.0/ogcapi-records-1.yaml +932 -0
  108. pycsw/core/schemas/ogc/ows/1.0.0/ows19115subset.xsd +222 -0
  109. pycsw/core/schemas/ogc/ows/1.0.0/owsAll.xsd +20 -0
  110. pycsw/core/schemas/ogc/ows/1.0.0/owsCommon.xsd +155 -0
  111. pycsw/core/schemas/ogc/ows/1.0.0/owsDataIdentification.xsd +112 -0
  112. pycsw/core/schemas/ogc/ows/1.0.0/owsExceptionReport.xsd +67 -0
  113. pycsw/core/schemas/ogc/ows/1.0.0/owsGetCapabilities.xsd +108 -0
  114. pycsw/core/schemas/ogc/ows/1.0.0/owsOperationsMetadata.xsd +161 -0
  115. pycsw/core/schemas/ogc/ows/1.0.0/owsServiceIdentification.xsd +55 -0
  116. pycsw/core/schemas/ogc/ows/1.0.0/owsServiceProvider.xsd +46 -0
  117. pycsw/core/schemas/ogc/ows/1.1.0/ows19115subset.xsd +236 -0
  118. pycsw/core/schemas/ogc/ows/1.1.0/owsAll.xsd +23 -0
  119. pycsw/core/schemas/ogc/ows/1.1.0/owsCommon.xsd +158 -0
  120. pycsw/core/schemas/ogc/ows/1.1.0/owsContents.xsd +87 -0
  121. pycsw/core/schemas/ogc/ows/1.1.0/owsDataIdentification.xsd +128 -0
  122. pycsw/core/schemas/ogc/ows/1.1.0/owsDomainType.xsd +280 -0
  123. pycsw/core/schemas/ogc/ows/1.1.0/owsExceptionReport.xsd +77 -0
  124. pycsw/core/schemas/ogc/ows/1.1.0/owsGetCapabilities.xsd +113 -0
  125. pycsw/core/schemas/ogc/ows/1.1.0/owsGetResourceByID.xsd +52 -0
  126. pycsw/core/schemas/ogc/ows/1.1.0/owsInputOutputData.xsd +60 -0
  127. pycsw/core/schemas/ogc/ows/1.1.0/owsManifest.xsd +125 -0
  128. pycsw/core/schemas/ogc/ows/1.1.0/owsOperationsMetadata.xsd +141 -0
  129. pycsw/core/schemas/ogc/ows/1.1.0/owsServiceIdentification.xsd +61 -0
  130. pycsw/core/schemas/ogc/ows/1.1.0/owsServiceProvider.xsd +48 -0
  131. pycsw/core/schemas/ogc/ows/2.0/ows19115subset.xsd +364 -0
  132. pycsw/core/schemas/ogc/ows/2.0/owsAdditionalParameters.xsd +114 -0
  133. pycsw/core/schemas/ogc/ows/2.0/owsAll.xsd +29 -0
  134. pycsw/core/schemas/ogc/ows/2.0/owsCommon.xsd +275 -0
  135. pycsw/core/schemas/ogc/ows/2.0/owsContents.xsd +163 -0
  136. pycsw/core/schemas/ogc/ows/2.0/owsDataIdentification.xsd +202 -0
  137. pycsw/core/schemas/ogc/ows/2.0/owsDomainType.xsd +388 -0
  138. pycsw/core/schemas/ogc/ows/2.0/owsExceptionReport.xsd +126 -0
  139. pycsw/core/schemas/ogc/ows/2.0/owsGetCapabilities.xsd +220 -0
  140. pycsw/core/schemas/ogc/ows/2.0/owsGetResourceByID.xsd +83 -0
  141. pycsw/core/schemas/ogc/ows/2.0/owsInputOutputData.xsd +98 -0
  142. pycsw/core/schemas/ogc/ows/2.0/owsManifest.xsd +181 -0
  143. pycsw/core/schemas/ogc/ows/2.0/owsOperationsMetadata.xsd +234 -0
  144. pycsw/core/schemas/ogc/ows/2.0/owsServiceIdentification.xsd +98 -0
  145. pycsw/core/schemas/ogc/ows/2.0/owsServiceProvider.xsd +64 -0
  146. pycsw/core/schemas/w3c/1999/xlink.xsd +271 -0
  147. pycsw/core/schemas/w3c/2001/xml.xsd +287 -0
  148. pycsw/core/util.py +552 -0
  149. pycsw/oaipmh.py +311 -0
  150. pycsw/ogc/__init__.py +29 -0
  151. pycsw/ogc/api/__init__.py +28 -0
  152. pycsw/ogc/api/oapi.py +558 -0
  153. pycsw/ogc/api/records.py +1414 -0
  154. pycsw/ogc/api/templates/_base.html +76 -0
  155. pycsw/ogc/api/templates/collection.html +44 -0
  156. pycsw/ogc/api/templates/collections.html +45 -0
  157. pycsw/ogc/api/templates/conformance.html +21 -0
  158. pycsw/ogc/api/templates/exception.html +8 -0
  159. pycsw/ogc/api/templates/item.html +228 -0
  160. pycsw/ogc/api/templates/items.html +337 -0
  161. pycsw/ogc/api/templates/landing_page.html +27 -0
  162. pycsw/ogc/api/templates/openapi.html +58 -0
  163. pycsw/ogc/api/templates/queryables.html +50 -0
  164. pycsw/ogc/api/templates/stac_items.html +173 -0
  165. pycsw/ogc/api/templates/static/favicon.ico +0 -0
  166. pycsw/ogc/api/templates/static/logo-horizontal.png +0 -0
  167. pycsw/ogc/api/templates/static/logo-vertical-darkbg.png +0 -0
  168. pycsw/ogc/api/util.py +252 -0
  169. pycsw/ogc/csw/__init__.py +29 -0
  170. pycsw/ogc/csw/cql.py +133 -0
  171. pycsw/ogc/csw/csw2.py +2042 -0
  172. pycsw/ogc/csw/csw3.py +2193 -0
  173. pycsw/ogc/fes/__init__.py +29 -0
  174. pycsw/ogc/fes/fes1.py +433 -0
  175. pycsw/ogc/fes/fes2.py +451 -0
  176. pycsw/ogc/gml/__init__.py +29 -0
  177. pycsw/ogc/gml/gml3.py +240 -0
  178. pycsw/ogc/gml/gml32.py +243 -0
  179. pycsw/opensearch.py +857 -0
  180. pycsw/plugins/__init__.py +29 -0
  181. pycsw/plugins/outputschemas/__init__.py +31 -0
  182. pycsw/plugins/outputschemas/atom.py +143 -0
  183. pycsw/plugins/outputschemas/datacite.py +375 -0
  184. pycsw/plugins/outputschemas/dif.py +213 -0
  185. pycsw/plugins/outputschemas/fgdc.py +180 -0
  186. pycsw/plugins/outputschemas/gm03.py +240 -0
  187. pycsw/plugins/profiles/__init__.py +29 -0
  188. pycsw/plugins/profiles/apiso/__init__.py +29 -0
  189. pycsw/plugins/profiles/apiso/apiso.py +757 -0
  190. pycsw/plugins/profiles/apiso/schemas/ogc/csw/2.0.2/profiles/apiso/1.0.0/apiso.xsd +13 -0
  191. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/basicTypes.xsd +429 -0
  192. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gco.xsd +12 -0
  193. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gco/gcoBase.xsd +61 -0
  194. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/applicationSchema.xsd +42 -0
  195. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/citation.xsd +275 -0
  196. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/constraints.xsd +106 -0
  197. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/content.xsd +188 -0
  198. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/dataQuality.xsd +554 -0
  199. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/distribution.xsd +202 -0
  200. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/extent.xsd +205 -0
  201. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/freeText.xsd +122 -0
  202. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/gmd.xsd +12 -0
  203. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/identification.xsd +348 -0
  204. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/maintenance.xsd +86 -0
  205. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataApplication.xsd +175 -0
  206. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataEntity.xsd +70 -0
  207. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/metadataExtension.xsd +99 -0
  208. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/portrayalCatalogue.xsd +36 -0
  209. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/referenceSystem.xsd +100 -0
  210. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmd/spatialRepresentation.xsd +237 -0
  211. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/basicTypes.xsd +267 -0
  212. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateOperations.xsd +639 -0
  213. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateReferenceSystems.xsd +526 -0
  214. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coordinateSystems.xsd +401 -0
  215. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/coverage.xsd +462 -0
  216. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/datums.xsd +342 -0
  217. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/dictionary.xsd +129 -0
  218. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/direction.xsd +80 -0
  219. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/dynamicFeature.xsd +142 -0
  220. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/feature.xsd +215 -0
  221. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryAggregates.xsd +216 -0
  222. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryBasic0d1d.xsd +304 -0
  223. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryBasic2d.xsd +123 -0
  224. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryComplexes.xsd +89 -0
  225. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/geometryPrimitives.xsd +892 -0
  226. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gml.xsd +14 -0
  227. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/gmlBase.xsd +305 -0
  228. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/grids.xsd +58 -0
  229. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/measures.xsd +167 -0
  230. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/observation.xsd +90 -0
  231. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/referenceSystems.xsd +69 -0
  232. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporal.xsd +263 -0
  233. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporalReferenceSystems.xsd +183 -0
  234. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/temporalTopology.xsd +124 -0
  235. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/topology.xsd +372 -0
  236. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/units.xsd +156 -0
  237. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gml/valueObjects.xsd +212 -0
  238. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/catalogues.xsd +112 -0
  239. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/codelistItem.xsd +168 -0
  240. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/crsItem.xsd +1030 -0
  241. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/extendedTypes.xsd +75 -0
  242. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/gmx.xsd +2 -0
  243. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/gmxUsage.xsd +127 -0
  244. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gmx/uomItem.xsd +162 -0
  245. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gsr/gsr.xsd +12 -0
  246. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gsr/spatialReferencing.xsd +24 -0
  247. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gss/geometry.xsd +35 -0
  248. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gss/gss.xsd +12 -0
  249. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gts/gts.xsd +12 -0
  250. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/gts/temporalObjects.xsd +34 -0
  251. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/serviceMetadata.xsd +197 -0
  252. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/serviceModel.xsd +220 -0
  253. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20060504/srv/srv.xsd +13 -0
  254. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/basicTypes.xsd +431 -0
  255. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gco.xsd +12 -0
  256. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gco/gcoBase.xsd +63 -0
  257. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/applicationSchema.xsd +43 -0
  258. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/citation.xsd +276 -0
  259. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/constraints.xsd +107 -0
  260. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/content.xsd +190 -0
  261. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/dataQuality.xsd +556 -0
  262. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/distribution.xsd +203 -0
  263. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/extent.xsd +206 -0
  264. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/freeText.xsd +123 -0
  265. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/gmd.xsd +12 -0
  266. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/identification.xsd +349 -0
  267. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/maintenance.xsd +87 -0
  268. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataApplication.xsd +176 -0
  269. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataEntity.xsd +71 -0
  270. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/metadataExtension.xsd +100 -0
  271. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/portrayalCatalogue.xsd +37 -0
  272. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/referenceSystem.xsd +101 -0
  273. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmd/spatialRepresentation.xsd +238 -0
  274. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/catalogues.xsd +113 -0
  275. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/codelistItem.xsd +169 -0
  276. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/crsItem.xsd +1031 -0
  277. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/extendedTypes.xsd +76 -0
  278. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmx.xsd +12 -0
  279. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/gmxUsage.xsd +128 -0
  280. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gmx/uomItem.xsd +163 -0
  281. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/gsr.xsd +12 -0
  282. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gsr/spatialReferencing.xsd +25 -0
  283. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/geometry.xsd +36 -0
  284. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gss/gss.xsd +12 -0
  285. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/gts.xsd +12 -0
  286. pycsw/plugins/profiles/apiso/schemas/ogc/iso/19139/20070417/gts/temporalObjects.xsd +35 -0
  287. pycsw/plugins/profiles/ebrim/__init__.py +29 -0
  288. pycsw/plugins/profiles/ebrim/ebrim.py +174 -0
  289. pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim-iri.xsd +146 -0
  290. pycsw/plugins/profiles/ebrim/schemas/ogc/csw/2.0.2/profiles/ebrim/1.0/csw-ebrim.xsd +104 -0
  291. pycsw/plugins/profiles/iso19115p3/__init__.py +29 -0
  292. pycsw/plugins/profiles/iso19115p3/iso19115p3.py +854 -0
  293. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/cat.xsd +13 -0
  294. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/catalogues.xsd +53 -0
  295. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/codelistItem.xsd +54 -0
  296. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/crsItem.xsd +181 -0
  297. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cat/1.0/uomItem.xsd +38 -0
  298. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/cit.xsd +7 -0
  299. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/1.0/citation.xsd +514 -0
  300. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/2.0/cit.xsd +10 -0
  301. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/cit/2.0/citation.xsd +523 -0
  302. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gco/1.0/baseTypes2014.xsd +530 -0
  303. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gco/1.0/gco.xsd +16 -0
  304. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/extendedTypes.xsd +92 -0
  305. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/extendedTypes_autoFromShapeChange.xsd +60 -0
  306. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gcx/1.0/gcx.xsd +8 -0
  307. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/extent.xsd +241 -0
  308. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gex/1.0/gex.xsd +9 -0
  309. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gmw/1.0/gmlWrapperTypes2014.xsd +159 -0
  310. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/gmw/1.0/gmw.xsd +14 -0
  311. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/lan/1.0/lan.xsd +8 -0
  312. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/lan/1.0/language.xsd +140 -0
  313. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/1.0/acquisitionInformationImagery.xsd +622 -0
  314. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/1.0/mac.xsd +11 -0
  315. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/acquisitionInformationImagery.xsd +590 -0
  316. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/event.xsd +108 -0
  317. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mac/2.0/mac.xsd +10 -0
  318. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mas/1.0/applicationSchema.xsd +61 -0
  319. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mas/1.0/mas.xsd +9 -0
  320. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/AbstractCommonClasses.xsd +358 -0
  321. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/commonClasses.xsd +220 -0
  322. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mcc/1.0/mcc.xsd +8 -0
  323. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/constraints.xsd +188 -0
  324. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mco/1.0/mco.xsd +8 -0
  325. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md1/1.0/md1.xsd +9 -0
  326. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md1/1.0/metadataWExtendedType.xsd +4 -0
  327. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md2/1.0/md2.xsd +15 -0
  328. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/md2/1.0/metadataWithExtensions.xsd +4 -0
  329. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mda/1.0/mda.xsd +8 -0
  330. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mda/1.0/metadataApplication.xsd +200 -0
  331. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/mdb.xsd +14 -0
  332. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/1.0/metadataBase.xsd +98 -0
  333. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/mdb.xsd +20 -0
  334. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdb/2.0/metadataBase.xsd +102 -0
  335. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mds/1.0/mds.xsd +22 -0
  336. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mds/1.0/metadataDataServices.xsd +4 -0
  337. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdt/1.0/mdt.xsd +13 -0
  338. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mdt/1.0/metadataTransfer.xsd +111 -0
  339. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/metadataExtension.xsd +156 -0
  340. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mex/1.0/mex.xsd +8 -0
  341. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/maintenance.xsd +76 -0
  342. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mmi/1.0/mmi.xsd +8 -0
  343. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mpc/1.0/mpc.xsd +8 -0
  344. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mpc/1.0/portrayalCatalogue.xsd +31 -0
  345. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/content.xsd +416 -0
  346. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/contentInformationImagery.xsd +185 -0
  347. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/1.0/mrc.xsd +11 -0
  348. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/content.xsd +419 -0
  349. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/contentInformationImagery.xsd +171 -0
  350. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrc/2.0/mrc.xsd +11 -0
  351. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/distribution.xsd +267 -0
  352. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrd/1.0/mrd.xsd +8 -0
  353. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/identification.xsd +517 -0
  354. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mri/1.0/mri.xsd +9 -0
  355. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/lineage.xsd +147 -0
  356. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/lineageImagery.xsd +236 -0
  357. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/1.0/mrl.xsd +9 -0
  358. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/lineage.xsd +147 -0
  359. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/lineageImagery.xsd +312 -0
  360. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrl/2.0/mrl.xsd +11 -0
  361. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/mrs.xsd +8 -0
  362. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/mrs/1.0/referenceSystem.xsd +47 -0
  363. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/msr.xsd +10 -0
  364. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/spatialRepresentation.xsd +375 -0
  365. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/1.0/spatialRepresentationImagery.xsd +119 -0
  366. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/msr.xsd +15 -0
  367. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/spatialRepresentation.xsd +381 -0
  368. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/msr/2.0/spatialRepresentationImagery.xsd +120 -0
  369. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/serviceInformation.xsd +272 -0
  370. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.0/srv.xsd +6 -0
  371. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.1/serviceInformation.xsd +278 -0
  372. pycsw/plugins/profiles/iso19115p3/schemas/ogc/iso/iso19115-3/srv/2.1/srv.xsd +6 -0
  373. pycsw/plugins/profiles/profile.py +141 -0
  374. pycsw/plugins/repository/__init__.py +29 -0
  375. pycsw/plugins/repository/odc/__init__.py +29 -0
  376. pycsw/plugins/repository/odc/odc.py +153 -0
  377. pycsw/server.py +938 -0
  378. pycsw/sru.py +217 -0
  379. pycsw/stac/__init__.py +29 -0
  380. pycsw/stac/api.py +571 -0
  381. pycsw/wsgi.py +233 -0
  382. pycsw/wsgi_flask.py +345 -0
pycsw/stac/api.py ADDED
@@ -0,0 +1,571 @@
1
+ # =================================================================
2
+ #
3
+ # Authors: Tom Kralidis <tomkralidis@gmail.com>
4
+ #
5
+ # Copyright (c) 2024 Tom Kralidis
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person
8
+ # obtaining a copy of this software and associated documentation
9
+ # files (the "Software"), to deal in the Software without
10
+ # restriction, including without limitation the rights to use,
11
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following
14
+ # conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be
17
+ # included in all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26
+ # OTHER DEALINGS IN THE SOFTWARE.
27
+ #
28
+ # =================================================================
29
+
30
+ from copy import deepcopy
31
+ import json
32
+ import logging
33
+ import os
34
+
35
+ from pygeofilter.parsers.ecql import parse as parse_ecql
36
+
37
+ from pycsw import __version__
38
+ from pycsw.core.pygeofilter_evaluate import to_filter
39
+ from pycsw.ogc.api.oapi import gen_oapi
40
+ from pycsw.ogc.api.records import API, build_anytext
41
+ from pycsw.core.util import geojson_geometry2bbox, wkt2geom
42
+
43
+ LOGGER = logging.getLogger(__name__)
44
+
45
+ #: Return headers for requests (e.g:X-Powered-By)
46
+ HEADERS = {
47
+ 'Content-Type': 'application/json',
48
+ 'X-Powered-By': f'pycsw {__version__}'
49
+ }
50
+
51
+ THISDIR = os.path.dirname(os.path.realpath(__file__))
52
+
53
+
54
+ CONFORMANCE_CLASSES = [
55
+ 'http://www.opengis.net/spec/ogcapi-common-1/1.0/conf/core',
56
+ 'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/collections',
57
+ 'http://www.opengis.net/spec/ogcapi-common-2/1.0/conf/simple-query',
58
+ 'http://www.opengis.net/spec/ogcapi-features-1/1.0/conf/core',
59
+ 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables',
60
+ 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/queryables-query-parameters',
61
+ 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/filter',
62
+ 'http://www.opengis.net/spec/ogcapi-features-3/1.0/conf/features-filter',
63
+ 'http://www.opengis.net/spec/ogcapi-features-4/1.0/conf/create-replace-delete',
64
+ 'http://www.opengis.net/spec/cql2/1.0/conf/cql2-json',
65
+ 'http://www.opengis.net/spec/cql2/1.0/conf/cql2-text',
66
+ 'https://api.stacspec.org/v1.0.0/core',
67
+ 'https://api.stacspec.org/v1.0.0/ogcapi-features',
68
+ 'https://api.stacspec.org/v1.0.0/item-search',
69
+ 'https://api.stacspec.org/v1.0.0/item-search#filter',
70
+ 'https://api.stacspec.org/v1.0.0/item-search#free-text',
71
+ 'https://api.stacspec.org/v1.0.0-rc.1/collection-search',
72
+ 'https://api.stacspec.org/v1.0.0-rc.1/collection-search#free-text',
73
+ 'https://api.stacspec.org/v1.0.0/collections/extensions/transaction',
74
+ 'https://api.stacspec.org/v1.0.0/ogcapi-features/extensions/transaction'
75
+ ]
76
+
77
+
78
+ class STACAPI(API):
79
+ """STAC API object"""
80
+
81
+ def __init__(self, config: dict):
82
+ """
83
+ constructor
84
+
85
+ :param config: pycsw configuration dict
86
+
87
+ :returns: `pycsw.ogc.api.STACAPI` instance
88
+ """
89
+
90
+ super().__init__(config)
91
+ self.mode = 'stac-api'
92
+
93
+ self.config['server']['url'] += '/stac'
94
+ LOGGER.debug(f"Server URL: {self.config['server']['url']}")
95
+
96
+ def landing_page(self, headers_, args):
97
+ """
98
+ Provide API landing page
99
+
100
+ :param headers_: copy of HEADERS object
101
+ :param args: request parameters
102
+
103
+ :returns: tuple of headers, status code, content
104
+ """
105
+
106
+ headers_['Content-Type'] = 'application/json'
107
+
108
+ response = {
109
+ 'stac_version': '1.0.0',
110
+ 'id': 'pycsw-catalogue',
111
+ 'type': 'Catalog',
112
+ 'conformsTo': CONFORMANCE_CLASSES,
113
+ 'links': [],
114
+ 'title': self.config['metadata']['identification']['title'],
115
+ 'description':
116
+ self.config['metadata']['identification']['description'],
117
+ 'keywords':
118
+ self.config['metadata']['identification']['keywords']
119
+ }
120
+
121
+ LOGGER.debug('Creating links')
122
+ response['links'] = [{
123
+ 'rel': 'self',
124
+ 'type': 'application/json',
125
+ 'href': f"{self.config['server']['url']}/"
126
+ }, {
127
+ 'rel': 'root',
128
+ 'type': 'application/json',
129
+ 'href': f"{self.config['server']['url']}/"
130
+ }, {
131
+ 'rel': 'service-doc',
132
+ 'type': 'text/html',
133
+ 'href': f"{self.config['server']['url']}/openapi?f=html"
134
+ }, {
135
+ 'rel': 'service-desc',
136
+ 'type': 'application/vnd.oai.openapi+json;version=3.0',
137
+ 'href': f"{self.config['server']['url']}/openapi?f=json"
138
+ }, {
139
+ 'rel': 'conformance',
140
+ 'type': 'application/json',
141
+ 'href': f"{self.config['server']['url']}/conformance"
142
+ }, {
143
+ 'rel': 'data',
144
+ 'type': 'application/json',
145
+ 'href': f"{self.config['server']['url']}/collections"
146
+ }, {
147
+ 'rel': 'http://www.opengis.net/def/rel/ogc/1.0/queryables',
148
+ 'type': 'application/schema+json',
149
+ 'title': 'Queryables',
150
+ 'href': f"{self.config['server']['url']}/queryables"
151
+ }, {
152
+ 'rel': 'search',
153
+ 'type': 'application/geo+json',
154
+ 'href': f"{self.config['server']['url']}/search"
155
+ }
156
+ ]
157
+
158
+ return self.get_response(200, headers_, response)
159
+
160
+ def openapi(self, headers_, args):
161
+ """
162
+ Provide OpenAPI document / Swagger
163
+
164
+ :param headers_: copy of HEADERS object
165
+ :param args: request parameters
166
+
167
+ :returns: tuple of headers, status code, content
168
+ """
169
+
170
+ headers_['Content-Type'] = self.get_content_type(headers_, args)
171
+ if headers_['Content-Type'] == 'application/json':
172
+ headers_['Content-Type'] = 'application/vnd.oai.openapi+json;version=3.0'
173
+
174
+ filepath = f"{THISDIR}/../core/schemas/ogc/ogcapi/records/part1/1.0/ogcapi-records-1.yaml"
175
+
176
+ response = gen_oapi(self.config, filepath, self.mode)
177
+
178
+ return self.get_response(200, headers_, response, 'openapi.html')
179
+
180
+ def conformance(self, headers_, args):
181
+ """
182
+ Provide API conformance
183
+
184
+ :param headers_: copy of HEADERS object
185
+ :param args: request parameters
186
+
187
+ :returns: tuple of headers, status code, content
188
+ """
189
+
190
+ headers_['Content-Type'] = 'application/json'
191
+ headers_['Accept'] = 'application/json'
192
+
193
+ response = {
194
+ 'conformsTo': CONFORMANCE_CLASSES
195
+ }
196
+
197
+ return self.get_response(200, headers_, response)
198
+
199
+ def collections(self, headers_, args):
200
+ """
201
+ Provide API collections
202
+
203
+ :param headers_: copy of HEADERS object
204
+ :param args: request parameters
205
+
206
+ :returns: tuple of headers, status code, content
207
+ """
208
+
209
+ headers_['Content-Type'] = 'application/json'
210
+
211
+ collections = []
212
+
213
+ # LOGGER.debug('Generating default metadata:main collection')
214
+ # collection_info = self.get_collection_info()
215
+ # collections.append(collection_info)
216
+
217
+ LOGGER.debug('Generating virtual collections')
218
+
219
+ filters = None
220
+ query_args = []
221
+
222
+ LOGGER.debug('Handling collection level search')
223
+ for k, v in args.items():
224
+ if k == 'bbox':
225
+ query_args.append(f'BBOX(geometry, {v})')
226
+ elif k == 'datetime':
227
+ if '/' not in v:
228
+ query_args.append(f'date = "{v}"')
229
+ else:
230
+ begin, end = v.split('/')
231
+ if begin != '..':
232
+ query_args.append(f'time_begin >= "{begin}"')
233
+ if end != '..':
234
+ query_args.append(f'time_end <= "{end}"')
235
+ elif k == 'q':
236
+ if v not in [None, '']:
237
+ query_args.append(build_anytext('anytext', v))
238
+
239
+ limit = int(args.get('limit', self.config['server']['maxrecords']))
240
+
241
+ if query_args:
242
+ ast = parse_ecql(' AND '.join(query_args))
243
+ LOGGER.debug(f'Abstract syntax tree: {ast}')
244
+ filters = to_filter(ast, self.repository.dbtype, self.repository.query_mappings)
245
+ LOGGER.debug(f'Filter: {filters}')
246
+
247
+ virtual_collections = self.repository.query_collections(filters, limit)
248
+
249
+ for virtual_collection in virtual_collections:
250
+ virtual_collection_info = self.get_collection_info(
251
+ virtual_collection.identifier, virtual_collection)
252
+
253
+ collections.append(virtual_collection_info)
254
+
255
+ response = {
256
+ 'collections': collections
257
+ }
258
+
259
+ LOGGER.debug('Generating STAC collections')
260
+
261
+ query_args.append("typename = 'stac:Collection'")
262
+ ast = parse_ecql(' AND '.join(query_args))
263
+ LOGGER.debug(f'Abstract syntax tree: {ast}')
264
+ filters = to_filter(ast, self.repository.dbtype, self.repository.query_mappings)
265
+ LOGGER.debug(f'Filter: {filters}')
266
+ sc_query = self.repository.session.query(
267
+ self.repository.dataset).filter(filters).limit(limit).all()
268
+
269
+ for sc in sc_query:
270
+ id_found = False
271
+
272
+ for collection_ in response['collections']:
273
+ if sc.identifier == collection_['id']:
274
+ id_found = True
275
+
276
+ if not id_found:
277
+ LOGGER.debug('Adding STAC collection')
278
+ sc2 = sc
279
+ sc2.title = sc.title or sc.identifier
280
+ sc2.abstract = sc.abstract or sc.identifier
281
+ response['collections'].append(self.get_collection_info(
282
+ sc2.identifier, sc2
283
+ ))
284
+
285
+ url_base = f"{self.config['server']['url']}/collections"
286
+
287
+ for collection in response['collections']:
288
+ collection['links'].append({
289
+ 'rel': 'self',
290
+ 'type': 'application/json',
291
+ 'href': f"{url_base}/{collection['id']}"
292
+ })
293
+
294
+ response['links'] = [{
295
+ 'rel': 'self',
296
+ 'type': 'application/json',
297
+ 'href': url_base
298
+ }, {
299
+ 'rel': 'root',
300
+ 'type': 'application/json',
301
+ 'href': f"{self.config['server']['url']}/"
302
+ }, {
303
+ 'rel': 'parent',
304
+ 'type': 'application/json',
305
+ 'href': self.config['server']['url']
306
+ }]
307
+
308
+ response['collections'] = response['collections'][:limit]
309
+ response['numberMatched'] = len(response['collections'])
310
+ response['numberReturned'] = len(response['collections'])
311
+
312
+ return self.get_response(200, headers_, response)
313
+
314
+ def collection(self, headers_, args, collection='metadata:main'):
315
+ """
316
+ Provide API collections
317
+
318
+ :param headers_: copy of HEADERS object
319
+ :param args: request parameters
320
+ :param collection: collection name
321
+
322
+ :returns: tuple of headers, status code, content
323
+ """
324
+
325
+ headers_['Content-Type'] = 'application/json'
326
+
327
+ LOGGER.debug(f'Generating {collection} collection')
328
+
329
+ if collection == 'metadata:main':
330
+ collection_info = self.get_collection_info()
331
+ else:
332
+ try:
333
+ virtual_collection = self.repository.query_ids([collection])[0]
334
+ collection_info = self.get_collection_info(
335
+ virtual_collection.identifier, virtual_collection)
336
+ except IndexError:
337
+ return self.get_exception(
338
+ 404, headers_, 'InvalidParameterValue', 'STAC collection not found')
339
+
340
+ response = collection_info
341
+ url_base = f"{self.config['server']['url']}/collections/{collection}"
342
+
343
+ response['links'] = [{
344
+ 'rel': 'self',
345
+ 'type': 'application/json',
346
+ 'href': url_base
347
+ }, {
348
+ 'rel': 'root',
349
+ 'type': 'application/json',
350
+ 'href': f"{self.config['server']['url']}/"
351
+ }, {
352
+ 'rel': 'parent',
353
+ 'type': 'application/json',
354
+ 'href': f"{self.config['server']['url']}/collections"
355
+ }, {
356
+ 'rel': 'items',
357
+ 'type': 'application/geo+json',
358
+ 'href': f"{url_base}/items"
359
+ }]
360
+
361
+ return self.get_response(200, headers_, response)
362
+
363
+ def queryables(self, headers_, args, collection='metadata:main'):
364
+ """
365
+ Provide collection queryables
366
+
367
+ :param headers_: copy of HEADERS object
368
+ :param args: request parameters
369
+ :param collection: name of collection
370
+
371
+ :returns: tuple of headers, status code, content
372
+ """
373
+
374
+ headers_['Accept'] = 'application/json'
375
+ headers, status, response = super().queryables(headers_, args, collection)
376
+
377
+ return self.get_response(status, headers, json.loads(response))
378
+
379
+ def items(self, headers_, json_post_data, args, collection='metadata:main'):
380
+ """
381
+ Provide collection items
382
+
383
+ :param headers_: copy of HEADERS object
384
+ :param json_post_data: `dict` of JSON POST data
385
+ :param args: request parameters
386
+ :param collection: collection name
387
+
388
+ :returns: tuple of headers, status code, content
389
+ """
390
+
391
+ headers_['Accept'] = 'application/json'
392
+ headers, status, response = super().items(headers_, json_post_data, args, collection)
393
+
394
+ if collection not in self.get_all_collections():
395
+ msg = 'Invalid collection'
396
+ LOGGER.exception(msg)
397
+ return self.get_exception(400, headers_, 'InvalidParameterValue', msg)
398
+
399
+ response = json.loads(response)
400
+ response2 = deepcopy(response)
401
+ response2['features'] = []
402
+
403
+ LOGGER.debug('Filtering on STAC items')
404
+ for record in response['features']:
405
+ if record.get('stac_version') is None:
406
+ record['links'].extend([{
407
+ 'rel': 'self',
408
+ 'type': 'application/geo+json',
409
+ 'href': f"{self.config['server']['url']}/collections/{collection}/items/{record['id']}"
410
+ }, {
411
+ 'rel': 'root',
412
+ 'type': 'application/json',
413
+ 'href': f"{self.config['server']['url']}/"
414
+ }, {
415
+ 'rel': 'parent',
416
+ 'type': 'application/json',
417
+ 'href': f"{self.config['server']['url']}/collections/{collection}"
418
+ }])
419
+ response2['features'].append(links2stacassets(collection, record))
420
+ else:
421
+ response2['features'].append(record)
422
+
423
+ if record.get('bbox') is None:
424
+ geometry = record.get('geometry')
425
+ if geometry is not None:
426
+ LOGGER.debug('Calculating bbox from geometry')
427
+ bbox = geojson_geometry2bbox(geometry)
428
+ record['bbox'] = [float(t) for t in bbox.split(',')]
429
+
430
+ for link in record['links']:
431
+ if link.get('rel') is None:
432
+ LOGGER.debug('Missing link relation; adding rel=related')
433
+ link['rel'] = 'related'
434
+
435
+ for count, value in enumerate(response2['links']):
436
+ if value['rel'] == 'alternate':
437
+ response2['links'].pop(count)
438
+
439
+ response2['links'].extend([{
440
+ 'rel': 'root',
441
+ 'type': 'application/json',
442
+ 'href': f"{self.config['server']['url']}/"
443
+ }
444
+ ])
445
+
446
+ return self.get_response(status, headers, response2)
447
+
448
+ def item(self, headers_, args, collection, item):
449
+ """
450
+ Provide collection item
451
+
452
+ :param headers_: copy of HEADERS object
453
+ :param args: request parameters
454
+ :param collection: name of collection
455
+ :param item: record identifier
456
+
457
+ :returns: tuple of headers, status code, content
458
+ """
459
+
460
+ headers_['Accept'] = 'application/geo+json'
461
+ headers, status, response = super().item(headers_, args, collection, item)
462
+
463
+ if collection not in self.get_all_collections():
464
+ msg = 'Invalid collection'
465
+ LOGGER.exception(msg)
466
+ return self.get_exception(400, headers_, 'InvalidParameterValue', msg)
467
+
468
+ response = json.loads(response)
469
+
470
+ if 'id' not in response:
471
+ return self.get_exception(
472
+ 404, headers_, 'InvalidParameterValue', 'item not found')
473
+
474
+ response = links2stacassets(collection, response)
475
+
476
+ return self.get_response(status, headers_, response)
477
+
478
+ def get_collection_info(self, collection_name: str = 'metadata:main',
479
+ collection_info: dict = {}) -> dict:
480
+ """
481
+ Generate collection metadata
482
+
483
+ :param collection_name: name of collection
484
+ default is 'metadata:main' main collection
485
+ :param collection_info: `dict` of collection info
486
+
487
+ :returns: `dict` of collection
488
+ """
489
+
490
+ if collection_name == 'metadata:main':
491
+ id_ = collection_name
492
+ title = self.config['metadata']['identification']['title']
493
+ description = self.config['metadata']['identification']['description'] # noqa
494
+ else:
495
+ id_ = collection_name
496
+ title = collection_info.title
497
+ description = collection_info.abstract
498
+
499
+ return {
500
+ 'id': id_,
501
+ 'stac_version': '1.0.0',
502
+ 'license': 'other',
503
+ 'extent': {
504
+ 'spatial': {
505
+ 'bbox': [wkt2geom(collection_info.wkt_geometry)]
506
+ },
507
+ 'temporal': {'interval': [[
508
+ collection_info.time_begin, collection_info.time_end
509
+ ]]}
510
+ },
511
+ 'title': title,
512
+ 'description': description,
513
+ 'type': 'Collection',
514
+ 'links': [{
515
+ 'rel': 'collection',
516
+ 'type': 'application/json',
517
+ 'href': f"{self.config['server']['url']}/collections/{collection_name}"
518
+ }, {
519
+ 'rel': 'items',
520
+ 'type': 'application/geo+json',
521
+ 'href': f"{self.config['server']['url']}/collections/{collection_name}/items"
522
+ }]
523
+ }
524
+
525
+ def manage_collection_item(self, headers_, action='create', item=None, data=None, collection=None):
526
+ if action == 'create' and data is not None and 'features' in data:
527
+ LOGGER.debug('STAC ItemCollection detected')
528
+
529
+ for feature in data['features']:
530
+ data2 = feature
531
+ if collection is not None:
532
+ data2['collection'] = collection
533
+
534
+ headers, status, content = super().manage_collection_item(
535
+ headers_=headers_, action='create', data=data2)
536
+
537
+ return self.get_response(201, headers_, {})
538
+
539
+ else: # default/super
540
+ LOGGER.debug('STAC Collection detected')
541
+ if collection is not None:
542
+ data['collection'] = collection
543
+ if data is not None and 'id' in data:
544
+ item=data['id']
545
+
546
+ return super().manage_collection_item(
547
+ headers_=headers_, action=action, item=item, data=data)
548
+
549
+
550
+ def links2stacassets(collection, record):
551
+ LOGGER.debug('Transforming enclosure links to STAC assets')
552
+
553
+ if 'stac_version' not in record:
554
+ record['stac_version'] = '1.0.0'
555
+ if 'collection' not in record:
556
+ record['collection'] = collection
557
+
558
+ links_assets = [i for i in record['links'] if i.get('rel', '') == 'enclosure']
559
+ links_to_keep = [i for i in record['links'] if i.get('rel', '') != 'enclosure']
560
+
561
+ record['links'] = links_to_keep
562
+
563
+ LOGGER.debug('Adding assets')
564
+ if links_assets:
565
+ if 'assets' not in record:
566
+ record['assets'] = {}
567
+
568
+ for count, value in enumerate(links_assets):
569
+ record['assets'][count] = value
570
+
571
+ return record