def test_get_mentions_two_mentions_multiline(self):
     text = "Hello [url=https://www.astrobin.com/users/foo/]@Foo Smith[/url]\nHello " \
            "[url=https://www.astrobin.com/users/bar/]@Bar Test[/url]"
     mentions = MentionsService.get_mentions(text)
     self.assertTrue("foo" in mentions)
     self.assertTrue("bar" in mentions)
 def test_get_mentions_no_www(self):
     text = "Hello [url=https://astrobin.com/users/foo/]@Foo Bar[/url]"
     self.assertEqual(["foo"], MentionsService.get_mentions(text))
 def test_get_mentions_localhost_and_port(self):
     text = "Hello [url=http://localhost:8084/users/foo/]@Foo Bar[/url]"
     self.assertEqual(["foo"], MentionsService.get_mentions(text))
Beispiel #4
0
    def send_notifications(self, force=False):
        if self.comment.pending_moderation and not force:
            return

        instance = self.comment

        model_class = instance.content_type.model_class()
        obj = instance.content_type.get_object_for_this_type(id=instance.object_id)
        object_owner = None
        notification = None
        mentions = MentionsService.get_mentions(instance.text)
        url = None

        if model_class == Image:
            object_owner = obj.user
            notification = 'new_comment'
            url = settings.BASE_URL + instance.get_absolute_url()
        elif hasattr(model_class, 'edit_proposal_by'):
            object_owner = obj.edit_proposal_by
            notification = 'new_comment_to_edit_proposal'
            url = instance.get_absolute_url()
        elif model_class == Iotd:
            object_owner = obj.judge
            notification = 'new_comment_to_scheduled_iotd'
            url = AppRedirectionService.redirect(f'/iotd/judgement-queue#comments-{obj.pk}-{instance.pk}')

        if UserService(object_owner).shadow_bans(instance.author):
            log.info("Skipping notification for comment because %d shadow-bans %d" % (
                object_owner.pk, instance.author.pk))
            return

        exclude = MentionsService.get_mentioned_users_with_notification_enabled(mentions, 'new_comment_mention')

        if instance.parent and \
                instance.parent.author != instance.author and \
                not instance.pending_moderation:
            recipients = [x for x in [instance.parent.author] if x not in exclude]
            if recipients:
                push_notification(
                    recipients, instance.author, 'new_comment_reply',
                    {
                        'url': build_notification_url(url, instance.author),
                        'user': instance.author.userprofile.get_display_name(),
                        'user_url': settings.BASE_URL + reverse(
                            'user_page', kwargs={'username': instance.author.username}
                        ),
                    }
                )

        if model_class == Image:
            if (force or not instance.pending_moderation) and not obj.is_wip:
                add_story(instance.author,
                          verb='VERB_COMMENTED_IMAGE',
                          action_object=instance,
                          target=obj)

        if object_owner and notification:
            if instance.author != object_owner and \
                    (instance.parent is None or instance.parent.author != object_owner) and \
                    not instance.pending_moderation:
                recipients = [x for x in [object_owner] if x not in exclude]
                if recipients:
                    push_notification(
                        recipients, instance.author, notification,
                        {
                            'url': build_notification_url(url, instance.author),
                            'user': instance.author.userprofile.get_display_name(),
                            'user_url': settings.BASE_URL + reverse(
                                'user_page', kwargs={'username': instance.author.username}
                            ),
                        }
                    )
 def test_get_mentions_no_mentions(self):
     self.assertEqual([], MentionsService.get_mentions("hello"))
Beispiel #6
0
def image_post_save(sender, instance, created, **kwargs):
    # type: (object, Image, bool, object) -> None

    if created:
        instance.user.userprofile.premium_counter += 1
        instance.user.userprofile.save(keep_deleted=True)

        if not instance.is_wip:
            if not instance.skip_notifications:
                push_notification_for_new_image.apply_async(args=(
                    instance.user.pk,
                    instance.pk,
                ))
            if instance.moderator_decision == 1:
                add_story(instance.user,
                          verb='VERB_UPLOADED_IMAGE',
                          action_object=instance)

        if Image.all_objects.filter(user=instance.user).count() == 1:
            push_notification(
                [instance.user], None, 'congratulations_for_your_first_image',
                {
                    'BASE_URL': settings.BASE_URL,
                    'PREMIUM_MAX_IMAGES_FREE':
                    settings.PREMIUM_MAX_IMAGES_FREE,
                    'url': reverse_url('image_detail',
                                       args=(instance.get_id(), ))
                })

        mentions = MentionsService.get_mentions(instance.description_bbcode)
    else:
        mentions = cache.get("image.%d.image_pre_save_mentions" % instance.pk,
                             [])

    for username in mentions:
        user = get_object_or_None(User, username=username)
        if not user:
            try:
                profile = get_object_or_None(UserProfile, real_name=username)
                if profile:
                    user = profile.user
            except MultipleObjectsReturned:
                user = None
        if user and user != instance.user:
            thumb = instance.thumbnail_raw('gallery', None, sync=True)
            push_notification(
                [user], instance.user, 'new_image_description_mention', {
                    'image':
                    instance,
                    'image_thumbnail':
                    thumb.url if thumb else None,
                    'url':
                    build_notification_url(
                        settings.BASE_URL + instance.get_absolute_url(),
                        instance.user),
                    'user':
                    instance.user.userprofile.get_display_name(),
                    'user_url':
                    settings.BASE_URL + reverse_url(
                        'user_page', kwargs={'username': instance.user}),
                })

    if not instance.uploader_in_progress:
        groups = instance.user.joined_group_set.filter(autosubmission=True)
        for group in groups:
            if instance.is_wip:
                group.images.remove(instance)
            else:
                group.images.add(instance)

        if instance.user.userprofile.updated < datetime.datetime.now(
        ) - datetime.timedelta(minutes=5):
            instance.user.save()
            try:
                instance.user.userprofile.save(keep_deleted=True)
            except UserProfile.DoesNotExist:
                pass

        UserService(instance.user).clear_gallery_image_list_cache()

        if instance.user.userprofile.auto_submit_to_iotd_tp_process:
            IotdService.submit_to_iotd_tp_process(instance.user, instance,
                                                  False)
Beispiel #7
0
def forum_post_post_save(sender, instance, created, **kwargs):
    def notify_subscribers(mentions):
        # type: (List[str]) -> None
        recipients = list(
            instance.topic.subscribers.exclude(pk__in=list(
                set([instance.user.pk] + [
                    x.pk for x in MentionsService.
                    get_mentioned_users_with_notification_enabled(
                        mentions, 'new_forum_post_mention')
                ]))))

        if recipients:
            push_notification(
                recipients, instance.user, 'new_forum_reply', {
                    'user':
                    instance.user.userprofile.get_display_name(),
                    'user_url':
                    settings.BASE_URL + reverse_url(
                        'user_page', kwargs={'username': instance.user}),
                    'post_url':
                    build_notification_url(
                        settings.BASE_URL + instance.get_absolute_url(),
                        instance.user),
                    'topic_url':
                    build_notification_url(
                        settings.BASE_URL + instance.topic.get_absolute_url(),
                        instance.user),
                    'topic_name':
                    instance.topic.name,
                    'unsubscribe_url':
                    build_notification_url(
                        settings.BASE_URL +
                        reverse_url('pybb:delete_subscription',
                                    args=[instance.topic.id]), instance.user)
                })

    def notify_mentioned(mentions):
        # type: (List[str]) -> None
        for username in mentions:
            user = get_object_or_None(User, username=username)
            if user is None:
                try:
                    profile = get_object_or_None(UserProfile,
                                                 real_name=username)
                    if profile:
                        user = profile.user
                except MultipleObjectsReturned:
                    user = None
            if user:
                push_notification(
                    [user], instance.user, 'new_forum_post_mention', {
                        'url':
                        build_notification_url(
                            settings.BASE_URL + instance.get_absolute_url(),
                            instance.user),
                        'user':
                        instance.user.userprofile.get_display_name(),
                        'user_url':
                        settings.BASE_URL + reverse_url(
                            'user_page', kwargs={'username': instance.user}),
                        'post':
                        instance.topic.name,
                    })

    if created:
        if hasattr(instance.topic.forum, 'group'):
            instance.topic.forum.group.save()  # trigger date_updated update

        if get_pybb_profile(instance.user).autosubscribe and \
                perms.may_subscribe_topic(instance.user, instance.topic):
            instance.topic.subscribers.add(instance.user)

        mentions = MentionsService.get_mentions(instance.body)
        if not instance.on_moderation:
            notify_subscribers(mentions)
            notify_mentioned(mentions)
        else:
            NotificationsService.email_superusers(
                'New forum post needs moderation',
                '%s%s' % (settings.BASE_URL, instance.get_absolute_url()))

    else:
        mentions = cache.get(
            "post.%d.forum_post_pre_save_mentions" % instance.pk, [])
        cache.delete("post.%d.forum_post_pre_save_mentions" % instance.pk)
        if cache.get("post.%d.forum_post_pre_save_approved" % instance.pk):
            push_notification(
                [instance.user], None, 'forum_post_approved', {
                    'url':
                    build_notification_url(settings.BASE_URL +
                                           instance.get_absolute_url())
                })
            notify_subscribers(mentions)
            notify_mentioned(mentions)
            cache.delete("post.%d.forum_post_pre_save_approved" % instance.pk)

    cache_key = make_template_fragment_key(
        'home_page_latest_from_forums',
        (instance.user.pk, instance.user.userprofile.language))
    cache.delete(cache_key)
Beispiel #8
0
def nested_comment_post_save(sender, instance, created, **kwargs):
    if created:
        model_class = instance.content_type.model_class()
        obj = instance.content_type.get_object_for_this_type(
            id=instance.object_id)
        url = settings.BASE_URL + instance.get_absolute_url()
        mentions = MentionsService.get_mentions(instance.text)

        if model_class == Image:
            image = instance.content_type.get_object_for_this_type(
                id=instance.object_id)
            if image.is_wip:
                return

            if UserService(obj.user).shadow_bans(instance.author):
                log.info(
                    "Skipping notification for comment because %d shadow-bans %d"
                    % (obj.user.pk, instance.author.pk))
                return

            if instance.author != obj.user:
                push_notification(
                    [obj.user], 'new_comment', {
                        'url':
                        url,
                        'user':
                        instance.author.userprofile.get_display_name(),
                        'user_url':
                        settings.BASE_URL + reverse_url(
                            'user_page',
                            kwargs={'username': instance.author.username}),
                    })

            if instance.parent and instance.parent.author != instance.author:
                push_notification(
                    [instance.parent.author], 'new_comment_reply', {
                        'url':
                        url,
                        'user':
                        instance.author.userprofile.get_display_name(),
                        'user_url':
                        settings.BASE_URL + reverse_url(
                            'user_page',
                            kwargs={'username': instance.author.username}),
                    })

            add_story(instance.author,
                      verb='VERB_COMMENTED_IMAGE',
                      action_object=instance,
                      target=obj)

        elif model_class == Gear:
            if not instance.parent:
                gear, gear_type = get_correct_gear(obj.id)
                user_attr_lookup = {
                    'Telescope': 'telescopes',
                    'Camera': 'cameras',
                    'Mount': 'mounts',
                    'FocalReducer': 'focal_reducers',
                    'Software': 'software',
                    'Filter': 'filters',
                    'Accessory': 'accessories',
                }

                recipients = [
                    x.user for x in UserProfile.objects.filter(
                        **{user_attr_lookup[gear_type]: gear})
                ]
                notification = 'new_gear_discussion'
            else:
                notification = 'new_comment_reply'
                recipients = [instance.parent.author]

            push_notification(
                recipients, notification, {
                    'url':
                    url,
                    'user':
                    instance.author.userprofile.get_display_name(),
                    'user_url':
                    settings.BASE_URL +
                    reverse_url('user_page',
                                kwargs={'username': instance.author.username}),
                })

            add_story(instance.author,
                      verb='VERB_COMMENTED_GEAR',
                      action_object=instance,
                      target=gear)

        if hasattr(instance.content_object, "updated"):
            # This will trigger the auto_now fields in the content_object
            # We do it only if created, because the content_object needs to
            # only be updated if the number of comments changes.
            instance.content_object.save(keep_deleted=True)
    else:
        mentions = cache.get(
            "user.%d.comment_pre_save_mentions" % instance.author.pk, [])

    for username in mentions:
        try:
            user = User.objects.get(username=username)
            push_notification(
                [user], 'new_comment_mention', {
                    'url':
                    settings.BASE_URL + instance.get_absolute_url(),
                    'user':
                    instance.author.userprofile.get_display_name(),
                    'user_url':
                    settings.BASE_URL + reverse_url(
                        'user_page', kwargs={'username': instance.author}),
                })
        except User.DoesNotExist:
            pass
 def test_get_mentions_empty_string(self):
     self.assertEquals([], MentionsService.get_mentions(""))
 def test_get_mentions_unique_mentions(self):
     text = "Hello [url=https://www.astrobin.com/users/foo/]@Foo Smith[/url] and [url=https://www.astrobin.com/users/foo/]@Foo Smith[/url]"
     self.assertEquals(["foo"], MentionsService.get_mentions(text))
 def test_get_mentions_two_mentions_multiline(self):
     text = "Hello [url=https://www.astrobin.com/users/foo/]@Foo Smith[/url]\nHello [url=https://www.astrobin.com/users/bar/]@Bar Test[/url]"
     self.assertEquals(["foo", "bar"], MentionsService.get_mentions(text))
Beispiel #12
0
def forum_post_post_save(sender, instance, created, **kwargs):
    def notify_subscribers():
        push_notification(
            list(instance.topic.subscribers.exclude(pk=instance.user.pk)),
            instance.user, 'new_forum_reply', {
                'user':
                instance.user.userprofile.get_display_name(),
                'user_url':
                settings.BASE_URL +
                reverse_url('user_page', kwargs={'username': instance.user}),
                'post_url':
                build_notification_url(
                    settings.BASE_URL + instance.get_absolute_url(),
                    instance.user),
                'topic_url':
                build_notification_url(
                    settings.BASE_URL + instance.topic.get_absolute_url(),
                    instance.user),
                'topic_name':
                instance.topic.name,
                'unsubscribe_url':
                build_notification_url(
                    settings.BASE_URL + reverse_url('pybb:delete_subscription',
                                                    args=[instance.topic.id]),
                    instance.user)
            })

    if created:
        mentions = MentionsService.get_mentions(instance.body)

        if hasattr(instance.topic.forum, 'group'):
            instance.topic.forum.group.save()  # trigger date_updated update

        if get_pybb_profile(instance.user).autosubscribe and \
                perms.may_subscribe_topic(instance.user, instance.topic):
            instance.topic.subscribers.add(instance.user)

        if not instance.on_moderation:
            notify_subscribers()
        else:
            NotificationsService.email_superusers(
                'New forum post needs moderation',
                '%s%s' % (settings.BASE_URL, instance.get_absolute_url()))

    else:
        mentions = cache.get(
            "user.%d.forum_post_pre_save_mentions" % instance.user.pk, [])

        if cache.get("user.%d.forum_post_pre_save_approved" %
                     instance.user.pk):
            notify_subscribers()

    for username in mentions:
        try:
            user = User.objects.get(username=username)
            push_notification(
                [user], instance.user, 'new_forum_post_mention', {
                    'url':
                    build_notification_url(
                        settings.BASE_URL + instance.get_absolute_url(),
                        instance.user),
                    'user':
                    instance.user.userprofile.get_display_name(),
                    'user_url':
                    settings.BASE_URL + reverse_url(
                        'user_page', kwargs={'username': instance.user}),
                    'post':
                    instance.topic.name,
                })
        except User.DoesNotExist:
            pass

    cache_key = make_template_fragment_key(
        'home_page_latest_from_forums',
        (instance.user.pk, instance.user.userprofile.language))
    cache.delete(cache_key)