Skip to content

Commit a3ffc82

Browse files
committed
extend the sniffing capability to head out to the endpoint to find out what it is
some comments: - it may return an array of protocols, if multiple are supported - for backwards compatibility, you need to set first=False to allow multiple (multiple is also slow) - you need to set extended=True to activate the extended sniffing
1 parent 519bda6 commit a3ffc82

File tree

3 files changed

+113
-4
lines changed

3 files changed

+113
-4
lines changed

geolinks/__init__.py

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,21 @@
2828
# =================================================================
2929

3030
import logging
31+
from owslib.wms import WebMapService as WMS
32+
from owslib.wfs import WebFeatureService as WFS
33+
from owslib.ogcapi.features import Features as OAPIF
34+
from owslib.ogcapi.coverages import Coverages as OAPIC
35+
from owslib.ogcapi.records import Records as OAPIR
36+
from owslib.wcs import WebCoverageService as WCS
37+
from owslib.csw import CatalogueServiceWeb as CSW
38+
from owslib.wps import WebProcessingService as WPS
39+
from owslib.sos import SensorObservationService as SOS
40+
from owslib.wmts import WebMapTileService as WMTS
3141

3242
LOGGER = logging.getLogger(__name__)
3343

3444
__version__ = '0.2-dev'
3545

36-
3746
def inurl(needles, haystack, position='any'):
3847
"""convenience function to make string.find return bool"""
3948

@@ -60,7 +69,7 @@ def inurl(needles, haystack, position='any'):
6069
return False
6170

6271

63-
def sniff_link(url):
72+
def sniff_link(url, extended=False, first=True):
6473
"""performs basic heuristics to detect what the URL is"""
6574

6675
protocol = None
@@ -105,6 +114,105 @@ def sniff_link(url):
105114
elif inurl(['kml', 'kmz'], link, 'end'):
106115
protocol = 'OGC:KML'
107116
else:
108-
LOGGER.info('No link type detected')
117+
if (extended):
118+
protocol = []
119+
#for each servicetype, head out to see if it is valid
120+
try:
121+
wms = WMS(link)
122+
if (wms.identification.type == 'OGC:WMS'):
123+
if (first):
124+
return wms.identification.type
125+
else:
126+
protocol.append(wms.identification.type)
127+
except:
128+
pass # No need to log?
129+
try:
130+
wmts = WMTS(link)
131+
if (wmts.identification.type == 'OGC:WMTS'):
132+
if (first):
133+
return wmts.identification.type
134+
else:
135+
protocol.append(wmts.identification.type)
136+
except:
137+
pass
138+
try:
139+
wps = WPS(link, verbose=False, skip_caps=True)
140+
wps.getcapabilities()
141+
if (wps.identification.type == 'OGC:WPS'):
142+
if (first):
143+
return wps.identification.type
144+
else:
145+
protocol.append(wps.identification.type)
146+
except:
147+
pass
148+
try:
149+
wfs = WFS(link)
150+
if (wfs.identification.type == 'OGC:WFS'):
151+
if (first):
152+
return wfs.identification.type
153+
else:
154+
protocol.append(wfs.identification.type)
155+
except:
156+
pass
157+
try:
158+
csw = CSW('http://geodiscover.cgdi.ca/wes/serviceManagerCSW/csw')
159+
if (csw.identification.type == 'OGC:CSW'):
160+
if (first):
161+
return csw.identification.type
162+
else:
163+
protocol.append(csw.identification.type)
164+
except:
165+
pass
166+
try:
167+
wcs = WCS(link)
168+
if (wcs.identification.type == 'OGC:WCS'):
169+
if (first):
170+
return wcs.identification.type
171+
else:
172+
protocol.append(wcs.identification.type)
173+
except:
174+
pass
175+
try:
176+
sos = SOS(link)
177+
if (sos.identification.type == 'OGC:SOS'):
178+
if (first):
179+
return sos.identification.type
180+
else:
181+
protocol.append(sos.identification.type)
182+
except:
183+
pass
184+
try:
185+
oapir = OAPIR(link)
186+
if (oapir.conformance()):
187+
if (first):
188+
return "OGCAPI:records"
189+
else:
190+
protocol.append("OGCAPI:records")
191+
except:
192+
pass
193+
try:
194+
oapif = OAPIF(link)
195+
if (oapir.conformance()):
196+
if (first):
197+
return "OGCAPI:features"
198+
else:
199+
protocol.append("OGCAPI:features")
200+
except:
201+
pass
202+
try:
203+
oapic = OAPIC(link)
204+
if (oapir.conformance()):
205+
if (first):
206+
return "OGCAPI:coverages"
207+
else:
208+
protocol.append("OGCAPI:coverages")
209+
except:
210+
pass
211+
212+
if len(protocol) == 1:
213+
protocol = protocol[0]
214+
215+
else:
216+
LOGGER.info('No link type detected')
109217

110218
return protocol

tests/run_tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_link_types(self):
4747
"""simple link type tests"""
4848

4949
for test in self.test_data['test_data']:
50-
self.assertEqual(sniff_link(test['link']), test['expected'],
50+
self.assertEqual(sniff_link(test['link'],extended=True), test['expected'],
5151
'Expected %s and %s to be equal' %
5252
(test['link'], test['expected']))
5353

tests/test_data.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"test_data": [
33
{"link": "http://host/wms?service=WMS", "expected": "OGC:WMS"},
4+
{"link": "https://maps.isric.org/mapserv?map=/map/bdod.map", "expected": "OGC:WMS"},
45
{"link": "http://host/ows?service=WFS", "expected": "OGC:WFS"},
56
{"link": "http://host/ows?service=WCS", "expected": "OGC:WCS"},
67
{"link": "http://host/ows?service=WPS", "expected": "OGC:WPS"},

0 commit comments

Comments
 (0)