Skip to content

Commit

Permalink
Merge branch 'master' into 846-unicode-api-json
Browse files Browse the repository at this point in the history
  • Loading branch information
tobes committed Jun 27, 2013
2 parents 02049cc + 493745b commit 0439001
Show file tree
Hide file tree
Showing 92 changed files with 1,133 additions and 1,042 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Expand Up @@ -423,7 +423,7 @@ v1.5 2011-11-07
Major:
* New visual theme (#1108)
* Package & Resource edit overhaul (#1294/#1348/#1351/#1368/#1296)
* JS and CSS reorganisation (#1282, #1349, #1380)
* JS and CSS reorganization (#1282, #1349, #1380)
* Apache Solr used for search in core instead of Postgres (#1275, #1361, #1365)
* Authorization system now embedded in the logic layer (#1253)
* Captcha added for user registration (#1307, #1431)
Expand Down
1 change: 1 addition & 0 deletions bin/ckan_edit_local.py
Expand Up @@ -84,6 +84,7 @@ def canada_extras():
'Level of Government':'level_of_government',
}
license_mapping = {
# CS: bad_spelling ignore
'http://geogratis.ca/geogratis/en/licence.jsp':'geogratis',
'Crown Copyright':'canada-crown',
}
Expand Down
2 changes: 1 addition & 1 deletion ckan/__init__.py
@@ -1,4 +1,4 @@
__version__ = '2.1a'
__version__ = '2.2a'

__description__ = 'Comprehensive Knowledge Archive Network (CKAN) Software'
__long_description__ = \
Expand Down
2 changes: 1 addition & 1 deletion ckan/config/deployment.ini_tmpl
Expand Up @@ -107,7 +107,7 @@ ckan.preview.loadable = html htm rdf+xml owl+xml xml n3 n-triples turtle plain a
ckan.locale_default = en
ckan.locale_order = en pt_BR ja it cs_CZ ca es fr el sv sr sr@latin no sk fi ru de pl nl bg ko_KR hu sa sl lv
ckan.locales_offered =
ckan.locales_filtered_out =
ckan.locales_filtered_out = en_GB


## Feeds Settings
Expand Down
5 changes: 4 additions & 1 deletion ckan/config/routing.py
Expand Up @@ -279,7 +279,6 @@ def make_map():
requirements=dict(action='|'.join([
'edit',
'delete',
'members',
'member_new',
'member_delete',
'history',
Expand All @@ -291,6 +290,10 @@ def make_map():
])))
m.connect('group_about', '/group/about/{id}', action='about',
ckan_icon='info-sign'),
m.connect('group_edit', '/group/edit/{id}', action='edit',
ckan_icon='edit')
m.connect('group_members', '/group/members/{id}', action='members',
ckan_icon='group'),
m.connect('group_activity', '/group/activity/{id}/{offset}',
action='activity', ckan_icon='time'),
m.connect('group_read', '/group/{id}', action='read',
Expand Down
14 changes: 9 additions & 5 deletions ckan/controllers/api.py
Expand Up @@ -164,7 +164,7 @@ def action(self, logic_function, ver=None):
except KeyError:
log.error('Can\'t find logic function: %s' % logic_function)
return self._finish_bad_request(
_('Action name not known: %s') % str(logic_function))
_('Action name not known: %s') % logic_function)

context = {'model': model, 'session': model.Session, 'user': c.user,
'api_version': ver}
Expand All @@ -175,9 +175,9 @@ def action(self, logic_function, ver=None):
request_data = self._get_request_data(try_url_params=
side_effect_free)
except ValueError, inst:
log.error('Bad request data: %s' % str(inst))
log.error('Bad request data: %s' % inst)
return self._finish_bad_request(
_('JSON Error: %s') % str(inst))
_('JSON Error: %s') % inst)
if not isinstance(request_data, dict):
# this occurs if request_data is blank
log.error('Bad request data - not dict: %r' % request_data)
Expand Down Expand Up @@ -216,6 +216,7 @@ def action(self, logic_function, ver=None):
error_dict['__type'] = 'Validation Error'
return_dict['error'] = error_dict
return_dict['success'] = False
# CS nasty_string ignore
log.error('Validation error: %r' % str(e.error_dict))
return self._finish(409, return_dict, content_type='json')
except search.SearchQueryError, e:
Expand Down Expand Up @@ -340,7 +341,7 @@ def create(self, ver=None, register=None, subregister=None,
data_dict.update(request_data)
except ValueError, inst:
return self._finish_bad_request(
_('JSON Error: %s') % str(inst))
_('JSON Error: %s') % inst)

action = self._get_action_from_map(action_map, register, subregister)
if not action:
Expand All @@ -363,6 +364,7 @@ def create(self, ver=None, register=None, subregister=None,
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
except ValidationError, e:
# CS: nasty_string ignore
log.error('Validation error: %r' % str(e.error_dict))
return self._finish(409, e.error_dict, content_type='json')
except DataError, e:
Expand Down Expand Up @@ -402,7 +404,7 @@ def update(self, ver=None, register=None, subregister=None,
data_dict.update(request_data)
except ValueError, inst:
return self._finish_bad_request(
_('JSON Error: %s') % str(inst))
_('JSON Error: %s') % inst)

action = self._get_action_from_map(action_map, register, subregister)
if not action:
Expand All @@ -418,6 +420,7 @@ def update(self, ver=None, register=None, subregister=None,
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
except ValidationError, e:
# CS: nasty_string ignore
log.error('Validation error: %r' % str(e.error_dict))
return self._finish(409, e.error_dict, content_type='json')
except DataError, e:
Expand Down Expand Up @@ -465,6 +468,7 @@ def delete(self, ver=None, register=None, subregister=None,
extra_msg = e.extra_msg
return self._finish_not_found(extra_msg)
except ValidationError, e:
# CS: nasty_string ignore
log.error('Validation error: %r' % str(e.error_dict))
return self._finish(409, e.error_dict, content_type='json')

Expand Down
4 changes: 2 additions & 2 deletions ckan/controllers/group.py
Expand Up @@ -281,7 +281,7 @@ def pager_url(q=None, page=None):
default_facet_titles = {'groups': _('Groups'),
'tags': _('Tags'),
'res_format': _('Formats'),
'license': _('License')}
'license_id': _('License')}

for facet in g.facets:
if facet in default_facet_titles:
Expand Down Expand Up @@ -524,7 +524,7 @@ def _save_edit(self, id, context):
if id != group['name']:
self._force_reindex(group)

h.redirect_to('%s_read' % str(group['type']), id=group['name'])
h.redirect_to('%s_read' % group['type'], id=group['name'])
except NotAuthorized:
abort(401, _('Unauthorized to read group %s') % id)
except NotFound, e:
Expand Down
4 changes: 2 additions & 2 deletions ckan/controllers/organization.py
Expand Up @@ -19,7 +19,7 @@ def _group_form(self, group_type=None):
return 'organization/new_organization_form.html'

def _form_to_db_schema(self, group_type=None):
return lookup_group_plugin(group_type).form_to_db_schema()
return group.lookup_group_plugin(group_type).form_to_db_schema()

def _db_to_form_schema(self, group_type=None):
'''This is an interface to manipulate data from the database
Expand Down Expand Up @@ -48,7 +48,7 @@ def _read_template(self, group_type):
return 'organization/read.html'

def _history_template(self, group_type):
return lookup_group_plugin(group_type).history_template()
return group.lookup_group_plugin(group_type).history_template()

def _edit_template(self, group_type):
return 'organization/edit.html'
Expand Down
31 changes: 9 additions & 22 deletions ckan/controllers/package.py
Expand Up @@ -1319,9 +1319,9 @@ def resource_datapreview(self, id, resource_id):
'''
Embeded page for a resource data-preview.
Depending on the type, different previews are loaded.
This could be an img tag where the image is loaded directly or an iframe that
embeds a webpage, recline or a pdf preview.
Depending on the type, different previews are loaded. This could be an
img tag where the image is loaded directly or an iframe that embeds a
webpage, recline or a pdf preview.
'''
context = {
'model': model,
Expand All @@ -1335,30 +1335,17 @@ def resource_datapreview(self, id, resource_id):
c.package = get_action('package_show')(context, {'id': id})

data_dict = {'resource': c.resource, 'package': c.package}
on_same_domain = datapreview.resource_is_on_same_domain(data_dict)
data_dict['resource']['on_same_domain'] = on_same_domain

# FIXME this wants to not use plugins as it is an imported name
# and we already import it an p should really only be in
# extensu=ions in my opinion also just make it look nice and be
# readable grrrrrr
plugins = p.PluginImplementations(p.IResourcePreview)
plugins_that_can_preview = [plugin for plugin in plugins
if plugin.can_preview(data_dict)]
if len(plugins_that_can_preview) == 0:
abort(409, _('No preview has been defined.'))
if len(plugins_that_can_preview) > 1:
log.warn('Multiple previews are possible. {0}'.format(
plugins_that_can_preview))

plugin = plugins_that_can_preview[0]
plugin.setup_template_variables(context, data_dict)
preview_plugin = datapreview.get_preview_plugin(data_dict)

c.resource_json = json.dumps(c.resource)
if preview_plugin is None:
abort(409, _('No preview has been defined.'))

preview_plugin.setup_template_variables(context, data_dict)
c.resource_json = json.dumps(c.resource)
except NotFound:
abort(404, _('Resource not found'))
except NotAuthorized:
abort(401, _('Unauthorized to read resource %s') % id)
else:
return render(plugin.preview_template(context, data_dict))
return render(preview_plugin.preview_template(context, data_dict))
2 changes: 1 addition & 1 deletion ckan/lib/activity_streams.py
Expand Up @@ -256,7 +256,7 @@ def activity_list_to_html(context, activity_stream, extra_vars):

if not activity_type in activity_stream_string_functions:
raise NotImplementedError("No activity renderer for activity "
"type '%s'" % str(activity_type))
"type '%s'" % activity_type)

if activity_type in activity_stream_string_icons:
activity_icon = activity_stream_string_icons[activity_type]
Expand Down
15 changes: 7 additions & 8 deletions ckan/lib/celery_app.py
Expand Up @@ -4,7 +4,6 @@

from pylons import config as pylons_config
from pkg_resources import iter_entry_points, VersionConflict
#from celery.loaders.base import BaseLoader

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -49,16 +48,16 @@
log.critical(error)
pass

celery.conf.update(default_config)
celery.loader.conf.update(default_config)

try:
for key, value in config.items('app:celery'):
if key in LIST_PARAMS:
celery.conf[key.upper()] = value.split()
celery.loader.conf[key.upper()] = value.split()
default_config[key.upper()] = value.split()
else:
celery.conf[key.upper()] = value
celery.loader.conf[key.upper()] = value.split()
default_config[key.upper()] = value
except ConfigParser.NoSectionError:
pass

# Thes update of configuration means it is only possible to set each
# key once so this is done once all of the options have been decided.
celery.conf.update(default_config)
celery.loader.conf.update(default_config)
53 changes: 45 additions & 8 deletions ckan/lib/datapreview.py
Expand Up @@ -6,6 +6,7 @@
"""

import urlparse
import logging

import pylons.config as config

Expand All @@ -16,6 +17,8 @@
'n3', 'n-triples', 'turtle', 'plain',
'atom', 'rss', 'txt']

log = logging.getLogger(__name__)


def compare_domains(urls):
''' Return True if the domains of the provided are the same.
Expand All @@ -41,22 +44,56 @@ def compare_domains(urls):
return True


def resource_is_on_same_domain(data_dict):
def _on_same_domain(data_dict):
# compare CKAN domain and resource URL
ckan_url = config.get('ckan.site_url', '//localhost:5000')
resource_url = data_dict['resource']['url']

return compare_domains([ckan_url, resource_url])


def can_be_previewed(data_dict):
'''
Determines whether there is an extension that can preview the resource.
def get_preview_plugin(data_dict):
'''Determines whether there is an extension that can preview the resource.
:param data_dict: contains a resource and package dict.
The resource dict has to have a value for ``on_same_domain``
:type data_dict: dictionary
'''
data_dict['resource']['on_same_domain'] = resource_is_on_same_domain(data_dict)
plugins = p.PluginImplementations(p.IResourcePreview)
return any(plugin.can_preview(data_dict) for plugin in plugins)
Returns a dict of plugins that can preview or ones that are fixable'''

data_dict['resource']['on_same_domain'] = _on_same_domain(data_dict)

plugins_that_can_preview = []
plugins_fixable = []
for plugin in p.PluginImplementations(p.IResourcePreview):
p_info = {'plugin': plugin, 'quality': 1}
data = plugin.can_preview(data_dict)
# old school plugins return true/False
if isinstance(data, bool):
p_info['can_preview'] = data
else:
# new school provide a dict
p_info.update(data)
# if we can preview
if p_info['can_preview']:
plugins_that_can_preview.append(p_info)
elif p_info.get('fixable'):
plugins_fixable.append(p_info)

num_plugins = len(plugins_that_can_preview)
if num_plugins == 0:
# we didn't find any. see if any could be made to work
for plug in plugins_fixable:
log.info('%s would allow previews to fix: %s' % (
plug['plugin'], plug['fixable']))
preview_plugin = None
elif num_plugins == 1:
# just one available
preview_plugin = plugins_that_can_preview[0]['plugin']
else:
# multiple plugins so get the best one
plugs = [pl['plugin'] for pl in plugins_that_can_preview]
log.warn('Multiple previews are possible. {0}'.format(plugs))
preview_plugin = max(plugins_that_can_preview,
key=lambda x: x['quality'])['plugin']
return preview_plugin
10 changes: 9 additions & 1 deletion ckan/lib/helpers.py
Expand Up @@ -611,6 +611,13 @@ def check_access(action, data_dict=None):
return authorized


def get_action(action_name, data_dict=None):
'''Calls an action function from a template.'''
if data_dict is None:
data_dict = {}
return logic.get_action(action_name)({}, data_dict)


def linked_user(user, maxlength=0, avatar=20):
if user in [model.PSEUDO_USER__LOGGED_IN, model.PSEUDO_USER__VISITOR]:
return user
Expand Down Expand Up @@ -1505,7 +1512,7 @@ def resource_preview(resource, pkg_id):
if not loadable_in_iframe:
loadable_in_iframe = datapreview.DEFAULT_LOADABLE_IFRAME

if datapreview.can_be_previewed(data_dict):
if datapreview.get_preview_plugin(data_dict):
url = url_for(controller='package', action='resource_datapreview',
resource_id=resource['id'], id=pkg_id, qualified=True)
elif format_lower in direct_embed:
Expand Down Expand Up @@ -1587,6 +1594,7 @@ def SI_number_span(number):
'subnav_named_route',
'default_group_type',
'check_access',
'get_action',
'linked_user',
'group_name_to_title',
'markdown_extract',
Expand Down
1 change: 1 addition & 0 deletions ckan/lib/plugins.py
Expand Up @@ -192,6 +192,7 @@ def setup_template_variables(self, context, data_dict):
c.groups_available = authz_fn(context, data_dict)

c.licenses = [('', '')] + base.model.Package.get_license_options()
# CS: bad_spelling ignore 2 lines
c.licences = c.licenses
deprecate_context_item('licences', 'Use `c.licenses` instead')
c.is_sysadmin = ckan.new_authz.is_sysadmin(c.user)
Expand Down

0 comments on commit 0439001

Please sign in to comment.