[ckan-changes] [okfn/ckan] e8f48c: [merge] from release-v1.6.1

GitHub noreply at github.com
Wed May 2 18:05:41 UTC 2012


  Branch: refs/heads/release-dgu1
  Home:   https://github.com/okfn/ckan
  Commit: e8f48cd5c2327ccd01b2b0da1f9bb78e824670e1
      https://github.com/okfn/ckan/commit/e8f48cd5c2327ccd01b2b0da1f9bb78e824670e1
  Author: David Read <david.read at hackneyworkshop.com>
  Date:   2012-05-02 (Wed, 02 May 2012)

  Changed paths:
    M ckan/controllers/user.py
    M ckan/lib/alphabet_paginate.py
    M ckan/lib/base.py
    M ckan/public/css/style.css
    M ckan/templates/tag/index.html
    M ckan/templates/user/list.html
    M ckan/templates/user/login.html
    M ckan/templates/user/logout.html
    M ckan/tests/functional/test_user.py
    M ckan/tests/lib/test_alphabet_pagination.py

  Log Message:
  -----------
  [merge] from release-v1.6.1


diff --git a/ckan/controllers/user.py b/ckan/controllers/user.py
index d17df6f..81ec29f 100644
--- a/ckan/controllers/user.py
+++ b/ckan/controllers/user.py
@@ -52,6 +52,11 @@ def _setup_template_variables(self, context):
 
     ## end hooks
 
+    def _get_repoze_handler(self, handler_name):
+        '''Returns the URL that repoze.who will respond to and perform a
+        login or logout.'''
+        return getattr(request.environ['repoze.who.plugins']['friendlyform'], handler_name)
+        
     def index(self):
         LIMIT = 20
 
@@ -165,7 +170,9 @@ def _save_new(self, context):
             return self.new(data_dict, errors, error_summary)
         if not c.user:
             # Redirect to a URL picked up by repoze.who which performs the login
-            h.redirect_to('/login_generic?login=%s&password=%s' % (
+            login_url = self._get_repoze_handler('login_handler_path')
+            h.redirect_to('%s?login=%s&password=%s' % (
+                login_url,
                 str(data_dict['name']),
                 quote(data_dict['password1'].encode('utf-8'))))
         else:
@@ -257,6 +264,7 @@ def login(self):
             g.openid_enabled = False
 
         if not c.user:
+            c.login_handler = h.url_for(self._get_repoze_handler('login_handler_path'))
             return render('user/login.html')
         else:
             return render('user/logout_first.html')
@@ -283,10 +291,10 @@ def logged_in(self):
             h.redirect_to(locale=lang, controller='user', action='login')
 
     def logout(self):
-        # save our language in the session so we don't loose it
+        # save our language in the session so we don't lose it
         session['lang'] = request.environ.get('CKAN_LANG')
         session.save()
-        h.redirect_to('/user/logout')
+        h.redirect_to(self._get_repoze_handler('logout_handler_path'))
 
     def set_lang(self, lang):
         # this allows us to set the lang in session.  Used for logging
diff --git a/ckan/lib/alphabet_paginate.py b/ckan/lib/alphabet_paginate.py
index 0afa88f..b75bf27 100644
--- a/ckan/lib/alphabet_paginate.py
+++ b/ckan/lib/alphabet_paginate.py
@@ -1,6 +1,7 @@
 '''
-Based on webhelpers.paginator, but each page is for items beginning
- with a particular letter.
+Based on webhelpers.paginator, but:
+ * each page is for items beginning with a particular letter
+ * output is suitable for Bootstrap
 
  Example:
         c.page = h.Page(
@@ -43,7 +44,12 @@ def __init__(self, collection, alpha_attribute, page, other_text, paging_thresho
         self.other_text = other_text
         self.paging_threshold = paging_threshold
         self.controller_name = controller_name
-        self.available = dict( (c,0,) for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" )
+
+        self.letters = [char for char in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] + [self.other_text]
+        
+        # Work out which alphabet letters are 'available' i.e. have some results
+        # because we grey-out those which aren't.
+        self.available = dict( (c,0,) for c in self.letters )
         for c in self.collection:
             if isinstance(c, unicode):
                 x = c[0]
@@ -51,35 +57,42 @@ def __init__(self, collection, alpha_attribute, page, other_text, paging_thresho
                 x = c[self.alpha_attribute][0]
             else:
                 x = getattr(c, self.alpha_attribute)[0]
+            x = x.upper()
+            if x not in self.letters:
+                x = self.other_text
             self.available[x] = self.available.get(x, 0) + 1
 
     def pager(self, q=None):
         '''Returns pager html - for navigating between the pages.
            e.g. Something like this:
-             <div class='pager'>
-                 <span class="pager_curpage">A</span>
-                 <a class="pager_link" href="/package/list?page=B">B</a>
-                 <a class="pager_link" href="/package/list?page=C">C</a>
+             <ul class='pagination pagination-alphabet'>
+                 <li class="active"><a href="/package/list?page=A">A</a></li>
+                 <li><a href="/package/list?page=B">B</a></li>
+                 <li><a href="/package/list?page=C">C</a></li>
                     ...
-                 <a class="pager_link" href="/package/list?page=Z">Z</a
-                 <a class="pager_link" href="/package/list?page=Other">Other</a
-             </div>
+                 <li class="disabled"><a href="/package/list?page=Z">Z</a></li>
+                 <li><a href="/package/list?page=Other">Other</a></li>
+             </ul>
         '''
         if self.item_count < self.paging_threshold:
             return ''
         pages = []
         page = q or self.page
-        letters = [char for char in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] + [self.other_text]
-        for letter in letters:
+        for letter in self.letters:
+            href = url_for(controller=self.controller_name, action='index', page=letter)
+            link = HTML.a(href=href, c=letter)
             if letter != page:
                 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)
+                    li_class = ''
                 else:
-                    page_element = HTML.span(class_="pager_empty", c=letter)
+                    li_class = 'disabled'
             else:
-                page_element = HTML.span(class_='pager_curpage', c=letter)
+                li_class = 'active'
+            attributes = {'class_': li_class} if li_class else {}
+            page_element = HTML.li(link, **attributes)
             pages.append(page_element)
-        div = HTML.tag('div', class_='pager', *pages)
+        ul = HTML.tag('ul', *pages)
+        div = HTML.div(ul, class_='pagination pagination-alphabet')
         return div
 
 
diff --git a/ckan/lib/base.py b/ckan/lib/base.py
index ffb79a7..4f77150 100644
--- a/ckan/lib/base.py
+++ b/ckan/lib/base.py
@@ -169,9 +169,11 @@ def _identify_user(self):
         b) For API calls he may set a header with his API key.
         If the user is identified then:
           c.user = user name (unicode)
+          c.userobj = user object
           c.author = user name
         otherwise:
           c.user = None
+          c.userobj = None
           c.author = user\'s IP address (unicode)
         '''
         # see if it was proxied first
@@ -180,8 +182,10 @@ def _identify_user(self):
             c.remote_addr = request.environ.get('REMOTE_ADDR', 'Unknown IP Address')
 
         # environ['REMOTE_USER'] is set by repoze.who if it authenticates a user's
-        # cookie or OpenID. (But it doesn't check the user (still) exists in our
-        # database - we need to do that here.
+        # cookie or OpenID. But repoze.who doesn't check the user (still)
+        # exists in our database - we need to do that here. (Another way would
+        # be with an userid_checker, but that would mean another db access.
+        # See: http://docs.repoze.org/who/1.0/narr.html#module-repoze.who.plugins.sql )
         c.user = request.environ.get('REMOTE_USER', '')
         if c.user:
             c.user = c.user.decode('utf8')
@@ -210,38 +214,41 @@ def __call__(self, environ, start_response):
         # the request is routed to. This routing information is
         # available in environ['pylons.routes_dict']
 
+        try:
+            res = WSGIController.__call__(self, environ, start_response)
+        finally:
+            model.Session.remove()
+
         # Clean out any old cookies as they may contain api keys etc
         # This also improves the cachability of our pages as cookies
         # prevent proxy servers from caching content unless they have
         # been configured to ignore them.
-        # we do not want to clear cookies when setting the user lang
-        if not environ.get('PATH_INFO').startswith('/user/set_lang'):
-            for cookie in request.cookies:
-                if cookie.startswith('ckan') and cookie not in ['ckan']:
-                    response.delete_cookie(cookie)
-                # Remove the ckan session cookie if not used e.g. logged out
-                elif cookie == 'ckan' and not c.user:
-                    # Check session for valid data (including flash messages)
-                    # (DGU also uses session for a shopping basket-type behaviour)
-                    is_valid_cookie_data = False
-                    for key, value in session.items():
-                        if not key.startswith('_') and value:
-                            is_valid_cookie_data = True
-                            break
-                    if not is_valid_cookie_data:
-                        if session.id:
-                            if not session.get('lang'):
-                                session.delete()
-                        else:
-                            response.delete_cookie(cookie)
-                # Remove auth_tkt repoze.who cookie if user not logged in.
-                elif cookie == 'auth_tkt' and not session.id:
-                    response.delete_cookie(cookie)
-
-        try:
-            return WSGIController.__call__(self, environ, start_response)
-        finally:
-            model.Session.remove()
+        for cookie in request.cookies:
+            if cookie.startswith('ckan') and cookie not in ['ckan']:
+                response.delete_cookie(cookie)
+            # Remove the ckan session cookie if not used e.g. logged out
+            elif cookie == 'ckan' and not c.user:
+                # Check session for valid data (including flash messages)
+                # (DGU also uses session for a shopping basket-type behaviour)
+                is_valid_cookie_data = False
+                for key, value in session.items():
+                    if not key.startswith('_') and value:
+                        is_valid_cookie_data = True
+                        break
+                if not is_valid_cookie_data:
+                    if session.id:
+                        if not session.get('lang'):
+                            self.log.debug('No session data any more - deleting session')
+                            self.log.debug('Session: %r', session.items())
+                            session.delete()
+                    else:
+                        response.delete_cookie(cookie)
+                        self.log.debug('No session data any more - deleting session cookie')
+            # Remove auth_tkt repoze.who cookie if user not logged in.
+            elif cookie == 'auth_tkt' and not session.id:
+                response.delete_cookie(cookie)
+
+        return res
 
     def __after__(self, action, **params):
         self._set_cors()
diff --git a/ckan/public/css/style.css b/ckan/public/css/style.css
index d0d261c..2e9a938 100644
--- a/ckan/public/css/style.css
+++ b/ckan/public/css/style.css
@@ -381,28 +381,8 @@ ul.no-break li {
 /* ============== */
 /* = Pagination = */
 /* ============== */
-.pager {
-	width: 100%;
-	text-align: center;
-	margin: 0 0 1.2em 0;
-	clear: both;
-}
-.pager span, .pager a {
-	text-decoration: none;
-	margin: 0em;
-	border: none;
-	padding: 0.3em 0.1em;
-}
-.pager a:hover, .pager a:active {
-	color: #fff;
-	background-color: #c22;
-}
-.pager span.pager_dotdot {
-	color: #aaa;
-}
-.pager span.pager_curpage {
-	font-weight: bold;
-	border: 1px solid #ddd;
+.pagination-alphabet a { 
+        padding: 0 6px;
 }
 
 /* ====== */
diff --git a/ckan/templates/tag/index.html b/ckan/templates/tag/index.html
index 17292e9..8c383c8 100644
--- a/ckan/templates/tag/index.html
+++ b/ckan/templates/tag/index.html
@@ -8,9 +8,9 @@
   <div py:match="content">
     <h2>Tags</h2>
 
-    <form id="tag-search" action="" method="GET">
+    <form class="form-inline" id="tag-search" action="" method="GET">
       <input type="text" id="q" name="q" value="${c.q}" />
-      <input type="submit" name="search" value="${_('Search')} »" />
+      <input class="btn btn-primary" type="submit" name="search" value="${_('Search')} »" />
     </form>
     
     <hr />
diff --git a/ckan/templates/user/list.html b/ckan/templates/user/list.html
index 3c736b4..1ef2655 100644
--- a/ckan/templates/user/list.html
+++ b/ckan/templates/user/list.html
@@ -8,9 +8,10 @@
   
   <py:match path="primarysidebar">
     <li class="widget-container widget_text">
-      <form id="user-search" class="user-search" action="" method="GET">
-        <input type="text" id="q" name="q" value="${c.q}" />
-        <input type="submit" class="btn btn-small" name="" value="${_('Search')} »" />
+      <h3>Search Users</h3>
+      <form id="user-search" class="form-inline user-search" action="" method="GET">
+        <input type="text" class="input-medium" id="q" name="q" value="${c.q}" />
+        <input type="submit" class="btn btn-small btn-primary" name="" value="${_('Search')} »" />
       </form>
       <p py:if="c.q" i18n:msg="item_count">
         <strong>${c.page.item_count}</strong> users found.
diff --git a/ckan/templates/user/login.html b/ckan/templates/user/login.html
index 6cabb81..6e3f936 100644
--- a/ckan/templates/user/login.html
+++ b/ckan/templates/user/login.html
@@ -18,25 +18,39 @@
   
   <py:def function="page_title">Login - User</py:def>
   <py:def function="page_heading">Login to ${g.site_title}</py:def>
+  <py:def function="body_class">no-sidebar</py:def>
 
   <div py:match="content">
-    
-    <form action="${h.url_for('/login_generic')}" method="post" class="simple-form" id="login">  
+
+    <form action="${c.login_handler}" method="post" class="form-horizontal" id="login">  
       <fieldset>
         <!--legend i18n:msg="site_title">Login</legend-->
+        <div class="control-group">
+          <label class="control-label" for="login">Login:</label>
+          <div class="controls">
+            <input type="text" class="input-xlarge" name="login" id="login" value="" />
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label" for="password">Password:</label>
+          <div class="controls">
+            <input type="password" name="password" id="password" value="" />
+          </div>
+        </div>
+        <div class="control-group">
+          <label class="control-label" for="remember">Remember me:</label>
+          <!-- optional 2 year cookie expiry -->
+          <div class="controls">
+            <input type="checkbox" name="remember" id="remember" value="63072000" checked="checked"/>
+          </div>
+        </div>        
 
-        <label for="login">Login:</label>
-        <input type="text" name="login" value="" />
-        <br/>
-        <label for="password">Password:</label>
-        <input type="password" name="password" value="" />
-        <!-- 50 year timeout -->
-        <input type="hidden" name="remember" value="1576800000" />
-        <br/>
+        <div class="form-actions">
+          <button name="s" id="s" type="submit" class="btn btn-primary">Sign In</button>
+          — 
+          <a href="${h.url_for('reset')}">Forgot your password?</a>
+        </div>
       </fieldset>
-      <input name="s" id="s" type="submit" class="btn primary" value="${_('Sign In')}"/>
-      — 
-      <a href="${h.url_for(controller='user', action='request_reset')}">Forgot your password?</a>
     </form>
     <br/> 
     <!-- Simple OpenID Selector -->
diff --git a/ckan/templates/user/logout.html b/ckan/templates/user/logout.html
index e40ec5c..0f37272 100644
--- a/ckan/templates/user/logout.html
+++ b/ckan/templates/user/logout.html
@@ -6,6 +6,7 @@
 
   <py:def function="page_title">Logout</py:def>
   <py:def function="page_heading">Logout from ${g.site_title}</py:def>
+  <py:def function="body_class">no-sidebar</py:def>
 
   <div py:match="content">
     <p>You have logged out successfully.</p>
diff --git a/ckan/tests/functional/test_user.py b/ckan/tests/functional/test_user.py
index 5ab1efc..eb44bd9 100644
--- a/ckan/tests/functional/test_user.py
+++ b/ckan/tests/functional/test_user.py
@@ -168,11 +168,14 @@ def test_login(self):
         fv = res.forms['login']
         fv['login'] = str(username)
         fv['password'] = str(password)
+        fv['remember'] = False
         res = fv.submit()
 
         # check cookies set
         cookies = self._get_cookie_headers(res)
         assert cookies
+        for cookie in cookies:
+            assert not 'max-age' in cookie.lower(), cookie
 
         # first get redirected to user/logged_in
         assert_equal(res.status, 302)
@@ -206,6 +209,32 @@ def test_login(self):
         print res
         assert 'testlogin' in res.body, res.body
 
+    def test_login_remembered(self):
+        # create test user
+        username = u'testlogin2'
+        password = u'letmein'
+        CreateTestData.create_user(name=username,
+                                   password=password)
+        user = model.User.by_name(username)
+
+        # do the login
+        offset = url_for(controller='user', action='login')
+        res = self.app.get(offset)
+        fv = res.forms['login']
+        fv['login'] = str(username)
+        fv['password'] = str(password)
+        fv['remember'] = True
+        res = fv.submit()
+
+        # check cookies set
+        cookies = self._get_cookie_headers(res)
+        assert cookies
+        # check cookie is remembered via Max-Age and Expires
+        # (both needed for cross-browser compatibility)
+        for cookie in cookies:
+            assert 'Max-Age=63072000;' in cookie, cookie
+            assert 'Expires=' in cookie, cookie
+
     def test_login_wrong_password(self):
         # create test user
         username = u'testloginwrong'
diff --git a/ckan/tests/lib/test_alphabet_pagination.py b/ckan/tests/lib/test_alphabet_pagination.py
index a1bf6ae..8afc276 100644
--- a/ckan/tests/lib/test_alphabet_pagination.py
+++ b/ckan/tests/lib/test_alphabet_pagination.py
@@ -1,5 +1,7 @@
 import re
 
+from nose.tools import assert_equal
+
 from ckan.tests import *
 from ckan.tests import regex_related
 from ckan.lib.create_test_data import CreateTestData
@@ -28,6 +30,16 @@ def setup_class(cls):
     def teardown_class(cls):
         model.repo.rebuild_db()
 
+    def test_00_model(self):
+        query = model.Session.query(model.Package)
+        page = h.AlphaPage(
+            collection=query,
+            alpha_attribute='title',
+            page='A',
+            other_text=other,
+        )
+        assert_equal(page.available, {'Other': 20, 'A': 10, 'C': 10, 'B': 10, 'E': 0, 'D': 10, 'G': 0, 'F': 0, 'I': 0, 'H': 0, 'K': 0, 'J': 0, 'M': 0, 'L': 0, 'O': 0, 'N': 0, 'Q': 0, 'P': 0, 'S': 0, 'R': 0, 'U': 0, 'T': 0, 'W': 0, 'V': 0, 'Y': 0, 'X': 0, 'Z': 0})
+
     def test_01_package_page(self):
         query = model.Session.query(model.Package)
         page = h.AlphaPage(
@@ -37,11 +49,12 @@ def test_01_package_page(self):
             other_text=other,
         )
         pager = page.pager()
-        assert pager.startswith('<div class="pager">'), pager
-        assert '<span class="pager_curpage">A</span>' in pager, pager
+        assert pager.startswith('<div class="pagination pagination-alphabet">'), pager
+        assert '<li class="active"><a href="/tag?page=A">A</a></li>' in pager, pager
         url_base = '/packages'
-        assert re.search('\<span class="pager_empty"\>B\<\/span\>', pager), pager
-        assert re.search('\<span class="pager_empty"\>Other\<\/span\>', pager), pager
+        assert re.search(r'\<li\>\<a href="\/tag\?page=B"\>B\<\/a\>\<\/li\>', pager), pager
+        assert re.search(r'\<li class="disabled"\>\<a href="\/tag\?page=E"\>E\<\/a\>\<\/li\>', pager), pager
+        assert re.search(r'\<li\>\<a href="\/tag\?page=Other"\>Other\<\/a\>\<\/li\>', pager), pager
 
 
     def test_02_package_items(self):


================================================================
  Commit: 064053aed704e4b92bc3d7b9aa03ed100e376e14
      https://github.com/okfn/ckan/commit/064053aed704e4b92bc3d7b9aa03ed100e376e14
  Author: David Read <david.read at hackneyworkshop.com>
  Date:   2012-05-02 (Wed, 02 May 2012)

  Changed paths:
    M ckan/lib/cli.py
    M ckan/model/__init__.py

  Log Message:
  -----------
  Fix logging for cli commands. Add logging to db upgrade etc.


diff --git a/ckan/lib/cli.py b/ckan/lib/cli.py
index d11a1f4..389ad17 100644
--- a/ckan/lib/cli.py
+++ b/ckan/lib/cli.py
@@ -3,11 +3,15 @@
 import sys
 import logging
 from pprint import pprint
+import re
 
 import paste.script
 from paste.registry import Registry
 from paste.script.util.logging_config import fileConfig
-import re
+
+#NB No CKAN imports are allowed until after the config file is loaded.
+#   i.e. do the imports in methods, after _load_config is called.
+#   Otherwise loggers get disabled.
 
 class MockTranslator(object):
     def gettext(self, value):
@@ -33,11 +37,7 @@ class CkanCommand(paste.script.command.Command):
     group_name = 'ckan'
 
     def _load_config(self):
-        # Avoids vdm logging warning
-        logging.basicConfig(level=logging.ERROR)
-
         from paste.deploy import appconfig
-        from ckan.config.environment import load_environment
         if not self.options.config:
             msg = 'No config file supplied'
             raise self.BadCommand(msg)
@@ -46,6 +46,10 @@ def _load_config(self):
             raise AssertionError('Config filename %r does not exist.' % self.filename)
         fileConfig(self.filename)
         conf = appconfig('config:' + self.filename)
+        assert 'ckan' not in dir() # otherwise loggers would be disabled
+        # We have now loaded the config. Now we can import ckan for the
+        # first time.
+        from ckan.config.environment import load_environment
         load_environment(conf.global_conf, conf.local_conf)
 
         self.registry=Registry()
diff --git a/ckan/model/__init__.py b/ckan/model/__init__.py
index c49cb1b..08574c5 100644
--- a/ckan/model/__init__.py
+++ b/ckan/model/__init__.py
@@ -94,6 +94,7 @@ def init_db(self):
 
                 self.init_configuration_data()
                 self.tables_created_and_initialised = True
+        log.info('Database initialised')
 
     def clean_db(self):
         metadata = MetaData(self.metadata.bind)
@@ -103,6 +104,7 @@ def clean_db(self):
 
         metadata.drop_all()
         self.tables_created_and_initialised = False
+        log.info('Database tables dropped')
 
     def init_const_data(self):
         '''Creates 'constant' objects that should always be there in
@@ -135,6 +137,7 @@ def create_db(self):
         self.metadata.create_all(bind=self.metadata.bind)
         self.init_const_data()
         self.init_configuration_data()
+        log.info('Database tables created')
 
     def latest_migration_version(self):
         import migrate.versioning.api as mig
@@ -156,6 +159,7 @@ def rebuild_db(self):
         self.session.remove()
         self.init_db()
         self.session.flush()
+        log.info('Database rebuilt')
 
     def delete_all(self):
         '''Delete all data from all tables.'''
@@ -169,7 +173,7 @@ def delete_all(self):
         for table in tables:
             connection.execute('delete from "%s"' % table.name)
         self.session.commit()
-
+        log.info('Database table data deleted')
 
     def setup_migration_version_control(self, version=None):
         import migrate.exceptions
@@ -191,9 +195,16 @@ def upgrade_db(self, version=None):
             meta.engine.name
         import migrate.versioning.api as mig
         self.setup_migration_version_control()
+        version_before = mig.db_version(self.metadata.bind, self.migrate_repository)
         mig.upgrade(self.metadata.bind, self.migrate_repository, version=version)
-        self.init_const_data()
+        version_after = mig.db_version(self.metadata.bind, self.migrate_repository)
+        if version_after != version_before:
+            log.info('CKAN database version upgraded: %s -> %s', version_before, version_after)
+        else:
+            log.info('CKAN database version remains as: %s', version_after)
 
+        self.init_const_data()
+        
         ##this prints the diffs in a readable format
         ##import pprint
         ##from migrate.versioning.schemadiff import getDiffOfModelAgainstDatabase


================================================================
  Commit: 62ebfabcbae261d87d59ed523857c823bfe8fb32
      https://github.com/okfn/ckan/commit/62ebfabcbae261d87d59ed523857c823bfe8fb32
  Author: David Read <david.read at hackneyworkshop.com>
  Date:   2012-05-02 (Wed, 02 May 2012)

  Changed paths:
    M ckan/config/environment.py
    M ckan/lib/helpers.py
    M ckan/logic/__init__.py
    M doc/configuration.rst

  Log Message:
  -----------
  Spelling typos.


diff --git a/ckan/config/environment.py b/ckan/config/environment.py
index 8d42f4b..d5cf049 100644
--- a/ckan/config/environment.py
+++ b/ckan/config/environment.py
@@ -30,12 +30,12 @@ class _Helpers(object):
     def __init__(self, helpers, restrict=True):
         functions = {}
         allowed = helpers.__allowed_functions__
-        # list of functions due to be depreciated
-        self.depreciated = []
+        # list of functions due to be deprecated
+        self.deprecated = []
 
         for helper in dir(helpers):
             if helper not in allowed:
-                self.depreciated.append(helper)
+                self.deprecated.append(helper)
                 if restrict:
                     continue
             functions[helper] = getattr(helpers, helper)
@@ -63,14 +63,14 @@ def null_function(cls, *args, **kw):
     def __getattr__(self, name):
         ''' return the function/object requested '''
         if name in self.functions:
-            if name in self.depreciated:
-                msg = 'Template helper function `%s` is depriciated' % name
+            if name in self.deprecated:
+                msg = 'Template helper function `%s` is deprecated' % name
                 self.log.warn(msg)
             return self.functions[name]
         else:
-            if name in self.depreciated:
+            if name in self.deprecated:
                 msg = 'Template helper function `%s` is not available ' \
-                      'as it has been depriciated.\nYou can enable it ' \
+                      'as it has been deprecated.\nYou can enable it ' \
                       'by setting ckan.restrict_template_vars = true ' \
                       'in your .ini file.' % name
                 self.log.critical(msg)
diff --git a/ckan/lib/helpers.py b/ckan/lib/helpers.py
index 92c40a6..cc33ad9 100644
--- a/ckan/lib/helpers.py
+++ b/ckan/lib/helpers.py
@@ -254,7 +254,7 @@ def are_there_flash_messages():
 
 def nav_link(*args, **kwargs):
     # nav_link() used to need c passing as the first arg
-    # this is depriciated as pointless
+    # this is deprecated as pointless
     # throws error if ckan.restrict_template_vars is True
     # When we move to strict helpers then this should be removed as a wrapper
     if len(args) > 2 or (len(args) > 1 and 'controller' in kwargs):
@@ -277,7 +277,7 @@ def _nav_link(text, controller, **kwargs):
 
 def nav_named_link(*args, **kwargs):
     # subnav_link() used to need c passing as the first arg
-    # this is depriciated as pointless
+    # this is deprecated as pointless
     # throws error if ckan.restrict_template_vars is True
     # When we move to strict helpers then this should be removed as a wrapper
     if len(args) > 3 or (len(args) > 0 and 'text' in kwargs) or \
@@ -298,7 +298,7 @@ def _nav_named_link(text, name, **kwargs):
 
 def subnav_link(*args, **kwargs):
     # subnav_link() used to need c passing as the first arg
-    # this is depriciated as pointless
+    # this is deprecated as pointless
     # throws error if ckan.restrict_template_vars is True
     # When we move to strict helpers then this should be removed as a wrapper
     if len(args) > 2 or (len(args) > 1 and 'action' in kwargs):
@@ -316,7 +316,7 @@ def _subnav_link(text, action, **kwargs):
 
 def subnav_named_route(*args, **kwargs):
     # subnav_link() used to need c passing as the first arg
-    # this is depriciated as pointless
+    # this is deprecated as pointless
     # throws error if ckan.restrict_template_vars is True
     # When we move to strict helpers then this should be removed as a wrapper
     if len(args) > 2 or (len(args) > 0 and 'text' in kwargs) or \
@@ -373,7 +373,7 @@ def facet_items(*args, **kwargs):
     """
     _log.warning('Deprecated function: ckan.lib.helpers:facet_items().  Will be removed in v1.8')
     # facet_items() used to need c passing as the first arg
-    # this is depriciated as pointless
+    # this is deprecated as pointless
     # throws error if ckan.restrict_template_vars is True
     # When we move to strict helpers then this should be removed as a wrapper
     if len(args) > 2 or (len(args) > 0 and 'name' in kwargs) or (len(args) > 1 and 'limit' in kwargs):
@@ -724,7 +724,7 @@ def dump_json(obj, **kw):
 
 def auto_log_message(*args):
     # auto_log_message() used to need c passing as the first arg
-    # this is depriciated as pointless
+    # this is deprecated as pointless
     # throws error if ckan.restrict_template_vars is True
     # When we move to strict helpers then this should be removed as a wrapper
     if len(args) and asbool(config.get('ckan.restrict_template_vars', 'false')):
@@ -811,7 +811,7 @@ def process_names(items):
            'default_group_type',
            'facet_items',
            'facet_title',
-         #  am_authorized, # depreciated
+         #  am_authorized, # deprecated
            'check_access',
            'linked_user',
            'linked_authorization_group',
diff --git a/ckan/logic/__init__.py b/ckan/logic/__init__.py
index 30cd4ae..fa37d8a 100644
--- a/ckan/logic/__init__.py
+++ b/ckan/logic/__init__.py
@@ -227,7 +227,7 @@ def get_action(action):
 
 def get_or_bust(data_dict, keys):
     '''Try and get values from dictionary and if they are not there
-    raise a validataion error.
+    raise a validation error.
 
     data_dict: a dictionary
     keys: either a single string key in which case will return a single value,
diff --git a/doc/configuration.rst b/doc/configuration.rst
index 0ac49fb..7bcc747 100644
--- a/doc/configuration.rst
+++ b/doc/configuration.rst
@@ -673,7 +673,7 @@ This is a directory where SQL database backups are to be written, assuming a scr
 
 
 
-Compatability
+Compatibility
 -------------
 
 .. index::


================================================================
Compare: https://github.com/okfn/ckan/compare/e8f48cd^...62ebfab


More information about the ckan-changes mailing list