Skip to content

Commit

Permalink
Merge branch 'master' into feature-2375-demo-theme
Browse files Browse the repository at this point in the history
  • Loading branch information
tobes committed Jun 13, 2012
2 parents e934ffc + 39943a7 commit c04bc38
Show file tree
Hide file tree
Showing 20 changed files with 758 additions and 602 deletions.
9 changes: 1 addition & 8 deletions ckan/config/deployment.ini_tmpl
Expand Up @@ -24,7 +24,7 @@ app_instance_uuid = ${app_instance_uuid}

# List the names of CKAN extensions to activate.
# Note: This line is required to be here for packaging, even if it is empty.
ckan.plugins = stats
ckan.plugins = stats synchronous_search

# If you'd like to fine-tune the individual locations of the cache data dirs
# for the Cache data, or the Session saves, un-comment the desired settings
Expand Down Expand Up @@ -83,13 +83,6 @@ package_form = standard
# * queue - native Python Queue (debugging and tests only)
#carrot_messaging_library = pyamqplib

## Update the search index synchronously (i.e. in-process rather than
## out-of-process as would be case if using AMQP framework)
## Set to false to disable, true to enable
## Default enabled (and enabled if option entirely absent)
## NOTE this is mutually exclusive with ckan.async_notifier
ckan.build_search_index_synchronously = true

## Perform search just using database (rather than use e.g. solr).
## In this setup search is crude and limited .e.g no full-text search, no faceting ...
## However, very useful for getting up and running quickly with CKAN
Expand Down
112 changes: 112 additions & 0 deletions ckan/i18n/check_po_files.py
@@ -0,0 +1,112 @@
#!/usr/bin/env python
'''Script for checking for common translation mistakes in po files, see:
paster check-po-files --help
for usage.
Requires polib <http://pypi.python.org/pypi/polib>:
pip install polib
'''
import re
import polib
import paste.script.command

def simple_conv_specs(s):
'''Return the simple Python string conversion specifiers in the string s.
e.g. ['%s', '%i']
See http://docs.python.org/library/stdtypes.html#string-formatting
'''
simple_conv_specs_re = re.compile('\%\w')
return simple_conv_specs_re.findall(s)

def test_simple_conv_specs():
assert simple_conv_specs("Authorization function not found: %s") == (
['%s'])
assert simple_conv_specs("Problem purging revision %s: %s") == (
['%s', '%s'])
assert simple_conv_specs(
"Cannot create new entity of this type: %s %s") == ['%s', '%s']
assert simple_conv_specs("Could not read parameters: %r") == ['%r']
assert simple_conv_specs("User %r not authorized to edit %r") == (
['%r', '%r'])
assert simple_conv_specs(
"Please <a href=\"%s\">update your profile</a> and add your email "
"address and your full name. "
"%s uses your email address if you need to reset your password.") == (
['%s', '%s'])
assert simple_conv_specs(
"You can use %sMarkdown formatting%s here.") == ['%s', '%s']
assert simple_conv_specs(
"Name must be a maximum of %i characters long") == ['%i']
assert simple_conv_specs("Blah blah %s blah %(key)s blah %i") == (
['%s', '%i'])

def mapping_keys(s):
'''Return a sorted list of the mapping keys in the string s.
e.g. ['%(name)s', '%(age)i']
See http://docs.python.org/library/stdtypes.html#string-formatting
'''
mapping_keys_re = re.compile('\%\([^\)]*\)\w')
return sorted(mapping_keys_re.findall(s))

def test_mapping_keys():
assert mapping_keys(
"You have requested your password on %(site_title)s to be reset.\n"
"\n"
"Please click the following link to confirm this request:\n"
"\n"
" %(reset_link)s\n") == ['%(reset_link)s', '%(site_title)s']
assert mapping_keys(
"The input field %(name)s was not expected.") == ['%(name)s']
assert mapping_keys(
"[1:You searched for \"%(query)s\". ]%(number_of_results)s "
"datasets found.") == ['%(number_of_results)s', '%(query)s']
assert mapping_keys("Blah blah %s blah %(key)s blah %i") == (
['%(key)s']), mapping_keys("Blah blah %s blah %(key)s blah %i")

def replacement_fields(s):
'''Return a sorted list of the Python replacement fields in the string s.
e.g. ['{}', '{2}', '{object}', '{target}']
See http://docs.python.org/library/string.html#formatstrings
'''
repl_fields_re = re.compile('\{[^\}]*\}')
return sorted(repl_fields_re.findall(s))

def test_replacement_fields():
assert replacement_fields(
"{actor} added the tag {object} to the dataset {target}") == (
['{actor}', '{object}', '{target}'])
assert replacement_fields("{actor} updated their profile") == ['{actor}']

class CheckPoFiles(paste.script.command.Command):

usage = "[FILE] ..."
group_name = 'ckan'
summary = 'Check po files for common mistakes'
parser = paste.script.command.Command.standard_parser(verbose=True)

def command(self):
test_simple_conv_specs()
test_mapping_keys()
test_replacement_fields()
for path in self.args:
print 'Checking file {}'.format(path)
po = polib.pofile(path)
for entry in po.translated_entries():
for function in (simple_conv_specs, mapping_keys,
replacement_fields):
if not function(entry.msgid) == function(entry.msgstr):
print " Format specifiers don't match:"
print u' {0} -> {1}'.format(entry.msgid, entry.msgstr)
4 changes: 1 addition & 3 deletions ckan/public/css/style.css
Expand Up @@ -719,10 +719,9 @@ body.package.search #menusearch {
}
.dataset-search {
margin-bottom: 35px;
padding-right: 100px;
}
input.search {
width: 100%;
width: 380px;
float: left;
font-size: 1.2em;
margin: 0px;
Expand All @@ -740,7 +739,6 @@ input.search {
display: inline-block;
float: left;
margin-left: 9px;
margin-right: -100px;
}


Expand Down
18 changes: 18 additions & 0 deletions ckan/public/scripts/application.js
Expand Up @@ -51,6 +51,24 @@ CKAN.Utils = CKAN.Utils || {};
CKAN.DataPreview.loadEmbeddedPreview(preload_resource, reclineState);
}

if ($(document.body).hasClass('search')) {
// Calculate the optimal width for the search input regardless of the
// width of the submit button (which can vary depending on translation).
(function resizeSearchInput() {
var form = $('#dataset-search'),
input = form.find('[name=q]'),
button = form.find('[type=submit]'),
offset = parseFloat(button.css('margin-left'));

// Grab the horizontal properties of the input that affect the width.
$.each(['padding-left', 'padding-right', 'border-left-width', 'border-right-width'], function (i, prop) {
offset += parseFloat(input.css(prop)) || 0;
});

input.width(form.outerWidth() - button.outerWidth() - offset);
})();
}

var isDatasetNew = $('body.package.new').length > 0;
if (isDatasetNew) {
// Set up magic URL slug editor
Expand Down
70 changes: 17 additions & 53 deletions ckanext/organizations/templates/organization_read.html
Expand Up @@ -4,8 +4,9 @@
py:strip="">

<xi:include href="facets.html" />
<py:def function="page_title">${c.group.display_name}</py:def>
<py:def function="page_heading">${c.group.display_name}</py:def>

<py:def function="page_title">${c.group_dict.display_name}</py:def>
<py:def function="page_heading">${c.group_dict.display_name}</py:def>
<py:if test="c.group.image_url">
<py:def function="page_logo">${c.group.image_url}</py:def>
</py:if>
Expand All @@ -17,8 +18,8 @@
from ckan import model

if config.get('ckan.auth.profile', '') == 'publisher':
group_administrators = c.group.members_of_type(model.User, 'admin')
group_editors = c.group.members_of_type(model.User, 'editor')
group_administrators = [u for u in c.group.members_of_type(model.User, 'admin')]
group_editors = [u for u in c.group.members_of_type(model.User, 'editor')]
in_group = c.userobj and c.group in c.userobj.get_groups()
else:
group_administrators = c.group_admins
Expand All @@ -38,17 +39,17 @@ <h3>Administrators</h3>
</li>
</py:if>
<py:if test='group_editors and in_group'>
<li>
<h3>Members</h3>
<ul class="no-break">
<li py:for="editor in group_editors">${h.linked_user(editor)}</li>
</ul>
</li>
<li>
<h3>Members</h3>
<ul class="no-break">
<li py:for="editor in group_editors">${h.linked_user(editor)}</li>
</ul>
</li>
</py:if>
</ul>
</li>
${facet_sidebar('tags')}
${facet_sidebar('res_format')}
${facet_div('tags', 'Tags')}
${facet_div('res_format', 'Resource Formats')}
</py:match>

<py:match path="content">
Expand All @@ -59,59 +60,22 @@ <h3 py:if="c.group['state'] != 'active'">State: ${c.group['state']}</h3>
</div>
<div id="notes-remainder"></div>
<div id="notes-toggle" style="display: none;">
<button class="more pretty-button"><img src="/images/chevron-down.png"/></button>
<button class="less pretty-button" style="display: none;"><img src="/images/chevron-up.png"/></button>
<button class="more btn"><img src="/images/chevron-down.png"/></button>
<button class="less btn" style="display: none;"><img src="/images/chevron-up.png"/></button>
</div>
</div>
<div class="group-dataset-list">
<h3>Datasets</h3>

<form id="dataset-search" class="dataset-search" method="GET">
<input type="search" class="search" name="q" value="${c.q}" autocomplete="off" results="0" placeholder="${_('Search')}..." />
<py:for each="(k, v) in c.fields">
<input type="hidden" name="${k}" value="${v}" />
</py:for>
<input type="submit" value="${_('Search')}" class="pretty-button primary button" />
</form>
<xi:include href="package/search_form.html" />
${field_list()}

<p i18n:msg="query, number_of_results"><span py:if="c.q">You searched for "${c.q}". </span>${c.page.item_count} datasets found.</p>
${c.page.pager()}

<py:for each="package in c.page.items">
<div class="search-result ${'fullyopen' if (package.isopen and package.get('resources')) else None}">
<p class="extra-links">
<a class="view-more-link" href="${h.url_for(controller='package', action='read', id=package.get('name'))}">View</a>
</p>
<a class="main-link" href="${h.url_for(controller='package', action='read', id=package.get('name'))}">${package.get('title') or package.get('name')}</a>
&nbsp;&nbsp;
<py:if test="package.resources">
<py:for each="resource in package.resources">
<py:if test="resource.get('format')">
<a href="${resource.get('url')}"
title="${resource.get('description')}"><span class="format-box">${resource.get('format')}</span></a>
</py:if>
</py:for>
</py:if>
<p class="result-description">${h.markdown_extract(package.notes)}</p>

<span class="result-url">
<py:if test="package.isopen">
<a href="http://opendefinition.org/okd/" title="This dataset satisfies the Open Definition.">
<img src="http://assets.okfn.org/images/ok_buttons/od_80x15_blue.png" alt="[Open Data]" />
</a>
</py:if>
<py:if test="not package.isopen">
${h.icon('lock')} Not Openly Licensed
</py:if>
</span>
</div>
</py:for>
${package_list_from_dict(c.page.items)}
${c.page.pager()}
</div>
</py:match>

<xi:include href="organization_layout.html" />
</html>


37 changes: 14 additions & 23 deletions doc/coding-standards.rst
Expand Up @@ -20,14 +20,14 @@ Generally, follow the `commit guidelines from the Pro Git book`_:
change and contrasting the new with the previous behaviour.

- Use the imperative present tense as if you were giving commands to the
codebase to change its behaviour, e.g. "Add tests for", "make xyzzy do
frotz", not "Adding tests for", "I added tests for", "[This patch] makes
xyzzy do frotz" or "[I] changed xyzzy to do frotz".
codebase to change its behaviour, e.g. *Add tests for*, *make xyzzy do
frotz*, **not** *Adding tests for*, *I added tests for*, *[This patch] makes
xyzzy do frotz* or *[I] changed xyzzy to do frotz*.

- Try to write the commit message so that a new CKAN developer could understand
it, i.e. using plain English as far as possible, and not referring to too
much assumed knowledge or to external resources such as mailing list
dicsussions (summarize the relevant points in the commit message instead).
discussions (summarize the relevant points in the commit message instead).

.. _commit guidelines from the Pro Git book: http://git-scm.com/book/en/Distributed-Git-Contributing-to-a-Project#Commit-Guidelines

Expand All @@ -37,34 +37,25 @@ should be few commits that don't refer to a trac ticket, e.g. if you find a
typo in a docstring and quickly fix it you wouldn't bother to create a ticket
for this.

Use the `github-trac plugin`_'s syntax. Anywhere in the commit message:
Put the ticket number in square brackets (e.g. ``[#123]``) at the start of the
first line of the commit message. You can also reference other Trac tickets
elsewhere in your commit message by just using the ticket number on its own
(e.g. ``see #456``). Full example:

::

closes #123

will automatically close ticket #123 on `trac.ckan.org`_, and add a link to the
commit to the trac ticket (close, closed, fix, fixed and fixes would also
work). If your commit relates to a ticket but doesn't close it, then:

::

see #123

will add a link to the commit to ticket #123 on `trac.ckan.org`_, but will not
change the status of the ticket (references, refs, ref, addresses and re would
also work).

.. _github-trac plugin: https://github.com/davglass/github-trac
[#2505] Update source install instructions
Following feedback from markw (see #2406).

.. _trac.ckan.org: http://trac.ckan.org/

Example CKAN commit message:
Longer example CKAN commit message:

::

Refactor user controller a little, closes #2304

[#2304] Refactor user controller a little
Move initialisation of a few more template variables into
_setup_template_variables(), and change read(), edit(), and followers() to use
it. This removes some code duplication and fixes issues with the followers
Expand Down
19 changes: 0 additions & 19 deletions doc/configuration.rst
Expand Up @@ -460,25 +460,6 @@ These are the setup parameters for AMQP messaging. These only apply if the messa
Search Settings
---------------

.. index::
single: build_search_index_synchronously

build_search_index_synchronously
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Example::

ckan.build_search_index_synchronously=

Default (if you don't define it)::
indexing is on

This controls the operation of the CKAN search indexing. If you don't define this option then indexing is on. You will want to turn this off if you have a non-synchronous search index extension installed. In this case you need to define the option equal to blank (as in the example).

Another way to turn indexing on is to add ``synchronous_search`` to ``ckan.plugins``::

ckan.plugins = synchronous_search

.. index::
single: ckan.site_id

Expand Down

0 comments on commit c04bc38

Please sign in to comment.