Repository: obspy/obspy

Issue:
Oddities in IRIS FDSNWS-event `contributors` and `catalogs`
@iris-edu @chad-iris  I just noticed (while checking on some of our FDSNWS tests) that at some point the response for querying `catalogs` and `contributors` must've changed. The individual entity names are suffixed by a line break and a space character. This would be easy to handle in obspy, but I don't think we really want to do it and it should rather be be fixed upstream, I think.

http://service.iris.edu/fdsnws/event/1/contributors
http://service.iris.edu/fdsnws/event/1/catalogs

```xml
<Contributors>
 <total>265
 </total>
 <Contributor>A
 </Contributor>
 <Contributor>AEI
 </Contributor>
 <Contributor>AEIC
 </Contributor>
...
```


Discussion:

Resolving patch:
diff --git a/obspy/clients/fdsn/client.py b/obspy/clients/fdsn/client.py
--- a/obspy/clients/fdsn/client.py
+++ b/obspy/clients/fdsn/client.py
@@ -1618,6 +1618,12 @@ def run(self):
                 try:
                     self.services["available_event_catalogs"] = \
                         parse_simple_xml(wadl)["catalogs"]
+                    # XXX can be removed when IRIS/Earthscope drops its event
+                    # webservice
+                    if '.iris.' in url or 'earthscope' in url:
+                        self.services["available_event_catalogs"] = \
+                            _cleanup_earthscope(
+                                self.services["available_event_catalogs"])
                 except ValueError:
                     msg = "Could not parse the catalogs at '%s'." % url
                     warnings.warn(msg)
@@ -1625,6 +1631,12 @@ def run(self):
                 try:
                     self.services["available_event_contributors"] = \
                         parse_simple_xml(wadl)["contributors"]
+                    # XXX can be removed when IRIS/Earthscope drops its event
+                    # webservice
+                    if '.iris.' in url or 'earthscope' in url:
+                        self.services["available_event_contributors"] = \
+                            _cleanup_earthscope(
+                                self.services["available_event_contributors"])
                 except ValueError:
                     msg = "Could not parse the contributors at '%s'." % url
                     warnings.warn(msg)
@@ -2078,6 +2090,21 @@ def _validate_eida_token(token):
     return False
 
 
+def _cleanup_earthscope(items):
+    """
+    IRIS/Earthscope has all "catalogs" and "contributors" suffixed with "\n "
+    and has confirmed that this will not be fixed. So need to clean up here.
+
+    Can be removed when Earthscope drops its event service
+    """
+    new_items = []
+    for item in items:
+        if item.endswith('\n '):
+            item = item[:-2]
+        new_items.append(item)
+    return new_items
+
+
 if __name__ == '__main__':
     import doctest
     doctest.testmod(exclude_empty=True)


Test patch:
diff --git a/obspy/clients/fdsn/tests/test_client.py b/obspy/clients/fdsn/tests/test_client.py
--- a/obspy/clients/fdsn/tests/test_client.py
+++ b/obspy/clients/fdsn/tests/test_client.py
@@ -27,7 +27,7 @@
 from obspy.core.util.base import NamedTemporaryFile
 from obspy.clients.fdsn import Client, RoutingClient
 from obspy.clients.fdsn.client import (build_url, parse_simple_xml,
-                                       get_bulk_string)
+                                       get_bulk_string, _cleanup_earthscope)
 from obspy.clients.fdsn.header import (DEFAULT_USER_AGENT, URL_MAPPINGS,
                                        FDSNException, FDSNRedirectException,
                                        FDSNNoDataException,
@@ -391,6 +391,7 @@ def test_iris_event_contributors_availability(self):
         xml = lxml.etree.fromstring(response.content)
         expected = {
             elem.text for elem in xml.xpath('/Contributors/Contributor')}
+        expected = set(_cleanup_earthscope(expected))
         # check that we have some values in there
         assert len(expected) > 5
         assert {*self.client.services["available_event_contributors"]} == \