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) )
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)
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)
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, } }, ) )
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)
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, )
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, } }, ))