def action_handler(verb, **kwargs): """ Handler function to create Action instance upon action signal call. """ kwargs.pop('signal', None) actor = kwargs.pop('sender') # We must store the unstranslated string # If verb is an ugettext_lazyed string, fetch the original string if hasattr(verb, '_proxy____args'): verb = verb._proxy____args[0] newaction = apps.get_model('actstream', 'action')( actor_content_type=ContentType.objects.get_for_model(actor) if actor is not None else None, actor_object_id=actor.pk if actor is not None else None, verb=str(verb), public=bool(kwargs.pop('public', True)), description=kwargs.pop('description', None), timestamp=kwargs.pop('timestamp', now()) ) for opt in ('target', 'action_object'): obj = kwargs.pop(opt, None) if obj is not None: check(obj) setattr(newaction, '%s_object_id' % opt, obj.pk) setattr(newaction, '%s_content_type' % opt, ContentType.objects.get_for_model(obj)) if settings.USE_JSONFIELD and len(kwargs): newaction.data = kwargs newaction.save(force_insert=True) return newaction
def actor(self, obj, **kwargs): """ Stream of most recent actions where obj is the actor. Keyword arguments will be passed to Action.objects.filter """ check(obj) return obj.actor_actions.public(**kwargs)
def follow(user, obj, send_action=True, actor_only=True, flag='', **kwargs): """ Creates a relationship allowing the object's activities to appear in the user's stream. Returns the created ``Follow`` instance. If ``send_action`` is ``True`` (the default) then a ``<user> started following <object>`` action signal is sent. Extra keyword arguments are passed to the action.send call. If ``actor_only`` is ``True`` (the default) then only actions where the object is the actor will appear in the user's activity stream. Set to ``False`` to also include actions where this object is the action_object or the target. If ``flag`` not an empty string then the relationship would marked by this flag. Example:: follow(request.user, group, actor_only=False) follow(request.user, group, actor_only=False, flag='liking') """ check(obj) instance, created = apps.get_model('actstream', 'follow').objects.get_or_create( user=user, object_id=obj.pk, flag=flag, content_type=ContentType.objects.get_for_model(obj), actor_only=actor_only ) if send_action and created: if not flag: action.send(user, verb=_('started following'), target=obj, **kwargs) else: action.send(user, verb=_('started %s' % flag), target=obj, **kwargs) return instance
def for_object(self, instance): """ Filter to a specific instance. """ check(instance) # content_type = ContentType.objects.get_for_model(instance).pk return self.filter(follow_object_id=instance.pk)
def follow(user, obj, send_action=True, actor_only=True, **kwargs): """ Creates a relationship allowing the object's activities to appear in the user's stream. Returns the created ``Follow`` instance. If ``send_action`` is ``True`` (the default) then a ``<user> started following <object>`` action signal is sent. Extra keyword arguments are passed to the action.send call. If ``actor_only`` is ``True`` (the default) then only actions where the object is the actor will appear in the user's activity stream. Set to ``False`` to also include actions where this object is the action_object or the target. Example:: follow(request.user, group, actor_only=False) """ check(obj) instance, created = get_model('actstream', 'follow').objects.get_or_create( user=user, follow_object_id=obj.pk, actor_only=actor_only) if send_action and created: action.send(user, verb=_('started following'), target=obj, **kwargs) return instance
def for_object(self, instance): """ Filter to a specific instance. """ check(instance) content_type = ContentType.objects.get_for_model(instance).pk return self.filter(content_type=content_type, object_id=instance.pk)
def mystream(self, obj, **kwargs): """ Custom stream for users. Includes votes and comments info. """ q = Q() check(obj) objects_by_content_type = defaultdict(lambda: []) following = ( get_model("actstream", "follow").objects.filter(user=obj).values_list("content_type_id", "object_id") ) if not len(following): return self.none() for content_type_id, object_id in following.iterator(): objects_by_content_type[content_type_id].append(object_id) for content_type_id, object_ids in objects_by_content_type.items(): q = ( q | Q(actor_content_type=content_type_id, actor_object_id__in=object_ids) | Q(target_content_type=content_type_id, target_object_id__in=object_ids) | Q(action_object_content_type=content_type_id, action_object_object_id__in=object_ids) ) return self.filter(q, **kwargs)
def related_action_object(self, obj, **kwargs): """ Stream of most recent actions where obj is the related action_object. Keyword arguments will be passed to Action.objects.filter """ check(obj) return obj.related_action_object_actions.public(**kwargs)
def action_object(self, obj, **kwargs): """ Stream of most recent actions where obj is the action_object. Keyword arguments will be passed to Action.objects.filter """ check(obj) return obj.action_object_actions.public(**kwargs)
def follow(user, obj, send_action=True, actor_only=True, **kwargs): """ Creates a relationship allowing the object's activities to appear in the user's stream. Returns the created ``Follow`` instance. If ``send_action`` is ``True`` (the default) then a ``<user> started following <object>`` action signal is sent. Extra keyword arguments are passed to the action.send call. If ``actor_only`` is ``True`` (the default) then only actions where the object is the actor will appear in the user's activity stream. Set to ``False`` to also include actions where this object is the action_object or the target. Example:: follow(request.user, group, actor_only=False) """ check(obj) instance, created = get_model('actstream', 'follow').objects.get_or_create( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj), actor_only=actor_only) if send_action and created: action.send(user, verb=_('started following'), target=obj, **kwargs) return instance
def unfollow(user, obj, send_action=False, flag=''): """ Removes a "follow" relationship. Set ``send_action`` to ``True`` (``False is default) to also send a ``<user> stopped following <object>`` action signal. Pass a string value to ``flag`` to determine which type of "follow" relationship you want to remove. Example:: unfollow(request.user, other_user) unfollow(request.user, other_user, flag='watching') """ check(obj) qs = apps.get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj) ) if flag: qs = qs.filter(flag=flag) qs.delete() if send_action: if not flag: action.send(user, verb=_('stopped following'), target=obj) else: action.send(user, verb=_('stopped %s' % flag), target=obj)
def action_handler(verb, **kwargs): """ Handler function to create Action instance upon action signal call. """ kwargs.pop('signal', None) actor = kwargs.pop('sender') # We must store the unstranslated string # If verb is an ugettext_lazyed string, fetch the original string if hasattr(verb, '_proxy____args'): verb = verb._proxy____args[0] newaction = get_model('actstream', 'action')( actor_content_type=ContentType.objects.get_for_model(actor), actor_object_id=actor.pk, verb=text_type(verb), public=bool(kwargs.pop('public', True)), description=kwargs.pop('description', None), timestamp=kwargs.pop('timestamp', now()) ) for opt in ('target', 'action_object'): obj = kwargs.pop(opt, None) if obj is not None: check(obj) setattr(newaction, '%s_object_id' % opt, obj.pk) setattr(newaction, '%s_content_type' % opt, ContentType.objects.get_for_model(obj)) if settings.USE_JSONFIELD and len(kwargs): newaction.data = kwargs newaction.save(force_insert=True) return newaction
def unfollow(user, obj, send_action=False, flag=''): """ Removes a "follow" relationship. Set ``send_action`` to ``True`` (``False is default) to also send a ``<user> stopped following <object>`` action signal. Pass a string value to ``flag`` to determine which type of "follow" relationship you want to remove. Example:: unfollow(request.user, other_user) unfollow(request.user, other_user, flag='watching') """ check(obj) qs = apps.get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj)) if flag: qs = qs.filter(flag=flag) qs.delete() if send_action: if not flag: action.send(user, verb=_('stopped following'), target=obj) else: action.send(user, verb=_('stopped %s' % flag), target=obj)
def mystream(self, obj, **kwargs): """ Custom stream for users. Includes votes and comments info. """ q = Q() check(obj) objects_by_content_type = defaultdict(lambda: []) following = get_model('actstream', 'follow').objects\ .filter(user=obj).values_list('content_type_id', 'object_id', ) if not len(following): return self.none() for content_type_id, object_id in following.iterator(): objects_by_content_type[content_type_id].append(object_id) for content_type_id, object_ids in objects_by_content_type.items(): q = q | Q( actor_content_type=content_type_id, actor_object_id__in=object_ids, ) | Q( target_content_type=content_type_id, target_object_id__in=object_ids, ) | Q( action_object_content_type=content_type_id, action_object_object_id__in=object_ids, ) return self.filter(q, **kwargs)
def followers_qs(self, actor): """ Returns a queryset of User objects who are following the given actor (eg my followers). """ check(actor) return self.filter( content_type=ContentType.objects.get_for_model(actor), object_id=actor.pk).select_related('user')
def unfollow(user, obj, ftype, send_action=True): check(obj) Follow.objects.filter(user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj), ftype=ftype).delete() if send_action: action.send(user, verb='un%s' % ftype, target=obj)
def model_actions(self, model, **kwargs): """ Stream of most recent actions by any particular model """ check(model) ctype = ContentType.objects.get_for_model(model) return self.public( (Q(target_content_type=ctype) | Q(action_object_content_type=ctype) | Q(actor_content_type=ctype)), **kwargs)
def followers_qs(self, actor): """ Returns a queryset of User objects who are following the given actor (eg my followers). """ check(actor) return self.filter( content_type=ContentType.objects.get_for_model(actor), object_id=actor.pk ).select_related('user')
def model_actions(self, model, **kwargs): """ Stream of most recent actions by any particular model """ check(model) ctype = ContentType.objects.get_for_model(model) return self.public( (Q(target_content_type=ctype) | Q(action_object_content_type=ctype) | Q(actor_content_type=ctype)), **kwargs )
def followers(self, actor): """ Returns a list of User objects who are following the given actor (eg my followers). """ check(actor) return [ follow.user for follow in self.filter( follow_object_id=actor.pk).select_related('user') ]
def for_object(self, instance, follow_type=None): """ Filter to a specific instance. """ check(instance) content_type = ContentType.objects.get_for_model(instance).pk queryset = self.filter(content_type=content_type, object_id=instance.pk) if follow_type: queryset = queryset.filter(follow_type=follow_type) return queryset
def following(self, user, *models): """ Returns a list of actors that the given user is following (eg who im following). Items in the list can be of any model unless a list of restricted models are passed. Eg following(user, User) will only return users following the given user """ qs = self.filter(user=user) for model in models: check(model) qs = qs.filter(content_type=ContentType.objects.get_for_model(model)) return [follow.follow_object for follow in qs.fetch_generic_relations('follow_object')]
def any(self, obj, **kwargs): """ Stream of most recent actions where obj is the actor OR target OR action_object. """ check(obj) ctype = ContentType.objects.get_for_model(obj) return self.public( Q(actor_content_type=ctype, actor_object_id=obj.pk) | Q(target_content_type=ctype, target_object_id=obj.pk) | Q(action_object_content_type=ctype, action_object_object_id=obj.pk), **kwargs )
def following_qs(self, user, *models): """ Returns a queryset of actors that the given user is following (eg who im following). Items in the list can be of any model unless a list of restricted models are passed. Eg following(user, User) will only return users following the given user """ qs = self.filter(user=user) ctype_filters = Q() for model in models: check(model) ctype_filters |= Q(content_type=ContentType.objects.get_for_model(model)) qs = qs.filter(ctype_filters) return qs.fetch_generic_relations('follow_object')
def is_following(user, obj): """ Checks if a "follow" relationship exists. Returns True if exists, False otherwise. Example:: is_following(request.user, group) """ check(obj) return apps.get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj)).exists()
def is_following(user, obj): """ Checks if a "follow" relationship exists. Returns True if exists, False otherwise. Example:: is_following(request.user, group) """ check(obj) return get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj) ).exists()
def any(self, obj, **kwargs): """ Stream of most recent actions where obj is the actor OR target OR action_object. """ check(obj) ctype = ContentType.objects.get_for_model(obj) return self.public( Q( # actor_content_type=ctype, actor_id=obj.pk, ) | Q( # target_content_type=ctype, target_id=obj.pk, ) | Q( action_object_content_type=ctype, action_object_object_id=obj.pk, ), **kwargs)
def unfollow(user, obj, send_action=False): """ Removes a "follow" relationship. Set ``send_action`` to ``True`` (``False is default) to also send a ``<user> stopped following <object>`` action signal. Example:: unfollow(request.user, other_user) """ check(obj) get_model('actstream', 'follow').objects.filter( user=user, follow_object_id=obj.pk).delete() if send_action: action.send(user, verb=_('stopped following'), target=obj)
def unfollow(user, obj, send_action=False): """ Removes a "follow" relationship. Set ``send_action`` to ``True`` (``False is default) to also send a ``<user> stopped following <object>`` action signal. Example:: unfollow(request.user, other_user) """ check(obj) apps.get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj)).delete()
def user(self, obj, with_user_activity=False, follow_flag=None, **kwargs): """Create a stream of the most recent actions by objects that the user is following.""" q = Q() qs = self.public() if not obj: return qs.none() check(obj) if with_user_activity: q = q | Q( actor_content_type=ContentType.objects.get_for_model(obj), actor_object_id=obj.pk ) follows = apps.get_model('actstream', 'follow').objects.filter(user=obj) if follow_flag: follows = follows.filter(flag=follow_flag) content_types = ContentType.objects.filter( pk__in=follows.values('content_type_id') ) if not (content_types.exists() or with_user_activity): return qs.none() for content_type in content_types: object_ids = follows.filter(content_type=content_type) q = q | Q( actor_content_type=content_type, actor_object_id__in=object_ids.values('object_id') ) | Q( target_content_type=content_type, target_object_id__in=object_ids.filter( actor_only=False).values('object_id') ) | Q( action_object_content_type=content_type, action_object_object_id__in=object_ids.filter( actor_only=False).values('object_id') ) | Q( related_action_object_content_type=content_type, related_action_object_object_id__in=object_ids.filter( actor_only=False).values('object_id') ) return qs.filter(q, **kwargs)
def user(self, obj, **kwargs): """ Stream of most recent actions by objects that the passed User obj is following. """ q = Q() qs = self.public() if not obj: return qs.none() check(obj) actors_by_content_type = defaultdict(lambda: []) others_by_content_type = defaultdict(lambda: []) if kwargs.pop('with_user_activity', False): object_content_type = ContentType.objects.get_for_model(obj) actors_by_content_type[object_content_type.id].append(obj.pk) follow_gfks = get_model('actstream', 'follow').objects.filter(user=obj).values_list( 'content_type_id', 'object_id', 'actor_only') for content_type_id, object_id, actor_only in follow_gfks.iterator(): actors_by_content_type[content_type_id].append(object_id) if not actor_only: others_by_content_type[content_type_id].append(object_id) if len(actors_by_content_type) + len(others_by_content_type) == 0: return qs.none() for content_type_id, object_ids in actors_by_content_type.items(): q = q | Q( actor_content_type=content_type_id, actor_object_id__in=object_ids, ) for content_type_id, object_ids in others_by_content_type.items(): q = q | Q( target_content_type=content_type_id, target_object_id__in=object_ids, ) | Q( action_object_content_type=content_type_id, action_object_object_id__in=object_ids, ) return qs.filter(q, **kwargs)
def user(self, obj, **kwargs): """ Stream of most recent actions by objects that the passed User obj is following. """ q = Q() qs = self.public() if not obj: return qs.none() check(obj) actors_by_content_type = defaultdict(lambda: []) others_by_content_type = defaultdict(lambda: []) if kwargs.pop('with_user_activity', False): object_content_type = ContentType.objects.get_for_model(obj) actors_by_content_type[object_content_type.id].append(obj.pk) follow_gfks = get_model('actstream', 'follow').objects.filter( user=obj).values_list('content_type_id', 'object_id', 'actor_only') for content_type_id, object_id, actor_only in follow_gfks.iterator(): actors_by_content_type[content_type_id].append(object_id) if not actor_only: others_by_content_type[content_type_id].append(object_id) if len(actors_by_content_type) + len(others_by_content_type) == 0: return qs.none() for content_type_id, object_ids in actors_by_content_type.items(): q = q | Q( actor_content_type=content_type_id, actor_object_id__in=object_ids, ) for content_type_id, object_ids in others_by_content_type.items(): q = q | Q( target_content_type=content_type_id, target_object_id__in=object_ids, ) | Q( action_object_content_type=content_type_id, action_object_object_id__in=object_ids, ) return qs.filter(q, **kwargs)
def unfollow(user, obj, send_action=False): """ Removes a "follow" relationship. Set ``send_action`` to ``True`` (``False is default) to also send a ``<user> stopped following <object>`` action signal. Example:: unfollow(request.user, other_user) """ check(obj) get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj) ).delete() if send_action: action.send(user, verb=_('stopped following'), target=obj)
def location(self, obj, **kwargs): """ Actstream for location - we try to include also actions related to different content types published in this location, eg. comments and votes. """ q = Q() check(obj) if not hasattr(obj, 'published_items'): return self.none() self_type = ContentType.objects.get_for_model(obj) q = q | Q(target_content_type=self_type, target_object_id=obj.pk) for ct, id_list in obj.published_items().iteritems(): q = q | Q(target_content_type=ct, target_object_id__in=id_list) return self.filter(q, **kwargs)
def ngostream(self, obj, **kwargs): """ Activity stream for NGO, presents actions of all memebers. """ q = Q() check(obj) if not hasattr(obj, 'users'): return self.none() self_type = ContentType.objects.get_for_model(obj) user_type = ContentType.objects.get(app_label="auth", model="user") user_list = [int(x.pk) for x in obj.users.all()] q = q | Q(target_content_type=self_type, target_object_id=obj.pk) q = q | Q(actor_content_type=user_type, actor_object_id__in=user_list) return self.filter(q, **kwargs)
def follow(user, obj, ftype, send_action=True, actor_only=True, **kwargs): check(obj) instance, created = Follow.objects.get_or_create( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj), actor_only=actor_only, ftype=ftype) if send_action and created: action.send(user, verb=ftype, target=obj, **kwargs) if obj.__class__.__name__ not in RECIPIENT: recipient = obj else: recipient = getattr(obj, RECIPIENT[obj.__class__.__name__], None) if recipient and user != recipient: notify.send(sender=user, recipient=recipient, verb=ftype, target=obj) return instance
def mystream(self, obj, **kwargs): """ Custom stream for users. Includes votes and comments info. """ q = Q() check(obj) objects_by_content_type = defaultdict(lambda: []) following = get_model('actstream', 'follow').objects\ .filter(user=obj).values_list('content_type_id', 'object_id', ) for content_type_id, object_id in following.iterator(): objects_by_content_type[content_type_id].append(object_id) for content_type_id, object_ids in objects_by_content_type.items(): q = q | Q(actor_content_type=content_type_id, actor_object_id__in=object_ids, ) | Q( target_content_type=content_type_id, target_object_id__in=object_ids, ) | Q( action_object_content_type=content_type_id, action_object_object_id__in=object_ids, ) return self.filter(q, **kwargs)
def action_handler(verb, **kwargs): """ Handler function to create Action instance upon action signal call. """ db = kwargs.pop('db', getattr(settings, 'DEFAULT_DB_ALIAS', 'default')) kwargs.pop('signal', None) actor = kwargs.pop('sender') parent_activity = kwargs.pop('parent_activity', None) activity_type = kwargs.pop('type', None) # We must store the unstranslated string # If verb is an ugettext_lazyed string, fetch the original string if hasattr(verb, '_proxy____args'): verb = verb._proxy____args[0] action_model = apps.get_model('actstream', 'action') newaction = action_model(actor_content_type=ContentType.objects.db_manager( db).get_for_model(actor), actor_object_id=actor.pk, verb=text_type(verb), public=bool(kwargs.pop('public', True)), description=kwargs.pop('description', None), timestamp=kwargs.pop('timestamp', now()), parent_activity=parent_activity, type=activity_type) for opt in ('target', 'action_object', 'permission'): obj = kwargs.pop(opt, None) if obj is not None: check(obj) setattr(newaction, '%s_object_id' % opt, obj.pk) setattr(newaction, '%s_content_type' % opt, ContentType.objects.db_manager(db).get_for_model(obj)) if settings.USE_JSONFIELD and len(kwargs): newaction.data = kwargs newaction.save(force_insert=True, using=db) return newaction
def is_following(user, obj, flag=''): """ Checks if a "follow" relationship exists. Returns True if exists, False otherwise. Pass a string value to ``flag`` to determine which type of "follow" relationship you want to check. Example:: is_following(request.user, group) is_following(request.user, group, flag='liking') """ check(obj) qs = apps.get_model('actstream', 'follow').objects.filter( user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj) ) if flag: qs = qs.filter(flag=flag) return qs.exists()