From e86e672e20d05065d7026c83eda3c136e94e3b8b Mon Sep 17 00:00:00 2001 From: Chuck Harmston Date: Fri, 17 May 2013 13:42:35 -0500 Subject: [PATCH] Add locale and region data to app detail API (bugs 873198, 873200) --- docs/api/topics/apps.rst | 26 ++++++++++++++++++++++++++ mkt/api/base.py | 20 ++++++++++---------- mkt/api/tests/nose.cfg | 1 + mkt/regions/api.py | 16 ++++++++++++++++ mkt/regions/tests/test_api.py | 23 +++++++++++++++++++++++ mkt/webapps/tests/test_utils_.py | 15 +++++++++++++++ mkt/webapps/utils.py | 8 +++++++- 7 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 mkt/regions/api.py create mode 100644 mkt/regions/tests/test_api.py diff --git a/docs/api/topics/apps.rst b/docs/api/topics/apps.rst index d9b47a4bc5..3e3973d6ef 100644 --- a/docs/api/topics/apps.rst +++ b/docs/api/topics/apps.rst @@ -100,6 +100,26 @@ App "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": { "developed": false, "installed": false, @@ -128,6 +148,11 @@ App currency formatted using the currency symbol and the locale representations of numbers. Example: "1,00 $US". For more information on this see :ref:`payment tiers `. + :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 user for the app. If the user is anonymous this object will not be present. @@ -315,3 +340,4 @@ Valid transitions that users can initiate are: enable or disable an app. .. _`terms of use`: https://marketplace.firefox.com/developers/terms +.. _`mobile country code`: http://en.wikipedia.org/wiki/List_of_mobile_country_codes diff --git a/mkt/api/base.py b/mkt/api/base.py index 23532ca9f7..fde8779c33 100644 --- a/mkt/api/base.py +++ b/mkt/api/base.py @@ -225,6 +225,16 @@ class Marketplace(object): if 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): """ @@ -286,16 +296,6 @@ class MarketplaceModelResource(Marketplace, ModelResource): raise ImmediateHttpResponse(response=http.HttpNotFound()) 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): """ If `slug_lookup` is specified on the Meta of a resource, add diff --git a/mkt/api/tests/nose.cfg b/mkt/api/tests/nose.cfg index b9947b7c7a..a7b0377805 100644 --- a/mkt/api/tests/nose.cfg +++ b/mkt/api/tests/nose.cfg @@ -16,6 +16,7 @@ tests=mkt.abuse.tests.test_resources, mkt.home.tests.test_api, mkt.ratings.tests.test_resources, mkt.receipts.tests.test_api, + mkt.regions.tests.test_api, mkt.reviewers.tests.test_api, mkt.search.tests.test_api, mkt.webapps.tests.test_utils_, diff --git a/mkt/regions/api.py b/mkt/regions/api.py new file mode 100644 index 0000000000..a4025e6d76 --- /dev/null +++ b/mkt/regions/api.py @@ -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 diff --git a/mkt/regions/tests/test_api.py b/mkt/regions/tests/test_api.py new file mode 100644 index 0000000000..ce90c31321 --- /dev/null +++ b/mkt/regions/tests/test_api.py @@ -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)) diff --git a/mkt/webapps/tests/test_utils_.py b/mkt/webapps/tests/test_utils_.py index 1761111b41..dfabc4d28e 100644 --- a/mkt/webapps/tests/test_utils_.py +++ b/mkt/webapps/tests/test_utils_.py @@ -61,6 +61,21 @@ class TestAppToDict(amo.tests.TestCase): res = app_to_dict(self.app, profile=self.profile) 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): fixtures = fixture('prices') diff --git a/mkt/webapps/utils.py b/mkt/webapps/utils.py index da263add50..4bd6c28649 100644 --- a/mkt/webapps/utils.py +++ b/mkt/webapps/utils.py @@ -3,6 +3,7 @@ import commonware.log import amo from amo.utils import find_language, no_translation +from mkt.regions.api import RegionResource 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.models import AddonPaymentAccount - cv = app.current_version version_data = { 'version': getattr(cv, 'version', None), 'release_notes': getattr(cv, 'releasenotes', None) } + supported_locales = getattr(app.current_version, 'supported_locales', '') + data = { 'app_type': app.app_type, '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), }) for cr in app.content_ratings.all()]) or None, 'current_version': version_data, + 'default_locale': app.default_locale, 'image_assets': dict([(ia.slug, (ia.image_url, ia.hue)) for ia in app.image_assets.all()]), 'icons': dict([(icon_size, @@ -74,7 +77,10 @@ def app_to_dict(app, currency=None, profile=None): 'price_locale': None, 'ratings': {'average': app.average_rating, 'count': app.total_reviews}, + 'regions': RegionResource().dehydrate_objects(app.get_regions()), 'slug': app.app_slug, + 'supported_locales': (supported_locales.split(',') if supported_locales + else []) } if app.premium: