Add ratings information to the add-on search/detail API
This commit is contained in:
Родитель
1c273a1dc5
Коммит
5ba2a02245
|
@ -233,6 +233,7 @@ nitpick_ignore = [
|
|||
('http:obj', 'array'),
|
||||
('http:obj', 'boolean'),
|
||||
('http:obj', 'int'),
|
||||
('http:obj', 'float'),
|
||||
('http:obj', 'object'),
|
||||
('http:obj', 'string'),
|
||||
('http:obj', 'string|object|null'),
|
||||
|
|
|
@ -102,6 +102,9 @@ This endpoint allows you to fetch a specific add-on by id, slug or guid.
|
|||
:>json string previews[].image_url: The URL (including a cachebusting query string) to the preview image.
|
||||
:>json string previews[].thumbnail_url: The URL (including a cachebusting query string) to the preview image thumbnail.
|
||||
:>json boolean public_stats: Boolean indicating whether the add-on stats are public or not.
|
||||
:>json object ratings: Object holding ratings summary information about the add-on.
|
||||
:>json int ratings.count: The number of user ratings for the add-on.
|
||||
:>json float ratings.average: The average user rating for the add-on.
|
||||
:>json string review_url: The URL to the review page for this add-on.
|
||||
:>json string slug: The add-on slug.
|
||||
:>json string status: The :ref:`add-on status <addon-detail-status>`.
|
||||
|
|
|
@ -113,7 +113,14 @@ class AddonIndexer(BaseSearchIndexer):
|
|||
'modified': {'type': 'date', 'index': 'no'},
|
||||
},
|
||||
},
|
||||
'public_stats': {'type': 'boolean'},
|
||||
'public_stats': {'type': 'boolean', 'index': 'no'},
|
||||
'ratings': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'count': {'type': 'short', 'index': 'no'},
|
||||
'average': {'type': 'float', 'index': 'no'}
|
||||
}
|
||||
},
|
||||
'slug': {'type': 'string'},
|
||||
'status': {'type': 'byte'},
|
||||
'summary': {'type': 'string', 'analyzer': 'snowball'},
|
||||
|
@ -230,6 +237,10 @@ class AddonIndexer(BaseSearchIndexer):
|
|||
# transformer that sets it.
|
||||
data['previews'] = [{'id': preview.id, 'modified': preview.modified}
|
||||
for preview in obj.all_previews]
|
||||
data['ratings'] = {
|
||||
'average': obj.average_rating,
|
||||
'count': obj.total_reviews,
|
||||
}
|
||||
data['tags'] = getattr(obj, 'tag_list', [])
|
||||
|
||||
# Handle localized fields.
|
||||
|
|
|
@ -119,6 +119,7 @@ class AddonSerializer(serializers.ModelSerializer):
|
|||
icon_url = serializers.SerializerMethodField()
|
||||
name = TranslationSerializerField()
|
||||
previews = PreviewSerializer(many=True, source='all_previews')
|
||||
ratings = serializers.SerializerMethodField()
|
||||
review_url = serializers.SerializerMethodField()
|
||||
status = ReverseChoiceField(choices=amo.STATUS_CHOICES_API.items())
|
||||
summary = TranslationSerializerField()
|
||||
|
@ -134,9 +135,9 @@ class AddonSerializer(serializers.ModelSerializer):
|
|||
fields = ('id', 'authors', 'current_version', 'default_locale',
|
||||
'description', 'edit_url', 'guid', 'homepage', 'icon_url',
|
||||
'is_listed', 'name', 'last_updated', 'previews',
|
||||
'public_stats', 'review_url', 'slug', 'status', 'summary',
|
||||
'support_email', 'support_url', 'tags', 'theme_data', 'type',
|
||||
'url')
|
||||
'public_stats', 'ratings', 'review_url', 'slug', 'status',
|
||||
'summary', 'support_email', 'support_url', 'tags',
|
||||
'theme_data', 'type', 'url')
|
||||
|
||||
def to_representation(self, obj):
|
||||
data = super(AddonSerializer, self).to_representation(obj)
|
||||
|
@ -165,6 +166,12 @@ class AddonSerializer(serializers.ModelSerializer):
|
|||
return absolutify(obj.get_default_icon_url(64))
|
||||
return absolutify(obj.get_icon_url(64))
|
||||
|
||||
def get_ratings(self, obj):
|
||||
return {
|
||||
'average': obj.average_rating,
|
||||
'count': obj.total_reviews,
|
||||
}
|
||||
|
||||
def get_theme_data(self, obj):
|
||||
theme_data = None
|
||||
|
||||
|
@ -276,6 +283,9 @@ class ESAddonSerializer(BaseESSerializer, AddonSerializer):
|
|||
# for us when its to_representation() method is called.
|
||||
obj.all_previews = data.get('previews', [])
|
||||
|
||||
obj.average_rating = data.get('ratings', {}).get('average')
|
||||
obj.total_reviews = data.get('ratings', {}).get('count')
|
||||
|
||||
if data['type'] == amo.ADDON_PERSONA:
|
||||
persona_data = data.get('persona')
|
||||
if persona_data:
|
||||
|
|
|
@ -47,7 +47,7 @@ class TestAddonIndexer(TestCase):
|
|||
'app', 'appversion', 'authors', 'boost', 'category',
|
||||
'current_version', 'description', 'has_theme_rereview',
|
||||
'has_version', 'listed_authors', 'name', 'name_sort', 'platforms',
|
||||
'previews', 'public_stats', 'summary', 'tags',
|
||||
'previews', 'public_stats', 'ratings', 'summary', 'tags',
|
||||
]
|
||||
|
||||
# Fields that need to be present in the mapping, but might be skipped
|
||||
|
@ -149,6 +149,10 @@ class TestAddonIndexer(TestCase):
|
|||
assert extracted['listed_authors'] == [
|
||||
{'name': u'55021 التطب', 'id': 55021, 'username': '55021'}]
|
||||
assert extracted['platforms'] == [PLATFORM_ALL.id]
|
||||
assert extracted['ratings'] == {
|
||||
'average': self.addon.average_rating,
|
||||
'count': self.addon.total_reviews,
|
||||
}
|
||||
assert extracted['tags'] == []
|
||||
|
||||
def test_extract_version_and_files(self):
|
||||
|
|
|
@ -22,6 +22,7 @@ class AddonSerializerOutputTestMixin(object):
|
|||
|
||||
def test_basic(self):
|
||||
self.addon = addon_factory(
|
||||
average_rating=4.21,
|
||||
description=u'My Addôn description',
|
||||
file_kw={
|
||||
'hash': 'fakehash',
|
||||
|
@ -38,6 +39,7 @@ class AddonSerializerOutputTestMixin(object):
|
|||
support_email=u'support@example.org',
|
||||
support_url=u'https://support.example.org/support/my-addon/',
|
||||
tags=['some_tag', 'some_other_tag'],
|
||||
total_reviews=666,
|
||||
)
|
||||
AddonUser.objects.create(user=user_factory(username='hidden_author'),
|
||||
addon=self.addon, listed=False)
|
||||
|
@ -127,6 +129,10 @@ class AddonSerializerOutputTestMixin(object):
|
|||
assert result_preview['thumbnail_url'] == absolutify(
|
||||
second_preview.thumbnail_url)
|
||||
|
||||
assert result['ratings'] == {
|
||||
'average': self.addon.average_rating,
|
||||
'count': self.addon.total_reviews,
|
||||
}
|
||||
assert result['public_stats'] == self.addon.public_stats
|
||||
assert result['review_url'] == absolutify(
|
||||
reverse('editors.review', args=[self.addon.pk]))
|
||||
|
|
Загрузка…
Ссылка в новой задаче