Skip to content

Commit

Permalink
Merge branch 'master' into feature-1781-add-term-translation-table
Browse files Browse the repository at this point in the history
  • Loading branch information
kindly committed Feb 14, 2012
2 parents 0decb55 + dc5ca52 commit c26a741
Show file tree
Hide file tree
Showing 45 changed files with 3,429 additions and 97 deletions.
2 changes: 1 addition & 1 deletion ckan/config/routing.py
Expand Up @@ -257,9 +257,9 @@ def make_map():
)
map.connect('group_read', '/group/{id}', controller='group', action='read')


register_package_behaviour(map)
register_group_behaviour(map)


# authz group
map.redirect("/authorizationgroups", "/authorizationgroup")
Expand Down
4 changes: 3 additions & 1 deletion ckan/controllers/api.py
@@ -1,4 +1,5 @@
import logging
import cgi

from paste.util.multidict import MultiDict
from webob.multidict import UnicodeMultiDict
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
21 changes: 8 additions & 13 deletions ckan/controllers/group.py
Expand Up @@ -54,13 +54,9 @@ def register_pluggable_behaviour(map):
# Our version of routes doesn't allow the environ to be passed into the match call
# and so we have to set it on the map instead. This looks like a threading problem
# waiting to happen but it is executed sequentially from instead the routing setup
e = map.environ
map.environ = {'REQUEST_METHOD': 'GET'}
match = map.match('/%s/new' % (group_type,))
map.environ = e
if match:
raise Exception, "Plugin %r would overwrite existing urls" % plugin


map.connect('%s_index' % (group_type,),
'/%s' % (group_type,), controller='group', action='index')
map.connect('%s_new' % (group_type,),
'/%s/new' % (group_type,), controller='group', action='new')
map.connect('%s_read' % (group_type,),
Expand Down Expand Up @@ -145,7 +141,7 @@ def check_data_dict(self, data_dict):

def setup_template_variables(self, context, data_dict):
c.is_sysadmin = Authorizer().is_sysadmin(c.user)

## This is messy as auths take domain object not data_dict
context_group = context.get('group',None)
group = context_group or c.group
Expand Down Expand Up @@ -315,7 +311,6 @@ def pager_url(q=None, page=None):
return render('group/read.html')

def new(self, data=None, errors=None, error_summary=None):

group_type = request.path.strip('/').split('/')[0]
if group_type == 'group':
group_type = None
Expand Down Expand Up @@ -372,7 +367,6 @@ def edit(self, id, data=None, errors=None, error_summary=None):
group = context.get("group")
c.group = group


try:
check_access('group_update',context)
except NotAuthorized, e:
Expand Down Expand Up @@ -416,6 +410,7 @@ def _save_new(self, context, group_type=None):
tuplize_dict(parse_params(request.params))))
data_dict['type'] = group_type or 'group'
context['message'] = data_dict.get('log_message', '')
data_dict['users'] = [{'name': c.user, 'capacity': 'admin'}]
group = get_action('group_create')(context, data_dict)

# Redirect to the appropriate _read route for the type of group
Expand All @@ -432,17 +427,17 @@ def _save_new(self, context, group_type=None):
return self.new(data_dict, errors, error_summary)

def _save_edit(self, id, context):
try:
try:
data_dict = clean_dict(unflatten(
tuplize_dict(parse_params(request.params))))
context['message'] = data_dict.get('log_message', '')
data_dict['id'] = id
group = get_action('group_update')(context, data_dict)
h.redirect_to(controller='group', action='read', id=group['name'])
h.redirect_to('%s_read' % str(group['type']), id=group['name'])
except NotAuthorized:
abort(401, _('Unauthorized to read group %s') % id)
except NotFound, e:
abort(404, _('Package not found'))
abort(404, _('Group not found'))
except DataError:
abort(400, _(u'Integrity Error'))
except ValidationError, e:
Expand Down
10 changes: 2 additions & 8 deletions ckan/controllers/package.py
Expand Up @@ -67,13 +67,6 @@ def register_pluggable_behaviour(map):
"""
global _default_controller_behaviour

# Check this method hasn't been invoked already.
# TODO: This method seems to be being invoked more than once during running of
# the tests. So I've disbabled this check until I figure out why.
#if _default_controller_behaviour is not None:
#raise ValueError, "Pluggable package controller behaviour is already defined "\
#"'%s'" % _default_controller_behaviour

# Create the mappings and register the fallback behaviour if one is found.
for plugin in PluginImplementations(IDatasetForm):
if plugin.is_fallback():
Expand All @@ -84,7 +77,6 @@ def register_pluggable_behaviour(map):

for package_type in plugin.package_types():
# Create a connection between the newly named type and the package controller
# but first we need to make sure we are not clobbering an existing domain
map.connect('/%s/new' % (package_type,), controller='package', action='new')
map.connect('%s_read' % (package_type,), '/%s/{id}' % (package_type,), controller='package', action='read')
map.connect('%s_action' % (package_type,),
Expand Down Expand Up @@ -448,6 +440,8 @@ def new(self, data=None, errors=None, error_summary=None):
'save': 'save' in request.params,
'schema': self._form_to_db_schema(package_type=package_type)}

# Package needs to have a publisher group in the call to check_access
# and also to save it
try:
check_access('package_create',context)
except NotAuthorized:
Expand Down
32 changes: 26 additions & 6 deletions ckan/lib/alphabet_paginate.py
Expand Up @@ -21,7 +21,8 @@
from routes import url_for

class AlphaPage(object):
def __init__(self, collection, alpha_attribute, page, other_text, paging_threshold=50):
def __init__(self, collection, alpha_attribute, page, other_text, paging_threshold=50,
controller_name='tag'):
'''
@param collection - sqlalchemy query of all the items to paginate
@param alpha_attribute - name of the attribute (on each item of the
Expand All @@ -31,12 +32,22 @@ def __init__(self, collection, alpha_attribute, page, other_text, paging_thresho
non-alphabetic first character.
@param paging_threshold - the minimum number of items required to
start paginating them.
@param controller_name - The name of the controller that will be linked to,
which defaults to tag. The controller name should be the
same as the route so for some this will be the full
controller name such as 'A.B.controllers.C:ClassName'
'''
self.collection = collection
self.alpha_attribute = alpha_attribute
self.page = page
self.other_text = other_text
self.paging_threshold = paging_threshold
self.controller_name = controller_name
self.available = dict( (c,0,) for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" )
for c in self.collection:
x = c if isinstance( c, unicode ) else getattr(c, self.alpha_attribute)[0]
self.available[x] = self.available.get(x, 0) + 1



def pager(self, q=None):
Expand All @@ -58,10 +69,13 @@ def pager(self, q=None):
letters = [char for char in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] + [self.other_text]
for letter in letters:
if letter != page:
page = HTML.a(class_='pager_link', href=url_for(controller='tag', action='index', page=letter), c=letter)
if self.available.get(letter, 0):
page_element = HTML.a(class_='pager_link', href=url_for(controller=self.controller_name, action='index', page=letter),c=letter)
else:
page_element = HTML.span(class_="pager_empty", c=letter)
else:
page = HTML.span(class_='pager_curpage', c=letter)
pages.append(page)
page_element = HTML.span(class_='pager_curpage', c=letter)
pages.append(page_element)
div = HTML.tag('div', class_='pager', *pages)
return div

Expand Down Expand Up @@ -96,10 +110,16 @@ def items(self):
elif isinstance(self.collection,list):
if self.item_count >= self.paging_threshold:
if self.page != self.other_text:
items = [x for x in self.collection if x[0:1].lower() == self.page.lower()]
if isinstance(self.collection[0], dict):
items = [x for x in self.collection if x[self.alpha_attribute][0:1].lower() == self.page.lower()]
else:
items = [x for x in self.collection if getattr(x,self.alpha_attribute)[0:1].lower() == self.page.lower()]
else:
# regexp search
items = [x for x in self.collection if re.match('^[^a-zA-Z].*',x)]
if isinstance(self.collection[0], dict):
items = [x for x in self.collection if re.match('^[^a-zA-Z].*',x[self.alpha_attribute])]
else:
items = [x for x in self.collection if re.match('^[^a-zA-Z].*',x)]
items.sort()
else:
items = self.collection
Expand Down
19 changes: 15 additions & 4 deletions ckan/lib/create_test_data.py
Expand Up @@ -273,7 +273,7 @@ def pkg(pkg_name):


@classmethod
def create_groups(cls, group_dicts, admin_user_name=None):
def create_groups(cls, group_dicts, admin_user_name=None, auth_profile=""):
'''A more featured interface for creating groups.
All group fields can be filled, packages added and they can
have an admin user.'''
Expand All @@ -289,6 +289,7 @@ def create_groups(cls, group_dicts, admin_user_name=None):
group_attributes = set(('name', 'title', 'description', 'parent_id'))
for group_dict in group_dicts:
group = model.Group(name=unicode(group_dict['name']))
group.type = auth_profile or 'group'
for key in group_dict:
if key in group_attributes:
setattr(group, key, group_dict[key])
Expand All @@ -307,7 +308,7 @@ def create_groups(cls, group_dicts, admin_user_name=None):
model.repo.commit_and_remove()

@classmethod
def create(cls):
def create(cls, auth_profile=""):
import ckan.model as model
model.Session.remove()
rev = model.repo.new_revision()
Expand All @@ -318,8 +319,13 @@ def create(cls):
* Package: warandpeace
* Associated tags, etc etc
'''
if auth_profile == "publisher":
publisher_group = model.Group(name=u"publisher_group", type="publisher")

cls.pkg_names = [u'annakarenina', u'warandpeace']
pkg1 = model.Package(name=cls.pkg_names[0])
if auth_profile == "publisher":
pkg1.group = publisher_group
model.Session.add(pkg1)
pkg1.title = u'A Novel By Tolstoy'
pkg1.version = u'0.7a'
Expand Down Expand Up @@ -373,6 +379,9 @@ def create(cls):
tag1 = model.Tag(name=u'russian')
tag2 = model.Tag(name=u'tolstoy')

if auth_profile == "publisher":
pkg2.group = publisher_group

# Flexible tag, allows spaces, upper-case,
# and all punctuation except commas
tag3 = model.Tag(name=u'Flexible \u30a1')
Expand All @@ -390,10 +399,12 @@ def create(cls):
# group
david = model.Group(name=u'david',
title=u'Dave\'s books',
description=u'These are books that David likes.')
description=u'These are books that David likes.',
type=auth_profile or 'group')
roger = model.Group(name=u'roger',
title=u'Roger\'s books',
description=u'Roger likes these books.')
description=u'Roger likes these books.',
type=auth_profile or 'group')
for obj in [david, roger]:
model.Session.add(obj)

Expand Down
16 changes: 12 additions & 4 deletions ckan/lib/dictization/model_save.py
Expand Up @@ -219,6 +219,7 @@ def package_membership_list_save(group_dicts, package, context):
member_obj = model.Member(table_id = package.id,
table_name = 'package',
group = group,
group_id=group.id,
state = 'active')
session.add(member_obj)

Expand Down Expand Up @@ -262,7 +263,8 @@ def relationship_list_save(relationship_dicts, package, attr, context):
relationship_list.append(relationship)

def package_dict_save(pkg_dict, context):

import uuid

model = context["model"]
package = context.get("package")
allow_partial_update = context.get("allow_partial_update", False)
Expand All @@ -277,6 +279,9 @@ def package_dict_save(pkg_dict, context):

pkg = table_dict_save(pkg_dict, Package, context)

if not pkg.id:
pkg.id = str(uuid.uuid4())

package_resource_list_save(pkg_dict.get("resources", []), pkg, context)
package_tag_list_save(pkg_dict.get("tags", []), pkg, context)
package_membership_list_save(pkg_dict.get("groups", []), pkg, context)
Expand All @@ -295,7 +300,6 @@ def package_dict_save(pkg_dict, context):
return pkg

def group_member_save(context, group_dict, member_table_name):

model = context["model"]
session = context["session"]
group = context['group']
Expand Down Expand Up @@ -327,14 +331,15 @@ def group_member_save(context, group_dict, member_table_name):
session.add(entity_member[entity_id])

for entity_id in set(entities.keys()) - set(entity_member.keys()):
member = Member(group=group, table_id=entity_id[0],
member = Member(group=group, group_id=group.id, table_id=entity_id[0],
table_name=member_table_name[:-1],
capacity=entity_id[1])
session.add(member)


def group_dict_save(group_dict, context):

import uuid

model = context["model"]
session = context["session"]
group = context.get("group")
Expand All @@ -345,6 +350,9 @@ def group_dict_save(group_dict, context):
group_dict["id"] = group.id

group = table_dict_save(group_dict, Group, context)
if not group.id:
group.id = str(uuid.uuid4())

context['group'] = group

group_member_save(context, group_dict, 'packages')
Expand Down
2 changes: 1 addition & 1 deletion ckan/lib/helpers.py
Expand Up @@ -148,7 +148,7 @@ def subnav_named_route(c, text, routename,**kwargs):
""" Generate a subnav element based on a named route """
return link_to(
text,
url_for(routename, **kwargs),
url_for(str(routename), **kwargs),
class_=('active' if c.action == kwargs['action'] else '')
)

Expand Down
4 changes: 2 additions & 2 deletions ckan/logic/__init__.py
@@ -1,7 +1,7 @@
import logging
from ckan.lib.base import _
import ckan.authz
import ckan.new_authz as new_authz
from ckan.new_authz import is_authorized
from ckan.lib.navl.dictization_functions import flatten_dict, DataError
from ckan.plugins import PluginImplementations
from ckan.plugins.interfaces import IActions
Expand Down Expand Up @@ -129,7 +129,7 @@ def check_access(action, context, data_dict=None):
# # TODO Check the API key is valid at some point too!
# log.debug('Valid API key needed to make changes')
# raise NotAuthorized
logic_authorization = new_authz.is_authorized(action, context, data_dict)
logic_authorization = is_authorized(action, context, data_dict)
if not logic_authorization['success']:
msg = logic_authorization.get('msg','')
raise NotAuthorized(msg)
Expand Down
3 changes: 2 additions & 1 deletion ckan/logic/action/create.py
Expand Up @@ -180,14 +180,15 @@ def group_create(context, data_dict):
rev.message = _(u'REST API: Create object %s') % data.get("name")

group = group_dict_save(data, context)

if user:
admins = [model.User.by_name(user.decode('utf8'))]
else:
admins = []
model.setup_default_user_roles(group, admins)
# Needed to let extensions know the group id
session.flush()

for item in PluginImplementations(IGroupController):
item.create(group)

Expand Down
6 changes: 3 additions & 3 deletions ckan/logic/auth/create.py
Expand Up @@ -6,14 +6,13 @@
def package_create(context, data_dict=None):
model = context['model']
user = context['user']

check1 = check_access_old(model.System(), model.Action.PACKAGE_CREATE, context)

if not check1:
return {'success': False, 'msg': _('User %s not authorized to create packages') % str(user)}
else:

check2 = check_group_auth(context,data_dict)
check2 = _check_group_auth(context,data_dict)
if not check2:
return {'success': False, 'msg': _('User %s not authorized to edit these groups') % str(user)}

Expand Down Expand Up @@ -74,7 +73,8 @@ def user_create(context, data_dict=None):
else:
return {'success': True}

def check_group_auth(context, data_dict):

def _check_group_auth(context, data_dict):
if not data_dict:
return True

Expand Down

0 comments on commit c26a741

Please sign in to comment.