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 Mar 13, 2012
2 parents a75a230 + 897f012 commit caf8a5d
Show file tree
Hide file tree
Showing 114 changed files with 12,118 additions and 4,924 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "doc/_themes/sphinx-theme-okfn"]
path = doc/_themes/sphinx-theme-okfn
url = git://github.com/okfn/sphinx-theme-okfn.git
13 changes: 13 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ http://ckan.org/.
* Developer mailing list: ckan-dev@lists.okfn.org
* Issue tracker: http://trac.ckan.org/

Building Documentation
======================

1. Install python-sphinx

2. Initialize the theme submodule::

git submodule init
git submodule update

3. Run the command to build the docs::

python setup.py build_sphinx

Copying and License
===================
Expand Down
9 changes: 7 additions & 2 deletions ckan/config/deployment.ini_tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ ckan.site_url =
## Favicon (default is the CKAN software favicon)
ckan.favicon = /images/icons/ckan.ico

## The gravatar default to use. This can be any of the pre-defined strings
## as defined on http://en.gravatar.com/site/implement/images/ (e.g. "identicon"
## or "mm"). Or it can be a url, e.g. "http://example.com/images/avatar.jpg"
ckan.gravatar_default = identicon

## Solr support
#solr_url = http://127.0.0.1:8983/solr

Expand Down Expand Up @@ -161,8 +166,8 @@ ckan.locale_order = en de fr it es pl ru nl sv no cs_CZ hu pt_BR fi bg ca sq sr
ckan.locales_filtered_out = el ro lt sl

## Webstore
## Uncommment to enable webstore
# ckan.webstore.enabled = 1
## Uncommment to enable datastore
# ckan.datastore.enabled = 1

## ===================================
## Extensions
Expand Down
7 changes: 7 additions & 0 deletions ckan/config/middleware.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Pylons middleware initialization"""
import urllib
import logging

from beaker.middleware import CacheMiddleware, SessionMiddleware
Expand Down Expand Up @@ -177,7 +178,13 @@ def __call__(self, environ, start_response):

# Current application url
path_info = environ['PATH_INFO']
# sort out weird encodings
path_info = '/'.join(urllib.quote(pce,'') for pce in path_info.split('/'))

qs = environ.get('QUERY_STRING')
# sort out weird encodings
qs = urllib.quote(qs, '')

if qs:
environ['CKAN_CURRENT_URL'] = '%s?%s' % (path_info, qs)
else:
Expand Down
15 changes: 9 additions & 6 deletions ckan/config/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ def make_map():
conditions=GET)
m.connect('/util/resource/format_autocomplete',
action='format_autocomplete', conditions=GET)
m.connect('/util/resource/format_icon',
action='format_icon', conditions=GET)
m.connect('/util/authorizationgroup/autocomplete',
action='authorizationgroup_autocomplete')
m.connect('/util/group/autocomplete', action='group_autocomplete')
Expand All @@ -129,13 +131,13 @@ def make_map():
m.connect('/util/status', action='status')

## Webstore
if config.get('ckan.webstore.enabled', False):
map.connect('webstore_read', '/api/data/{id}{url:(/.*)?}',
controller='webstore', action='read', url='',
if config.get('ckan.datastore.enabled', False):
map.connect('datastore_read', '/api/data/{id}{url:(/.*)?}',
controller='datastore', action='read', url='',
conditions={'method': ['GET']}
)
map.connect('webstore_write', '/api/data/{id}{url:(/.*)?}',
controller='webstore', action='write', url='',
map.connect('datastore_write', '/api/data/{id}{url:(/.*)?}',
controller='datastore', action='write', url='',
conditions={'method': ['PUT','POST', 'DELETE']}
)

Expand Down Expand Up @@ -175,6 +177,7 @@ def make_map():
m.connect('/dataset/{action}/{id}',
requirements=dict(action='|'.join([
'edit',
'editresources',
'authz',
'history',
'read_ajax',
Expand All @@ -193,7 +196,7 @@ def make_map():
##map.connect('/group/edit/{id}', controller='group_formalchemy', action='edit')

# 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)
# names below based on the group.type ('group' is the default type)
with SubMapper(map, controller='group') as m:
m.connect('group_index', '/group', action='index')
m.connect('group_list', '/group/list', action='list')
Expand Down
148 changes: 69 additions & 79 deletions ckan/controllers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from webob.multidict import UnicodeMultiDict

from ckan.lib.base import BaseController, response, c, _, gettext, request
from ckan.lib.helpers import json, date_str_to_datetime
from ckan.lib.helpers import json, date_str_to_datetime, format_icon, icon_url
import ckan.model as model
import ckan.rating
from ckan.lib.search import (query_for, QueryOptions, SearchIndexError, SearchError,
Expand Down Expand Up @@ -96,35 +96,27 @@ def _finish_ok(self, response_data=None,
'''
if resource_location:
status_int = 201
self._set_response_header('Location',
resource_location)
self._set_response_header('Location', resource_location)
else:
status_int = 200

return self._finish(status_int, response_data,
content_type=content_type)
return self._finish(status_int, response_data, content_type)

def _finish_not_authz(self):
response_data = _('Access denied')
return self._finish(status_int=403,
response_data=response_data,
content_type='json')
return self._finish(403, response_data, 'json')

def _finish_not_found(self, extra_msg=None):
response_data = _('Not found')
if extra_msg:
response_data = '%s - %s' % (response_data, extra_msg)
return self._finish(status_int=404,
response_data=response_data,
content_type='json')
return self._finish(404, response_data, 'json')

def _finish_bad_request(self, extra_msg=None):
response_data = _('Bad request')
if extra_msg:
response_data = '%s - %s' % (response_data, extra_msg)
return self._finish(status_int=400,
response_data=response_data,
content_type='json')
return self._finish(400, response_data, 'json')

def _wrap_jsonp(self, callback, response_msg):
return '%s(%s);' % (callback, response_msg)
Expand Down Expand Up @@ -215,31 +207,38 @@ def action(self, logic_function):
return self._finish(409, return_dict, content_type='json')
return self._finish_ok(return_dict)

def _get_action_from_map(self, action_map, register, subregister):
# Helper function to get the action function specified in the action map

# translate old package calls to use dataset
if register == 'package':
register = 'dataset'

action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
if action:
return get_action(action)

def list(self, ver=None, register=None, subregister=None, id=None):
context = {'model': model, 'session': model.Session,
'user': c.user, 'api_version': ver}
log.debug('listing: %s' % context)
action_map = {
'revision': get_action('revision_list'),
'group': get_action('group_list'),
'dataset': get_action('package_list'),
'package': get_action('package_list'),
'tag': get_action('tag_list'),
'licenses': get_action('licence_list'),
('dataset', 'relationships'): get_action('package_relationships_list'),
('package', 'relationships'): get_action('package_relationships_list'),
('dataset', 'revisions'): get_action('package_revision_list'),
('package', 'revisions'): get_action('package_revision_list'),
('package', 'activity'): get_action('package_activity_list'),
('dataset', 'activity'): get_action('package_activity_list'),
('group', 'activity'): get_action('group_activity_list'),
('user', 'activity'): get_action('user_activity_list'),
('activity', 'details'): get_action('activity_detail_list')
'revision': 'revision_list',
'group': 'group_list',
'dataset': 'package_list',
'tag': 'tag_list',
'licenses': 'licence_list',
('dataset', 'relationships'): 'package_relationships_list',
('dataset', 'revisions'): 'package_revision_list',
('dataset', 'activity'): 'package_activity_list',
('group', 'activity'): 'group_activity_list',
('user', 'activity'): 'user_activity_list',
('activity', 'details'): 'activity_detail_list',
}

action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
action = self._get_action_from_map(action_map, register, subregister)
if not action:
return self._finish_bad_request(
gettext('Cannot list entity of this type: %s') % register)
Expand All @@ -253,27 +252,22 @@ def list(self, ver=None, register=None, subregister=None, id=None):

def show(self, ver=None, register=None, subregister=None, id=None, id2=None):
action_map = {
'revision': get_action('revision_show'),
'group': get_action('group_show_rest'),
'tag': get_action('tag_show_rest'),
'dataset': get_action('package_show_rest'),
'package': get_action('package_show_rest'),
('dataset', 'relationships'): get_action('package_relationships_list'),
('package', 'relationships'): get_action('package_relationships_list'),
'revision': 'revision_show',
'group': 'group_show_rest',
'tag': 'tag_show_rest',
'dataset': 'package_show_rest',
('dataset', 'relationships'): 'package_relationships_list',
}
for type in model.PackageRelationship.get_all_types():
action_map[('dataset', type)] = 'package_relationships_list'

context = {'model': model, 'session': model.Session, 'user': c.user,
'api_version': ver}
data_dict = {'id': id, 'id2': id2, 'rel': subregister}

for type in model.PackageRelationship.get_all_types():
action_map[('dataset', type)] = get_action('package_relationships_list')
action_map[('package', type)] = get_action('package_relationships_list')
log.debug('show: %s' % context)

action = action_map.get((register, subregister))
if not action:
action = action_map.get(register)
action = self._get_action_from_map(action_map, register, subregister)
if not action:
return self._finish_bad_request(
gettext('Cannot read entity of this type: %s') % register)
Expand All @@ -291,17 +285,13 @@ def _represent_package(self, package):
def create(self, ver=None, register=None, subregister=None, id=None, id2=None):

action_map = {
('dataset', 'relationships'): get_action('package_relationship_create_rest'),
('package', 'relationships'): get_action('package_relationship_create_rest'),
'group': get_action('group_create_rest'),
'dataset': get_action('package_create_rest'),
'package': get_action('package_create_rest'),
'rating': get_action('rating_create'),
'group': 'group_create_rest',
'dataset': 'package_create_rest',
'rating': 'rating_create',
('dataset', 'relationships'): 'package_relationship_create_rest',
}

for type in model.PackageRelationship.get_all_types():
action_map[('dataset', type)] = get_action('package_relationship_create_rest')
action_map[('package', type)] = get_action('package_relationship_create_rest')
action_map[('dataset', type)] = 'package_relationship_create_rest'

context = {'model': model, 'session': model.Session, 'user': c.user,
'api_version': ver}
Expand All @@ -314,9 +304,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))
if not action:
action = action_map.get(register)
action = self._get_action_from_map(action_map, register, subregister)
if not action:
return self._finish_bad_request(
gettext('Cannot create new entity of this type: %s %s') % \
Expand Down Expand Up @@ -352,15 +340,12 @@ def create(self, ver=None, register=None, subregister=None, id=None, id2=None):

def update(self, ver=None, register=None, subregister=None, id=None, id2=None):
action_map = {
('dataset', 'relationships'): get_action('package_relationship_update_rest'),
('package', 'relationships'): get_action('package_relationship_update_rest'),
'dataset': get_action('package_update_rest'),
'package': get_action('package_update_rest'),
'group': get_action('group_update_rest'),
'dataset': 'package_update_rest',
'group': 'group_update_rest',
('dataset', 'relationships'): 'package_relationship_update_rest',
}
for type in model.PackageRelationship.get_all_types():
action_map[('dataset', type)] = get_action('package_relationship_update_rest')
action_map[('package', type)] = get_action('package_relationship_update_rest')
action_map[('dataset', type)] = 'package_relationship_update_rest'

context = {'model': model, 'session': model.Session, 'user': c.user,
'api_version': ver, 'id': id}
Expand All @@ -372,9 +357,8 @@ 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))
if not action:
action = action_map.get(register)

action = self._get_action_from_map(action_map, register, subregister)
if not action:
return self._finish_bad_request(
gettext('Cannot update entity of this type: %s') % \
Expand All @@ -401,15 +385,12 @@ def update(self, ver=None, register=None, subregister=None, id=None, id2=None):

def delete(self, ver=None, register=None, subregister=None, id=None, id2=None):
action_map = {
('dataset', 'relationships'): get_action('package_relationship_delete_rest'),
('package', 'relationships'): get_action('package_relationship_delete_rest'),
'group': get_action('group_delete'),
'dataset': get_action('package_delete'),
'package': get_action('package_delete'),
'group': 'group_delete',
'dataset': 'package_delete',
('dataset', 'relationships'): 'package_relationship_delete_rest',
}
for type in model.PackageRelationship.get_all_types():
action_map[('dataset', type)] = get_action('package_relationship_delete_rest')
action_map[('package', type)] = get_action('package_relationship_delete_rest')
action_map[('dataset', type)] = 'package_relationship_delete_rest'

context = {'model': model, 'session': model.Session, 'user': c.user,
'api_version': ver}
Expand All @@ -418,9 +399,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))
if not action:
action = action_map.get(register)
action = self._get_action_from_map(action_map, register, subregister)
if not action:
return self._finish_bad_request(
gettext('Cannot delete entity of this type: %s %s') %\
Expand Down Expand Up @@ -638,11 +617,14 @@ def convert_to_dict(user):
def is_slug_valid(self):
slug = request.params.get('slug') or ''
slugtype = request.params.get('type') or ''
disallowed = ['new', 'edit', 'search']
if slugtype==u'package':
response_data = dict(valid=not bool(package_exists(slug)))
response_data = dict(valid=not bool(package_exists(slug)
or slug in disallowed ))
return self._finish_ok(response_data)
if slugtype==u'group':
response_data = dict(valid=not bool(group_exists(slug)))
response_data = dict(valid=not bool(group_exists(slug) or
slug in disallowed ))
return self._finish_ok(response_data)
return self._finish_bad_request('Bad slug type: %s' % slugtype)

Expand Down Expand Up @@ -713,6 +695,14 @@ def munge_tag(self):
munged_tag = munge_tag(tag)
return self._finish_ok(munged_tag)

def format_icon(self):
f = request.params.get('format')
out = {
'format' : f,
'icon' : icon_url(format_icon(f))
}
return self._finish_ok(out)

def status(self):
context = {'model': model, 'session': model.Session}
data_dict = {}
Expand Down

0 comments on commit caf8a5d

Please sign in to comment.