@@ -35,6 +35,8 @@ def _xmd(self, obj):
3535 pass
3636 elif isinstance (val , six .string_types ):
3737 md [attr ] = val
38+ elif isinstance (val , bytes ):
39+ md [attr ] = val
3840 elif isinstance (val , int ):
3941 md [attr ] = val
4042 elif isinstance (val , list ):
@@ -57,7 +59,6 @@ def getcapabilities(self, debug=False, **kw):
5759 caps = self ._xmd (ows )
5860 if not debug :
5961 if "request" in caps : del caps ["request" ]
60- if "response" in caps : del caps ["response" ]
6162 if "owscommon" in caps : del caps ["owscommon" ]
6263 return caps
6364
@@ -70,13 +71,41 @@ class CswService(OwsService):
7071 def __init__ (self , endpoint = None ):
7172 super (CswService , self ).__init__ (endpoint )
7273 self .sortby = SortBy ([SortProperty ('dc:identifier' )])
74+ # check capabilities
75+ log .warn ("IN SETUP: %s" , endpoint )
76+ _cap = self .getcapabilities (endpoint )['response' ]
77+ self .capabilities = etree .ElementTree (etree .fromstring (_cap ))
78+ self .output_schemas = {
79+ 'GetRecords' : self ._get_output_schemas ('GetRecords' ),
80+ 'GetRecordById' : self ._get_output_schemas ('GetRecordById' ),
81+ }
82+ log .warn ("OUTPUTSCHEMAS: %s" , self .output_schemas )
83+
84+ def _get_output_schemas (self , operation ):
85+ _cap_ns = self .capabilities .getroot ().nsmap
86+ _ows_ns = _cap_ns .get ('ows' )
87+ if not _ows_ns :
88+ raise CswError ('Bad getcapabilities response: OWS namespace not found ' + str (_cap_ns ))
89+ _op = self .capabilities .find ("//{{{}}}Operation[@name='{}']" .format (_ows_ns , operation ))
90+ _schemas = _op .find ("{{{}}}Parameter[@name='outputSchema']" .format (_ows_ns ))
91+ _values = map (lambda v : v .text , _schemas .findall ("{{{}}}Value" .format (_ows_ns )))
92+ output_schemas = {}
93+ for key , value in _schemas .nsmap .items ():
94+ if value in _values :
95+ output_schemas .update ({key : value })
96+ return output_schemas
7397
7498 def getrecords (self , qtype = None , keywords = [],
7599 typenames = "csw:Record" , esn = "brief" ,
76100 skip = 0 , count = 10 , outputschema = "gmd" , ** kw ):
77- from owslib .csw import namespaces
78101 constraints = []
79102 csw = self ._ows (** kw )
103+ log .warn ("OUTPUT_SCHEMA: %s" , outputschema )
104+
105+ # check target csw server capabilities for requested output schema
106+ output_schemas = self .output_schemas ['GetRecords' ]
107+ if not output_schemas .get (outputschema ):
108+ raise CswError ('Output schema \' {}\' not supported by target server: ' .format (output_schemas ))
80109
81110 if qtype is not None :
82111 constraints .append (PropertyIsEqualTo ("dc:type" , qtype ))
@@ -87,24 +116,29 @@ def getrecords(self, qtype=None, keywords=[],
87116 "esn" : esn ,
88117 "startposition" : skip ,
89118 "maxrecords" : count ,
90- "outputschema" : namespaces [outputschema ],
119+ "outputschema" : output_schemas [outputschema ],
91120 "sortby" : self .sortby
92- }
121+ }
93122 log .info ('Making CSW request: getrecords2 %r' , kwa )
94123 csw .getrecords2 (** kwa )
95124 if csw .exceptionreport :
96125 err = 'Error getting records: %r' % \
97126 csw .exceptionreport .exceptions
98- # log.error(err)
127+ log .error (err )
99128 raise CswError (err )
100129 return [self ._xmd (r ) for r in list (csw .records .values ())]
101130
102131 def getidentifiers (self , qtype = None , typenames = "csw:Record" , esn = "brief" ,
103132 keywords = [], limit = None , page = 10 , outputschema = "gmd" ,
104133 startposition = 0 , cql = None , ** kw ):
105- from owslib .csw import namespaces
106134 constraints = []
107135 csw = self ._ows (** kw )
136+ log .warn ("OUTPUT_SCHEMA: %s" , outputschema )
137+
138+ # fetch target csw server capabilities for requested output schema
139+ output_schemas = self .output_schemas ['GetRecords' ]
140+ if not output_schemas .get (outputschema ):
141+ raise CswError ('Output schema \' {}\' not supported by target server: ' .format (output_schemas ))
108142
109143 if qtype is not None :
110144 constraints .append (PropertyIsEqualTo ("dc:type" , qtype ))
@@ -115,20 +149,20 @@ def getidentifiers(self, qtype=None, typenames="csw:Record", esn="brief",
115149 "esn" : esn ,
116150 "startposition" : startposition ,
117151 "maxrecords" : page ,
118- "outputschema" : namespaces [outputschema ],
152+ "outputschema" : output_schemas [outputschema ],
119153 "cql" : cql ,
120154 "sortby" : self .sortby
121155 }
122156 i = 0
123157 matches = 0
124158 while True :
125- log .info ('Making CSW request: getrecords2 %r' , kwa )
159+ log .warn ('Making CSW request: getrecords2 %r' , kwa )
126160
127161 csw .getrecords2 (** kwa )
128162 if csw .exceptionreport :
129163 err = 'Error getting identifiers: %r' % \
130164 csw .exceptionreport .exceptions
131- # log.error(err)
165+ log .error (err )
132166 raise CswError (err )
133167
134168 if matches == 0 :
@@ -154,11 +188,15 @@ def getidentifiers(self, qtype=None, typenames="csw:Record", esn="brief",
154188 kwa ["startposition" ] = startposition
155189
156190 def getrecordbyid (self , ids = [], esn = "full" , outputschema = "gmd" , ** kw ):
157- from owslib .csw import namespaces
158191 csw = self ._ows (** kw )
192+ # fetch target csw server capabilities for requested output schema
193+ output_schemas = output_schemas = self .output_schemas ['GetRecordById' ]
194+ if not output_schemas .get (outputschema ):
195+ raise CswError ('Output schema \' {}\' not supported by target server: ' .format (output_schemas ))
196+
159197 kwa = {
160198 "esn" : esn ,
161- "outputschema" : namespaces [outputschema ],
199+ "outputschema" : output_schemas [outputschema ],
162200 }
163201 # Ordinary Python version's don't support the metadata argument
164202 log .info ('Making CSW request: getrecordbyid %r %r' , ids , kwa )
@@ -168,14 +206,17 @@ def getrecordbyid(self, ids=[], esn="full", outputschema="gmd", **kw):
168206 csw .exceptionreport .exceptions
169207 #log.error(err)
170208 raise CswError (err )
171- if not csw .records :
209+ elif csw .records :
210+ record = self ._xmd (list (csw .records .values ())[0 ])
211+ elif csw .response :
212+ record = self ._xmd (etree .fromstring (csw .response ))
213+ else :
172214 return
173- record = self ._xmd (list (csw .records .values ())[0 ])
174215
175216 ## strip off the enclosing results container, we only want the metadata
176- #md = csw._exml.find("/gmd:MD_Metadata")#, namespaces=namespaces)
177- # Ordinary Python version's don't support the metadata argument
178- md = csw ._exml .find ("/{http://www.isotc211.org/2005/gmd}MD_Metadata" )
217+ # '/{schema}*' expression should be safe enough and is able to match the
218+ # desired schema followed by both MD_Metadata or MI_Metadata (iso19115[-2])
219+ md = csw ._exml .find ("/{{{schema}}}*" . format ( schema = output_schemas [ outputschema ]) )
179220 mdtree = etree .ElementTree (md )
180221 try :
181222 record ["xml" ] = etree .tostring (mdtree , pretty_print = True , encoding = str )
0 commit comments