[ckan-changes] [okfn/ckan] 7c7320: [#2304] Add follower counts to user and dataset pa...

GitHub noreply at github.com
Fri Apr 20 19:04:21 UTC 2012


  Branch: refs/heads/feature-2304-follow
  Home:   https://github.com/okfn/ckan
  Commit: 7c7320971d5d5e71916ed952692fe4731ddec2a5
      https://github.com/okfn/ckan/commit/7c7320971d5d5e71916ed952692fe4731ddec2a5
  Author: Sean Hammond <seanhammond at lavabit.com>
  Date:   2012-04-20 (Fri, 20 Apr 2012)

  Changed paths:
    M ckan/controllers/package.py
    M ckan/controllers/user.py
    M ckan/logic/action/get.py
    M ckan/templates/package/read.html
    M ckan/templates/user/read.html
    M ckan/tests/functional/api/test_follow.py

  Log Message:
  -----------
  [#2304] Add follower counts to user and dataset pages

More work is needed to place them in a consistent location in the tab
bar (currently they look different on user pages than on dataset pages)


diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py
index 18c2b2a..286c151 100644
--- a/ckan/controllers/package.py
+++ b/ckan/controllers/package.py
@@ -304,6 +304,10 @@ def read(self, id, format='html'):
                 ckan.logic.action.get.package_activity_list_html(context,
                     {'id': c.current_package_id})
 
+        # Add the package's number of followers to the context for templates.
+        c.num_followers = ckan.logic.action.get.dataset_follower_count(
+                context, {'id':c.pkg.id})
+
         PackageSaver().render_package(c.pkg_dict, context)
 
         template = self._read_template( package_type )
diff --git a/ckan/controllers/user.py b/ckan/controllers/user.py
index 7f46b4f..6801676 100644
--- a/ckan/controllers/user.py
+++ b/ckan/controllers/user.py
@@ -14,6 +14,7 @@
 from ckan.logic import tuplize_dict, clean_dict, parse_params
 from ckan.logic.schema import user_new_form_schema, user_edit_form_schema
 from ckan.logic.action.get import user_activity_list_html
+from ckan.logic.action.get import user_follower_count
 from ckan.lib.captcha import check_recaptcha, CaptchaError
 
 log = logging.getLogger(__name__)
@@ -101,6 +102,8 @@ def read(self, id=None):
         c.about_formatted = self._format_about(user_dict['about'])
         c.user_activity_stream = user_activity_list_html(context,
             {'id':c.user_dict['id']})
+        c.num_followers = user_follower_count(context,
+                {'id':c.user_dict['id']})
         return render('user/read.html')
 
     def me(self, locale=None):
diff --git a/ckan/logic/action/get.py b/ckan/logic/action/get.py
index 21e21c3..b59c4e3 100644
--- a/ckan/logic/action/get.py
+++ b/ckan/logic/action/get.py
@@ -1297,6 +1297,35 @@ def recently_changed_packages_activity_list_html(context, data_dict):
             data_dict)
     return _activity_list_to_html(context, activity_stream)
 
+def follower_count(context, data_dict):
+    model = context['model']
+    followee_id = data_dict['id']
+    followee_type = data_dict['type']
+    follower_table = model.follower_table
+    q = select([func.count(follower_table.c.followee_id)])
+    q = q.where(follower_table.c.followee_id == followee_id)
+    q = q.where(follower_table.c.followee_type == followee_type)
+    conn = model.Session.connection()
+    cursor = conn.execute(q)
+    result_rows = cursor.fetchall()
+    assert len(result_rows) == 1
+    result_row = result_rows[0]
+    assert len(result_row) == 1
+    count = result_row[0]
+    return count
+
+def user_follower_count(context, data_dict):
+    return follower_count(context, {
+        'id': data_dict['id'],
+        'type': 'user',
+        })
+
+def dataset_follower_count(context, data_dict):
+    return follower_count(context, {
+        'id': data_dict['id'],
+        'type': 'dataset',
+        })
+
 def follower_list(context, data_dict):
     '''Return a list of all of the followers of an object (such as a user or a
     dataset.
diff --git a/ckan/templates/package/read.html b/ckan/templates/package/read.html
index a9da991..f74ee8c 100644
--- a/ckan/templates/package/read.html
+++ b/ckan/templates/package/read.html
@@ -54,6 +54,10 @@
       </ul>
     </li>
 
+    <li>
+      <h3>${c.num_followers} Followers</h3>
+    </li>
+
     <li py:if="c.package_relationships" class="sidebar-section">
       <h3>Related Datasets</h3>
       <ul class="related-datasets">
diff --git a/ckan/templates/user/read.html b/ckan/templates/user/read.html
index 681f0db..5722fad 100644
--- a/ckan/templates/user/read.html
+++ b/ckan/templates/user/read.html
@@ -58,6 +58,10 @@
               <strong>${c.user_dict['number_of_edits']}</strong>
               <span>Edits</span>
             </li>
+            <li>
+              <strong>${c.num_followers}</strong>
+              <span>Followers</span>
+            </li>
           </ul>
         </div>
       </div><!-- /row -->
diff --git a/ckan/tests/functional/api/test_follow.py b/ckan/tests/functional/api/test_follow.py
index 8919671..3edbfb2 100644
--- a/ckan/tests/functional/api/test_follow.py
+++ b/ckan/tests/functional/api/test_follow.py
@@ -33,6 +33,13 @@ def test_user_follow_user(self):
 
         # TODO: Test following and retrieving followers by name as well as by ID.
 
+        # Record the users number of followers before.
+        params = json.dumps({'id': self.russianfan.id})
+        response = self.app.post('/api/action/user_follower_count',
+                params=params).json
+        assert response['success'] is True
+        count_before = response['result']
+
         # Make one user a follower of another user.
         before = datetime.datetime.now()
         params = json.dumps({
@@ -45,10 +52,8 @@ def test_user_follow_user(self):
                 'Authorization': str(self.annafan.apikey)
                 }
         response = self.app.post('/api/action/follower_create',
-            params=params, extra_environ=extra_environ)
+            params=params, extra_environ=extra_environ).json
         after = datetime.datetime.now()
-        assert not response.errors
-        response = response.json
         assert response['success'] is True
         assert response['result']
         follower = response['result']
@@ -62,9 +67,7 @@ def test_user_follow_user(self):
         # Check that the follower appears in the followee's list of followers.
         params = json.dumps({'id': self.russianfan.id})
         response = self.app.post('/api/action/user_follower_list',
-                params=params)
-        assert not response.errors
-        response = response.json
+                params=params).json
         assert response['success'] is True
         assert response['result']
         followers = response['result']
@@ -77,6 +80,13 @@ def test_user_follow_user(self):
         timestamp = datetime_from_string(follower['datetime'])
         assert (timestamp >= before and timestamp <= after), str(timestamp)
 
+        # Check that the user's follower count has increased by 1.
+        params = json.dumps({'id': self.russianfan.id})
+        response = self.app.post('/api/action/user_follower_count',
+                params=params).json
+        assert response['success'] is True
+        assert response['result'] == count_before + 1
+
     def test_user_follow_dataset(self):
         '''Test a user following a dataset via the API.'''
         raise NotImplementedError


================================================================



More information about the ckan-changes mailing list