3434from django .template .defaultfilters import slugify
3535from requests .auth import HTTPBasicAuth
3636from geonode .layers .models import Dataset
37- from geonode .base .models import ResourceBase
37+ from geonode .base .models import Link , ResourceBase
3838from geonode .layers .enumerations import GXP_PTYPES
3939from geonode .thumbs .thumbnails import create_thumbnail
4040
@@ -184,21 +184,23 @@ def get_ogc_wms_url(self, wms_url, version=None):
184184 logger .exception (e )
185185 return ogc_wms_url
186186
187- def get_capabilities (self ) -> requests .Response :
187+ def wms_call (self , kind = "GetCapabilities" , override_version = None , additional_params = {} ) -> requests .Response :
188188 params = self ._base_wms_parameters .copy ()
189189 params .update (
190190 {
191- "request" : "GetCapabilities" ,
191+ "request" : kind ,
192192 }
193193 )
194194 (wms_url , _service , _version , _request ) = self ._get_cleaned_url_params (self .remote_url )
195195 if _service :
196196 params ["service" ] = _service
197- if _version :
198- params ["version" ] = _version
197+ if override_version or _version :
198+ params ["version" ] = override_version or _version
199199 if wms_url .query :
200200 for _param in parse_qsl (wms_url .query ):
201201 params [_param [0 ]] = _param [1 ]
202+ # updating default params with custom ones
203+ params = {** params , ** additional_params }
202204
203205 # checking if the services is under basic auth
204206 # getting the service
@@ -214,11 +216,11 @@ def get_capabilities(self) -> requests.Response:
214216 service = has_basic_auth .first ()
215217 basic_auth = HTTPBasicAuth (service .username , service .get_password ())
216218
217- get_capabilities_response = self .http_session .get (
219+ response = self .http_session .get (
218220 self .get_ogc_wms_url (wms_url , version = _version ), params = params , auth = basic_auth
219221 )
220- get_capabilities_response .raise_for_status ()
221- return get_capabilities_response
222+ response .raise_for_status ()
223+ return response
222224
223225 def get_num_available_resources (self ) -> int :
224226 data = self ._get_data ()
@@ -251,7 +253,7 @@ def list_resources(self, offset: typing.Optional[int] = 0) -> typing.List[base.B
251253
252254 def check_availability (self , timeout_seconds : typing .Optional [int ] = 5 ) -> bool :
253255 try :
254- response = self .get_capabilities ()
256+ response = self .wms_call ()
255257 except (requests .HTTPError , requests .ConnectionError ):
256258 result = False
257259 else :
@@ -340,7 +342,7 @@ def get_resource(
340342
341343 def _get_data (self ) -> typing .Dict :
342344 """Return data from the harvester URL in JSON format."""
343- get_capabilities_response = self .get_capabilities ()
345+ get_capabilities_response = self .wms_call ()
344346 root = etree .fromstring (get_capabilities_response .content , parser = XML_PARSER )
345347 nsmap = _get_nsmap (root .nsmap )
346348
@@ -546,6 +548,29 @@ def finalize_resource_update(
546548 forced_crs = target_crs ,
547549 overwrite = True ,
548550 )
551+ # ref GeoNode #13010
552+ # A describeLayer is perfomed to see if we can add the WDS link
553+ # to the resource
554+ response = self .wms_call (
555+ kind = "DescribeLayer" , override_version = "1.1.1" , additional_params = {"layers" : geonode_resource .alternate }
556+ )
557+ # check if the owsType is WFS
558+ if response :
559+ if (
560+ etree .fromstring (response .content , parser = XML_PARSER ).find ("LayerDescription" ).attrib .get ("owsType" )
561+ == "WFS"
562+ ):
563+ Link .objects .get_or_create (
564+ resource = geonode_resource ,
565+ url = geonode_resource .ows_url ,
566+ name = f"OGC WFS: { geonode_resource .workspace } Service" ,
567+ defaults = dict (
568+ extension = "html" ,
569+ url = geonode_resource .ows_url ,
570+ mime = "text/html" ,
571+ link_type = "OGC:WFS" ,
572+ ),
573+ )
549574
550575
551576def _get_nsmap (original : typing .Dict ):
0 commit comments