From efbbeeca70b0a47cb55d745a137890dabee9f698 Mon Sep 17 00:00:00 2001 From: afabiani Date: Thu, 21 Nov 2019 17:43:44 +0100 Subject: [PATCH] Py3 compatibility --- src/geoserver/catalog.py | 60 +++++++++++++++++++------------------ src/geoserver/layergroup.py | 4 ++- src/geoserver/resource.py | 4 ++- src/geoserver/store.py | 4 ++- src/geoserver/style.py | 5 +++- src/geoserver/support.py | 20 +++++++------ 6 files changed, 55 insertions(+), 42 deletions(-) diff --git a/src/geoserver/catalog.py b/src/geoserver/catalog.py index e37ed85..b873bfb 100644 --- a/src/geoserver/catalog.py +++ b/src/geoserver/catalog.py @@ -8,8 +8,9 @@ # LICENSE.txt file in the root directory of this source tree. # ######################################################################### -from datetime import datetime, timedelta + import logging +from datetime import datetime, timedelta from geoserver.layer import Layer from geoserver.resource import FeatureType from geoserver.store import ( @@ -32,6 +33,7 @@ import requests from requests.packages.urllib3.util.retry import Retry from requests.adapters import HTTPAdapter +from six import string_types try: from past.builtins import basestring @@ -77,9 +79,9 @@ def _name(named): as long as it's a string * otherwise, we raise a ValueError """ - if isinstance(named, basestring) or named is None: + if isinstance(named, string_types) or named is None: return named - elif hasattr(named, 'name') and isinstance(named.name, basestring): + elif hasattr(named, 'name') and isinstance(named.name, string_types): return named.name else: raise ValueError("Can't interpret %s as a name or a configuration object" % named) @@ -100,14 +102,15 @@ class Catalog(object): - Namespaces, which provide unique identifiers for resources """ - def __init__(self, service_url, username="admin", password="geoserver", validate_ssl_certificate=True, access_token=None): + def __init__(self, service_url, username="admin", password="geoserver", validate_ssl_certificate=True, access_token=None, retries=3, backoff_factor=0.9): self.service_url = service_url.strip("/") self.username = username self.password = password self.validate_ssl_certificate = validate_ssl_certificate self.access_token = access_token - self.setup_connection() - + self.retries = retries + self.backoff_factor = backoff_factor + self.setup_connection(retries=self.retries, backoff_factor=self.backoff_factor) self._cache = {} self._version = None @@ -121,20 +124,21 @@ def __getstate__(self): def __setstate__(self, state): '''restore http connection upon unpickling''' self.__dict__.update(state) - self.setup_connection() + self.setup_connection(retries=self.retries, backoff_factor=self.backoff_factor) - def setup_connection(self): + def setup_connection(self, retries=3, backoff_factor=0.9): self.client = requests.session() self.client.verify = self.validate_ssl_certificate parsed_url = urlparse(self.service_url) retry = Retry( - total = 6, - status = 6, - backoff_factor = 0.9, + total = retries or self.retries, + status = retries or self.retries, + read = retries or self.retries, + connect = retries or self.retries, + backoff_factor = backoff_factor or self.backoff_factor, status_forcelist = [502, 503, 504], method_whitelist = set(['HEAD', 'TRACE', 'GET', 'PUT', 'POST', 'OPTIONS', 'DELETE']) ) - self.client.mount("{}://".format(parsed_url.scheme), HTTPAdapter(max_retries=retry)) def http_request(self, url, data=None, method='get', headers={}): @@ -295,8 +299,6 @@ def save(self, obj, content_type="application/xml"): def _return_first_item(self, _list): if len(_list) == 0: return None - elif len(_list) > 1: - raise AmbiguousRequestError("Multiple items found") else: return _list[0] @@ -330,7 +332,7 @@ def get_stores(self, names=None, workspaces=None): if names is None: names = [] - elif isinstance(names, basestring): + elif isinstance(names, string_types): names = [s.strip() for s in names.split(',') if s.strip()] if stores and names: @@ -348,7 +350,7 @@ def get_store(self, name, workspace=None): return self._return_first_item(stores) def create_datastore(self, name, workspace=None): - if isinstance(workspace, basestring): + if isinstance(workspace, string_types): workspace = self.get_workspaces(names=workspace)[0] elif workspace is None: workspace = self.get_default_workspace() @@ -381,7 +383,7 @@ def create_wmslayer(self, workspace, store, name, nativeName=None): return self.get_layer(name) def add_data_to_store(self, store, name, data, workspace=None, overwrite = False, charset = None): - if isinstance(store, basestring): + if isinstance(store, string_types): store = self.get_stores(names=store, workspaces=[workspace])[0] if workspace is not None: workspace = _name(workspace) @@ -498,7 +500,7 @@ def create_imagemosaic(self, name, data, configure='first', workspace=None, over if hasattr(data, 'read'): # Adding this check only to pass tests. We should drop support for passing a file object upload_data = data - elif isinstance(data, basestring): + elif isinstance(data, string_types): if os.path.splitext(data)[-1] == ".zip": upload_data = open(data, 'rb') else: @@ -652,7 +654,7 @@ def add_granule(self, data, store, workspace=None): params = dict() workspace_name = workspace - if isinstance(store, basestring): + if isinstance(store, string_types): store_name = store else: store_name = store.name @@ -690,7 +692,7 @@ def delete_granule(self, coverage, store, granule_id, workspace=None): params = dict() workspace_name = workspace - if isinstance(store, basestring): + if isinstance(store, string_types): store_name = store else: store_name = store.name @@ -741,7 +743,7 @@ def list_granules(self, coverage, store, workspace=None, filter=None, limit=None params['offset'] = offset workspace_name = workspace - if isinstance(store, basestring): + if isinstance(store, string_types): store_name = store else: store_name = store.name @@ -903,7 +905,7 @@ def get_resources(self, names=None, stores=None, workspaces=None): resources = [] for s in _stores: try: - if isinstance(s, basestring): + if isinstance(s, string_types): s = self.get_store( s, workspace=workspaces[0] if workspaces else None @@ -914,7 +916,7 @@ def get_resources(self, names=None, stores=None, workspaces=None): if names is None: names = [] - elif isinstance(names, basestring): + elif isinstance(names, string_types): names = [s.strip() for s in names.split(',') if s.strip()] if resources and names: @@ -944,7 +946,7 @@ def get_layer(self, name): return None def get_layers(self, resource=None): - if isinstance(resource, basestring): + if isinstance(resource, string_types): ws_name = None if self.get_short_version() >= "2.13": if ":" in resource: @@ -978,7 +980,7 @@ def get_layergroups(self, names=None, workspaces=None): groups = self.get_xml(url) layergroups.extend([LayerGroup(self, g.find("name").text, None) for g in groups.findall("layerGroup")]) workspaces = [] - elif isinstance(workspaces, basestring): + elif isinstance(workspaces, string_types): workspaces = [s.strip() for s in workspaces.split(',') if s.strip()] elif isinstance(workspaces, Workspace): workspaces = [workspaces] @@ -1001,7 +1003,7 @@ def get_layergroups(self, names=None, workspaces=None): if names is None: names = [] - elif isinstance(names, basestring): + elif isinstance(names, string_types): names = [s.strip() for s in names.split(',') if s.strip()] if layergroups and names: @@ -1039,7 +1041,7 @@ def get_styles(self, names=None, workspaces=None): styles = self.get_xml(url) all_styles.extend([Style(self, s.find('name').text) for s in styles.findall("style")]) workspaces = [] - elif isinstance(workspaces, basestring): + elif isinstance(workspaces, string_types): workspaces = [s.strip() for s in workspaces.split(',') if s.strip()] elif isinstance(workspaces, Workspace): workspaces = [workspaces] @@ -1066,7 +1068,7 @@ def get_styles(self, names=None, workspaces=None): if names is None: names = [] - elif isinstance(names, basestring): + elif isinstance(names, string_types): names = [s.strip() for s in names.split(',') if s.strip()] if all_styles and names: @@ -1157,7 +1159,7 @@ def get_workspaces(self, names=None): ''' if names is None: names = [] - elif isinstance(names, basestring): + elif isinstance(names, string_types): names = [s.strip() for s in names.split(',') if s.strip()] data = self.get_xml("{}/workspaces.xml".format(self.service_url)) diff --git a/src/geoserver/layergroup.py b/src/geoserver/layergroup.py index 9253b7f..9cb6a59 100644 --- a/src/geoserver/layergroup.py +++ b/src/geoserver/layergroup.py @@ -8,6 +8,8 @@ # LICENSE.txt file in the root directory of this source tree. # ######################################################################### + +from six import string_types try: from urllib.parse import urljoin except: @@ -73,7 +75,7 @@ class LayerGroup(ResourceInfo): def __init__(self, catalog, name, workspace=None): super(LayerGroup, self).__init__() - assert isinstance(name, basestring) + assert isinstance(name, string_types) self.catalog = catalog self.name = name diff --git a/src/geoserver/resource.py b/src/geoserver/resource.py index fcff22f..099c7e8 100644 --- a/src/geoserver/resource.py +++ b/src/geoserver/resource.py @@ -8,6 +8,8 @@ # LICENSE.txt file in the root directory of this source tree. # ######################################################################### + +from six import string_types try: from urllib.parse import urljoin except: @@ -84,7 +86,7 @@ def __init__(self, catalog, workspace, store, name, href=None): super(_ResourceBase, self).__init__() if not href: assert isinstance(store, ResourceInfo) - assert isinstance(name, basestring) + assert isinstance(name, string_types) assert workspace is not None else: parts = href.split('/') diff --git a/src/geoserver/store.py b/src/geoserver/store.py index a73aa9f..fc32958 100644 --- a/src/geoserver/store.py +++ b/src/geoserver/store.py @@ -8,6 +8,8 @@ # LICENSE.txt file in the root directory of this source tree. # ######################################################################### + +from six import string_types import geoserver.workspace as ws from geoserver.resource import featuretype_from_index, coverage_from_index, wmslayer_from_index from geoserver.support import ResourceInfo, xml_property, key_value_pairs, write_bool, write_dict, write_string, build_url @@ -44,7 +46,7 @@ def __init__(self, catalog, workspace, name): super(DataStore, self).__init__() assert isinstance(workspace, ws.Workspace) - assert isinstance(name, basestring) + assert isinstance(name, string_types) self.catalog = catalog self.workspace = workspace self.name = name diff --git a/src/geoserver/style.py b/src/geoserver/style.py index 9c7311d..14e1863 100644 --- a/src/geoserver/style.py +++ b/src/geoserver/style.py @@ -8,7 +8,10 @@ # LICENSE.txt file in the root directory of this source tree. # ######################################################################### + +from six import string_types from geoserver.support import ResourceInfo, build_url, xml_property + try: from past.builtins import basestring except ImportError: @@ -25,7 +28,7 @@ class Style(ResourceInfo): def __init__(self, catalog, name, workspace=None, style_format="sld10"): super(Style, self).__init__() - assert isinstance(name, basestring) + assert isinstance(name, string_types) assert style_format in Style.supported_formats self.catalog = catalog diff --git a/src/geoserver/support.py b/src/geoserver/support.py index 4104131..8678829 100644 --- a/src/geoserver/support.py +++ b/src/geoserver/support.py @@ -8,11 +8,13 @@ # LICENSE.txt file in the root directory of this source tree. # ######################################################################### + +import os import logging from xml.etree.ElementTree import TreeBuilder, tostring from tempfile import mkstemp from zipfile import ZipFile -import os +from six import string_types try: from urllib.parse import urljoin, quote, urlencode, urlparse @@ -55,7 +57,7 @@ def clean_segment(segment): Cleans the segment and encodes to UTF-8 if the segment is unicode. """ segment = segment.strip('/') - if isinstance(segment, basestring): + if isinstance(segment, string_types): segment = segment.encode('utf-8') return segment @@ -171,7 +173,7 @@ def write(builder, pairs): if k == 'port': v = str(v) builder.start("entry", dict(key=k)) - v = v if isinstance(v, basestring) else str(v) + v = v if isinstance(v, string_types) else str(v) builder.data(v) builder.end("entry") builder.end(name) @@ -247,7 +249,7 @@ def prepare_upload_bundle(name, data): zip_file = ZipFile(path, 'w') for ext, stream in data.items(): fname = "%s.%s" % (name, ext) - if (isinstance(stream, basestring)): + if (isinstance(stream, string_types)): zip_file.write(stream, fname) else: zip_file.writestr(fname, stream.read()) @@ -381,14 +383,14 @@ def _multipier(self, name): def resolution_millis(self): '''if set, get the value of resolution in milliseconds''' - if self.resolution is None or not isinstance(self.resolution, basestring): + if self.resolution is None or not isinstance(self.resolution, string_types): return self.resolution val, mult = self.resolution.split(' ') return int(float(val) * self._multipier(mult) * 1000) def resolution_str(self): '''if set, get the value of resolution as " s", for example: "8 seconds"''' - if self.resolution is None or isinstance(self.resolution, basestring): + if self.resolution is None or isinstance(self.resolution, string_types): return self.resolution seconds = self.resolution / 1000. biggest = self._lookup[0] @@ -620,7 +622,7 @@ def metadata(node): def _decode_list(data): rv = [] for item in data: - if isinstance(item, basestring): + if isinstance(item, string_types): item = item.encode('utf-8') elif isinstance(item, list): item = _decode_list(item) @@ -633,9 +635,9 @@ def _decode_list(data): def _decode_dict(data): rv = {} for key, value in data.items(): - if isinstance(key, basestring): + if isinstance(key, string_types): key = key.encode('utf-8') - if isinstance(value, basestring): + if isinstance(value, string_types): value = value.encode('utf-8') elif isinstance(value, list): value = _decode_list(value)