Esempio n. 1
0
    def assert_loid(self, create=True, new=True):
        loid = LoId.load(self.request, self.context, create=create)
        self.assertIsNotNone(loid.loid)
        self.assertIsNotNone(loid.created)
        self.assertIs(loid.new, new)

        loid.save()

        if not new:
            self.assertFalse(bool(self.context.cookies.add.called))
            g.events.queue_production.assert_item_count(0)
        else:
            self.context.cookies.add.assert_has_calls(
                [
                    call(LOID_COOKIE, quote(loid.loid), expires=ANY),
                    call(LOID_CREATED_COOKIE, to_isodate(loid.created), expires=ANY),
                ]
            )
            payload = self.make_event_payload()
            payload.update(
                {
                    "loid_new": True,
                    "loid": loid.loid,
                    "loid_created": to_epoch_milliseconds(loid.created),
                    "loid_version": 0,
                }
            )
            g.events.queue_production.assert_event_item(
                dict(event_topic="loid_events", event_type="ss.create_loid", payload=payload)
            )
Esempio n. 2
0
    def comment_event(self, new_comment, request=None, context=None):
        """Create a 'comment' event for event-collector.

        new_comment: An r2.models.Comment object
        request, context: Should be pylons.request & pylons.c respectively
        """
        from r2.models import Comment, Link

        event = Event(
            topic="comment_events",
            event_type="ss.comment",
            time=new_comment._date,
            request=request,
            context=context,
            truncatable_field="comment_body",
        )

        event.add("comment_id", new_comment._id)
        event.add("comment_fullname", new_comment._fullname)

        event.add_text("comment_body", new_comment.body)

        post = Link._byID(new_comment.link_id)
        event.add("post_id", post._id)
        event.add("post_fullname", post._fullname)
        event.add("post_created_ts", to_epoch_milliseconds(post._date))
        if post.promoted:
            event.add("post_is_promoted", bool(post.promoted))

        if new_comment.parent_id:
            parent = Comment._byID(new_comment.parent_id)
        else:
            # If this is a top-level comment, parent is the same as the post
            parent = post
        event.add("parent_id", parent._id)
        event.add("parent_fullname", parent._fullname)
        event.add("parent_created_ts", to_epoch_milliseconds(parent._date))

        event.add("user_neutered", new_comment.author_slow._spam)

        event.add_subreddit_fields(new_comment.subreddit_slow)

        self.save_event(event)
Esempio n. 3
0
    def comment_event(self, new_comment, request=None, context=None):
        """Create a 'comment' event for event-collector.

        new_comment: An r2.models.Comment object
        request, context: Should be pylons.request & pylons.c respectively
        """
        from r2.models import Comment, Link

        event = Event(
            topic="comment_events",
            event_type="ss.comment",
            time=new_comment._date,
            request=request,
            context=context,
            truncatable_field="comment_body",
        )

        event.add("comment_id", new_comment._id)
        event.add("comment_fullname", new_comment._fullname)

        event.add_text("comment_body", new_comment.body)

        post = Link._byID(new_comment.link_id)
        event.add("post_id", post._id)
        event.add("post_fullname", post._fullname)
        event.add("post_created_ts", to_epoch_milliseconds(post._date))
        if post.promoted:
            event.add("post_is_promoted", bool(post.promoted))

        if new_comment.parent_id:
            parent = Comment._byID(new_comment.parent_id)
        else:
            # If this is a top-level comment, parent is the same as the post
            parent = post
        event.add("parent_id", parent._id)
        event.add("parent_fullname", parent._fullname)
        event.add("parent_created_ts", to_epoch_milliseconds(parent._date))

        event.add("user_neutered", new_comment.author_slow._spam)

        event.add_subreddit_fields(new_comment.subreddit_slow)

        self.save_event(event)
Esempio n. 4
0
    def vote_event(self, vote):
        """Create a 'vote' event for event-collector

        vote: An r2.models.vote Vote object
        """

        # For mapping vote directions to readable names used by data team
        def get_vote_direction_name(vote):
            if vote.is_upvote:
                return "up"
            elif vote.is_downvote:
                return "down"
            else:
                return "clear"

        event = Event(
            topic="vote_server",
            event_type="server_vote",
            time=vote.date,
            data=vote.event_data["context"],
            obfuscated_data=vote.event_data["sensitive"],
        )

        event.add("vote_direction", get_vote_direction_name(vote))

        if vote.previous_vote:
            event.add("prev_vote_direction",
                get_vote_direction_name(vote.previous_vote))
            event.add(
                "prev_vote_ts",
                to_epoch_milliseconds(vote.previous_vote.date)
            )

        if vote.is_automatic_initial_vote:
            event.add("auto_self_vote", True)

        for name, value in vote.effects.serializable_data.iteritems():
            # rename the "notes" field to "details_text" for the event
            if name == "notes":
                name = "details_text"

            event.add(name, value)

        # add the note codes separately as "process_notes"
        event.add("process_notes", ", ".join(vote.effects.note_codes))

        event.add_subreddit_fields(vote.thing.subreddit_slow)
        event.add_target_fields(vote.thing)

        # add the rank of the vote if we have it (passed in through the API)
        rank = vote.data.get('rank')
        if rank:
            event.add("target_rank", rank)

        self.save_event(event)
Esempio n. 5
0
    def test_ftue_autocreate(self):
        request = MagicMock()
        context = MagicMock()
        request.cookies = {}
        loid = LoId.load(request, create=True)
        self.assertIsNotNone(loid.loid)
        self.assertIsNotNone(loid.created)
        self.assertTrue(loid.new)

        loid.save()

        context.cookies.add.assert_has_calls([
            call(
                LOID_COOKIE,
                quote(loid.loid),
                expires=ANY,
            ),
            call(
                LOID_CREATED_COOKIE,
                isodate(loid.created),
                expires=ANY,
            )
        ])
        self.amqp.assert_event_item(
            dict(
                event_topic="loid_events",
                event_type="ss.create_loid",
                payload={
                    'loid_new': True,
                    'loid': loid.loid,
                    'loid_created': to_epoch_milliseconds(loid.created),
                    'loid_version': 0,

                    'user_id': context.user._id,
                    'user_name': context.user.name,
                    'user_features': context.user.user_features,

                    'request_url': request.fullpath,
                    'domain': request.host,
                    'geoip_country': context.location,
                    'oauth2_client_id': context.oauth2_client._id,
                    'oauth2_client_app_type': context.oauth2_client.app_type,
                    'oauth2_client_name': context.oauth2_client.name,
                    'referrer_domain': self.domain_mock(),
                    'referrer_url': request.headers.get(),
                    'user_agent': request.user_agent,
                    'user_agent_parsed': request.parsed_agent.to_dict(),
                    'obfuscated_data': {
                        'client_ip': request.ip,
                    }
                },
            )
        )
Esempio n. 6
0
    def vote_event(self, vote):
        """Create a 'vote' event for event-collector

        vote: An r2.models.vote Vote object
        """

        # For mapping vote directions to readable names used by data team
        def get_vote_direction_name(vote):
            if vote.is_upvote:
                return "up"
            elif vote.is_downvote:
                return "down"
            else:
                return "clear"

        event = Event(
            topic="vote_server",
            event_type="server_vote",
            time=vote.date,
            data=vote.event_data["context"],
            obfuscated_data=vote.event_data["sensitive"],
        )

        event.add("vote_direction", get_vote_direction_name(vote))

        if vote.previous_vote:
            event.add("prev_vote_direction",
                      get_vote_direction_name(vote.previous_vote))
            event.add("prev_vote_ts",
                      to_epoch_milliseconds(vote.previous_vote.date))

        if vote.is_automatic_initial_vote:
            event.add("auto_self_vote", True)

        for name, value in vote.effects.serializable_data.iteritems():
            # rename the "notes" field to "details_text" for the event
            if name == "notes":
                name = "details_text"

            event.add(name, value)

        # add the note codes separately as "process_notes"
        event.add("process_notes", ", ".join(vote.effects.note_codes))

        event.add_subreddit_fields(vote.thing.subreddit_slow)
        event.add_target_fields(vote.thing)

        # add the rank of the vote if we have it (passed in through the API)
        rank = vote.data.get('rank')
        if rank:
            event.add("target_rank", rank)

        self.save_event(event)
Esempio n. 7
0
    def add_target_fields(self, target):
        if not target:
            return
        from r2.models import Comment, Link, Message

        self.add("target_id", target._id)
        self.add("target_fullname", target._fullname)
        self.add("target_age_seconds", target._age.total_seconds())

        target_type = target.__class__.__name__.lower()
        if target_type == "link" and target.is_self:
            target_type = "self"
        self.add("target_type", target_type)

        # If the target is an Account or Subreddit (or has a "name" attr),
        # add the target_name
        if hasattr(target, "name"):
            self.add("target_name", target.name)

        # Add info about the target's author for comments, links, & messages
        if isinstance(target, (Comment, Link, Message)):
            author = target.author_slow
            if target._deleted or author._deleted:
                self.add("target_author_id", 0)
                self.add("target_author_name", "[deleted]")
            else:
                self.add("target_author_id", author._id)
                self.add("target_author_name", author.name)

        # Add info about the url being linked to for link posts
        if isinstance(target, Link):
            self.add_text("target_title", target.title)
            if not target.is_self:
                self.add("target_url", target.url)
                self.add("target_url_domain", target.link_domain())

        # Add info about the link being commented on for comments
        if isinstance(target, Comment):
            link_fullname = Link._fullname_from_id36(to36(target.link_id))
            self.add("link_id", target.link_id)
            self.add("link_fullname", link_fullname)

        # Add info about when target was originally posted for links/comments
        if isinstance(target, (Comment, Link)):
            self.add("target_created_ts", to_epoch_milliseconds(target._date))

        hooks.get_hook("eventcollector.add_target_fields").call(
            event=self,
            target=target,
        )
Esempio n. 8
0
    def add_target_fields(self, target):
        if not target:
            return
        from r2.models import Comment, Link, Message

        self.add("target_id", target._id)
        self.add("target_fullname", target._fullname)
        self.add("target_age_seconds", target._age.total_seconds())

        target_type = target.__class__.__name__.lower()
        if target_type == "link" and target.is_self:
            target_type = "self"
        self.add("target_type", target_type)

        # If the target is an Account or Subreddit (or has a "name" attr),
        # add the target_name
        if hasattr(target, "name"):
            self.add("target_name", target.name)

        # Add info about the target's author for comments, links, & messages
        if isinstance(target, (Comment, Link, Message)):
            author = target.author_slow
            if target._deleted or author._deleted:
                self.add("target_author_id", 0)
                self.add("target_author_name", "[deleted]")
            else:
                self.add("target_author_id", author._id)
                self.add("target_author_name", author.name)

        # Add info about the url being linked to for link posts
        if isinstance(target, Link):
            self.add_text("target_title", target.title)
            if not target.is_self:
                self.add("target_url", target.url)
                self.add("target_url_domain", target.link_domain())

        # Add info about the link being commented on for comments
        if isinstance(target, Comment):
            link_fullname = Link._fullname_from_id36(to36(target.link_id))
            self.add("link_id", target.link_id)
            self.add("link_fullname", link_fullname)

        # Add info about when target was originally posted for links/comments
        if isinstance(target, (Comment, Link)):
            self.add("target_created_ts", to_epoch_milliseconds(target._date))

        hooks.get_hook("eventcollector.add_target_fields").call(
            event=self,
            target=target,
        )
Esempio n. 9
0
    def test_ftue_autocreate(self):
        request = MagicMock()
        context = MagicMock()
        request.cookies = {}
        loid = LoId.load(request, create=True)
        self.assertIsNotNone(loid.loid)
        self.assertIsNotNone(loid.created)
        self.assertTrue(loid.new)

        loid.save()

        context.cookies.add.assert_has_calls([
            call(
                LOID_COOKIE,
                quote(loid.loid),
                expires=ANY,
            ),
            call(
                LOID_CREATED_COOKIE,
                isodate(loid.created),
                expires=ANY,
            )
        ])
        self.amqp.assert_event_item(
            dict(
                event_topic="loid_events",
                event_type="ss.create_loid",
                payload={
                    'loid_new': True,
                    'loid': loid.loid,
                    'loid_created': to_epoch_milliseconds(loid.created),
                    'loid_version': 0,
                    'user_id': context.user._id,
                    'user_name': context.user.name,
                    'user_features': context.user.user_features,
                    'request_url': request.fullpath,
                    'domain': request.host,
                    'geoip_country': context.location,
                    'oauth2_client_id': context.oauth2_client._id,
                    'oauth2_client_app_type': context.oauth2_client.app_type,
                    'oauth2_client_name': context.oauth2_client.name,
                    'referrer_domain': self.domain_mock(),
                    'referrer_url': request.headers.get(),
                    'user_agent': request.user_agent,
                    'user_agent_parsed': request.parsed_agent.to_dict(),
                    'obfuscated_data': {
                        'client_ip': request.ip,
                    }
                },
            ))