def hdx_get_group_activity_list(context, data_dict): from ckanext.hdx_package.helpers import helpers as hdx_package_helpers group_uuid = data_dict.get('group_uuid', None) if group_uuid: check_access('group_show', context, data_dict) model = context['model'] offset = data_dict.get('offset', 0) limit = int( data_dict.get('limit', config.get('ckan.activity_list_limit', 31))) activity_objects = model.activity.group_activity_list(group_uuid, limit=limit, offset=offset) activity_stream = model_dictize.activity_list_dictize( activity_objects, context) else: if 'group_type' in data_dict and data_dict['group_type'] == 'organization': activity_stream = get_action( 'organization_activity_list')(context, data_dict) else: 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)
def hdx_get_group_activity_list(context, data_dict): from ckanext.hdx_package.helpers import helpers as hdx_package_helpers group_uuid = data_dict.get('group_uuid', None) if group_uuid: check_access('group_show', context, data_dict) model = context['model'] offset = data_dict.get('offset', 0) limit = int( data_dict.get('limit', config.get('ckan.activity_list_limit', 31))) activity_objects = model.activity.group_activity_list(group_uuid, limit=limit, offset=offset) activity_stream = model_dictize.activity_list_dictize(activity_objects, context) else: 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)
def _activities(self, page): limit = 100 offset = (page - 1) * limit if c.userobj.sysadmin: users = model.Session.query(model.User) activity_queries = [] for user in users: activity_queries += self._get_activity(user) else: activity_queries = self._get_activity(c.userobj) sql_activities = model.activity._activities_union_all( *activity_queries) total_count = sql_activities.count() has_more = total_count > offset + limit raw_activities = model.activity._activities_at_offset( sql_activities, limit, offset) context = { 'model': model, 'session': model.Session, 'user': c.user or c.author, 'auth_user_obj': c.userobj, 'for_view': True } activities = model_dictize.activity_list_dictize( raw_activities, context) extra_vars = { 'controller': 'user', 'action': 'activity', 'offset': offset, 'user_history': True } return activity_streams.activity_list_to_html(context, activities, extra_vars), has_more
def group_activity_list(context, data_dict): '''Return a group\'s public activity stream as a list of dicts.''' model = context['model'] group_id = data_dict['id'] query = model.Session.query(model.Activity) query = query.filter_by(object_id=group_id) query = query.order_by(desc(model.Activity.timestamp)) query = query.limit(15) activity_objects = query.all() return model_dictize.activity_list_dictize(activity_objects, context)
def user_activity_list(context, data_dict): '''Return a user's public activity stream. You must be authorized to view the user's profile. :param id: the id or name of the user :type id: string :param offset: where to start getting activity items from (optional, default: 0) :type offset: int :param limit: the maximum number of activities to return (optional, default: 31, the default value is configurable via the ckan.activity_list_limit setting) :type limit: int :rtype: list of dictionaries ''' # FIXME: Filter out activities whose subject or object the user is not # authorized to read. _check_access('user_show', context, data_dict) model = context['model'] user_ref = data_dict.get('id') # May be user name or id. user = model.User.get(user_ref) if user is None: raise logic.NotFound offset = data_dict.get('offset', 0) limit = int( data_dict.get('limit', config.get('ckan.activity_list_limit', 31))) activity_objects = model.activity.user_activity_list(user.id, limit=limit, offset=offset) res = model_dictize.activity_list_dictize(activity_objects, context) for activity in res: revision_id = activity.get('revision_id', None) if revision_id: executor_id = _get_action('revision_executor')(data_dict={ 'id': revision_id }) if executor_id: executor_obj = model.User.get(executor_id) activity['actor_id'] = executor_id activity['actor_fullname'] = executor_obj.fullname else: activity['actor_id'] = 'XXX-YYY-ZZZ' activity['actor_fullname'] = 'TESTER NAME' log.info('user activity list: %s', res) return res
def recently_changed_packages_activity_list(context, data_dict): '''Return an activity stream of all recently added or updated packages as a list of dicts. ''' model = context['model'] query = model.Session.query(model.Activity) query = query.filter(model.Activity.activity_type.endswith('package')) query = query.order_by(desc(model.Activity.timestamp)) query = query.limit(15) activity_objects = query.all() return model_dictize.activity_list_dictize(activity_objects, context)
def dictize_notifications(subscription_activities): '''Dictizes a subscription and its activity objects :param subscription_activities: {subscription: [activity, ...], ...} :returns: [{'subscription': {...}, {'activities': [{...}, ...]}}] ''' context = {'model': model, 'session': model.Session} notifications_dictized = [] for subscription, activities in subscription_activities.items(): subscription_dict = \ dictization.dictize_subscription(subscription, context) activity_dicts = model_dictize.activity_list_dictize( activities, context) notifications_dictized.append({ 'subscription': subscription_dict, 'activities': activity_dicts, }) return notifications_dictized
def dashboard_activity_list(context, data_dict): import ckan.model as model activity_dicts = logic.action.get.dashboard_activity_list( context, data_dict) is_subscribed = helpers.user_subscribed_to_news(context, data_dict) user_id = model.User.get(context['user']).id if is_subscribed: offset = data_dict.get('offset', 0) limit = int( data_dict.get('limit', config.get('ckan.activity_list_limit', 31))) news_activity_objects = model.Session.query(model.Activity) \ .filter((model.Activity.activity_type == 'new news') | \ (model.Activity.activity_type == 'changed news')) \ .limit(limit).offset(offset).all() news_activity_dicts = model_dictize.activity_list_dictize( news_activity_objects, context) # Mark the new (not yet seen by user) activities. strptime = datetime.strptime fmt = '%Y-%m-%dT%H:%M:%S.%f' last_viewed = model.Dashboard.get(user_id).activity_stream_last_viewed for activity in news_activity_dicts: if activity['user_id'] == user_id: # Never mark the user's own activities as new. activity['is_new'] = False else: activity['is_new'] = (strptime(activity['timestamp'], fmt) > last_viewed) activity_dicts.extend(news_activity_dicts) activity_dicts = {v['id']: v for v in activity_dicts}.values() activity_dicts.sort(key=itemgetter('timestamp'), reverse=True) return activity_dicts
def render_index(self): """ This function renders the NGDS home page. The page sent to the user depends on the deployment of the system i.e. if the deployment is a central node, then the page sent is the central home page, if it is a node-in-a-box, the page sent will be the map page. """ if g.node_in_a_box: return self.render_map() context = {'model': model, 'session': model.Session, 'user': c.user} activity_objects = model.Session.query(model.Activity).join(model.Package, model.Activity.object_id == model.Package.id). \ filter(model.Activity.activity_type == 'new package').order_by(desc(model.Activity.timestamp)). \ limit(5).all() activity_dicts = model_dictize.activity_list_dictize(activity_objects, context) c.recent_activity = activity_dicts c.image_files = helpers.get_home_images() helpers.get_contributors_list() return render('home/index_ngds.html')
:rtype: list of dictionaries ''' since = get_or_bust(data_dict, 'since_time') try: since_time = isodate(since, None) except Invalid, e: raise ValidationError({'since_time':e.error}) # hard limit this api to reduce opportunity for abuse limit = int(config.get('ckan.activity_list_hard_limit', 63)) activity_objects = _changed_packages_activity_list_since( since_time, limit) return model_dictize.activity_list_dictize(activity_objects, context) @side_effect_free def activity_list_from_user_since(context, data_dict): '''Return the activity stream of all recently added or changed packages. :param since_time: starting date/time Limited to 31 records (configurable via the ckan.activity_list_hard_limit setting) but may be called repeatedly with the timestamp of the last record to collect all activities. :param user_id: the user of the requested activity list :rtype: list of dictionaries '''
with the timestamp of the last record to collect all activities. :rtype: list of dictionaries ''' since = get_or_bust(data_dict, 'since_time') try: since_time = isodate(since, None) except Invalid, e: raise ValidationError({'since_time': e.error}) # hard limit this api to reduce opportunity for abuse limit = int(config.get('ckan.activity_list_hard_limit', 63)) activity_objects = _changed_packages_activity_list_since(since_time, limit) return model_dictize.activity_list_dictize(activity_objects, context) def _changed_packages_activity_list_since(since, limit): '''Return the site-wide stream of changed package activities since a given date. This activity stream includes recent 'new package', 'changed package' and 'deleted package' activities for the whole site. ''' q = model.activity._changed_packages_activity_query() q = q.order_by(model.Activity.timestamp) q = q.filter(model.Activity.timestamp > since) return q.limit(limit)
def fetch_recent_package_activity_list_html( context, user=None, user_not=None, only_privatized=False, only_resourceful=False, limit=30): # Fetch recent revisions, store as list oredered by time recent_revisions_query = ( model.Session.query(model.PackageRevision, model.User.id) .join(model.Revision, model.PackageRevision.revision_id == model.Revision.id) .join(model.User, model.Revision.author == model.User.name) .distinct()) if only_resourceful: recent_revisions_query = ( recent_revisions_query .join(model.Resource, model.Resource.package_id == model.PackageRevision.id) .filter(model.Resource.state == "active")) if user is not None: recent_revisions_query = recent_revisions_query.filter( model.Revision.author == user) if user_not is not None: recent_revisions_query = recent_revisions_query.filter( model.Revision.author != user_not) if only_privatized: recent_revisions_query = recent_revisions_query.filter( model.PackageRevision.private) recent_revisions_query = ( recent_revisions_query .order_by(model.PackageRevision.metadata_modified.desc()) .limit(limit)) recent_revisions = [r for r in recent_revisions_query] # Fetch related packages, store by id packages = {r.id: None for r, uid in recent_revisions} packages_query = ( model.Session.query(model.Package) .filter(model.Package.id.in_(packages.keys()))) for package in packages_query: packages[package.id] = package # Fetch related packages' first revision timestamps packages_created = {} packages_created_query = ( model.Session.query( model.PackageRevision.id.label('id'), func.min(model.PackageRevision.metadata_modified).label('ts')) .filter(model.PackageRevision.id.in_(packages.keys())) .group_by(model.PackageRevision.id)) for package_id, created in packages_created_query: packages_created[package_id] = created # Fetch previous revisions for the recent revisions packages_previous = {} packages_previous_query = ( model.Session.query(model.PackageRevision.revision_id.label("rid"), model.PackageRevision) .from_statement(text(""" select p.revision_id as rid, r.* from package_revision r left join ( select l.revision_id, r.id, max(r.metadata_modified) as previous_timestamp from package_revision r join package_revision l on r.id = l.id where l.revision_id = ANY(:ids) and r.metadata_modified < l.metadata_modified group by l.revision_id, r.id, l.metadata_modified ) p on r.id = p.id where r.metadata_modified = p.previous_timestamp """)) .params(ids=[r.revision_id for r, uid in recent_revisions])) for rid, package in packages_previous_query: packages_previous[rid] = package # Add support for new color for privacy-changed packages activity_streams.activity_stream_string_icons['changed package privacy'] = 'sitemap' activity_streams.activity_stream_string_functions['changed package privacy'] = \ activity_streams.activity_stream_string_changed_package # Create activity objects based on revision data def revision_to_activity(r, uid): pr = packages_previous.get(r.revision_id) if only_privatized and (pr is None or (pr.private or not r.private)): return None privacy_changed = pr is not None and pr.private != r.private activity_type = None if r.state in ('active', 'draft'): if packages_created[r.id] == r.metadata_modified: activity_type = 'new package' elif privacy_changed: activity_type = 'changed package privacy' else: activity_type = 'changed package' elif r.state in ('deleted'): activity_type = 'deleted package' else: log.warning("Unknown package state, skipping: %s" % r.state) return None d = {'package': dictization.table_dictize( packages[r.id], context={'model': model})} activity = model.Activity(uid, r.id, r.revision_id, activity_type, d) activity.timestamp = r.metadata_modified return activity activity_objects = ( (r for r in (revision_to_activity(r, uid) for r, uid in recent_revisions) if r is not None)) # Render activity list snippet changed_packages = model_dictize.activity_list_dictize(activity_objects, context) return activity_streams.activity_list_to_html( context, changed_packages, {'offset': 0})
def fetch_recent_package_activity_list_html( context, user_id=None, user_id_not=None, only_privatized=False, only_resourceful=False, limit=30): # Fetch recent revisions, store as list oredered by time recent_revisions_query = model.Session.query(model.PackageRevision).distinct() if only_resourceful: recent_revisions_query = ( recent_revisions_query .join(model.Resource, model.Resource.package_id == model.PackageRevision.id) .filter(model.Resource.state == "active")) if user_id is not None: recent_revisions_query = recent_revisions_query.filter( model.PackageRevision.creator_user_id == user_id) if user_id_not is not None: recent_revisions_query = recent_revisions_query.filter( model.PackageRevision.creator_user_id != user_id_not) if only_privatized: recent_revisions_query = recent_revisions_query.filter( model.PackageRevision.private) recent_revisions_query = ( recent_revisions_query .order_by(model.PackageRevision.revision_timestamp.desc()) .limit(limit)) recent_revisions = [r for r in recent_revisions_query] # Fetch related packages, store by id packages = {r.id: None for r in recent_revisions} packages_query = ( model.Session.query(model.Package) .filter(model.Package.id.in_(packages.keys()))) for package in packages_query: packages[package.id] = package # Fetch related packages' first revision timestamps packages_created = {} packages_created_query = ( model.Session.query( model.PackageRevision.id.label('id'), func.min(model.PackageRevision.revision_timestamp).label('ts')) .filter(model.PackageRevision.id.in_(packages.keys())) .group_by(model.PackageRevision.id)) for package_id, created in packages_created_query: packages_created[package_id] = created # Fetch previous revisions for the recent revisions packages_previous = {} packages_previous_query = ( model.Session.query(model.PackageRevision.revision_id.label("rid"), model.PackageRevision) .from_statement(text(""" select p.revision_id as rid, r.* from package_revision r left join ( select l.revision_id, r.id, max(r.revision_timestamp) as previous_timestamp from package_revision r join package_revision l on r.id = l.id where l.revision_id = ANY(:ids) and r.revision_timestamp < l.revision_timestamp group by l.revision_id, r.id, l.revision_timestamp ) p on r.id = p.id where r.revision_timestamp = p.previous_timestamp """)) .params(ids=[r.revision_id for r in recent_revisions])) for rid, package in packages_previous_query: packages_previous[rid] = package # Add support for new color for privacy-changed packages activity_streams.activity_stream_string_icons['changed package privacy'] = 'sitemap' activity_streams.activity_stream_string_functions['changed package privacy'] = \ activity_streams.activity_stream_string_changed_package # Create activity objects based on revision data def revision_to_activity(r): pr = packages_previous.get(r.revision_id) if only_privatized and (pr is None or (pr.private or not r.private)): return None privacy_changed = pr is not None and pr.private != r.private activity_type = None if r.state in ('active', 'draft'): if packages_created[r.id] == r.revision_timestamp: activity_type = 'new package' elif privacy_changed: activity_type = 'changed package privacy' else: activity_type = 'changed package' elif r.state in ('deleted'): activity_type = 'deleted package' else: log.warning("Unknown package state, skipping: %s" % r.state) return None d = {'package': dictization.table_dictize( packages[r.id], context={'model': model})} activity = model.Activity(r.creator_user_id, r.id, r.revision_id, activity_type, d) activity.timestamp = r.revision_timestamp return activity activity_objects = ( (r for r in (revision_to_activity(r) for r in recent_revisions) if r is not None)) # Render activity list snippet changed_packages = model_dictize.activity_list_dictize(activity_objects, context) return activity_streams.activity_list_to_html( context, changed_packages, {'offset': 0})