Skip to content

Commit

Permalink
Merge branch 'master' into 4291-werkzeug-dev-server
Browse files Browse the repository at this point in the history
  • Loading branch information
tino097 committed Sep 3, 2018
2 parents 052c4b0 + 49d348a commit 792be10
Show file tree
Hide file tree
Showing 20 changed files with 189 additions and 49 deletions.
2 changes: 0 additions & 2 deletions CHANGELOG.rst
Expand Up @@ -172,8 +172,6 @@ Changes and deprecations:
* The old Celery based background jobs have been removed in CKAN 2.8 in favour of the new RQ based
jobs (http://docs.ckan.org/en/latest/maintaining/background-tasks.html). Extensions can still
of course use Celery but they will need to handle the management themselves.
* `ckan.recaptcha.version` config option is removed, since v2 is the only valid
version now (#4061)
* After introducing dataset blueprint, `h.get_facet_items_dict` takes search_facets as second argument.
This change is aimed to reduce usage of global variables in context. For a while, it has default value
of None, in which case, `c.search_facets` will be used. But all template designers are strongly advised
Expand Down
7 changes: 6 additions & 1 deletion ckan/config/middleware/flask_app.py
Expand Up @@ -210,13 +210,16 @@ def hello_world_post():
app = plugin.make_middleware(app, config)

# Fanstatic
fanstatic_enable_rollup = asbool(app_conf.get('fanstatic_enable_rollup',
False))
if debug:
fanstatic_config = {
'versioning': True,
'recompute_hashes': True,
'minified': False,
'bottom': True,
'bundle': False,
'rollup': fanstatic_enable_rollup,
}
else:
fanstatic_config = {
Expand All @@ -225,6 +228,7 @@ def hello_world_post():
'minified': True,
'bottom': True,
'bundle': True,
'rollup': fanstatic_enable_rollup,
}
root_path = config.get('ckan.root_path', None)
if root_path:
Expand Down Expand Up @@ -312,7 +316,8 @@ def ckan_after_request(response):

def helper_functions():
u'''Make helper functions (`h`) available to Flask templates'''
helpers.load_plugin_helpers()
if not helpers.helper_functions:
helpers.load_plugin_helpers()
return dict(h=helpers.helper_functions)


Expand Down
4 changes: 4 additions & 0 deletions ckan/config/middleware/pylons_app.py
Expand Up @@ -75,13 +75,16 @@ def make_pylons_stack(conf, full_stack=True, static_files=True,
cleanup_pylons_response_string)

# Fanstatic
fanstatic_enable_rollup = asbool(app_conf.get('fanstatic_enable_rollup',
False))
if asbool(config.get('debug', False)):
fanstatic_config = {
'versioning': True,
'recompute_hashes': True,
'minified': False,
'bottom': True,
'bundle': False,
'rollup': fanstatic_enable_rollup,
}
else:
fanstatic_config = {
Expand All @@ -90,6 +93,7 @@ def make_pylons_stack(conf, full_stack=True, static_files=True,
'minified': True,
'bottom': True,
'bundle': True,
'rollup': fanstatic_enable_rollup,
}
root_path = config.get('ckan.root_path', None)
if root_path:
Expand Down
15 changes: 13 additions & 2 deletions ckan/lib/fanstatic_resources.py
Expand Up @@ -38,7 +38,7 @@ def get_resource(lib_name, resource_name):
res = getattr(module, '%s' % resource_name)
return res

def create_resource(path, lib_name, count, inline=False):
def create_resource(path, lib_name, count, inline=False, supersedes=None):
''' create the fanstatic Resource '''
renderer = None
kw = {}
Expand Down Expand Up @@ -83,6 +83,12 @@ def create_resource(path, lib_name, count, inline=False):
script=inline,
renderer=renderer,
other_browsers=other_browsers)
if supersedes:
superseded_library, superseded_resource_path = supersedes
for _library in get_library_registry().values():
if _library.name == superseded_library:
kw['supersedes'] = [_library.known_resources[superseded_resource_path]]
break
resource = Resource(library, path, **kw)

# Add our customised ordering
Expand Down Expand Up @@ -116,6 +122,7 @@ def create_resource(path, lib_name, count, inline=False):
IE_conditionals = {}
custom_render_order = {}
inline_scripts = {}
supersedes = {}

# parse the resource.config file if it exists
config_path = os.path.join(resource_path, 'resource.config')
Expand Down Expand Up @@ -150,6 +157,9 @@ def create_resource(path, lib_name, count, inline=False):
if f not in IE_conditionals:
IE_conditionals[f] = []
IE_conditionals[f].append(n)
if config.has_section('supersedes'):
items = config.items('supersedes')
supersedes = dict((n, v.split('/', 1)) for (n, v) in items)

# add dependencies for resources in groups
for group in groups:
Expand Down Expand Up @@ -210,7 +220,8 @@ def create_resource(path, lib_name, count, inline=False):
inline = inline_scripts[resource_name].strip()
else:
inline = None
create_resource(resource_name, name, count, inline=inline)
create_resource(resource_name, name, count, inline=inline,
supersedes=supersedes.get(resource_name))
count += 1

# add groups
Expand Down
2 changes: 1 addition & 1 deletion ckan/lib/search/query.py
Expand Up @@ -20,7 +20,7 @@
VALID_SOLR_PARAMETERS = set([
'q', 'fl', 'fq', 'rows', 'sort', 'start', 'wt', 'qf', 'bf', 'boost',
'facet', 'facet.mincount', 'facet.limit', 'facet.field',
'extras', 'fq_list', 'tie', 'defType', 'mm'
'extras', 'fq_list', 'tie', 'defType', 'mm', 'df'
])

# for (solr) package searches, this specifies the fields that are searched
Expand Down
2 changes: 1 addition & 1 deletion ckan/logic/action/create.py
Expand Up @@ -227,7 +227,7 @@ def package_create(context, data_dict):
return_id_only = context.get('return_id_only', False)

if return_id_only:
return context['id']
return pkg.id

return _get_action('package_show')(
context.copy(), {'id': pkg.id}
Expand Down
3 changes: 3 additions & 0 deletions ckan/logic/action/get.py
Expand Up @@ -1814,6 +1814,9 @@ def package_search(context, data_dict):
for key in [key for key in data_dict.keys() if key.startswith('ext_')]:
data_dict['extras'][key] = data_dict.pop(key)

# set default search field
data_dict['df'] = 'text'

# check if some extension needs to modify the search params
for item in plugins.PluginImplementations(plugins.IPackageController):
data_dict = item.before_search(data_dict)
Expand Down
2 changes: 1 addition & 1 deletion ckan/public/base/javascript/modules/autocomplete.js
Expand Up @@ -266,7 +266,7 @@ this.ckan.module('autocomplete', function (jQuery) {
* Returns nothing.
*/
_onKeydown: function (event) {
if (event.which === 188) {
if (typeof event.key !== 'undefined' ? event.key === ',' : event.which === 188) {
event.preventDefault();
setTimeout(function () {
var e = jQuery.Event("keydown", { which: 13 });
Expand Down
16 changes: 14 additions & 2 deletions ckan/public/base/test/spec/modules/autocomplete.spec.js
Expand Up @@ -280,7 +280,7 @@ describe('ckan.modules.AutocompleteModule()', function () {

describe('._onKeydown(event)', function () {
beforeEach(function () {
this.keyDownEvent = jQuery.Event("keydown", { which: 188 });
this.keyDownEvent = jQuery.Event("keydown", { key: ',', which: 188 });
this.fakeEvent = {};
this.clock = sinon.useFakeTimers();
this.jQuery = sinon.stub(jQuery.fn, 'init', jQuery.fn.init);
Expand All @@ -294,7 +294,7 @@ describe('ckan.modules.AutocompleteModule()', function () {
this.Event.restore();
this.trigger.restore();
});

it('should trigger fake "return" keypress if a comma is pressed', function () {
this.module._onKeydown(this.keyDownEvent);

Expand All @@ -307,6 +307,7 @@ describe('ckan.modules.AutocompleteModule()', function () {
});

it('should do nothing if another key is pressed', function () {
this.keyDownEvent.key = '╚';
this.keyDownEvent.which = 200;

this.module._onKeydown(this.keyDownEvent);
Expand All @@ -315,5 +316,16 @@ describe('ckan.modules.AutocompleteModule()', function () {

assert.notCalled(this.Event);
});

it('should do nothing if key is pressed which has the comma key-code but is not a comma', function () {
this.keyDownEvent.key = 'ת';
this.keyDownEvent.which = 188;

this.module._onKeydown(this.keyDownEvent);

this.clock.tick(100);

assert.notCalled(this.Event);
});
});
});
2 changes: 1 addition & 1 deletion ckan/templates/snippets/language_selector.html
Expand Up @@ -3,7 +3,7 @@
<label for="field-lang-select">{{ _('Language') }}</label>
<select id="field-lang-select" name="url" data-module="autocomplete" data-module-dropdown-class="lang-dropdown" data-module-container-class="lang-container">
{% for locale in h.get_available_locales() %}
<option value="{% url_for h.current_url(), locale=locale.short_name %}" {% if locale.identifier == current_lang %}selected="selected"{% endif %}>
<option value="{% url_for h.current_url(), locale=locale.short_name %}" {% if locale.short_name == current_lang %}selected="selected"{% endif %}>
{{ locale.display_name or locale.english_name }}
</option>
{% endfor %}
Expand Down
11 changes: 11 additions & 0 deletions ckan/tests/logic/action/test_create.py
Expand Up @@ -5,6 +5,8 @@
'''
import __builtin__ as builtins

import six

import ckan
import ckan.logic as logic
import ckan.model as model
Expand Down Expand Up @@ -982,6 +984,15 @@ def test_tags(self):
for tag_dict in dataset['tags']])
assert_equals(tag_names, ['russian', 'tolstoy'])

def test_return_id_only(self):
dataset = helpers.call_action(
'package_create',
name='test-id',
context={'return_id_only': True},
)

assert isinstance(dataset, six.string_types)


class TestGroupCreate(helpers.FunctionalTestBase):

Expand Down
14 changes: 14 additions & 0 deletions ckan/tests/logic/action/test_update.py
Expand Up @@ -652,6 +652,20 @@ def test_tags(self):
for tag_dict in dataset_['tags']])
assert_equals(tag_names, ['russian', 'tolstoy'])

def test_return_id_only(self):
user = factories.User()
dataset = factories.Dataset(
user=user)

updated_dataset = helpers.call_action(
'package_update',
id=dataset['id'],
notes='Test',
context={'return_id_only': True},
)

assert_equals(updated_dataset, dataset['id'])


class TestUpdateSendEmailNotifications(object):
@classmethod
Expand Down
5 changes: 4 additions & 1 deletion ckanext/datastore/backend/postgres.py
Expand Up @@ -1414,7 +1414,10 @@ def upsert(context, data_dict):
context['connection'].execute(
u'SET LOCAL statement_timeout TO {0}'.format(timeout))
upsert_data(context, data_dict)
trans.commit()
if data_dict.get(u'dry_run', False):
trans.rollback()
else:
trans.commit()
return _unrename_json_field(data_dict)
except IntegrityError as e:
if e.orig.pgcode == _PG_ERR_CODE['unique_violation']:
Expand Down
3 changes: 3 additions & 0 deletions ckanext/datastore/logic/action.py
Expand Up @@ -229,6 +229,9 @@ def datastore_upsert(context, data_dict):
Possible options are: upsert, insert, update
(optional, default: upsert)
:type method: string
:param dry_run: set to True to abort transaction instead of committing,
e.g. to check for validation or type errors.
:type dry_run: bool (optional, default: False)
**Results:**
Expand Down
1 change: 1 addition & 0 deletions ckanext/datastore/logic/schema.py
Expand Up @@ -135,6 +135,7 @@ def datastore_upsert_schema():
'id': [ignore_missing],
'method': [ignore_missing, text_type, OneOf(
['upsert', 'insert', 'update'])],
'dry_run': [ignore_missing, boolean_validator],
'__junk': [empty],
'__before': [rename('id', 'resource_id')]
}
Expand Down

0 comments on commit 792be10

Please sign in to comment.