Repository: OCHA-DAP/hdx-ckan

Issue:
Default Country Page: activity stream
Blocked by #2102 and #2103 
Annotated (very annotated) design is here: 
https://docs.google.com/drawings/d/1qOBKZ7IO7zkEMHh2g3ZiAynh5PiAbO-_-SL4rd9uO_M/edit
Implement the activity stream section



Discussion:

Resolving patch:
diff --git a/ckanext-hdx_org_group/ckanext/hdx_org_group/controllers/country_controller.py b/ckanext-hdx_org_group/ckanext/hdx_org_group/controllers/country_controller.py
--- a/ckanext-hdx_org_group/ckanext/hdx_org_group/controllers/country_controller.py
+++ b/ckanext-hdx_org_group/ckanext/hdx_org_group/controllers/country_controller.py
@@ -37,12 +37,20 @@
                          'CG300']
 # http://localhost:8080/public/api2/values?it=PSP120&l=CHN&periodType=LATEST_YEAR
 
+
 class CountryController(group.GroupController):
 
     def read(self, id):
         self.get_country(id)
         self.get_dataset_results(c.group_dict.get('name', id))
 
+        # activity stream
+        context = {'model': model, 'session': model.Session,
+                   'user': c.user or c.author,
+                   'for_view': True}
+        country_uuid = c.group_dict.get('id', id)
+        self.get_activity_stream(context, country_uuid)
+
         return render('country/country.html')
 
     def get_country(self, id):
@@ -64,19 +72,19 @@ def get_country(self, id):
         except NotAuthorized:
             abort(401, _('Unauthorized to read group %s') % id)
 
-
     def get_dataset_results(self, country_id):
         upper_case_id = country_id.upper()
         top_line_results = self._get_top_line_num(upper_case_id)
         top_line_data = top_line_results.get('results', [])
 
         if not top_line_data:
-            log.warn('No top line numbers found for country: {}'.format(country_id))
-        top_line_data_dict = top_line_data#[ {el['indicatorTypeCode']:el} for el in top_line_data ]
+            log.warn(
+                'No top line numbers found for country: {}'.format(country_id))
+        # [ {el['indicatorTypeCode']:el} for el in top_line_data ]
+        top_line_data_dict = top_line_data
         c.top_line_data_dict = top_line_data_dict
 
-
-        chart_results =  self._get_chart_data(upper_case_id)
+        chart_results = self._get_chart_data(upper_case_id)
         chart_data = chart_results.get('results', [])
         if not chart_data:
             log.warn('No chart data found for country: {}'.format(country_id))
@@ -92,14 +100,12 @@ def get_dataset_results(self, country_id):
                 else:
                     chart_data_dict[ind_type] = [el]
 
-
         for code in chart_data_dict.keys():
-            chart_data_dict[code] = sorted(chart_data_dict[code], key=lambda x: x.get('datetime', None))
-
+            chart_data_dict[code] = sorted(
+                chart_data_dict[code], key=lambda x: x.get('datetime', None))
 
         c.chart_data_dict = chart_data_dict
 
-
     def _get_chart_data(self, country_id):
         data_dict = {
             'sorting': 'INDICATOR_TYPE_ASC',
@@ -118,7 +124,7 @@ def _get_top_line_num(self, country_id):
         result = get_action('hdx_get_indicator_values')({}, data_dict)
         return result
 
-
-    def get_activity_stream(self):
-        pass
-
+    def get_activity_stream(self, context, country_id):
+        act_data_dict = {'id': country_id, 'limit': 7}
+        c.hdx_group_activities = get_action(
+            'hdx_get_group_activity_list')(context, act_data_dict)
diff --git a/ckanext-hdx_org_group/ckanext/hdx_org_group/helpers/organization_helper.py b/ckanext-hdx_org_group/ckanext/hdx_org_group/helpers/organization_helper.py
--- a/ckanext-hdx_org_group/ckanext/hdx_org_group/helpers/organization_helper.py
+++ b/ckanext-hdx_org_group/ckanext/hdx_org_group/helpers/organization_helper.py
@@ -3,11 +3,27 @@
 
 @author: alexandru-m-g
 '''
+import ckan.logic as logic
+get_action = logic.get_action
+
 
 def sort_results_case_insensitive(results, sort_by):
     if results:
         if sort_by == 'title asc':
-            return sorted(results, key=lambda x: x.get('title','').lower())
+            return sorted(results, key=lambda x: x.get('title', '').lower())
         elif sort_by == 'title desc':
-            return sorted(results, key=lambda x: x.get('title','').lower(), reverse=True)
-    return results
\ No newline at end of file
+            return sorted(results, key=lambda x: x.get('title', '').lower(), reverse=True)
+    return results
+
+
+def hdx_get_group_activity_list(context, data_dict):
+    from ckanext.hdx_package.helpers import helpers as hdx_package_helpers
+    activity_stream = get_action('group_activity_list')(context, data_dict)
+    offset = int(data_dict.get('offset', 0))
+    extra_vars = {
+        'controller': 'group',
+        'action': 'activity',
+        'id': data_dict['id'],
+        'offset': offset,
+    }
+    return hdx_package_helpers._activity_list(context, activity_stream, extra_vars)
diff --git a/ckanext-hdx_org_group/ckanext/hdx_org_group/plugin.py b/ckanext-hdx_org_group/ckanext/hdx_org_group/plugin.py
--- a/ckanext-hdx_org_group/ckanext/hdx_org_group/plugin.py
+++ b/ckanext-hdx_org_group/ckanext/hdx_org_group/plugin.py
@@ -3,11 +3,13 @@
 import ckan.plugins.toolkit as tk
 import ckan.lib.plugins as lib_plugins
 
+
 class HDXOrgGroupPlugin(plugins.SingletonPlugin, lib_plugins.DefaultOrganizationForm):
     plugins.implements(plugins.IConfigurer, inherit=False)
     plugins.implements(plugins.IRoutes, inherit=True)
     plugins.implements(plugins.IGroupForm, inherit=False)
     plugins.implements(plugins.ITemplateHelpers, inherit=False)
+    plugins.implements(plugins.IActions)
 
     num_times_new_template_called = 0
     num_times_read_template_called = 0
@@ -24,6 +26,12 @@ def update_config(self, config):
     def get_helpers(self):
         return {}
 
+    def get_actions(self):
+        from ckanext.hdx_org_group.helpers import organization_helper as hdx_org_actions
+        return {
+            'hdx_get_group_activity_list': hdx_org_actions.hdx_get_group_activity_list
+        }
+
     # def get_auth_functions(self):
     #     return {
     #             'hdx_basic_user_info': helpers.auth.hdx_basic_user_info,
@@ -41,46 +49,60 @@ def group_types(self):
 
     def _modify_group_schema(self, schema):
         schema.update({
-                'description':[tk.get_validator('not_empty')],
-                'org_url':[tk.get_validator('not_missing'), tk.get_converter('convert_to_extras')],
-                'fts_id': [tk.get_validator('ignore_missing'),
-                          tk.get_converter('convert_to_extras')],
-                })
+            'description': [tk.get_validator('not_empty')],
+            'org_url': [tk.get_validator('not_missing'), tk.get_converter('convert_to_extras')],
+            'fts_id': [tk.get_validator('ignore_missing'),
+                       tk.get_converter('convert_to_extras')],
+        })
         return schema
 
     def form_to_db_schema(self):
         schema = super(HDXOrgGroupPlugin, self).form_to_db_schema()
         schema = self._modify_group_schema(schema)
         return schema
-        
+
 #     def check_data_dict(self, data_dict):
 #         return super(HDXOrgFormPlugin, self).check_data_dict(self, data_dict)
-    
+
     def db_to_form_schema(self):
         # There's a bug in dictionary validation when form isn't present
         if tk.request.urlvars['action'] == 'index' or tk.request.urlvars['action'] == 'edit' or tk.request.urlvars['action'] == 'new':
             schema = super(HDXOrgGroupPlugin, self).form_to_db_schema()
-            schema.update({'description':[tk.get_validator('not_empty')] })
-            schema.update({'org_url':[tk.get_validator('not_missing'), tk.get_converter('convert_to_extras')]})
-            schema.update({'fts_id':[tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')]})
+            schema.update({'description': [tk.get_validator('not_empty')]})
+            schema.update(
+                {'org_url': [tk.get_validator('not_missing'), tk.get_converter('convert_to_extras')]})
+            schema.update({'fts_id': [tk.get_validator(
+                'ignore_missing'), tk.get_converter('convert_to_extras')]})
             return schema
         else:
             return None
 
     def before_map(self, map):
-        map.connect('organization_bulk_process', '/organization/bulk_process/{org_id}', controller='ckanext.hdx_org_group.controllers.redirect_controller:RedirectController', action='redirect_to_org_list')
-        map.connect('organization_bulk_process_no_id', '/organization/bulk_process', controller='ckanext.hdx_org_group.controllers.redirect_controller:RedirectController', action='redirect_to_org_list')
-        map.connect('organizations_index', '/organization', controller='ckanext.hdx_org_group.controllers.organization_controller:HDXOrganizationController', action='index')
-        map.connect('request_membership', '/organization/{org_id}/request_membership', controller='ckanext.hdx_org_group.controllers.request_controller:HDXReqsOrgController', action='request_membership')
-        map.connect('request_editing_rights', '/organization/{org_id}/request_editing_rights', controller='ckanext.hdx_org_group.controllers.request_controller:HDXReqsOrgController', action='request_editor_for_org')
-        map.connect('/organization/request_new', controller='ckanext.hdx_org_group.controllers.request_controller:HDXReqsOrgController', action='request_new_organization')
-        map.connect('/organization/members/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='members')
-        map.connect('/organization/member_new/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='member_new')
-        map.connect('/organization/member_delete/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='member_delete')
-        map.connect('/organization/member_delete/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='member_delete')
-
-        map.connect('browse_list', '/browse', controller='ckanext.hdx_org_group.controllers.browse_controller:BrowseController', action='index')
-        map.connect('country_read', '/country/{id}', controller='ckanext.hdx_org_group.controllers.country_controller:CountryController', action='read')
+        map.connect('organization_bulk_process',
+                    '/organization/bulk_process/{org_id}', controller='ckanext.hdx_org_group.controllers.redirect_controller:RedirectController', action='redirect_to_org_list')
+        map.connect('organization_bulk_process_no_id', '/organization/bulk_process',
+                    controller='ckanext.hdx_org_group.controllers.redirect_controller:RedirectController', action='redirect_to_org_list')
+        map.connect('organizations_index', '/organization',
+                    controller='ckanext.hdx_org_group.controllers.organization_controller:HDXOrganizationController', action='index')
+        map.connect('request_membership', '/organization/{org_id}/request_membership',
+                    controller='ckanext.hdx_org_group.controllers.request_controller:HDXReqsOrgController', action='request_membership')
+        map.connect('request_editing_rights', '/organization/{org_id}/request_editing_rights',
+                    controller='ckanext.hdx_org_group.controllers.request_controller:HDXReqsOrgController', action='request_editor_for_org')
+        map.connect('/organization/request_new',
+                    controller='ckanext.hdx_org_group.controllers.request_controller:HDXReqsOrgController', action='request_new_organization')
+        map.connect(
+            '/organization/members/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='members')
+        map.connect(
+            '/organization/member_new/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='member_new')
+        map.connect(
+            '/organization/member_delete/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='member_delete')
+        map.connect(
+            '/organization/member_delete/{id}', controller='ckanext.hdx_org_group.controllers.member_controller:HDXOrgMemberController', action='member_delete')
+
+        map.connect('browse_list', '/browse',
+                    controller='ckanext.hdx_org_group.controllers.browse_controller:BrowseController', action='index')
+        map.connect(
+            'country_read', '/country/{id}', controller='ckanext.hdx_org_group.controllers.country_controller:CountryController', action='read')
 
         return map
 
@@ -112,10 +134,14 @@ def group_types(self):
         return []
 
     def _modify_group_schema(self, schema):
-        schema.update({'language_code':[tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')],})
-        schema.update({'relief_web_url':[tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')]})
-        schema.update({'hr_info_url':[tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')]})
-        schema.update({'geojson':[tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')]})
+        schema.update({'language_code': [
+                      tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')], })
+        schema.update({'relief_web_url': [
+                      tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')]})
+        schema.update({'hr_info_url': [
+                      tk.get_validator('ignore_missing'), tk.get_converter('convert_to_extras')]})
+        schema.update({'geojson': [tk.get_validator(
+            'ignore_missing'), tk.get_converter('convert_to_extras')]})
         return schema
 
     def form_to_db_schema(self):
@@ -124,15 +150,17 @@ def form_to_db_schema(self):
         return schema
 
     def db_to_form_schema(self):
-        #There's a bug in dictionary validation when form isn't present
+        # There's a bug in dictionary validation when form isn't present
         if tk.request.urlvars['action'] == 'index' or tk.request.urlvars['action'] == 'edit' or tk.request.urlvars['action'] == 'new':
             schema = super(HDXGroupPlugin, self).form_to_db_schema()
-            schema.update({'language_code': [tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
-            schema.update({'relief_web_url': [tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
-            schema.update({'hr_info_url': [tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
-            schema.update({'geojson': [tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
+            schema.update({'language_code': [
+                          tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
+            schema.update({'relief_web_url': [
+                          tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
+            schema.update({'hr_info_url': [
+                          tk.get_converter('convert_from_extras'), tk.get_validator('ignore_missing')]})
+            schema.update({'geojson': [tk.get_converter(
+                'convert_from_extras'), tk.get_validator('ignore_missing')]})
             return schema
         else:
             return None
-
-


Test patch: