def follow(user, actor, send_action=True): """ Creates a ``User`` -> ``Actor`` follow relationship such that the actor's activities appear in the user's stream. Also sends the ``<user> started following <actor>`` action signal. Returns the created ``Follow`` instance. If ``send_action`` is false, no "started following" signal will be created Syntax:: follow(<user>, <actor>) Example:: follow(request.user, group) """ content_type = ContentType.objects.get_for_model(actor) is_following = Follow.objects.filter(user = user, object_id = actor.pk, content_type = content_type) if not is_following: # don't allow double follows if send_action: action.send(user, verb=_('started following'), target=actor) return Follow.objects.create(user = user, object_id = actor.pk, content_type = content_type) else: return is_following[0]
def activity_handler_application_response(sender, application, **kwargs): if application.accepted or application.responded: status_verb = application.accepted and verbs.ACCEPT or verbs.REJECT action.send( application.task.user, verb=status_verb, action_object=application, target=application.task ) send_new_task_application_response_email.delay(application.id)
def test_correct_fields(self): follower = UserFactory() followed = UserFactory() q = QuestionFactory(creator=followed) # The above might make follows, which this test isn't about. Clear them out. Follow.objects.all().delete() follow(follower, followed) # Make a new action for the above. This should trigger notifications action.send(followed, verb='asked', action_object=q) act = Action.objects.order_by('-id')[0] notification = Notification.objects.get(action=act) serializer = api.NotificationSerializer(instance=notification) eq_(serializer.data['is_read'], False) eq_(serializer.data['actor'], { 'type': 'user', 'username': followed.username, 'display_name': followed.profile.name, 'avatar': profile_avatar(followed), }) eq_(serializer.data['verb'], 'asked') eq_(serializer.data['action_object']['type'], 'question') eq_(serializer.data['action_object']['id'], q.id) eq_(serializer.data['target'], None) # Check that the serialized data is in the correct format. If it is # not, this will throw an exception. datetime.strptime(serializer.data['timestamp'], '%Y-%m-%dT%H:%M:%SZ')
def test_correct_fields(self): follower = profile() followed = profile() q = question(creator=followed.user, save=True) # The above might make follows, which this test isn't about. Clear them out. Follow.objects.all().delete() follow(follower.user, followed.user) # Make a new action for the above. This should trigger notifications action.send(followed.user, verb='asked', action_object=q) act = Action.objects.order_by('-id')[0] notification = Notification.objects.get(action=act) serializer = api.NotificationSerializer(instance=notification) eq_(serializer.data['is_read'], False) eq_(serializer.data['actor'], { 'type': 'user', 'username': followed.user.username, 'display_name': followed.name, 'avatar': profile_avatar(followed.user), }) eq_(serializer.data['verb'], 'asked') eq_(serializer.data['action_object']['type'], 'question') eq_(serializer.data['action_object']['id'], q.id) eq_(serializer.data['target'], None) eq_(type(serializer.data['timestamp']), datetime)
def test_jsonfield(self): action.send(self.user, verb='said', text='foobar', tags=['sayings'], more_data={'pk': self.user.pk}) newaction = Action.objects.filter(verb='said')[0] self.assertEqual(newaction.data['text'], 'foobar') self.assertEqual(newaction.data['tags'], ['sayings']) self.assertEqual(newaction.data['more_data'], {'pk': self.user.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, 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 follow( user, actor, send_notify=False, send_action=True ): """ Creates a ``User`` -> ``Actor`` follow relationship such that the actor's activities appear in the user's stream. Also sends the ``<user> started following <actor>`` action signal. Returns the created ``Follow`` instance. If ``send_action`` is false, no "started following" signal will be created Syntax:: follow(<user>, <actor>) Example:: follow(request.user, group) """ from notify.models import Notify follow, created = Follow.objects.get_or_create( user=user, object_id=actor.pk, content_type=ContentType.objects.get_for_model( actor ) ) if send_action and created: action.send( user, verb=_( ActstreamSpecs.STARTED_FOLLOWING ), target=actor ) """ notify comment owner """ if send_notify: if ContentType.objects.get_for_model( actor ) == ContentType.objects.get( app_label="auth", model="user" ): email= render_to_string('email_templates/inc_email_follow.html', {'from_user':user, 'site_url':settings.SITE_DOMAIN}) _notify = Notify.objects.send( from_user=user, type=Notify.FOLLOWS, message = "", email_message = email, contact=None, to_user=actor) return follow
def follow(user, obj, send_action=True, actor_only=True): """ Creates a relationship allowing that the object's activities 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. 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) """ from actstream.models import Follow check_actionable_model(obj) follow, created = Follow.objects.get_or_create(user=user, object_id=obj.pk, content_type=ContentType.objects.get_for_model(obj), defaults={'actor_only': actor_only}) if send_action and created: action.send(user, verb=_('started following'), target=obj) return follow
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 activity_handler_progress_report(sender, instance, created, **kwargs): if created: action.send(instance.user, verb=verbs.REPORT, action_object=instance, target=instance.event) notify_new_progress_report.delay(instance.id) else: notify_new_progress_report_slack.delay(instance.id, updated=True)
def test_action_object(self): action.send(self.user1,verb='created comment',action_object=self.comment,target=self.group) created_action = Action.objects.get(verb='created comment') self.assertEqual(created_action.actor, self.user1) self.assertEqual(created_action.action_object, self.comment) self.assertEqual(created_action.target, self.group) self.assertEqual(unicode(created_action), u'admin created comment admin: Sweet Group!... on CoolGroup 0 minutes ago')
def activity_handler_new_task(sender, instance, created, **kwargs): if created: action.send(instance.user, verb=verbs.CREATE, action_object=instance) initialize_task_progress_events.delay(instance.id) # Create or Update HubSpot deal create_or_update_hubspot_deal_task.delay(instance.id)
def save(self, *args, **kwargs): # invalidate older votes from the same voter to the same election old_votes = self.election.cast_votes.filter(is_direct=True, invalidated_at_date=None, voter=self.request.user) for old_vote in old_votes: old_vote.invalidated_at_date = timezone.now() old_vote.is_counted = False old_vote.save() vote = super(VoteForm, self).save(commit=False) data = { "a": "vote", "answers": [], "election_hash": {"a": "hash/sha256/value", "value": self.election.hash}, "election_uuid": self.election.uuid } i = 0 for question in self.election.questions: data["answers"] += [{ "a": "plaintext-answer", "choices": [self.cleaned_data['question%d' % i]], }] i += 1 if self.request.user not in self.election.agora.members.all(): if self.election.agora.has_perms('join', self.request.user): # Join agora if possible from agora_site.agora_core.views import AgoraActionJoinView AgoraActionJoinView().post(self.request, self.election.agora.creator.username, self.election.agora.name) vote.voter = self.request.user vote.election = self.election vote.is_counted = self.request.user in self.election.agora.members.all() vote.is_direct = True if self.election.is_vote_secret() and ('submit-secret' in self.request.POST) and\ (self.request.user in self.election.agora.members.all() or\ self.election.agora.has_perms('join', self.request.user)): vote.is_public = False vote.reason = None else: vote.reason = self.cleaned_data['reason'] vote.is_public = True vote.data = data vote.casted_at_date = timezone.now() vote.create_hash() actstream_action.send(self.request.user, verb='voted', action_object=self.election, target=self.election.agora, geolocation=json.dumps(geolocate_ip(self.request.META.get('REMOTE_ADDR')))) vote.action_id = Action.objects.filter(actor_object_id=self.request.user.id, verb='voted', action_object_object_id=self.election.id, target_object_id=self.election.agora.id).order_by('-timestamp').all()[0].id vote.save() return vote
def send_action(user, verb, request, action_object=None, target=None): if request is None: ipaddr = "" geolocation = "[0,0]" else: ipaddr = request.META.get("REMOTE_ADDR") geolocation = json.dumps(geolocate_ip(request.META.get("REMOTE_ADDR"))) action.send(user, verb=verb, action_object=action_object, target=target, ipaddr=ipaddr, geolocation=geolocation)
def _makeNotification(self, is_read=False): # Make a new action. This should trigger notifications action.send(self.followed, verb='asked', action_object=self.question) act = Action.objects.order_by('-id')[0] n = Notification.objects.get(action=act) if is_read: n.is_read = True n.save() return n
def activity_handler_new_participant(sender, instance, created, **kwargs): if created: action.send(instance.created_by, verb=verbs.ADD, action_object=instance, target=instance.task) if not instance.responded and not instance.accepted: send_new_task_invitation_email.delay(instance.id) if instance.accepted: update_task_periodic_updates.delay(instance.task.id)
def activity_handler_new_participant(sender, instance, created, **kwargs): if created: action.send(instance.created_by, verb=verbs.ADD, action_object=instance, target=instance.task) if instance.status == STATUS_INITIAL: notify_task_invitation_email.delay(instance.id) if instance.status == STATUS_ACCEPTED: update_task_periodic_updates.delay(instance.task.id)
def save(self): obj = self.get_comment_object() obj.save() action.send(self.request.user, verb='commented', target=self.target_object, action_object=obj, ipaddr=self.request.META.get('REMOTE_ADDR'), geolocation=json.dumps(geolocate_ip(self.request.META.get('REMOTE_ADDR')))) return obj
def activity_handler_channel_user(sender, instance, created, **kwargs): if created: action.send( instance.user, verb=verbs.ADD, action_object=instance, target=instance.channel, timestamp=instance.created_at ) if instance.channel.type == CHANNEL_TYPE_DIRECT: clean_direct_channel(instance.channel)
def activity_handler_participation_response(sender, participation, **kwargs): if participation.accepted or participation.responded: status_verb = participation.accepted and verbs.ACCEPT or verbs.REJECT action.send( participation.task.user, verb=status_verb, action_object=participation, target=participation.task ) send_new_task_invitation_response_email.delay(participation.id) if participation.accepted: update_task_periodic_updates.delay(participation.task.id)
def test_store_untranslated_string(self): lang = get_language() activate('fr') verb = _('English') self.assertEqual(verb, 'Anglais') action.send(self.user1, verb=verb, action_object=self.comment, target=self.group, timestamp=self.testdate) self.assertTrue(Action.objects.filter(verb='English').exists()) activate(lang)
def activity_handler_participation_response(sender, participation, **kwargs): if participation.status != STATUS_INITIAL: status_verb = participation.status == STATUS_ACCEPTED and verbs.ACCEPT or verbs.REJECT action.send( participation.task.user, verb=status_verb, action_object=participation, target=participation.task ) notify_task_invitation_response.delay(participation.id) if participation.status == STATUS_ACCEPTED: update_task_periodic_updates.delay(participation.task.id)
def add_admin_membership_action(self, request, agora, username, welcome_message, **kwargs): ''' Adds an admin (specified with username) to this agora, sending a welcome message to this new admin via email ''' if not re.match("^[a-zA-Z0-9_]+$", username): raise ImmediateHttpResponse(response=http.HttpBadRequest()) user = get_object_or_404(User, username=username) # remve the request admin membership status and add user to the agora remove_perm('requested_admin_membership', user, agora) agora.admins.add(user) agora.save() # create an action for the event action.send(request.user, verb='added admin', action_object=agora, ipaddr=request.META.get('REMOTE_ADDR'), target=user, geolocation=json.dumps(geolocate_ip(request.META.get('REMOTE_ADDR')))) # Mail to the user if user.get_profile().has_perms('receive_email_updates'): translation.activate(user.get_profile().lang_code) context = get_base_email_context(request) context.update(dict( agora=agora, other_user=user, notification_text=_('As administrator of %(agora)s, %(user)s has ' 'himself promoted you to admin of this agora. You can remove ' 'your admin membership at anytime, and if you think he is ' 'spamming you please contact with this website ' 'administrators.\n\n') % dict( agora=agora.get_full_name(), user=request.user.username ) + welcome_message, to=user )) email = EmailMultiAlternatives( subject=_('%(site)s - Promoted to admin of agora %(agora)s') % dict( site=Site.objects.get_current().domain, agora=agora.get_full_name() ), body=render_to_string('agora_core/emails/agora_notification.txt', context), to=[user.email]) email.attach_alternative( render_to_string('agora_core/emails/agora_notification.html', context), "text/html") email.send() translation.deactivate() return self.create_response(request, dict(status="success"))
def remove_membership_action(self, request, agora, username, goodbye_message, **kwargs): ''' Remove a member (specified with username) from this agora, sending a goodbye message to this member via email ''' if not re.match("^[a-zA-Z0-9_]+$", username): raise ImmediateHttpResponse(response=http.HttpBadRequest()) user = get_object_or_404(User, username=username) # user might not be allowed to leave (because he's the owner, or because # he's not a member of this agora at all) if not agora.has_perms('leave', user): raise ImmediateHttpResponse(response=http.HttpForbidden()) agora.members.remove(user) agora.save() # create an action for the event action.send(request.user, verb='removed member', action_object=agora, ipaddr=request.META.get('REMOTE_ADDR'), target=user, geolocation=json.dumps(geolocate_ip(request.META.get('REMOTE_ADDR')))) # Mail to the user if user.get_profile().has_perms('receive_email_updates'): translation.activate(user.get_profile().lang_code) context = get_base_email_context(request) context.update(dict( agora=agora, other_user=user, notification_text=_('Your have been removed from membership ' 'from %(agora)s . Sorry about that!\n\n') % dict( agora=agora.get_full_name() ) + goodbye_message, to=user )) email = EmailMultiAlternatives( subject=_('%(site)s - membership removed from ' '%(agora)s') % dict( site=Site.objects.get_current().domain, agora=agora.get_full_name() ), body=render_to_string('agora_core/emails/agora_notification.txt', context), to=[user.email]) email.attach_alternative( render_to_string('agora_core/emails/agora_notification.html', context), "text/html") email.send() translation.deactivate() return self.create_response(request, dict(status="success"))
def activity_handler_new_application(sender, instance, created, **kwargs): if created: action.send(instance.user, verb=verbs.APPLY, action_object=instance, target=instance.task) if instance.remarks: # Send the developer's remarks as a message to the client channel = get_or_create_task_channel(instance.user, instance) Message.objects.create(channel=channel, **{'user': instance.user, 'body': instance.remarks}) # Notify new application notify_new_task_application.delay(instance.id)
def zombie_apocalypse(self): humans = self.humans[:] zombies = self.zombies[:] while humans: for z in self.zombies: victim = choice(humans) humans.remove(victim) zombies.append(victim) action.send(z, verb='killed', target=victim) if not humans: break
def test_store_untranslated_string(self): lang = get_language() activate("fr") verb = _(u'English') assert unicode(verb) == u"Anglais" action.send(self.user1, verb=verb, action_object=self.comment, target=self.group) self.assertTrue(Action.objects.filter(verb=u'English')) # restore language activate(lang)
def layer_download(request, layername): layer = _resolve_layer( request, layername, 'base.view_resourcebase', _PERMISSION_MSG_VIEW) if request.user.is_authenticated(): action.send(request.user, verb='downloaded', target=layer) splits = request.get_full_path().split("/") redir_url = urljoin(settings.OGC_SERVER['default']['PUBLIC_LOCATION'], "/".join(splits[4:])) return HttpResponseRedirect(redir_url)
def activity_handler_application_response(sender, application, **kwargs): if application.status != STATUS_INITIAL: status_verb = application.status == STATUS_ACCEPTED and verbs.ACCEPT or verbs.REJECT action.send( application.task.user, verb=status_verb, action_object=application, target=application.task ) notify_task_application_response.delay(application.id) if application.status == STATUS_ACCEPTED and application.hours_needed and application.task.is_task: task = application.task task.bid = Decimal(application.hours_needed) * application.task.dev_rate task.save()
def test_no_action_for_self(self): """Test that a notification is not sent for actions the user took.""" follower = UserFactory() q = QuestionFactory(creator=follower) # The above might make follows, which this test isn't about. Clear them out. Follow.objects.all().delete() follow(follower, q, actor_only=False) # Make a new action for the above. This should not trigger notifications. action.send(q.creator, verb='edited', action_object=q) act = Action.objects.order_by('-id')[0] eq_(Notification.objects.filter(action=act).count(), 0)
def activity_handler_new_application(sender, instance, created, **kwargs): if created: action.send(instance.user, verb='applied for task', action_object=instance, target=instance.task) # Send email notification to project owner send_new_task_application_email(instance) # Send email confirmation to applicant send_new_task_application_applicant_email(instance) else: update_fields = kwargs.get('update_fields', None) if update_fields: if 'accepted' in update_fields and instance.accepted: action.send(instance.task.user, verb='accepted a task application', action_object=instance, target=instance.task) elif 'responded' in update_fields and not instance.accepted: action.send(instance.task.user, verb='rejected a task application', action_object=instance, target=instance.task)
def create(self, validated_data): """ Creates the Message in the Action model """ request = self.context['request'] target_type = validated_data.get("target_content_type") target_id = validated_data.get("target_object_id") try: content_type = get_target(target_type) except TargetDoesNotExist: raise serializers.ValidationError({ 'target_type': _('Unknown target type') }) # yapf: disable else: try: target_object = \ content_type.get_object_for_this_type(pk=target_id) except content_type.model_class().DoesNotExist: raise serializers.ValidationError({ 'target_id': _('target_id not found') }) # yapf: disable else: # check if request.user has permission to the target_object permission = '{}.change_{}'.format( target_object._meta.app_label, target_object._meta.model_name) if not request.user.has_perm(permission, target_object): message = (_("You do not have permission to add messages " "to target_id %s.") % target_object) raise exceptions.PermissionDenied(detail=message) results = action.send( request.user, verb=MESSAGE, target=target_object, description=validated_data.get("description")) # results will be a list of tuples with the first item in the # tuple being the signal handler function and the second # being the object. We want to get the object of the first # element in the list whose function is `action_handler` try: instance = [ instance for (receiver, instance) in results if receiver == action_handler ].pop() except IndexError: # if you get here it means we have no instances raise serializers.ValidationError( "Message not created. Please retry.") else: return instance
def update(self, document, validated_data): """ Update and save document. """ tags = validated_data.pop('tags', None) draft = document.draft self.update_document(document, validated_data) user = self.context['request'].user if user: document.updated_by_user = user if not document.created_by_user: document.created_by_user = user # save as a revision document.save_with_revision(user) # these require that the document is saved if tags is not None: document.tags.set(*tags) # reload it to ensure tags are refreshed and we have an id for new documents document = Document.objects.get(pk=document.id) # signals if draft and not document.draft: action.send(user, verb='published', action_object=document, place_code=document.work.place.place_code) document_published.send(sender=self.__class__, document=document, request=self.context['request']) elif not draft and document.draft: action.send(user, verb='unpublished', action_object=document, place_code=document.work.place.place_code) return document
def test_from_action_to_realtime_notification(self, requests): """ Test that when an action is created, it results in a realtime notification being sent. """ response = mock.Mock() response.status_code = 200 requests.put.return_value = response # Create a user u = UserFactory() # Register realtime notifications for that user on a question q = QuestionFactory() url = "http://example.com/simple_push/asdf" ct = ContentType.objects.get_for_model(q) RealtimeRegistration.objects.create( creator=u, endpoint=url, content_type=ct, object_id=q.id ) # Create an action involving that question action.send(UserFactory(), verb="looked at funny", action_object=q) a = Action.objects.order_by("-id")[0] # Assert that they got notified. requests.put.assert_called_once_with(url, "version={}".format(a.id))
def edit_folder(request, folder_id=None): """ Display and process a form for editing a given folder. """ folder = get_object_or_404(Folder, id=folder_id, file_manager__space=request.SPACE) if request.method == 'POST': form = FolderForm(request.POST, instance=folder, space=request.SPACE) if form.is_valid(): folder = save_files_form(request, form) actstream_action.send(sender=request.user, verb=_("was edited"), target=request.SPACE, action_object=folder) return redirect('spaces_files:index') else: form = FolderForm(instance=folder, space=request.SPACE) extra_context = base_extra_context(request) extra_context["form"] = form return render(request, 'spaces_files/add_folder.html', extra_context)
def follow(user, obj, send_action=False, 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 ) print("action of create: ",obj) print("user of create: ",user) if send_action and created: if not flag: print("created following") action.send(user, verb=_('started following'), target=obj, **kwargs) print("end created following") else: action.send(user, verb=_('started %s' % flag), target=obj, **kwargs) return instance
def follow(user, actor, send_action=True): """ Creates a ``User`` -> ``Actor`` follow relationship such that the actor's activities appear in the user's stream. Also sends the ``<user> started following <actor>`` action signal. Returns the created ``Follow`` instance. If ``send_action`` is false, no "started following" signal will be created Syntax:: follow(<user>, <actor>) Example:: follow(request.user, group) """ if send_action: action.send(user, verb=_('started following'), target=actor) return Follow.objects.create( user=user, object_id=actor.pk, content_type=ContentType.objects.get_for_model(actor))
def test_action_object(self): created = action.send(self.user1, verb='created comment', action_object=self.comment, target=self.group, timestamp=self.testdate)[0][1] self.assertEqual(created.actor, self.user1) self.assertEqual(created.action_object, self.comment) self.assertEqual(created.target, self.group) self.assertEqual( str(created), 'admin created comment admin: Sweet Group!... on ' 'CoolGroup %s ago' % self.timesince)
def activity_handler_quote_status_changed(sender, quote, **kwargs): action_verb = VERB_MAP_STATUS_CHANGE.get(quote.status, None) if action_verb: action_user = quote if quote.status == STATUS_SUBMITTED: action_user = quote.user elif quote.status in [STATUS_APPROVED, STATUS_DECLINED]: action_user = quote.moderated_by elif quote.status in [STATUS_ACCEPTED, STATUS_REJECTED]: action_user = quote.reviewed_by action.send(action_user or quote, verb=action_verb, action_object=quote, target=quote.task) if quote.status == STATUS_ACCEPTED: task = quote.task task.approved = True task.bid = quote.fee task.save() notify_estimate_status_email(quote.id, estimate_type='quote')
def add_file(request, parent_id=None): if request.method == 'POST': form = FileForm(request.POST, request.FILES, space=request.SPACE) n12n_formset = NotificationFormSet(request.SPACE, request.POST) if form.is_valid(): file = save_files_form(request, form) actstream_action.send(sender=request.user, verb=_("was created"), target=request.SPACE, action_object=file) messages.success(request, _("File successfully created.")) process_n12n_formset(n12n_formset, 'spaces_files_file_create', request.SPACE, file, file.get_absolute_url()) redirect_target = file.parent.get_absolute_url( ) if file.parent else 'spaces_files:index' return redirect(redirect_target) else: form = FileForm(initial={'parent': parent_id}, space=request.SPACE) n12n_formset = NotificationFormSet(request.SPACE) extra_context = base_extra_context(request) extra_context["form"] = form extra_context["notification_formset"] = n12n_formset return render(request, 'spaces_files/add_file.html', extra_context)
def unfollow(user, actor, send_action=False): """ Removes ``User`` -> ``Actor`` follow relationship. Optionally sends the ``<user> stopped following <actor>`` action signal. Syntax:: unfollow(<user>, <actor>) Example:: unfollow(request.user, other_user) """ from actstream.models import Follow check_actionable_model(actor) Follow.objects.filter( user=user, object_id=actor.pk, content_type=ContentType.objects.get_for_model(actor)).delete() if send_action: action.send(user, verb=_('stopped following'), target=actor)
def test_zombies(self): from random import choice, randint humans = [ User.objects.create(username='******' % i) for i in range(10) ] zombies = [ User.objects.create(username='******' % j) for j in range(2) ] while len(humans): for z in zombies: if not len(humans): break victim = choice(humans) humans.pop(humans.index(victim)) victim.save() zombies.append(victim) action.send(z, verb='killed', target=victim) self.assertEqual( map(unicode, model_stream(User))[:5], map(unicode, Action.objects.order_by('-timestamp')[:5]))
def _the_zombies_are_coming(self, nums={'human': 10, 'zombie': 2}): from random import choice player_generator = lambda n: [ User.objects.create(username='******' % (n, i)) for i in range(nums[n]) ] humans = player_generator('human') zombies = player_generator('zombie') while len(humans): for z in zombies: if not len(humans): break victim = choice(humans) humans.pop(humans.index(victim)) victim.save() zombies.append(victim) action.send(z, verb='killed', target=victim) self.assertEqual( Action.objects.filter(verb='killed').count(), nums['human'])
def post(self, request, *args, **kwargs): object = get_object_or_404(User, id=request.POST['object_id']) if request.POST['ftype'] == 'follow': try: if request.user == object: return HttpResponse('不能关注自己') else: f = Follow(user=request.user, follow_object=object) f.save() action.send(request.user, verb='关注了', action_object=object) return HttpResponse('成功') except: return HttpResponse('早已关注') else: try: get_object_or_404(Follow, user=request.user, follow_object=object).delete() return HttpResponse('成功') except: return HttpResponse('失败')
def form_valid(self, form): ret = super(SpaceCreate, self).form_valid(form) root_redirect = redirect('wiki:get', '') if isinstance(ret, HttpResponseRedirect) and root_redirect.url != ret.url: # super().form_valid successfully created a new article, # now get the new article and create our own WikiArticle instance # for proper integration. new_article = self.newpath.article wiki = SpacesWiki.objects.get(space=self.request.SPACE) wiki_article = WikiArticle.objects.create(article=new_article, wiki=wiki) # create dashboard notification actstream_action.send(sender=self.request.user, verb=_("was created"), target=self.request.SPACE, action_object=wiki_article) # set title and link for notification mail self.notification_object_title = new_article self.notification_object_link = new_article.get_absolute_url() self.send_notification() return ret
def activity_handler_new_connection(sender, instance, created, **kwargs): if created: action.send( instance.from_user, verb='made a connection request', action_object=instance, target=instance.to_user) else: update_fields = kwargs.get('update_fields', None) if update_fields: if 'accepted' in update_fields and instance.accepted: action.send(instance.to_user, verb='accepted a connection request', action_object=instance) elif 'responded' in update_fields and not instance.accepted: action.send(instance.to_user, verb='rejected a connection request', action_object=instance)
def activity_handler_new_connection(sender, instance, created, **kwargs): if created: action.send(instance.from_user, verb=verbs.CONNECT, action_object=instance, target=instance.to_user) else: update_fields = kwargs.get('update_fields', None) if update_fields: if 'status' in update_fields and instance.status == STATUS_ACCEPTED: action.send(instance.to_user, verb=verbs.ACCEPT, action_object=instance) elif 'status' in update_fields and not instance.status == STATUS_REJECTED: action.send(instance.to_user, verb=verbs.REJECT, action_object=instance)
def save(self, *args, **kwargs): import markdown from agora_site.agora_core.templatetags.string_tags import urlify_markdown from django.template.defaultfilters import truncatewords_html election = super(CreateElectionForm, self).save(commit=False) election.agora = self.agora election.create_name() election.uuid = str(uuid.uuid4()) election.created_at_date = timezone.now() election.creator = self.request.user short_md = markdown.markdown(urlify_markdown( election.description[:140]), safe_mode="escape", enable_attributes=False) election.short_description = truncatewords_html(short_md, 25)[:140] election.url = self.request.build_absolute_uri( reverse('election-view', kwargs=dict(username=election.agora.creator.username, agoraname=election.agora.name, electionname=election.name))) election.questions = self.cleaned_data['questions'] election.election_type = election.questions[0]['tally_type'] election.comments_policy = self.agora.comments_policy if ("from_date" in self.cleaned_data) and ("to_date" in self.cleaned_data): from_date = self.cleaned_data["from_date"] to_date = self.cleaned_data["to_date"] election.voting_starts_at_date = from_date election.voting_extended_until_date = election.voting_ends_at_date = to_date # Anyone can create a voting for a given agora, but if you're not the # admin, it must be approved if election.creator in election.agora.admins.all(): election.is_approved = True election.approved_at_date = timezone.now() else: election.is_approved = False election.save() # create related action verb = 'created' if election.is_approved else 'proposed' actstream_action.send(self.request.user, verb=verb, action_object=election, target=election.agora, ipaddr=self.request.META.get('REMOTE_ADDR'), geolocation=json.dumps( geolocate_ip( self.request.META.get('REMOTE_ADDR')))) # send email to admins context = get_base_email_context(self.request) context.update( dict( election=election, action_user_url='/%s' % election.creator.username, )) for admin in election.agora.admins.all(): context['to'] = admin if not admin.has_perms('receive_email_updates'): continue translation.activate(admin.get_profile().lang_code) email = EmailMultiAlternatives( subject=_('Election %s created') % election.pretty_name, body=render_to_string('agora_core/emails/election_created.txt', context), to=[admin.email]) email.attach_alternative( render_to_string('agora_core/emails/election_created.html', context), "text/html") email.send() translation.deactivate() follow(self.request.user, election, actor_only=False, request=self.request) # used for tasks kwargs = dict(election_id=election.id, is_secure=self.request.is_secure(), site_id=Site.objects.get_current().id, remote_addr=self.request.META.get('REMOTE_ADDR'), user_id=self.request.user.id) # send email to admins send_election_created_mails.apply_async( kwargs=kwargs, task_id=election.task_id(send_election_created_mails)) # schedule start and end of the election. note that if election is not # approved, the start and end of the election won't really happen if from_date and to_date: start_election.apply_async( kwargs=kwargs, task_id=election.task_id(start_election), eta=election.voting_starts_at_date) end_election.apply_async(kwargs=kwargs, task_id=election.task_id(end_election), eta=election.voting_ends_at_date) return election
def form_valid(self, form): response = super().form_valid(form) action.send(sender=self.request.user, verb='写了新章节', action_object=self.object) return response
def activity_handler_task_applications_closed(sender, task, **kwargs): if not task.apply: action.send(task.user, verb=verbs.CLOSE_APPLY, target=task) send_task_application_not_selected_email.delay(task.id)
def activity_handler_task_closed(sender, task, **kwargs): if task.closed: action.send(task.user, verb=verbs.CLOSE, target=task)
def activity_handler_integration_activity(sender, instance, created, **kwargs): if created: action.send(instance.integration, verb=verbs.REPORT, action_object=instance, target=instance.integration.task)
def activity_handler_new_task(sender, instance, created, **kwargs): if created: action.send(instance.user, verb=verbs.CREATE, action_object=instance) initialize_task_progress_events.delay(instance.id)
def activity_handler_progress_report(sender, instance, created, **kwargs): if created: action.send(instance.user, verb=verbs.REPORT, action_object=instance, target=instance.event) notify_new_progress_report.delay(instance.id)
def activity_handler_integration(sender, instance, created, **kwargs): if created: action.send(instance.created_by, verb=verbs.INTEGRATE, action_object=instance, target=instance.task)
def activity_handler_progress_event(sender, instance, created, **kwargs): if created: action.send( instance.created_by or instance.task.user, verb=verbs.CREATE, action_object=instance, target=instance.task )
def activity_handler_quote(sender, instance, created, **kwargs): if created: action.send( instance.user, verb=verbs.CREATE, action_object=instance, target=instance.task )
def save(self, *args, **kwargs): # invalidate older votes from the same voter to the same election old_votes = self.election.cast_votes.filter(is_direct=True, invalidated_at_date=None, voter=self.request.user) for old_vote in old_votes: old_vote.invalidated_at_date = timezone.now() old_vote.is_counted = False old_vote.save() vote = super(VoteForm, self).save(commit=False) data = { "a": "vote", "answers": [], "election_hash": { "a": "hash/sha256/value", "value": self.election.hash }, "election_uuid": self.election.uuid } i = 0 for question in self.election.questions: data["answers"] += [{ "a": "plaintext-answer", "choices": [self.cleaned_data['question%d' % i]], }] i += 1 if self.request.user not in self.election.agora.members.all(): if self.election.agora.has_perms('join', self.request.user): # Join agora if possible from agora_site.agora_core.views import AgoraActionJoinView AgoraActionJoinView().post( self.request, self.election.agora.creator.username, self.election.agora.name) vote.voter = self.request.user vote.election = self.election vote.is_counted = self.request.user in self.election.agora.members.all( ) vote.is_direct = True if self.election.is_vote_secret and ('submit-secret' in self.request.POST) and\ (self.request.user in self.election.agora.members.all() or\ self.election.agora.has_perms('join', self.request.user)): vote.is_public = False vote.reason = None else: vote.reason = self.cleaned_data['reason'] vote.is_public = True vote.data = data vote.casted_at_date = timezone.now() vote.create_hash() actstream_action.send(self.request.user, verb='voted', action_object=self.election, target=self.election.agora, geolocation=json.dumps( geolocate_ip( self.request.META.get('REMOTE_ADDR')))) vote.action_id = Action.objects.filter( actor_object_id=self.request.user.id, verb='voted', action_object_object_id=self.election.id, target_object_id=self.election.agora.id).order_by( '-timestamp').all()[0].id vote.save() return vote
def setUp(self): self.testdate = datetime(2000, 1, 1) self.timesince = timesince(self.testdate).encode('utf8').replace( b'\xc2\xa0', b' ').decode() self.group_ct = ContentType.objects.get_for_model(Group) super(DataTestCase, self).setUp() self.group = Group.objects.create(name='CoolGroup') self.another_group = Group.objects.create(name='NiceGroup') if 'email' in getargspec(self.User.objects.create_superuser).args: self.user1 = self.User.objects.create_superuser( 'admin', '*****@*****.**', 'admin') self.user2 = self.User.objects.create_user('Two', '*****@*****.**') self.user3 = self.User.objects.create_user('Three', '*****@*****.**') self.user4 = self.User.objects.create_user('Four', '*****@*****.**') else: self.user1 = self.User.objects.create_superuser('admin', 'admin') self.user2 = self.User.objects.create_user('Two') self.user3 = self.User.objects.create_user('Three') self.user4 = self.User.objects.create_user('Four') # User1 joins group self.user1.groups.add(self.group) self.join_action = action.send(self.user1, verb='joined', target=self.group, timestamp=self.testdate)[0][1] # User1 follows User2 follow(self.user1, self.user2, timestamp=self.testdate) # User2 joins group self.user2.groups.add(self.group) action.send(self.user2, verb='joined', target=self.group, timestamp=self.testdate) # User2 follows group follow(self.user2, self.group, timestamp=self.testdate) # User1 comments on group # Use a site object here and predict the "__unicode__ method output" action.send(self.user1, verb='commented on', target=self.group, timestamp=self.testdate) self.comment = Site.objects.create(domain="admin: Sweet Group!...") # Group responds to comment action.send(self.group, verb='responded to', target=self.comment, timestamp=self.testdate) # User 3 did something but doesn't following someone action.send(self.user3, verb='liked actstream', timestamp=self.testdate) # User4 likes group follow(self.user4, self.another_group, timestamp=self.testdate, flag='liking') # User4 watches group follow(self.user4, self.another_group, timestamp=self.testdate, flag='watching') # User4 likes User1 follow(self.user4, self.user1, timestamp=self.testdate, flag='liking') # User4 blacklist user3 follow(self.user4, self.user3, timestamp=self.testdate, flag='blacklisting')
def activity_handler_task_payment_approved(sender, task, **kwargs): if task.payment_approved: action.send(task.payment_approved_by, verb=verbs.APPROVE_PAYMENT, target=task) notify_payment_link_client_email.delay(task.id)