Skip to content

Commit

Permalink
Merge branch 'master' of github.com:okfn/ckan into feature-1698-tag-t…
Browse files Browse the repository at this point in the history
…axonomies
  • Loading branch information
Sean Hammond committed Feb 15, 2012
2 parents 979ca6e + 00c071f commit d542c87
Show file tree
Hide file tree
Showing 62 changed files with 3,992 additions and 367 deletions.
2 changes: 1 addition & 1 deletion ckan/__init__.py
@@ -1,4 +1,4 @@
__version__ = '1.5.2a'
__version__ = '1.6.1a'
__description__ = 'Comprehensive Knowledge Archive Network (CKAN) Software'
__long_description__ = \
'''CKAN software provides a hub for datasets. The flagship site running CKAN
Expand Down
4 changes: 2 additions & 2 deletions ckan/config/deployment.ini_tmpl
Expand Up @@ -52,8 +52,8 @@ who.log_file = %(cache_dir)s/who_log.ini
# Location of RDF versions of datasets
#rdf_packages = http://semantic.ckan.net/record/

# Location of licenses group (defaults to local Python licenses dataset)
#licenses_group_url = http://licenses.opendefinition.org/2.0/ckan_original
# Location of licenses group (defaults to cached local version of ckan group)
#licenses_group_url = http://licenses.opendefinition.org/licenses/groups/ckan.json

# Dataset form to use
package_form = standard
Expand Down
43 changes: 22 additions & 21 deletions ckan/config/routing.py
Expand Up @@ -14,11 +14,11 @@

def make_map():
"""Create, configure and return the routes Mapper"""
# import controllers here rather than at root level because
# import controllers here rather than at root level because
# pylons config is initialised by this point.
from ckan.controllers.package import register_pluggable_behaviour as register_package_behaviour
from ckan.controllers.group import register_pluggable_behaviour as register_group_behaviour

map = Mapper(directory=config['pylons.paths']['controllers'],
always_scan=config['debug'])
map.minimization = False
Expand Down Expand Up @@ -116,7 +116,7 @@ def make_map():

map.connect('/api/search/{register}', controller='api', action='search')
map.connect('/api/tag_counts', controller='api', action='tag_counts')

map.connect('/api/rest', controller='api', action='index')

map.connect('/api/action/{logic_function}', controller='api', action='action',
Expand Down Expand Up @@ -182,6 +182,7 @@ def make_map():

map.connect('/api/2/util/authorizationgroup/autocomplete', controller='api',
action='authorizationgroup_autocomplete')
map.connect('/api/2/util/group/autocomplete', controller='api', action='group_autocomplete')

map.connect('/api/util/markdown', controller='api', action='markdown')
map.connect('/api/util/dataset/munge_name', controller='api', action='munge_package_name')
Expand All @@ -192,7 +193,7 @@ def make_map():
###########
## /END API
###########

map.redirect("/packages", "/dataset")
map.redirect("/packages/{url:.*}", "/dataset/{url}")
map.redirect("/package", "/dataset")
Expand Down Expand Up @@ -231,7 +232,7 @@ def make_map():
]))
)
map.connect('/dataset/{id}', controller='package', action='read')
map.connect('/dataset/{id}/resource/{resource_id}',
map.connect('/dataset/{id}/resource/{resource_id}',
controller='package', action="resource_read"
)

Expand All @@ -243,11 +244,11 @@ def make_map():
##map.connect('/group/new', controller='group_formalchemy', action='new')
##map.connect('/group/edit/{id}', controller='group_formalchemy', action='edit')

# These named routes are used for custom group forms which will use the
# These named routes are used for custom group forms which will use the
# names below based on the group.type (dataset_group is the default type)
map.connect('group_index', '/group', controller='group', action='index')
map.connect('group_list', '/group/list', controller='group', action='list')
map.connect('group_new', '/group/new', controller='group', action='new')
map.connect('group_new', '/group/new', controller='group', action='new')
map.connect('group_action', '/group/{action}/{id}', controller='group',
requirements=dict(action='|'.join([
'edit',
Expand All @@ -257,10 +258,10 @@ def make_map():
)
map.connect('group_read', '/group/{id}', controller='group', action='read')


register_package_behaviour(map)
register_group_behaviour(map)

register_group_behaviour(map)


# authz group
map.redirect("/authorizationgroups", "/authorizationgroup")
map.redirect("/authorizationgroups/{url:.*}", "/authorizationgroup/{url}")
Expand Down Expand Up @@ -301,17 +302,17 @@ def make_map():

map.connect('ckanadmin_index', '/ckan-admin', controller='admin', action='index')
map.connect('ckanadmin', '/ckan-admin/{action}', controller='admin')

# Storage routes
map.connect('storage_api', "/api/storage",
controller='ckan.controllers.storage:StorageAPIController',
map.connect('storage_api', "/api/storage",
controller='ckan.controllers.storage:StorageAPIController',
action='index')
map.connect('storage_api_set_metadata', '/api/storage/metadata/{label:.*}',
controller='ckan.controllers.storage:StorageAPIController',
map.connect('storage_api_set_metadata', '/api/storage/metadata/{label:.*}',
controller='ckan.controllers.storage:StorageAPIController',
action='set_metadata',
conditions={'method': ['PUT','POST']})
map.connect('storage_api_get_metadata', '/api/storage/metadata/{label:.*}',
controller='ckan.controllers.storage:StorageAPIController',
map.connect('storage_api_get_metadata', '/api/storage/metadata/{label:.*}',
controller='ckan.controllers.storage:StorageAPIController',
action='get_metadata',
conditions={'method': ['GET']})
map.connect('storage_api_auth_request',
Expand All @@ -337,12 +338,12 @@ def make_map():
map.connect('storage_file', '/storage/f/{label:.*}',
controller='ckan.controllers.storage:StorageController',
action='file')


for plugin in routing_plugins:
map = plugin.after_map(map)


map.redirect('/*(url)/', '/{url}',
_redirect_code='301 Moved Permanently')
map.connect('/*url', controller='template', action='view')
Expand Down
69 changes: 46 additions & 23 deletions ckan/controllers/api.py
@@ -1,6 +1,7 @@
import logging
import cgi

from paste.util.multidict import MultiDict
from paste.util.multidict import MultiDict
from webob.multidict import UnicodeMultiDict

from ckan.lib.base import BaseController, response, c, _, gettext, request
Expand Down Expand Up @@ -70,7 +71,8 @@ def _finish(self, status_int, response_data=None,
if status_int==200 and request.params.has_key('callback') and \
(request.method == 'GET' or \
c.logic_function and request.method == 'POST'):
callback = request.params['callback']
# escape callback to remove '<', '&', '>' chars
callback = cgi.escape(request.params['callback'])
response_msg = self._wrap_jsonp(callback, response_msg)
return response_msg

Expand Down Expand Up @@ -131,15 +133,15 @@ def _set_response_header(self, name, value):
def get_api(self, ver=None):
response_data = {}
response_data['version'] = ver or '1'
return self._finish_ok(response_data)
return self._finish_ok(response_data)

def action(self, logic_function):
function = get_action(logic_function)
if not function:
log.error('Can\'t find logic function: %s' % logic_function)
return self._finish_bad_request(
gettext('Action name not known: %s') % str(logic_function))

context = {'model': model, 'session': model.Session, 'user': c.user}
model.Session()._context = context
return_dict = {'help': function.__doc__}
Expand Down Expand Up @@ -178,7 +180,7 @@ def action(self, logic_function):
return_dict['success'] = False
return self._finish(404, return_dict, content_type='json')
except ValidationError, e:
error_dict = e.error_dict
error_dict = e.error_dict
error_dict['__type'] = 'Validation Error'
return_dict['error'] = error_dict
return_dict['success'] = False
Expand All @@ -190,17 +192,17 @@ def action(self, logic_function):
(_('Parameter Error'), e.extra_msg)}
return_dict['success'] = False
log.error('Parameter error: %r' % e.extra_msg)
return self._finish(409, return_dict, content_type='json')
return self._finish(409, return_dict, content_type='json')
except SearchQueryError, e:
return_dict['error'] = {'__type': 'Search Query Error',
'message': 'Search Query is invalid: %r' % e.args }
return_dict['success'] = False
return self._finish(400, return_dict, content_type='json')
return self._finish(400, return_dict, content_type='json')
except SearchError, e:
return_dict['error'] = {'__type': 'Search Error',
'message': 'Search error: %r' % e.args }
return_dict['success'] = False
return self._finish(409, return_dict, content_type='json')
return self._finish(409, return_dict, content_type='json')
return self._finish_ok(return_dict)

def list(self, ver=None, register=None, subregister=None, id=None):
Expand All @@ -225,7 +227,7 @@ def list(self, ver=None, register=None, subregister=None, id=None):
('activity', 'details'): get_action('activity_detail_list')
}

action = action_map.get((register, subregister))
action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
if not action:
Expand Down Expand Up @@ -259,14 +261,14 @@ def show(self, ver=None, register=None, subregister=None, id=None, id2=None):
action_map[('package', type)] = get_action('package_relationships_list')
log.debug('show: %s' % context)

action = action_map.get((register, subregister))
action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
if not action:
return self._finish_bad_request(
gettext('Cannot read entity of this type: %s') % register)
try:

return self._finish_ok(action(context, data_dict))
except NotFound, e:
extra_msg = e.extra_msg
Expand Down Expand Up @@ -303,7 +305,7 @@ def create(self, ver=None, register=None, subregister=None, id=None, id2=None):
return self._finish_bad_request(
gettext('JSON Error: %s') % str(inst))

action = action_map.get((register, subregister))
action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
if not action:
Expand Down Expand Up @@ -338,7 +340,7 @@ def create(self, ver=None, register=None, subregister=None, id=None, id2=None):
except:
model.Session.rollback()
raise

def update(self, ver=None, register=None, subregister=None, id=None, id2=None):
action_map = {
('dataset', 'relationships'): get_action('package_relationship_update_rest'),
Expand All @@ -361,7 +363,7 @@ def update(self, ver=None, register=None, subregister=None, id=None, id2=None):
except ValueError, inst:
return self._finish_bad_request(
gettext('JSON Error: %s') % str(inst))
action = action_map.get((register, subregister))
action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
if not action:
Expand Down Expand Up @@ -407,7 +409,7 @@ def delete(self, ver=None, register=None, subregister=None, id=None, id2=None):

log.debug('delete %s/%s/%s/%s' % (register, id, subregister, id2))

action = action_map.get((register, subregister))
action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
if not action:
Expand All @@ -427,7 +429,7 @@ def delete(self, ver=None, register=None, subregister=None, id=None, id2=None):
return self._finish(409, e.error_dict, content_type='json')

def search(self, ver=None, register=None):

log.debug('search %s params: %r' % (register, request.params))
ver = ver or '1' # i.e. default to v1
if register == 'revision':
Expand Down Expand Up @@ -466,7 +468,7 @@ def search(self, ver=None, register=None):
params['fl'] = 'id' if ver == '2' else 'name'

try:
if register == 'resource':
if register == 'resource':
query = query_for(model.Resource)

# resource search still uses ckan query parser
Expand Down Expand Up @@ -526,7 +528,7 @@ def _get_search_params(cls, request_params):
params = request_params
if not isinstance(params, (UnicodeMultiDict, dict)):
raise ValueError, _('Request params must be in form of a json encoded dictionary.')
return params
return params

def markdown(self, ver=None):
raw_markdown = request.params.get('q', '')
Expand Down Expand Up @@ -582,6 +584,27 @@ def user_autocomplete(self):
user_list = get_action('user_autocomplete')(context,data_dict)
return user_list

@jsonpify
def group_autocomplete(self):
q = request.params.get('q', '')
t = request.params.get('type', None)
limit = request.params.get('limit', 20)
try:
limit = int(limit)
except:
limit = 20
limit = min(50, limit)

query = model.Group.search_by_name(q, t)
def convert_to_dict(user):
out = {}
for k in ['id', 'name', 'title']:
out[k] = getattr(user, k)
return out
query = query.limit(limit)
out = map(convert_to_dict, query.all())
return out


@jsonpify
def authorizationgroup_autocomplete(self):
Expand All @@ -592,7 +615,7 @@ def authorizationgroup_autocomplete(self):
except:
limit = 20
limit = min(50, limit)

query = model.AuthorizationGroup.search(q)
def convert_to_dict(user):
out = {}
Expand All @@ -613,7 +636,7 @@ def is_slug_valid(self):
response_data = dict(valid=not bool(group_exists(slug)))
return self._finish_ok(response_data)
return self._finish_bad_request(gettext('Bad slug type: %s') % slugtype)


def dataset_autocomplete(self):
q = request.params.get('incomplete', '')
Expand Down Expand Up @@ -675,8 +698,8 @@ def munge_package_name(self):
def munge_title_to_package_name(self):
name = request.params.get('title') or request.params.get('name')
munged_name = munge_title_to_name(name)
return self._finish_ok(munged_name)
return self._finish_ok(munged_name)

def munge_tag(self):
tag = request.params.get('tag') or request.params.get('name')
munged_tag = munge_tag(tag)
Expand Down

0 comments on commit d542c87

Please sign in to comment.