Skip to content

Commit

Permalink
Merge branch 'master' into coding-standards-tests
Browse files Browse the repository at this point in the history
Conflicts:
	ckan/controllers/user.py
trivial merge
  • Loading branch information
tobes committed May 7, 2013
2 parents 745c679 + e88b2fb commit 87d955c
Show file tree
Hide file tree
Showing 51 changed files with 2,325 additions and 2,106 deletions.
22 changes: 8 additions & 14 deletions bin/travis-build
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,19 @@ sudo add-apt-repository -yy ppa:pitti/postgresql
sudo apt-get update -qq
sudo apt-get install solr-jetty postgresql-$PGVERSION

# Don't require a password to access DB
sudo sed -i -e 's/ident/trust/g' /etc/postgresql/$PGVERSION/main/pg_hba.conf

sudo service postgresql reload

# Setup postgres' users and databases
sudo -u postgres psql -c "CREATE USER ckan_default WITH PASSWORD 'pass';"
sudo -u postgres psql -c "CREATE USER datastore_default WITH PASSWORD 'pass';"
sudo -u postgres psql -c 'CREATE DATABASE ckan_test WITH OWNER ckan_default;'
sudo -u postgres psql -c 'CREATE DATABASE datastore_test WITH OWNER ckan_default;'

pip install -r pip-requirements.txt --use-mirrors
pip install -r pip-requirements-test.txt --use-mirrors

psql -c 'CREATE DATABASE ckan_test;' -U postgres
psql -c 'CREATE DATABASE ckan_test_datastore;' -U postgres

python setup.py develop

# Configure CKAN's configuration file
sed -i -e 's/.*solr_url.*/solr_url = http:\/\/127.0.0.1:8983\/solr/' test-core.ini
sed -i -e 's/.*ckan\.site_id.*/ckan.site_id = travis_ci/' test-core.ini
sed -i -e 's/^sqlalchemy.url.*/sqlalchemy.url = postgresql:\/\/postgres@\/ckan_test/' test-core.ini
sed -i -e 's/.*datastore.write_url.*/ckan.datastore.write_url = postgresql:\/\/postgres@\/ckan_test_datastore/' test-core.ini

# Configure Solr
echo "NO_START=0\nJETTY_HOST=127.0.0.1\nJETTY_PORT=8983\nJAVA_HOME=$JAVA_HOME" | sudo tee /etc/default/jetty
# FIXME the solr schema cannot be hardcoded as it is dependent on the ckan version
Expand All @@ -45,8 +39,8 @@ paster db init -c test-core.ini
# If Postgres >= 9.0, we don't need to use datastore's legacy mode.
if [ $PGVERSION != '8.4' ]
then
psql -c 'CREATE USER readonlyuser;' -U postgres
sed -i -e 's/.*datastore.read_url.*/ckan.datastore.read_url = postgresql:\/\/readonlyuser@\/ckan_test_datastore/' test-core.ini
psql -c 'CREATE USER datastore_default;' -U postgres
sed -i -e 's/.*datastore.read_url.*/ckan.datastore.read_url = postgresql:\/\/datastore_default@\/datastore_test/' test-core.ini
paster datastore set-permissions postgres -c test-core.ini
else
sed -i -e 's/.*datastore.read_url.*//' test-core.ini
Expand Down
34 changes: 16 additions & 18 deletions ckan/config/deployment.ini_tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,14 @@ use = egg:ckan
full_stack = true
cache_dir = %(here)s/data
beaker.session.key = ckan

# This is the secret token that the beaker library uses to hash the cookie sent
# to the client. `paster make-config` generates a unique value for this each
# time it generates a config file.
beaker.session.secret = ${app_instance_secret}

# `paster make-config` generates a unique value for this each time it generates
# a config file.
app_instance_uuid = ${app_instance_uuid}

# List the names of CKAN extensions to activate.
Expand All @@ -65,23 +72,20 @@ ckan.plugins = stats json_preview recline_preview
# Specify the database for SQLAlchemy to use:
# * Postgres is currently required for a production CKAN deployment
# * Sqlite (memory or file) can be used as a quick alternative for testing
sqlalchemy.url = postgresql://ckanuser:pass@localhost/ckan_dev
sqlalchemy.url = postgresql://ckan_default:pass@localhost/ckan_default
#sqlalchemy.url = sqlite:///
#sqlalchemy.url = sqlite:///%(here)s/somedb.db

# Un-comment and specify the URLs for the DataStore database.
# * Postgres is required
#ckan.datastore.write_url = postgresql://ckanuser:pass@localhost/datastore
#ckan.datastore.read_url = postgresql://readonlyuser:pass@localhost/datastore
#ckan.datastore.write_url = postgresql://ckan_default:pass@localhost/datastore_default
#ckan.datastore.read_url = postgresql://datastore_default:pass@localhost/datastore_default

# repoze.who config
who.config_file = %(here)s/who.ini
who.log_level = warning
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 cached local version of ckan group)
#licenses_group_url = http://licenses.opendefinition.org/licenses/groups/ckan.json

Expand Down Expand Up @@ -149,7 +153,7 @@ ckan.gravatar_default = identicon

## An 'id' for the site (using, for example, when creating entries in a common search index)
## If not specified derived from the site_url
# ckan.site_id = ckan.net
ckan.site_id = default

## API url to use (e.g. in AJAX callbacks)
## Enable if the API is at a different domain
Expand Down Expand Up @@ -244,7 +248,7 @@ ckan.feeds.author_link =

# To enable local file storage:
#ofs.impl = pairtree
#ofs.storage_dir = /my/path/to/storage/root/directory
#ofs.storage_dir = /var/lib/ckan/default

# To enable Google cloud storage:
#ofs.impl = google
Expand Down Expand Up @@ -302,24 +306,24 @@ ckan.debug_supress_header = false
keys = root, ckan, ckanext

[handlers]
keys = console, file
keys = console

[formatters]
keys = generic

[logger_root]
level = WARNING
handlers = console, file
handlers = console

[logger_ckan]
level = INFO
handlers = console, file
handlers = console
qualname = ckan
propagate = 0

[logger_ckanext]
level = DEBUG
handlers = console, file
handlers = console
qualname = ckanext
propagate = 0

Expand All @@ -329,11 +333,5 @@ args = (sys.stderr,)
level = NOTSET
formatter = generic

[handler_file]
class = logging.handlers.RotatingFileHandler
formatter = generic
level = NOTSET
args = ("ckan.log", "a", 20000000, 9)

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s
2 changes: 1 addition & 1 deletion ckan/controllers/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def pager_url(q=None, page=None):
'groups': _('Groups'),
'tags': _('Tags'),
'res_format': _('Formats'),
'license': _('Licence'),
'license_id': _('Licence'),
}

for facet in g.facets:
Expand Down
5 changes: 3 additions & 2 deletions ckan/controllers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ def display_name(followee):
action_functions.get(filter_type))
# Is this a valid type?
if action_function is None:
raise abort(404, _('Follow item not found'))
abort(404, _('Follow item not found'))
try:
followee = action_function(context, data_dict)
except NotFound:
Expand Down Expand Up @@ -574,7 +574,8 @@ def dashboard(self, id=None, offset=0):
c.dashboard_activity_stream_context = self._get_dashboard_context(
filter_type, filter_id, q)
c.dashboard_activity_stream = h.dashboard_activity_stream(
filter_type, filter_id, offset)
c.userobj.id, filter_type, filter_id, offset
)

# Mark the user's new activities as old whenever they view their
# dashboard page.
Expand Down
2 changes: 1 addition & 1 deletion ckan/lib/app_globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
'ckan.api_url': {},

# split string
'search.facets': {'default': 'organization groups tags res_format license',
'search.facets': {'default': 'organization groups tags res_format license_id',
'type': 'split',
'name': 'facets'},
'package_hide_extras': {'type': 'split'},
Expand Down
5 changes: 3 additions & 2 deletions ckan/lib/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ def render_template():
return render_jinja2(template_name, globs)

# Genshi templates
template = globs['app_globals'].genshi_loader.load(template_name,
cls=loader_class)
template = globs['app_globals'].genshi_loader.load(
template_name.encode('utf-8'), cls=loader_class
)
stream = template.generate(**globs)

for item in PluginImplementations(IGenshiStreamFilter):
Expand Down
2 changes: 1 addition & 1 deletion ckan/lib/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def find_template(template_name):
returns the full path is it exists. '''
template_paths = config['pylons.app_globals'].template_paths
for path in template_paths:
if os.path.exists(os.path.join(path, template_name)):
if os.path.exists(os.path.join(path, template_name.encode('utf-8'))):
return os.path.join(path, template_name)

def template_type(template_path):
Expand Down
6 changes: 6 additions & 0 deletions ckan/logic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ def get_action(action):
:rtype: callable
'''

# clean the action names
action = new_authz.clean_action_name(action)

if _actions:
if not action in _actions:
raise KeyError("Action '%s' not found" % action)
Expand All @@ -278,6 +282,7 @@ def get_action(action):
if not k.startswith('_'):
# Only load functions from the action module.
if isinstance(v, types.FunctionType):
k = new_authz.clean_action_name(k)
_actions[k] = v

# Whitelist all actions defined in logic/action/get.py as
Expand All @@ -290,6 +295,7 @@ def get_action(action):
fetched_actions = {}
for plugin in p.PluginImplementations(p.IActions):
for name, auth_function in plugin.get_actions().items():
name = new_authz.clean_action_name(name)
if name in resolved_action_plugins:
raise Exception(
'The action %r is already implemented in %r' % (
Expand Down
8 changes: 7 additions & 1 deletion ckan/logic/action/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,7 @@ def package_search(context, data_dict):
abort = data_dict.get('abort_search',False)

if data_dict.get('sort') in (None, 'rank'):
data_dict['sort'] = 'score desc, metadata_created desc'
data_dict['sort'] = 'score desc, metadata_modified desc'

results = []
if not abort:
Expand Down Expand Up @@ -1345,6 +1345,12 @@ def package_search(context, data_dict):
new_facet_dict['display_name'] = group.display_name
else:
new_facet_dict['display_name'] = key_
elif key == 'license_id':
license = model.Package.get_license_register().get(key_)
if license:
new_facet_dict['display_name'] = license.title
else:
new_facet_dict['display_name'] = key_
else:
new_facet_dict['display_name'] = key_
new_facet_dict['count'] = value_
Expand Down
10 changes: 10 additions & 0 deletions ckan/new_authz.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys
import re
from logging import getLogger

from pylons import config
Expand All @@ -18,6 +19,12 @@ class AuthFunctions:
def clear_auth_functions_cache():
AuthFunctions._functions.clear()


def clean_action_name(action_name):
''' Used to convert old style action names into new style ones '''
return re.sub('package', 'dataset', action_name)


def is_sysadmin(username):
''' returns True is username is a sysadmin '''
if not username:
Expand Down Expand Up @@ -62,6 +69,7 @@ def is_authorized(action, context, data_dict=None):
if is_sysadmin(context.get('user')):
return {'success': True}

action = clean_action_name(action)
auth_function = _get_auth_function(action)
if auth_function:
return auth_function(context, data_dict)
Expand Down Expand Up @@ -234,13 +242,15 @@ def _get_auth_function(action):

for key, v in module.__dict__.items():
if not key.startswith('_'):
key = clean_action_name(key)
AuthFunctions._functions[key] = v

# Then overwrite them with any specific ones in the plugins:
resolved_auth_function_plugins = {}
fetched_auth_functions = {}
for plugin in p.PluginImplementations(p.IAuthFunctions):
for name, auth_function in plugin.get_auth_functions().items():
name = clean_action_name(name)
if name in resolved_auth_function_plugins:
raise Exception(
'The auth function %r is already implemented in %r' % (
Expand Down
1 change: 0 additions & 1 deletion ckan/plugins/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""
Interfaces for plugins system
See doc/plugins.rst for more information
"""

__all__ = [
Expand Down

0 comments on commit 87d955c

Please sign in to comment.