spatial-d4science/ckanext/spatial/plugin.py

134 lines
4.5 KiB
Python

import os
from logging import getLogger
from genshi.input import HTML
from genshi.filters import Transformer
import ckan.lib.helpers as h
from ckan.lib.helpers import json
from ckan.plugins import implements, SingletonPlugin
from ckan.plugins import IRoutes, IConfigurer
from ckan.plugins import IConfigurable, IGenshiStreamFilter
from ckan.plugins import IPackageController
from ckan.logic import ValidationError
from ckan.logic.action.update import package_error_summary
import html
from ckanext.spatial.lib import save_package_extent
log = getLogger(__name__)
class SpatialQuery(SingletonPlugin):
implements(IRoutes, inherit=True)
implements(IPackageController, inherit=True)
def before_map(self, map):
map.connect('api_spatial_query', '/api/2/search/package/geo',
controller='ckanext.spatial.controllers.api:ApiController',
action='spatial_query')
return map
def create(self, package):
self.check_spatial_extra(package)
def edit(self, package):
self.check_spatial_extra(package)
def check_spatial_extra(self,package):
for extra in package.extras_list:
if extra.key == 'spatial':
if extra.state == 'active':
try:
log.debug('Received: %r' % extra.value)
geometry = json.loads(extra.value)
except ValueError,e:
error_dict = {'spatial':[u'Error decoding JSON object: %s' % str(e)]}
raise ValidationError(error_dict, error_summary=package_error_summary(error_dict))
except TypeError,e:
error_dict = {'spatial':[u'Error decoding JSON object: %s' % str(e)]}
raise ValidationError(error_dict, error_summary=package_error_summary(error_dict))
try:
save_package_extent(package.id,geometry)
except ValueError,e:
error_dict = {'spatial':[u'Error creating geometry: %s' % str(e)]}
raise ValidationError(error_dict, error_summary=package_error_summary(error_dict))
except Exception, e:
error_dict = {'spatial':[u'Error: %s' % str(e)]}
raise ValidationError(error_dict, error_summary=package_error_summary(error_dict))
elif extra.state == 'deleted':
# Delete extent from table
save_package_extent(package.id,None)
break
def delete(self, package):
save_package_extent(package.id,None)
class WMSPreview(SingletonPlugin):
implements(IGenshiStreamFilter)
implements(IRoutes, inherit=True)
implements(IConfigurer, inherit=True)
def filter(self, stream):
from pylons import request, tmpl_context as c
routes = request.environ.get('pylons.routes_dict')
if routes.get('controller') == 'package' and \
routes.get('action') == 'read' and c.pkg.id:
is_inspire = (c.pkg.extras.get('INSPIRE') == 'True')
# TODO: What about WFS, WCS...
is_wms = (c.pkg.extras.get('resource-type') == 'service')
if is_inspire and is_wms:
data = {'name': c.pkg.name}
stream = stream | Transformer('body//div[@class="resources subsection"]')\
.append(HTML(html.MAP_VIEW % data))
return stream
def before_map(self, map):
map.connect('map_view', '/package/:id/map',
controller='ckanext.spatial.controllers.view:ViewController',
action='wms_preview')
map.connect('proxy', '/proxy',
controller='ckanext.spatial.controllers.view:ViewController',
action='proxy')
map.connect('api_spatial_query', '/api/2/search/package/geo',
controller='ckanext.spatial.controllers.api:ApiController',
action='spatial_query')
return map
def update_config(self, config):
here = os.path.dirname(__file__)
template_dir = os.path.join(here, 'templates')
public_dir = os.path.join(here, 'public')
if config.get('extra_template_paths'):
config['extra_template_paths'] += ','+template_dir
else:
config['extra_template_paths'] = template_dir
if config.get('extra_public_paths'):
config['extra_public_paths'] += ','+public_dir
else:
config['extra_public_paths'] = public_dir