Add locale and region data to app detail API (bugs 873198, 873200)
This commit is contained in:
Родитель
36546f1d66
Коммит
e86e672e20
|
@ -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_,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче