Пример #1
0
 def test_addon_index(self):
     c = Collection.objects.get(pk=512)
     c.author = self.user
     eq_(c.addon_index, None)
     ids = c.addons.values_list('id', flat=True)
     c.save()
     eq_(c.addon_index, Collection.make_index(ids))
Пример #2
0
 def test_addon_index(self):
     c = Collection.objects.get(pk=512)
     c.author = self.user
     eq_(c.addon_index, None)
     ids = c.addons.values_list("id", flat=True)
     c.save()
     eq_(c.addon_index, Collection.make_index(ids))
Пример #3
0
def recommendations(request, version, platform, limit=9):
    """
    Figure out recommended add-ons for an anonymous user based on POSTed guids.

    POST body looks like {"guids": [...]} with an optional "token" key if
    they've been here before.
    """
    try:
        POST = json.loads(request.raw_post_data)
        guids = POST['guids']
    except (ValueError, TypeError, KeyError):
        # Errors: invalid json, didn't get a dict, didn't find "guids".
        return http.HttpResponseBadRequest()

    addon_ids = get_addon_ids(guids)
    index = Collection.make_index(addon_ids)

    ids, recs = Collection.get_recs_from_ids(addon_ids, request.APP, version)
    recs = _recommendations(request, version, platform, limit,
                            index, ids, recs)

    # We're only storing a percentage of the collections we see because the db
    # can't keep up with 100%.
    if not waffle.sample_is_active('disco-pane-store-collections'):
        return recs

    # Users have a token2 if they've been here before. The token matches
    # addon_index in their SyncedCollection.
    if 'token2' in POST:
        token = POST['token2']
        if token == index:
            # We've seen them before and their add-ons have not changed.
            return recs
        elif token != index:
            # We've seen them before and their add-ons changed. Remove the
            # reference to their old synced collection.
            (SyncedCollection.objects.filter(addon_index=index)
             .update(count=F('count') - 1))

    # Try to create the SyncedCollection. There's a unique constraint on
    # addon_index so it will fail if this addon_index already exists. If we
    # checked for existence first and then created a collection there would
    # be a race condition between multiple users with the same addon_index.
    try:
        c = SyncedCollection.objects.create(addon_index=index, count=1)
        c.set_addons(addon_ids)
    except IntegrityError:
        try:
            (SyncedCollection.objects.filter(addon_index=index)
             .update(count=F('count') + 1))
        except Exception, e:
            log.error(u'Could not count++ "%s" (%s).' % (index, e))
Пример #4
0
def recommendations(request, version, platform, limit=9):
    """
    Figure out recommended add-ons for an anonymous user based on POSTed guids.

    POST body looks like {"guids": [...]} with an optional "token" key if
    they've been here before.
    """
    try:
        POST = json.loads(request.raw_post_data)
        guids = POST['guids']
    except (ValueError, TypeError, KeyError):
        # Errors: invalid json, didn't get a dict, didn't find "guids".
        return http.HttpResponseBadRequest()

    addon_ids = get_addon_ids(guids)
    index = Collection.make_index(addon_ids)

    ids, recs = Collection.get_recs_from_ids(addon_ids, request.APP, version)
    recs = _recommendations(request, version, platform, limit,
                            index, ids, recs)

    # We're only storing a percentage of the collections we see because the db
    # can't keep up with 100%.
    if not waffle.sample_is_active('disco-pane-store-collections'):
        return recs

    # Users have a token2 if they've been here before. The token matches
    # addon_index in their SyncedCollection.
    if 'token2' in POST:
        token = POST['token2']
        if token == index:
            # We've seen them before and their add-ons have not changed.
            return recs
        elif token != index:
            # We've seen them before and their add-ons changed. Remove the
            # reference to their old synced collection.
            (SyncedCollection.objects.filter(addon_index=index)
             .update(count=F('count') - 1))

    # Try to create the SyncedCollection. There's a unique constraint on
    # addon_index so it will fail if this addon_index already exists. If we
    # checked for existence first and then created a collection there would
    # be a race condition between multiple users with the same addon_index.
    try:
        c = SyncedCollection.objects.create(addon_index=index, count=1)
        c.set_addons(addon_ids)
    except IntegrityError:
        try:
            (SyncedCollection.objects.filter(addon_index=index)
             .update(count=F('count') + 1))
        except Exception, e:
            log.error(u'Could not count++ "%s" (%s).' % (index, e))
Пример #5
0
def get_synced_collection(addon_ids, token):
    """
    Get a synced collection for these addons. May reuse an existing collection.

    The token is associated with the collection.
    """
    index = Collection.make_index(addon_ids)
    try:
        c = (SyncedCollection.objects.no_cache().filter(addon_index=index))[0]
    except IndexError:
        c = SyncedCollection.objects.create(listed=False)
        c.set_addons(addon_ids)

    c.token_set.create(token=token)
    return c
Пример #6
0
def recommendations(request, limit=5):
    """
    Figure out recommended add-ons for an anonymous user based on POSTed guids.

    POST body looks like {"guids": [...]} with an optional "token" key if
    they've been here before.
    """
    if request.method != 'POST':
        return http.HttpResponseNotAllowed(['POST'])

    try:
        POST = json.loads(request.raw_post_data)
        guids = POST['guids']
    except (ValueError, TypeError, KeyError):
        # Errors: invalid json, didn't get a dict, didn't find "guids".
        return http.HttpResponseBadRequest()

    addon_ids = get_addon_ids(guids)
    token = POST['token'] if 'token' in POST else get_random_token()

    if 'token' in POST:
        q = SyncedCollection.objects.filter(token_set__token=token)
        if q:
            # We've seen this user before.
            synced = q[0]
            if synced.addon_index == Collection.make_index(addon_ids):
                # Their add-ons didn't change, get out quick.
                recs = synced.get_recommendations()
                return _recommendations(request, limit, token, recs)
            else:
                # Remove the link to the current sync, make a new one below.
                synced.token_set.get(token=token).delete()

    synced = get_synced_collection(addon_ids, token)
    recs = synced.get_recommendations()
    return _recommendations(request, limit, token, recs)
Пример #7
0
    POST body looks like {"guids": [...]} with an optional "token" key if
    they've been here before.
    """
    if not compat_mode:
        compat_mode = get_compat_mode(version)

    try:
        POST = json.loads(request.raw_post_data)
        guids = POST['guids']
    except (ValueError, TypeError, KeyError), e:
        # Errors: invalid json, didn't get a dict, didn't find "guids".
        log.debug('Recommendations return 405 because: %s' % e)
        return http.HttpResponseBadRequest()

    addon_ids = get_addon_ids(guids)
    index = Collection.make_index(addon_ids)

    ids, recs = Collection.get_recs_from_ids(addon_ids, request.APP, version,
                                             compat_mode)
    recs = _recommendations(request, version, platform, limit, index, ids,
                            recs, compat_mode)

    # We're only storing a percentage of the collections we see because the db
    # can't keep up with 100%.
    if not waffle.sample_is_active('disco-pane-store-collections'):
        return recs

    # Users have a token2 if they've been here before. The token matches
    # addon_index in their SyncedCollection.
    if 'token2' in POST:
        token = POST['token2']
Пример #8
0
    POST body looks like {"guids": [...]} with an optional "token" key if
    they've been here before.
    """
    if not compat_mode:
        compat_mode = get_compat_mode(version)

    try:
        POST = json.loads(request.raw_post_data)
        guids = POST['guids']
    except (ValueError, TypeError, KeyError), e:
        # Errors: invalid json, didn't get a dict, didn't find "guids".
        log.debug('Recommendations return 405 because: %s' % e)
        return http.HttpResponseBadRequest()

    addon_ids = get_addon_ids(guids)
    index = Collection.make_index(addon_ids)

    ids, recs = Collection.get_recs_from_ids(addon_ids, request.APP, version,
                                             compat_mode)
    recs = _recommendations(request, version, platform, limit, index, ids,
                            recs, compat_mode)

    # We're only storing a percentage of the collections we see because the db
    # can't keep up with 100%.
    if not waffle.sample_is_active('disco-pane-store-collections'):
        return recs

    # Users have a token2 if they've been here before. The token matches
    # addon_index in their SyncedCollection.
    if 'token2' in POST:
        token = POST['token2']
Пример #9
0
 def test_addon_index(self):
     c = Collection.objects.get(pk=5)
     eq_(c.addon_index, None)
     ids = c.addons.values_list('id', flat=True)
     c.save()
     eq_(c.addon_index, Collection.make_index(ids))