Completed
Pull Request — master (#390)
by
unknown
24s
created

action_handler()   F

Complexity

Conditions 9

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
c 1
b 0
f 0
dl 0
loc 44
rs 3
1
from django.contrib.contenttypes.models import ContentType
2
from django.core.exceptions import FieldDoesNotExist
3
from django.utils.six import text_type
4
from django.utils.timezone import now
5
from django.utils.translation import ugettext_lazy as _
6
7
from actstream import get_action_model, get_follow_model, settings
8
from actstream.registry import check
9
from actstream.signals import action
10
11
12
def follow(user, obj, send_action=True, actor_only=True, flag='', **kwargs):
13
    """
14
    Creates a relationship allowing the object's activities to appear in the
15
    user's stream.
16
17
    Returns the created ``Follow`` instance.
18
19
    If ``send_action`` is ``True`` (the default) then a
20
    ``<user> started following <object>`` action signal is sent.
21
    Extra keyword arguments are passed to the action.send call.
22
23
    If ``actor_only`` is ``True`` (the default) then only actions where the
24
    object is the actor will appear in the user's activity stream. Set to
25
    ``False`` to also include actions where this object is the action_object or
26
    the target.
27
28
    If ``flag`` is not an empty string then the relationship would marked by
29
    this flag.
30
31
    Example::
32
33
        follow(request.user, group, actor_only=False)
34
        follow(request.user, group, actor_only=False, flag='liking')
35
    """
36
    check(obj)
37
    instance, created = get_follow_model().objects.get_or_create(
38
        user=user, object_id=obj.pk, flag=flag,
39
        content_type=ContentType.objects.get_for_model(obj),
40
        actor_only=actor_only
41
    )
42
    if send_action and created:
43
        if not flag:
44
            action.send(user, verb=_('started following'), target=obj, **kwargs)
45
        else:
46
            action.send(user, verb=_('started %s' % flag), target=obj, **kwargs)
47
    return instance
48
49
50
def unfollow(user, obj, send_action=False, flag=''):
51
    """
52
    Removes a "follow" relationship.
53
54
    Set ``send_action`` to ``True`` (``False is default) to also send a
55
    ``<user> stopped following <object>`` action signal. Pass a string value to
56
    ``flag`` to determine which type of "follow" relationship you want to
57
    remove.
58
59
    Example::
60
61
        unfollow(request.user, other_user)
62
        unfollow(request.user, other_user, flag='watching')
63
    """
64
    check(obj)
65
66
    qs = get_follow_model().objects.filter(
67
        user=user, object_id=obj.pk,
68
        content_type=ContentType.objects.get_for_model(obj)
69
    )
70
71
    if flag:
72
        qs = qs.filter(flag=flag)
73
74
    qs.delete()
75
76
    if send_action:
77
        if not flag:
78
            action.send(user, verb=_('stopped following'), target=obj)
79
        else:
80
            action.send(user, verb=_('stopped %s' % flag), target=obj)
81
82
83
def is_following(user, obj, flag=''):
84
    """
85
    Check if a "follow" relationship exists.
86
87
    Return True if exists, False otherwise. Pass a string value to ``flag`` to
88
    determine which type of "follow" relationship you want to check.
89
90
    Example::
91
92
        is_following(request.user, group)
93
        is_following(request.user, group, flag='liking')
94
    """
95
    return get_follow_model().objects.is_following(user, obj, flag)
96
97
98
def action_handler(verb, **kwargs):
99
    """
100
    Handler function to create Action instance upon action signal call.
101
    """
102
    Action = get_action_model()
103
    kwargs.pop('signal', None)
104
    actor = kwargs.pop('sender')
105
106
    # We must store the untranslated string
107
    # If verb is a ugettext_lazy string, fetch the original string
108
    if hasattr(verb, '_proxy____args'):
109
        verb = verb._proxy____args[0]
110
111
    newaction = Action(
112
        actor_content_type=ContentType.objects.get_for_model(actor),
113
        actor_object_id=actor.pk,
114
        verb=text_type(verb),
115
        public=bool(kwargs.pop('public', True)),
116
        description=kwargs.pop('description', None),
117
        timestamp=kwargs.pop('timestamp', now())
118
    )
119
120
    for opt in ('target', 'action_object'):
121
        obj = kwargs.pop(opt, None)
122
        if obj is not None:
123
            check(obj)
124
            setattr(newaction, '%s_object_id' % opt, obj.pk)
125
            setattr(newaction, '%s_content_type' % opt,
126
                    ContentType.objects.get_for_model(obj))
127
128
    # Support custom Action models
129
    for attribute in kwargs.keys():
130
        try:
131
            Action._meta.get_field(attribute)
132
        except FieldDoesNotExist:
133
            pass
134
        else:
135
            setattr(newaction, attribute, kwargs.pop(attribute))
136
137
    if settings.USE_JSONFIELD and len(kwargs):
138
        newaction.data = kwargs
139
140
    newaction.save(force_insert=True)
141
    return newaction
142