Add locale and region data to app detail API (bugs 873198, 873200)

This commit is contained in:
Chuck Harmston 2013-05-17 13:42:35 -05:00
Родитель 36546f1d66
Коммит e86e672e20
7 изменённых файлов: 98 добавлений и 11 удалений

Просмотреть файл

@ -100,6 +100,26 @@ App
"resource_uri": "/api/v1/apps/preview/37/" "resource_uri": "/api/v1/apps/preview/37/"
} }
], ],
"default_locale": "en-US",
"supported_locales": [
"en-US",
"es",
"it"
],
"regions": [
{
"adolescent": true,
"mcc": 310,
"name": "United States",
"slug": "us"
},
{
"adolescent": true,
"mcc": null,
"name": "Worldwide",
"slug": "worldwide"
}
],
"user": { "user": {
"developed": false, "developed": false,
"installed": false, "installed": false,
@ -128,6 +148,11 @@ App
currency formatted using the currency symbol and the locale currency formatted using the currency symbol and the locale
representations of numbers. Example: "1,00 $US". For more information representations of numbers. Example: "1,00 $US". For more information
on this see :ref:`payment tiers <localized-tier-label>`. on this see :ref:`payment tiers <localized-tier-label>`.
:param boolean regions > adolescent: an adolescent region has a sufficient
volume of data to calculate ratings and rankings independent of
worldwide data.
:param string|null regions > mcc: represents the region's ITU `mobile
country code`_.
:param object user: an object representing information specific to this :param object user: an object representing information specific to this
user for the app. If the user is anonymous this object will not user for the app. If the user is anonymous this object will not
be present. be present.
@ -315,3 +340,4 @@ Valid transitions that users can initiate are:
enable or disable an app. enable or disable an app.
.. _`terms of use`: https://marketplace.firefox.com/developers/terms .. _`terms of use`: https://marketplace.firefox.com/developers/terms
.. _`mobile country code`: http://en.wikipedia.org/wiki/List_of_mobile_country_codes

Просмотреть файл

@ -225,6 +225,16 @@ class Marketplace(object):
if errors: if errors:
raise self.form_errors(errors) raise self.form_errors(errors)
def dehydrate_objects(self, objects, request=None):
"""
Dehydrates each object using the full_dehydrate and then
returns the data for each object. This is useful for compound
results that return sub objects data. If you need request in the
dehydration, pass that through (eg: accessing region)
"""
return [self.full_dehydrate(Bundle(obj=o, request=request)).data
for o in objects]
class MarketplaceResource(Marketplace, Resource): class MarketplaceResource(Marketplace, Resource):
""" """
@ -286,16 +296,6 @@ class MarketplaceModelResource(Marketplace, ModelResource):
raise ImmediateHttpResponse(response=http.HttpNotFound()) raise ImmediateHttpResponse(response=http.HttpNotFound())
return obj return obj
def dehydrate_objects(self, objects, request=None):
"""
Dehydrates each object using the full_dehydrate and then
returns the data for each object. This is useful for compound
results that return sub objects data. If you need request in the
dehydration, pass that through (eg: accessing region)
"""
return [self.full_dehydrate(Bundle(obj=o, request=request)).data
for o in objects]
def base_urls(self): def base_urls(self):
""" """
If `slug_lookup` is specified on the Meta of a resource, add If `slug_lookup` is specified on the Meta of a resource, add

Просмотреть файл

@ -16,6 +16,7 @@ tests=mkt.abuse.tests.test_resources,
mkt.home.tests.test_api, mkt.home.tests.test_api,
mkt.ratings.tests.test_resources, mkt.ratings.tests.test_resources,
mkt.receipts.tests.test_api, mkt.receipts.tests.test_api,
mkt.regions.tests.test_api,
mkt.reviewers.tests.test_api, mkt.reviewers.tests.test_api,
mkt.search.tests.test_api, mkt.search.tests.test_api,
mkt.webapps.tests.test_utils_, mkt.webapps.tests.test_utils_,

16
mkt/regions/api.py Normal file
Просмотреть файл

@ -0,0 +1,16 @@
from mkt.api.base import MarketplaceResource
class RegionResource(MarketplaceResource):
class Meta(MarketplaceResource.Meta):
allowed_methods = []
fields = ('name', 'slug', 'mcc', 'adolescent')
resource_name = 'region'
include_resource_uri = False
def full_dehydrate(self, bundle):
bundle.data = {}
for field in self._meta.fields:
bundle.data[field] = getattr(bundle.obj, field)
return bundle

Просмотреть файл

@ -0,0 +1,23 @@
from nose.tools import eq_
from tastypie.bundle import Bundle
import amo
import amo.tests
from mkt.constants.regions import REGIONS_DICT as regions
from mkt.regions.api import RegionResource
class TestRegionResource(amo.tests.TestCase):
def setUp(self):
self.app = amo.tests.app_factory()
self.resource = RegionResource()
self.bundle = Bundle(obj=regions['us'], request=None)
def test_full_dehydrate(self):
res = self.resource.full_dehydrate(self.bundle)
eq_(res.obj, regions['us'])
for field in self.resource._meta.fields:
eq_(res.data[field], getattr(res.obj, field))

Просмотреть файл

@ -61,6 +61,21 @@ class TestAppToDict(amo.tests.TestCase):
res = app_to_dict(self.app, profile=self.profile) res = app_to_dict(self.app, profile=self.profile)
self.check_profile(res['user'], developed=True) self.check_profile(res['user'], developed=True)
def test_locales(self):
res = app_to_dict(self.app)
eq_(res['default_locale'], 'en-US')
eq_(res['supported_locales'], [])
def test_multiple_locales(self):
self.app.current_version.update(supported_locales='en-US,it')
res = app_to_dict(self.app)
self.assertSetEqual(res['supported_locales'], ['en-US', 'it'])
def test_regions(self):
res = app_to_dict(self.app)
self.assertSetEqual([region['slug'] for region in res['regions']],
[region.slug for region in self.app.get_regions()])
class TestAppToDictPrices(amo.tests.TestCase): class TestAppToDictPrices(amo.tests.TestCase):
fixtures = fixture('prices') fixtures = fixture('prices')

Просмотреть файл

@ -3,6 +3,7 @@ import commonware.log
import amo import amo
from amo.utils import find_language, no_translation from amo.utils import find_language, no_translation
from mkt.regions.api import RegionResource
log = commonware.log.getLogger('z.webapps') log = commonware.log.getLogger('z.webapps')
@ -43,13 +44,14 @@ def app_to_dict(app, currency=None, profile=None):
from mkt.developers.api import AccountResource from mkt.developers.api import AccountResource
from mkt.developers.models import AddonPaymentAccount from mkt.developers.models import AddonPaymentAccount
cv = app.current_version cv = app.current_version
version_data = { version_data = {
'version': getattr(cv, 'version', None), 'version': getattr(cv, 'version', None),
'release_notes': getattr(cv, 'releasenotes', None) 'release_notes': getattr(cv, 'releasenotes', None)
} }
supported_locales = getattr(app.current_version, 'supported_locales', '')
data = { data = {
'app_type': app.app_type, 'app_type': app.app_type,
'categories': list(app.categories.values_list('pk', flat=True)), 'categories': list(app.categories.values_list('pk', flat=True)),
@ -58,6 +60,7 @@ def app_to_dict(app, currency=None, profile=None):
'description': unicode(cr.get_rating().description), 'description': unicode(cr.get_rating().description),
}) for cr in app.content_ratings.all()]) or None, }) for cr in app.content_ratings.all()]) or None,
'current_version': version_data, 'current_version': version_data,
'default_locale': app.default_locale,
'image_assets': dict([(ia.slug, (ia.image_url, ia.hue)) 'image_assets': dict([(ia.slug, (ia.image_url, ia.hue))
for ia in app.image_assets.all()]), for ia in app.image_assets.all()]),
'icons': dict([(icon_size, 'icons': dict([(icon_size,
@ -74,7 +77,10 @@ def app_to_dict(app, currency=None, profile=None):
'price_locale': None, 'price_locale': None,
'ratings': {'average': app.average_rating, 'ratings': {'average': app.average_rating,
'count': app.total_reviews}, 'count': app.total_reviews},
'regions': RegionResource().dehydrate_objects(app.get_regions()),
'slug': app.app_slug, 'slug': app.app_slug,
'supported_locales': (supported_locales.split(',') if supported_locales
else [])
} }
if app.premium: if app.premium: