forked from MapStory/mapstory-meta
-
Notifications
You must be signed in to change notification settings - Fork 0
/
social_signals.py
164 lines (139 loc) · 6.49 KB
/
social_signals.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
from django.db.models.signals import post_save
from django.db.models.signals import m2m_changed
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from geonode.maps.models import Layer
from geonode.maps.models import Map
from geonode.maps.models import map_changed_signal
from mapstory.models import PublishingStatus
from mapstory.models import ContactDetail
from mapstory.models import UserActivity
from mapstory.templatetags import mapstory_tags
from dialogos.models import Comment
from agon_ratings.models import Rating
from mapstory.util import user
from mailer import send_html_mail
import datetime
def activity_summary(actions, plain_text=False):
sep = "\n" if plain_text else "<br/>"
return sep.join([mapstory_tags.activity_item(a, plain_text) for a in actions])
def batch_notification(days=1):
for u in User.objects.filter(useractivity__notification_preference='S'):
day_ago = datetime.datetime.now() - datetime.timedelta(days=days)
actions = u.useractivity.other_actor_actions.filter(timestamp_gte=day_ago)
if not actions: continue
send_html_mail("[MapStory] Daily Summary Notification",
message=activity_summary(actions, plain_text=True),
message_html=activity_summary(actions),
from_email="do-not-reply@mapstory.org",
recipient_list=[user.email])
def notify_handler(sender, instance, action, model, pk_set, **kwargs):
if action != 'post_add': return
if instance.notification_preference != 'E':
return
assert len(pk_set) == 1
real_action = getattr(model,'objects').get(id=iter(pk_set).next())
send_html_mail("[MapStory] Notification",
message=mapstory_tags.activity_item(real_action, plain_text=True),
message_html=mapstory_tags.activity_item(real_action),
from_email="do-not-reply@mapstory.org",
recipient_list=[instance.user.email])
def action(actor, verb, action_object=None, target=None, public=True):
'''using the signal api doesn't give us a ref to the new action...'''
# this'll cause some circular dep problems...
from actstream.models import Action
newaction = Action(
actor_content_type=ContentType.objects.get_for_model(actor),
actor_object_id=actor.pk,
verb=unicode(verb),
public=public,
timestamp=datetime.datetime.now())
if action_object:
newaction.action_object = action_object
newaction.action_object_content_type = ContentType.objects.get_for_model(action_object)
if target:
newaction.target = target
newaction.target_content_type = ContentType.objects.get_for_model(target)
newaction.save()
return newaction
def action_handler(create_verb='created', update_verb='updated', provide_user=True):
def handler(sender, instance, created, **kwargs):
if created and not create_verb:
return
try:
publish = getattr(instance, 'publish', None)
except PublishingStatus.DoesNotExist:
publish = None
if publish and publish.status != 'Public':
return
active_verb = create_verb if created else update_verb
actor = instance
action_object = None
if provide_user:
actor = user()
if not actor:
# a non request caused this
return
action_object = instance
action(actor, verb=active_verb, action_object=action_object)
return handler
def register_save_handler(model, **kwargs):
handler = action_handler(**kwargs)
post_save.connect(handler, sender=model, weak=False)
def rating_handler(sender, instance, created, **kwargs):
# fall back on the rating user if no request user is found (for tests)
actor = user() or instance.user
target = instance.content_object
act = action(actor, verb='rated', action_object=instance, target=target)
if actor != target.owner:
target.owner.useractivity.other_actor_actions.add(act)
def comment_handler(sender, instance, created, **kwargs):
actor = instance.author
if not actor: return
target = instance.content_object # object being commented on (map/layer)
parent = instance.parent # possible parent comment
if created:
verb = 'commented'
if parent:
verb = 'replied'
act = action(actor, verb=verb, action_object=instance, target=parent)
else:
act = action(actor, verb='edited', action_object=instance, target=target)
# track this activity - too expensive to query this out after the fact
# only track if the comment is
# a) on someone elses layer/map or
if actor != target.owner:
target.owner.useractivity.other_actor_actions.add(act)
# b) in reply to someone elses comment
elif parent and actor != parent.author:
parent.author.useractivity.other_actor_actions.add(act)
def publishing_handler(sender, instance, created, **kw):
if instance.status == 'Public':
what = instance.map or instance.layer
action(what.owner, 'published', action_object=what)
layers = getattr(what, 'local_layers', [])
for l in layers:
if l.owner != what.owner:
# make this hidden so it doesn't show up
act = action(what.owner, verb='published', action_object=l,
target=what, public=False)
# except here
l.owner.useractivity.other_actor_actions.add(act)
def map_handler(sender, what_changed, old, new, **kw):
if what_changed == 'layers' and sender.publish.status == 'Public':
added = old ^ new
layers = Layer.objects.filter(typename__in=added)
for l in layers:
act = action(sender.owner, verb='added', action_object=l,
target=sender)
# if the layer owner is not the map owner, tell the layer owner
if l.owner != sender.owner:
l.owner.useractivity.other_actor_actions.add(act)
register_save_handler(ContactDetail, create_verb='joined MapStory', provide_user=False)
register_save_handler(Layer, create_verb='uploaded')
register_save_handler(Map)
map_changed_signal.connect(map_handler)
post_save.connect(publishing_handler, sender=PublishingStatus)
post_save.connect(rating_handler, sender=Rating)
post_save.connect(comment_handler, sender=Comment)
m2m_changed.connect(notify_handler, sender=UserActivity.other_actor_actions.through)