Esempio n. 1
0
    def get_suggestions(self, feedback, request=None):
        # Note: This implementation assumes there aren't a fajillion
        # active rules. If that becomes a problem, we should
        # re-architect the db so that this is easier to implement.
        #
        # Further, each matching rule will kick off a GA event
        # request. We have to do those synchronously so that we're
        # guaranteed to have the "suggest" event before the "click"
        # event. Otherwise the data is not as meaningful.

        rules = TriggerRule.objects.all_enabled()
        links = []

        # Go through the rules and accrue links until we're done.
        # FIXME: Can we do one ga_track_event call for all the rules?
        for rule in rules:
            if rule.get_matcher().match(feedback):
                links.append(
                    Link(provider=PROVIDER,
                         provider_version=PROVIDER_VERSION,
                         cssclass=u'document',
                         summary=rule.title,
                         description=rule.description,
                         url=build_redirect_url(format_redirect(rule.slug))))

                # Track category: trigger-slug, action: suggest
                ga_track_event({
                    'cid': str(feedback.id),
                    'ec': build_ga_category(rule),
                    'ea': 'suggest',
                    'el': rule.url
                })
        return links
Esempio n. 2
0
    def handle_redirect(self, request, redirect):
        # If it's not a trigger redirect, return.
        if not redirect.startswith(TRIGGER):
            return

        # Get the response id for the last feedback left.
        response_id = request.session.get('response_id', None)
        if response_id is None:
            return

        # Extract the slug.
        try:
            trigger, slug = parse_redirect(redirect)
        except RedirectParseError:
            return

        # Get the rule that has that slug.
        try:
            rule = TriggerRule.objects.get(slug=slug)
        except TriggerRule.DoesNotExist:
            return

        # Track the event and then return the new url.
        ga_track_event({
            'cid': str(response_id),
            'ec': build_ga_category(rule),
            'ea': 'view',
            'el': rule.url
        }, async=True)

        return rule.url
Esempio n. 3
0
    def test_ga_track_event_async_false(self):
        """async=False, then delay() never gets called"""
        with requests_mock.Mocker() as m:
            m.post(GOOGLE_API_URL, text="")

            d = "fjord.base.google_utils.post_event.delay"
            with patch(d) as delay_patch:
                params = {"cid": "xxx", "ec": "ou812"}
                ga_track_event(params, async=False)
                eq_(delay_patch.call_count, 0)
Esempio n. 4
0
    def test_ga_track_event_async_false(self):
        """async=False, then delay() never gets called"""
        with requests_mock.Mocker() as m:
            m.post(GOOGLE_API_URL, text='')

            d = 'fjord.base.google_utils.post_event.delay'
            with patch(d) as delay_patch:
                params = {'cid': 'xxx', 'ec': 'ou812'}
                ga_track_event(params, async=False)
                assert delay_patch.call_count == 0
Esempio n. 5
0
    def test_ga_track_event_async_true(self):
        """async=True, then delay() gets called once"""
        with requests_mock.Mocker() as m:
            m.post(GOOGLE_API_URL, text="")

            post_event = "fjord.base.google_utils.post_event"
            post_event_delay = "fjord.base.google_utils.post_event.delay"
            with patch(post_event) as post_event_patch:
                with patch(post_event_delay) as post_event_delay_patch:
                    params = {"cid": "xxx", "ec": "ou812"}
                    ga_track_event(params, async=True)
                    assert post_event_patch.call_count == 0
                    assert post_event_delay_patch.call_count == 1
Esempio n. 6
0
    def get_suggestions(self, feedback, request=None):
        # Note: We only want to run suggestions for sad responses for
        # Firefox product with en-US locale and for feedback that has
        # more than 7 words.
        #
        # If any of that changes, we'll need to rethink this.
        if ((feedback.happy
             or feedback.locale != u'en-US'
             or feedback.product != u'Firefox'
             or len(feedback.description.split()) < 7)):
            return []

        session_key = SUMO_SUGGEST_SESSION_KEY.format(feedback.id)

        # Check the session to see if we've provided links already and
        # if so, re-use those.
        if request is not None:
            docs = request.session.get(session_key, None)
            if docs is not None:
                return self.docs_to_links(docs)

        try:
            docs = get_kb_articles(u'en-US', u'Firefox', feedback.description)
        except Exception:
            # FIXME: As we discover what exceptions actually get
            # kicked up, we can handle them individually as
            # appropriate.
            logger.exception('SUMO Suggest API raised exception.')
            return []

        # Note: This needs to be synchronous so that "suggest" events
        # come before their respective "view*" events.
        ga_track_event({
            'cid': str(feedback.id),
            'ec': EVENT_CATEGORY,
            'ea': 'suggest'
        }, async=False)

        links = self.docs_to_links(docs)

        if request is not None:
            request.session[session_key] = docs

        return links
Esempio n. 7
0
    def test_ga_track_event_non_test(self):
        with patch('fjord.base.google_utils.requests') as req_patch:
            # Create a mock that we can call .post() on and query what
            # it got params-wise. It doesn't matter what the return
            # is.
            req_patch.post = MagicMock()
            params = {'cid': 'xxx', 'ec': 'ou812'}

            ga_track_event(params)

            req_patch.post.assert_called_once_with(
                GOOGLE_API_URL,
                data={
                    'tid': 'UA-35433268-26',
                    'v': '1',
                    't': 'event',
                    'ec': 'ou812',  # "test_" is not prepended.
                    'cid': 'xxx'
                })
Esempio n. 8
0
    def test_ga_track_event_non_test(self):
        with patch("fjord.base.google_utils.requests") as req_patch:
            # Create a mock that we can call .post() on and query what
            # it got params-wise. It doesn't matter what the return
            # is.
            req_patch.post = MagicMock()
            params = {"cid": "xxx", "ec": "ou812"}

            ga_track_event(params)

            req_patch.post.assert_called_once_with(
                GOOGLE_API_URL,
                data={
                    "tid": "UA-35433268-26",
                    "v": "1",
                    "t": "event",
                    "ec": "ou812",  # "test_" is not prepended.
                    "cid": "xxx",
                },
            )
Esempio n. 9
0
    def test_ga_track_event_non_test(self):
        with patch('fjord.base.google_utils.requests') as req_patch:
            # Create a mock that we can call .post() on and query what
            # it got params-wise. It doesn't matter what the return
            # is.
            req_patch.post = MagicMock()
            params = {'cid': 'xxx', 'ec': 'ou812'}

            ga_track_event(params)

            req_patch.post.assert_called_once_with(
                GOOGLE_API_URL,
                data={
                    'tid': 'UA-35433268-26',
                    'v': '1',
                    't': 'event',
                    'ec': 'ou812',  # "test_" is not prepended.
                    'cid': 'xxx'
                }
            )
Esempio n. 10
0
    def handle_redirect(self, request, redirect):
        # If it's not a trigger redirect, return.
        if not redirect.startswith(TRIGGER):
            return

        # Get the response id for the last feedback left.
        response_id = request.session.get('response_id', None)
        if response_id is None:
            return

        # Extract the slug.
        try:
            trigger, slug = parse_redirect(redirect)
        except RedirectParseError:
            return

        # Get the rule that has that slug.
        try:
            rule = TriggerRule.objects.get(slug=slug)
        except TriggerRule.DoesNotExist:
            return

        # Interpolate the url.
        destination_url = rule.url
        if '{' in destination_url:
            # Fetch the response so we can interpolate the url.
            try:
                response = FeedbackResponse.objects.get(id=response_id)
            except FeedbackResponse.DoesNotExist:
                return
            destination_url = interpolate_url(destination_url, response)

        # Track the event and then return the new url.
        ga_track_event({
            'cid': str(response_id),
            'ec': build_ga_category(rule),
            'ea': 'view',
            'el': destination_url,
        }, async=True)

        return destination_url
Esempio n. 11
0
    def handle_redirect(self, request, redirect):
        # If it's not a sumosuggest redirect, return.
        if not redirect.startswith('sumosuggest'):
            return

        # Get the response id for the last feedback left.
        response_id = request.session.get('response_id', None)
        if response_id is None:
            return

        # If the session has no links, then we have nothing to
        # redirect to, so return.
        session_key = SUMO_SUGGEST_SESSION_KEY.format(response_id)
        docs = request.session.get(session_key, None)
        if not docs:
            return

        # Extract the rank.
        try:
            trigger, rank = parse_redirect(redirect)
        except RedirectParseError:
            return

        if rank == 'aaq':
            url = SUMO_AAQ_URL
        else:
            try:
                url = docs[rank]['url']
            except IndexError:
                # This doc doesn't exist.
                return

        ga_track_event({
            'cid': str(response_id),
            'ec': EVENT_CATEGORY,
            'ea': 'view' if rank != 'aaq' else 'viewaaq',
            'el': url
        }, async=True)

        return url
Esempio n. 12
0
    def get_suggestions(self, feedback, request=None):
        # Note: This implementation assumes there aren't a fajillion
        # active rules. If that becomes a problem, we should
        # re-architect the db so that this is easier to implement.
        #
        # Further, each matching rule will kick off a GA event
        # request. We have to do those synchronously so that we're
        # guaranteed to have the "suggest" event before the "click"
        # event. Otherwise the data is not as meaningful.

        rules = TriggerRule.objects.all_enabled()
        links = []

        # Go through the rules and accrue links until we're done.
        # FIXME: Can we do one ga_track_event call for all the rules?
        for rule in rules:
            if rule.match(feedback):
                links.append(
                    Link(
                        provider=PROVIDER,
                        provider_version=PROVIDER_VERSION,
                        cssclass=u'document',
                        summary=rule.title,
                        description=rule.description,
                        url=build_redirect_url(format_redirect(rule.slug))
                    )
                )

                # Track category: trigger-slug, action: suggest
                ga_track_event({
                    'cid': str(feedback.id),
                    'ec': build_ga_category(rule),
                    'ea': 'suggest',
                    'el': rule.url
                })
        return links