[ckan-changes] commit/ckan: 3 new changesets

Bitbucket commits-noreply at bitbucket.org
Fri Oct 21 16:05:08 UTC 2011


3 new changesets in ckan:

http://bitbucket.org/okfn/ckan/changeset/a70906cf6cab/
changeset:   a70906cf6cab
branch:      feature-1378-welcome-banner
user:        zephod
date:        2011-10-20 18:26:23
summary:     [welcome][m]: Added neat top-bar mechanism to welcome new users.
affected #:  4 files (-1 bytes)

--- a/ckan/lib/app_globals.py	Mon Oct 17 15:07:58 2011 +0100
+++ b/ckan/lib/app_globals.py	Thu Oct 20 17:26:23 2011 +0100
@@ -21,6 +21,7 @@
                                   'http://assets.okfn.org/p/ckan/img/ckan.ico')
         self.site_logo = config.get('ckan.site_logo', '')
         self.site_url = config.get('ckan.site_url', '')
+        self.site_url_nice = self.site_url.replace('http://','').replace('www.','')
         self.site_description = config.get('ckan.site_description', '')
         
         self.facets = config.get('search.facets', 'groups tags res_format license').split()


--- a/ckan/public/css/style.css	Mon Oct 17 15:07:58 2011 +0100
+++ b/ckan/public/css/style.css	Thu Oct 20 17:26:23 2011 +0100
@@ -1222,6 +1222,32 @@
   color: #000;
 }
 
+.top-bar {
+  width: 100%;
+  /* Old background was a little less intrusive */
+  background: #fcba63;
+  background: #b22;
+  text-align: center;
+  padding: 0;
+  border-bottom: 1px solid #faa;
+  font-weight: bold;
+}
+.top-bar-text {
+  line-height: 30px;
+  color: #fff;
+}
+.top-bar-text a {
+  color: #fff;
+  text-decoration: underline;
+}
+.top-bar button.js-kill-button {
+  float: right;
+  margin-right: 20px;
+  margin-top: 3px;
+  padding: 2px 8px;
+}
+
+
 /* ============================= */
 /* = Inline resource edit form = */
 /* ============================= */


--- a/ckan/public/scripts/application.js	Mon Oct 17 15:07:58 2011 +0100
+++ b/ckan/public/scripts/application.js	Thu Oct 20 17:26:23 2011 +0100
@@ -18,6 +18,11 @@
       client: client
     };
 
+    var isFrontPage = $('body.index.home').length > 0;
+    if (isFrontPage) {
+      CKAN.Utils.setupTopBar($('.top-bar'));
+    }
+
     var isDatasetView = $('body.package.read').length > 0;
     if (isDatasetView) {
       var _dataset = new CKAN.Model.Dataset(preload_dataset);
@@ -83,8 +88,16 @@
     var messageDiv = $('<div />').html(msg).addClass(category).hide();
     $('.flash-messages').append(messageDiv);
     messageDiv.show(1200);
+  };
 
-  };
+  // Animate the appearance of an element by expanding its height
+  my.animateHeight = function(element, animTime) {
+    if (!animTime) animTime = 350;
+    element.show();
+    var finalHeight = element.height();
+    element.height(0);
+    element.animate({height:finalHeight}, animTime);
+  }
 
   my.bindInputChanges = function(input, callback) {
     input.keyup(callback);
@@ -93,6 +106,25 @@
     input.change(callback);
   };
 
+  my.setupTopBar = function(topBar) {
+
+    var cookieName = 'ckan_killtopbar';
+    var delay = 600;
+    var animTime = 600;
+    var isKilled = ($.cookie(cookieName)!=null);
+    if (isKilled) return;
+
+    // Show the top bar after a short timeout
+    setTimeout("CKAN.Utils.animateHeight($('.top-bar'),"+animTime+")",delay);
+
+    // Bind to the close button
+    topBar.find('.js-kill-button').live('click', function() {
+      console.log('killing top-bar');
+      $.cookie(cookieName, 'true', { expires: 365 });
+      topBar.hide();
+    });
+  };
+
   my.setupUrlEditor = function(slugType,readOnly) {
     // Page elements to hook onto
     var titleInput = $('.js-title');


--- a/ckan/templates/layout_base.html	Mon Oct 17 15:07:58 2011 +0100
+++ b/ckan/templates/layout_base.html	Thu Oct 20 17:26:23 2011 +0100
@@ -46,6 +46,10 @@
 
 <body class="${request.environ.get('pylons.routes_dict', {}).get('action')} 
              ${request.environ.get('pylons.routes_dict', {}).get('controller').split(':')[-1]}">
+   <div class="top-bar" style="display: none;">
+     <span class="top-bar-text">First time at ${g.site_url_nice}? Visit our <a href="${h.url_for(controller='home', action='about')}">About page</a> to find out more.</span>
+     <button class="pretty-button danger js-kill-button">x</button>
+  </div><div id="wrap"><div class="header outer"><header class="container">


http://bitbucket.org/okfn/ckan/changeset/16d65237f985/
changeset:   16d65237f985
branch:      feature-1410-gravatars
user:        zephod
date:        2011-10-21 17:57:07
summary:     [gravatars][m]: Added gravatar fetcher to helper. Gravatar now appears on user profile.
affected #:  11 files (-1 bytes)

--- a/ckan/lib/dictization/model_dictize.py	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/lib/dictization/model_dictize.py	Fri Oct 21 16:57:07 2011 +0100
@@ -186,6 +186,7 @@
     del result_dict['password']
     
     result_dict['display_name'] = user.display_name
+    result_dict['email_hash'] = user.email_hash
     result_dict['number_of_edits'] = user.number_of_edits()
     result_dict['number_administered_packages'] = user.number_administered_packages()
 


--- a/ckan/lib/helpers.py	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/lib/helpers.py	Fri Oct 21 16:57:07 2011 +0100
@@ -215,6 +215,12 @@
 def icon(name, alt=None):
     return literal('<img src="%s" height="16px" width="16px" alt="%s" /> ' % (icon_url(name), alt))
 
+def gravatar(email_hash, size=100):
+    return literal('''<a href="http://gravatar.com" target="_blank">
+      <img src="http://gravatar.com/avatar/%s?s=%d&d=mm" />
+    </a>''' % (email_hash, size))
+
+
 class Page(paginate.Page):
     
     # Curry the pager method of the webhelpers.paginate.Page class, so we have


--- a/ckan/model/user.py	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/model/user.py	Fri Oct 21 16:57:07 2011 +0100
@@ -49,6 +49,14 @@
         if self.fullname is not None and len(self.fullname.strip()) > 0:
             return self.fullname
         return self.name
+
+    @property
+    def email_hash(self):
+        import hashlib
+        e = ''
+        if self.email:
+            e = self.email.strip().lower()
+        return hashlib.md5(e).hexdigest()
         
     def get_reference_preferred_for_uri(self):
         '''Returns a reference (e.g. name, id, openid) for this user


--- a/ckan/public/css/style.css	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/public/css/style.css	Fri Oct 21 16:57:07 2011 +0100
@@ -554,6 +554,14 @@
   border-right: 1px solid #ccc; 
 }
 
+.gravatar {
+  border: 1px solid #777;
+  padding: 1px;
+  width: 120px;
+  height: 120px;
+  margin: 0 auto 10px auto;
+}
+
 /* ===================== */
 /* = Stateful stuff    = */
 /* ===================== */


--- a/ckan/templates/user/layout.html	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/templates/user/layout.html	Fri Oct 21 16:57:07 2011 +0100
@@ -6,11 +6,26 @@
   ><py:match path="minornavigation">
-    <ul class="tabbed" py:if="c.is_myself">
-      <li py:attrs="{'class':'current-tab'} if c.action=='read' else {}"><a href="${h.url_for(controller='user', action='read')}">My Profile</a></li>
-      <li py:attrs="{'class':'current-tab'} if c.action=='edit' else {}"><a href="${h.url_for(controller='user', action='edit')}">Edit Profile</a></li>
-      <li><a href="${h.url_for('/user/logout')}">Log out</a></li>
-    </ul>
+    <py:if test="c.is_myself">
+      <ul class="tabbed">
+        <li py:attrs="{'class':'current-tab'} if c.action=='read' else {}"><a href="${h.url_for(controller='user', action='read')}">My Profile</a></li>
+        <li py:attrs="{'class':'current-tab'} if c.action=='edit' else {}"><a href="${h.url_for(controller='user', action='edit')}">Edit Profile</a></li>
+        <li><a href="${h.url_for('/user/logout')}">Log out</a></li>
+      </ul>
+    </py:if>
+    <py:if test="not c.is_myself">
+      <py:if test="c.id">
+        <ul class="tabbed">
+          <li py:attrs="{'class':'current-tab'} if c.action=='read' else {}"><a href="${h.url_for(controller='user', action='read')}">View Profile</a></li>
+        </ul>
+      </py:if>
+      <py:if test="not c.id">
+        <ul class="tabbed">
+          <li py:attrs="{'class':'current-tab'} if c.action=='login' else {}"><a href="${h.url_for(controller='user', action='login')}">Login</a></li>
+          <li py:attrs="{'class':'current-tab'} if c.action=='register' else {}"><a href="${h.url_for('register')}">Register Account</a></li>
+        </ul>
+      </py:if>
+    </py:if></py:match>
   
 


--- a/ckan/templates/user/login.html	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/templates/user/login.html	Fri Oct 21 16:57:07 2011 +0100
@@ -34,10 +34,9 @@
         <input type="hidden" name="remember" value="1576800000" /><br/></fieldset>
-      ${h.submit('s', _('Login'))} — 
+      <input name="s" id="s" type="submit" class="pretty-button primary" value="Sign In"/>
+      — 
       <a href="${h.url_for('reset')}">Forgot your password?</a>
-      —
-      ${h.link_to(_('Not yet registered?'), h.url_for(action='register'))}
     </form><br/><!-- Simple OpenID Selector -->
@@ -66,7 +65,7 @@
         </p></div></fieldset>
-      <input id="openid_submit" type="submit" value="Sign in"/>
+      <input id="openid_submit" type="submit" class="pretty-button primary" value="Sign in with OpenID"/></form></div><xi:include href="layout.html" />


--- a/ckan/templates/user/logout.html	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/templates/user/logout.html	Fri Oct 21 16:57:07 2011 +0100
@@ -4,8 +4,10 @@
   
   <py:def function="page_title">Logout - User</py:def>
 
+  <py:def function="page_title">Logout</py:def>
+  <py:def function="page_heading">Logout from ${g.site_title}</py:def>
+
   <div py:match="content">
-    <h2>Logout</h2><p>You have logged out successfully.</p></div>
 


--- a/ckan/templates/user/new_user_form.html	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/templates/user/new_user_form.html	Fri Oct 21 16:57:07 2011 +0100
@@ -45,5 +45,5 @@
         </dd></dl>
-  <input id="save" name="save" type="submit" value="Register now »" />
+  <input id="save" name="save" type="submit" class="pretty-button primary" value="Register now »" /></form>


--- a/ckan/templates/user/read.html	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/templates/user/read.html	Fri Oct 21 16:57:07 2011 +0100
@@ -7,6 +7,9 @@
   <py:def function="body_class">user-view</py:def><py:match path="primarysidebar">
+    <div class="gravatar">
+      ${h.gravatar(c.user_dict['email_hash'],120)}
+    </div><li class="widget-container widget_text" py:if="not c.hide_welcome_message"><h3>Activity</h3><ul>


--- a/ckan/templates/user/request_reset.html	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/templates/user/request_reset.html	Fri Oct 21 16:57:07 2011 +0100
@@ -14,7 +14,7 @@
         <input name="user" value="" /><br/></fieldset><div>
-        ${h.submit('reset', _('Reset password'))}
+        <input type="submit" id="reset" name="reset" class="pretty-button primary" value="Reset Password" /></div></form></div>


--- a/ckan/tests/lib/test_helpers.py	Mon Oct 17 17:05:08 2011 +0100
+++ b/ckan/tests/lib/test_helpers.py	Fri Oct 21 16:57:07 2011 +0100
@@ -50,3 +50,15 @@
         two_months_ago_str = h.datetime_to_date_str(two_months_ago)
         res = h.time_ago_in_words_from_str(two_months_ago_str)
         assert_equal(res, '2 months')
+
+    def test_gravatar(self):
+        email = 'zephod at gmail.com'
+        expected =['<a href="http://gravatar.com" target="_blank">', '<img src="http://gravatar.com/avatar/7856421db6a63efa5b248909c472fbd2?s=200&d=mm" />', '</a>']
+        # Hash the email address
+        import hashlib
+        email_hash = hashlib.md5(email).hexdigest()
+        res = h.gravatar(email_hash, 200)
+        for e in expected:
+            assert e in res, e
+
+


http://bitbucket.org/okfn/ckan/changeset/5237b2e300b8/
changeset:   5237b2e300b8
branch:      feature-1368-ux-fixes
user:        zephod
date:        2011-10-21 18:04:57
summary:     [welcome][m]: Added welcome banner to front page.
affected #:  4 files (-1 bytes)

--- a/ckan/lib/app_globals.py	Mon Oct 17 15:16:56 2011 +0100
+++ b/ckan/lib/app_globals.py	Fri Oct 21 17:04:57 2011 +0100
@@ -21,6 +21,7 @@
                                   'http://assets.okfn.org/p/ckan/img/ckan.ico')
         self.site_logo = config.get('ckan.site_logo', '')
         self.site_url = config.get('ckan.site_url', '')
+        self.site_url_nice = self.site_url.replace('http://','').replace('www.','')
         self.site_description = config.get('ckan.site_description', '')
         
         self.facets = config.get('search.facets', 'groups tags res_format license').split()


--- a/ckan/public/css/style.css	Mon Oct 17 15:16:56 2011 +0100
+++ b/ckan/public/css/style.css	Fri Oct 21 17:04:57 2011 +0100
@@ -1222,6 +1222,32 @@
   color: #000;
 }
 
+.top-bar {
+  width: 100%;
+  /* Old background was a little less intrusive */
+  background: #fcba63;
+  background: #b22;
+  text-align: center;
+  padding: 0;
+  border-bottom: 1px solid #faa;
+  font-weight: bold;
+}
+.top-bar-text {
+  line-height: 30px;
+  color: #fff;
+}
+.top-bar-text a {
+  color: #fff;
+  text-decoration: underline;
+}
+.top-bar button.js-kill-button {
+  float: right;
+  margin-right: 20px;
+  margin-top: 3px;
+  padding: 2px 8px;
+}
+
+
 /* ============================= */
 /* = Inline resource edit form = */
 /* ============================= */


--- a/ckan/public/scripts/application.js	Mon Oct 17 15:16:56 2011 +0100
+++ b/ckan/public/scripts/application.js	Fri Oct 21 17:04:57 2011 +0100
@@ -18,6 +18,11 @@
       client: client
     };
 
+    var isFrontPage = $('body.index.home').length > 0;
+    if (isFrontPage) {
+      CKAN.Utils.setupTopBar($('.top-bar'));
+    }
+
     var isDatasetView = $('body.package.read').length > 0;
     if (isDatasetView) {
       var _dataset = new CKAN.Model.Dataset(preload_dataset);
@@ -83,8 +88,16 @@
     var messageDiv = $('<div />').html(msg).addClass(category).hide();
     $('.flash-messages').append(messageDiv);
     messageDiv.show(1200);
+  };
 
-  };
+  // Animate the appearance of an element by expanding its height
+  my.animateHeight = function(element, animTime) {
+    if (!animTime) animTime = 350;
+    element.show();
+    var finalHeight = element.height();
+    element.height(0);
+    element.animate({height:finalHeight}, animTime);
+  }
 
   my.bindInputChanges = function(input, callback) {
     input.keyup(callback);
@@ -93,6 +106,24 @@
     input.change(callback);
   };
 
+  my.setupTopBar = function(topBar) {
+
+    var cookieName = 'ckan_killtopbar';
+    var delay = 600;
+    var animTime = 600;
+    var isKilled = ($.cookie(cookieName)!=null);
+    if (isKilled) return;
+
+    // Show the top bar after a short timeout
+    setTimeout("CKAN.Utils.animateHeight($('.top-bar'),"+animTime+")",delay);
+
+    // Bind to the close button
+    topBar.find('.js-kill-button').live('click', function() {
+      $.cookie(cookieName, 'true', { expires: 365 });
+      topBar.hide();
+    });
+  };
+
   my.setupUrlEditor = function(slugType,readOnly) {
     // Page elements to hook onto
     var titleInput = $('.js-title');


--- a/ckan/templates/layout_base.html	Mon Oct 17 15:16:56 2011 +0100
+++ b/ckan/templates/layout_base.html	Fri Oct 21 17:04:57 2011 +0100
@@ -46,6 +46,10 @@
 
 <body class="${request.environ.get('pylons.routes_dict', {}).get('action')} 
              ${request.environ.get('pylons.routes_dict', {}).get('controller').split(':')[-1]}">
+   <div class="top-bar" style="display: none;">
+     <span class="top-bar-text">First time at ${g.site_title}? Visit our <a href="${h.url_for(controller='home', action='about')}">About page</a> to find out more.</span>
+     <button class="pretty-button danger js-kill-button">x</button>
+  </div><div id="wrap"><div class="header outer"><header class="container">

Repository URL: https://bitbucket.org/okfn/ckan/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list