Skip to content

Commit

Permalink
Merge pull request #9 from DingDingFan0207/Dingding/2to3_updates
Browse files Browse the repository at this point in the history
#4276 upgrade gsimporter to be compatible with python2&3
  • Loading branch information
Alessio Fabiani authored Dec 13, 2019
2 parents 6a39628 + aa0a680 commit 3cdd877
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 94 deletions.
8 changes: 4 additions & 4 deletions gsimporter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from client import Client
from api import BadRequest
from api import RequestFailed
from api import NotFound
from .client import Client
from .api import BadRequest
from .api import RequestFailed
from .api import NotFound
12 changes: 7 additions & 5 deletions gsimporter/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@
import tempfile
from os import path

_shp_exts = ["dbf","prj","shx"]
_shp_exts = _shp_exts + map(lambda s: s.upper(), _shp_exts)
_shp_exts = ["dbf", "prj", "shx"]
_shp_exts = _shp_exts + [s.upper() for s in _shp_exts]


def shp_files(fpath):
basename, ext = path.splitext(fpath)
paths = [ "%s.%s" % (basename,ext) for ext in _shp_exts ]
paths = ["%s.%s" % (basename, ext) for ext in _shp_exts]
paths.append(fpath)
return filter(lambda f: path.exists(f), paths)
return [f for f in paths if path.exists(f)]


def create_zip(fpaths):
_,payload = tempfile.mkstemp(suffix='.zip')
_, payload = tempfile.mkstemp(suffix='.zip')
zipf = ZipFile(payload, "w")
for fp in fpaths:
basename = path.basename(fp)
Expand Down
93 changes: 54 additions & 39 deletions gsimporter/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import os
import pprint

from urlparse import urlparse
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse

STATE_PENDING = "PENDING"
STATE_READY = "READY"
Expand All @@ -14,22 +17,27 @@

_logger = logging.getLogger("gsuploader")


class BadRequest(Exception):
'''Encapsulate a 400 or other 'invalid' request'''
pass


class RequestFailed(Exception):
'''Encapsulate a 500 or other 'failed' request'''
pass


class NotFound(Exception):
'''Encapsulate an HTTP 404 or other 'missing' request'''
pass


class BindingFailed(Exception):
'''Something in the API has changed'''
pass


def parse_response(args, parent=None):
'''Parse a top-level concept from the provided args.
:param args: a tuple of headers, response from an httplib2 request
Expand All @@ -39,24 +47,26 @@ def parse_response(args, parent=None):
headers, response = args
try:
resp = json.loads(response)
except ValueError,ex:
_logger.warn('invalid JSON response: %s',response)
except ValueError as ex:
_logger.warn('invalid JSON response: %s', response)
raise ex
if "import" in resp:
return Session(json=resp['import'], parent=parent)
elif "task" in resp:
return Task(resp['task'], parent=parent)
elif "imports" in resp:
return [ Session(json=j, parent=parent) for j in resp['imports'] ]
return [Session(json=j, parent=parent) for j in resp['imports']]
elif "tasks" in resp:
# non-recognized file tasks have null source.format
return [ Task(t, parent=parent) for t in resp['tasks'] ]
return [Task(t, parent=parent) for t in resp['tasks']]
raise Exception("Unknown response %s" % resp)


_Binding = collections.namedtuple('Binding', [
'name', 'expected', 'ro', 'binding'
])


def _binding(name, expected=True, ro=True, binding=None):
return _Binding(name, expected, ro, binding)

Expand Down Expand Up @@ -142,7 +152,7 @@ def _to_json_object(self, deep=True, top_level=True):
json[binding.name] = val
self._to_json_object_custom(json)
if top_level and self._object_name:
json = { self._object_name : json }
json = {self._object_name: json}
return json

def _to_json_object_custom(self, json):
Expand Down Expand Up @@ -189,12 +199,12 @@ class Target(_UploadBase):
)

def _bind_json(self, json):
if json.has_key('href'):
if 'href' in json:
self.href = json.get('href')
store_type = [ k for k in Target._store_types if k in json]
store_type = [k for k in Target._store_types if k in json]
if store_type:
if len(store_type) != 1:
self.binding_failed('invalid store entry: %s', json.keys())
self.binding_failed('invalid store entry: %s', list(json.keys()))
else:
self.store_type = store_type[0]
repr = json[self.store_type]
Expand All @@ -212,12 +222,12 @@ def change_datastore(self, store_name=None, workspace=None):
:param store_name: An optional existing datastore name
:param workspace: An optional workspace to use for referencing the store
'''
dataStore = { 'enabled' : True } # workaround for importer bug
dataStore = {'enabled': True} # workaround for importer bug
if store_name:
dataStore['name'] = store_name
if workspace:
dataStore['workspace'] = { 'name' : str(workspace) }
target_rep = { self.store_type : dataStore }
dataStore['workspace'] = {'name': str(workspace)}
target_rep = {self.store_type: dataStore}
self._client().put_json(self._url(None), json.dumps(target_rep))


Expand Down Expand Up @@ -251,7 +261,11 @@ class Layer(_UploadBase):
)

def set_target_layer_name(self, name):
data = { 'layer' : { 'name' : name }}
data = {'layer': {'name': name}}
self._client().put_json(self._url(None), json.dumps(data))

def set_target_srs(self, srs):
data = {'layer': {'srs': srs}}
self._client().put_json(self._url(None), json.dumps(data))


Expand All @@ -262,7 +276,7 @@ class Task(_UploadBase):
_binding('href'),
_binding('state'),
_binding('progress'),
_binding('updateMode', expected=False), # workaround for older versions
_binding('updateMode', expected=False), # workaround for older versions
_binding('data', binding=Data),
# a missing target implies the source must be imported into db
_binding('target', binding=Target, expected=False),
Expand All @@ -288,35 +302,35 @@ def set_target(self, store_name=None, workspace=None, store_type=None):
if workspace is None:
raise Exception("workspace required if target is not set")
if store_type not in Target._store_types:
raise Exception("store_type must be one of %s" % (Target._store_types,))
raise Exception("store_type must be one of %s" % (Target._store_types))
self.target = Target(None, self)
self.target.store_type = store_type
self.target.href = self._url(None) + "/target"
self.target.change_datastore(store_name, workspace)

def set_update_mode(self,update_mode):
data = { 'task' : {
'updateMode' : update_mode
def set_update_mode(self, update_mode):
data = {'task': {
'updateMode': update_mode
}}
self._client().put_json(self._url(None), json.dumps(data))

def set_charset(self,charset):
data = { 'task' : {
'source' : {
'charset' : charset
def set_charset(self, charset):
data = {'task': {
'source': {
'charset': charset
}
}}
self._client().put_json(self._url(None), json.dumps(data))

def set_srs(self, srs):
data = { 'layer' : { 'srs' : srs }}
data = {'layer': {'srs': srs}}
self._client().put_json(self._url(None), json.dumps(data))

def delete(self):
"""Delete the task"""
resp, content = self._client().delete(self._url(None))
if resp.status != 204:
raise Exception('expected 204 response code, got %s' % resp.status,content)
raise Exception('expected 204 response code, got %s' % resp.status, content)

def set_transforms(self, transforms, save=True):
"""Set the transforms of this Item. transforms is a list of dicts"""
Expand All @@ -328,7 +342,7 @@ def save_transforms(self):
"type": self.transform_type,
"transforms": self.transforms
}
data = { 'task' : { 'transformChain' : chain}}
data = {'task': {'transformChain': chain}}
self._client().put_json(self._url(None), json.dumps(data))

def add_transforms(self, transforms, save=True):
Expand All @@ -338,9 +352,9 @@ def add_transforms(self, transforms, save=True):
def remove_transforms(self, transforms, by_field=None, save=True):
'''remove transforms by equality or list of field values'''
if by_field:
self.transforms = [ t for t in self.transforms if t[by_field] not in transforms ]
self.transforms = [t for t in self.transforms if t[by_field] not in transforms]
else:
self.transforms = [ t for t in self.transforms if t not in transforms ]
self.transforms = [t for t in self.transforms if t not in transforms]
save and self.save_transforms()

def get_progress(self):
Expand All @@ -362,8 +376,8 @@ def get_progress(self):
if unicode_error:
progress['message'] += ' - it looks like an invalid character'
return progress
except ValueError,ex:
_logger.warn('invalid JSON response: %s',response)
except ValueError:
_logger.warn('invalid JSON response: %s', response)
raise RequestFailed('invalid JSON')
else:
raise Exception("Item does not have a progress endpoint")
Expand Down Expand Up @@ -398,12 +412,13 @@ def upload_task(self, files, use_url=False, initial_opts=None):
# @todo getting the task response updates the session tasks, but
# neglects to retreive the overall session status field
fname = os.path.basename(files[0])
_,ext = os.path.splitext(fname)
_, ext = os.path.splitext(fname)

def addopts(base):
if initial_opts:
# pass options in as value:key parameters, this allows multiple
# options per key
base = base + '&' + '&'.join(['option=%s:%s' % (v,k) for k,v in initial_opts.iteritems()])
base = base + '&' + '&'.join(['option=%s:%s' % (v, k) for k, v in initial_opts.items()])
return base
if use_url:
if ext == '.zip':
Expand All @@ -419,26 +434,26 @@ def addopts(base):
else:
url = self._url("imports/%s/tasks?expand=3" % self.id)
resp = self._client().post_multipart(addopts(url), files)
tasks = parse_response( resp )
tasks = parse_response(resp)
if not isinstance(tasks, list):
tasks = [tasks]
for t in tasks:
t._parent = self
self.tasks.extend(tasks)

def commit(self, async=False):
def commit(self, sync=False):
"""Run the session"""
#@todo check task status if we don't have it already?
url = self._url("imports/%s",self.id)
if async:
url = url + "?async=true&exec=true"
url = self._url("imports/%s", self.id)
if sync:
url = url + "?sync=true&exec=true"
resp, content = self._client().post(url)
if resp.status != 204:
raise Exception("expected 204 response code, got %s" % resp.status,content)
raise Exception("expected 204 response code, got %s" % resp.status, content)

def delete(self):
"""Delete this import session"""
url = self._url("imports/%s",self.id)
url = self._url("imports/%s", self.id)
resp, content = self._client().delete(url)
if resp.status != 204:
raise Exception('expected 204 response code, got %s' % resp.status,content)
raise Exception('expected 204 response code, got %s' % resp.status, content)
Loading

0 comments on commit 3cdd877

Please sign in to comment.