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))
def setUp(self): self.app = amo.tests.app_factory() self.resource = RegionResource() self.bundle = Bundle(obj=regions['us'], request=None)
def app_to_dict(app, region=None, profile=None, request=None): """Return app data as dict for API.""" # Sad circular import issues. from mkt.api.resources import AppResource from mkt.developers.api import AccountResource from mkt.developers.models import AddonPaymentAccount from mkt.submit.api import PreviewResource from mkt.webapps.models import reverse_version supported_locales = getattr(app.current_version, 'supported_locales', '') data = { 'app_type': app.app_type, 'author': app.developer_name, 'categories': list(app.categories.values_list('slug', flat=True)), 'content_ratings': dict([(cr.get_body().name, { 'name': cr.get_rating().name, 'description': unicode(cr.get_rating().description), }) for cr in app.content_ratings.all()]) or None, 'created': app.created, 'current_version': (app.current_version.version if getattr( app, 'current_version') else None), 'default_locale': app.default_locale, 'icons': dict([(icon_size, app.get_icon_url(icon_size)) for icon_size in (16, 48, 64, 128)]), 'is_packaged': app.is_packaged, 'manifest_url': app.get_manifest_url(), 'payment_required': False, 'previews': PreviewResource().dehydrate_objects(app.previews.all()), 'premium_type': amo.ADDON_PREMIUM_API[app.premium_type], 'public_stats': app.public_stats, 'price': 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 []), 'weekly_downloads': app.weekly_downloads if app.public_stats else None, 'versions': dict((v.version, reverse_version(v)) for v in app.versions.all()) } data['upsell'] = False if app.upsell and region in app.upsell.premium.get_price_region_ids(): upsell = app.upsell.premium data['upsell'] = { 'id': upsell.id, 'app_slug': upsell.app_slug, 'icon_url': upsell.get_icon_url(128), 'name': unicode(upsell.name), 'resource_uri': AppResource().get_resource_uri(upsell), } if app.premium: q = AddonPaymentAccount.objects.filter(addon=app) if len(q) > 0 and q[0].payment_account: data['payment_account'] = AccountResource().get_resource_uri( q[0].payment_account) if (region in app.get_price_region_ids() or payments_enabled(request)): data['price'] = app.get_price(region=region) data['price_locale'] = app.get_price_locale(region=region) data['payment_required'] = (bool(app.get_tier().price) if app.get_tier() else False) with no_translation(): data['device_types'] = [n.api_name for n in app.device_types] if profile: data['user'] = { 'developed': app.addonuser_set.filter(user=profile, role=amo.AUTHOR_ROLE_OWNER).exists(), 'installed': app.has_installed(profile), 'purchased': app.pk in profile.purchase_ids(), } return data
def es_app_to_dict(obj, region=None, profile=None, request=None): """ Return app data as dict for API where `app` is the elasticsearch result. """ # Circular import. from mkt.api.base import GenericObject from mkt.api.resources import AppResource, PrivacyPolicyResource from mkt.developers.api import AccountResource from mkt.developers.models import AddonPaymentAccount from mkt.webapps.models import Installed, Webapp src = obj._source # The following doesn't perform a database query, but gives us useful # methods like `get_detail_url`. If you use `obj` make sure the calls # don't query the database. is_packaged = src.get('app_type') != amo.ADDON_WEBAPP_HOSTED app = Webapp(app_slug=obj.app_slug, is_packaged=is_packaged) attrs = ('content_ratings', 'created', 'current_version', 'default_locale', 'homepage', 'manifest_url', 'previews', 'ratings', 'status', 'support_email', 'support_url', 'weekly_downloads') data = dict((a, getattr(obj, a, None)) for a in attrs) data.update({ 'absolute_url': absolutify(app.get_detail_url()), 'app_type': app.app_type, 'author': src.get('author', ''), 'categories': [c for c in obj.category], 'description': get_attr_lang(src, 'description', obj.default_locale), 'device_types': [DEVICE_TYPES[d].api_name for d in src.get('device')], 'icons': dict((i['size'], i['url']) for i in src.get('icons')), 'id': str(obj._id), 'is_packaged': is_packaged, 'name': get_attr_lang(src, 'name', obj.default_locale), 'payment_required': False, 'premium_type': amo.ADDON_PREMIUM_API[src.get('premium_type')], 'privacy_policy': PrivacyPolicyResource().get_resource_uri(GenericObject({'pk': obj._id})), 'public_stats': obj.has_public_stats, 'supported_locales': src.get('supported_locales', ''), 'slug': obj.app_slug, # TODO: Remove the type check once this code rolls out and our indexes # aren't between mapping changes. 'versions': dict((v.get('version'), v.get('resource_uri')) for v in src.get('versions') if type(v) == dict), }) if not data['public_stats']: data['weekly_downloads'] = None data['regions'] = RegionResource().dehydrate_objects( map(REGIONS_CHOICES_ID_DICT.get, app.get_region_ids(worldwide=True, excluded=obj.region_exclusions))) if src.get('premium_type') in amo.ADDON_PREMIUMS: acct = list(AddonPaymentAccount.objects.filter(addon=app)) if acct and acct.payment_account: data['payment_account'] = AccountResource().get_resource_uri( acct.payment_account) else: data['payment_account'] = None data['upsell'] = False if hasattr(obj, 'upsell'): exclusions = obj.upsell.get('region_exclusions') if exclusions is not None and region not in exclusions: data['upsell'] = obj.upsell data['upsell']['resource_uri'] = AppResource().get_resource_uri( Webapp(id=obj.upsell['id'])) data['price'] = data['price_locale'] = None try: price_tier = src.get('price_tier') if price_tier: price = Price.objects.get(name=price_tier) if (data['upsell'] or payments_enabled(request)): price_currency = price.get_price_currency(region=region) if price_currency and price_currency.paid: data['price'] = price.get_price(region=region) data['price_locale'] = price.get_price_locale( region=region) data['payment_required'] = bool(price.price) except Price.DoesNotExist: log.warning('Issue with price tier on app: {0}'.format(obj._id)) data['payment_required'] = True # TODO: Let's get rid of these from the API to avoid db hits. if profile and isinstance(profile, UserProfile): data['user'] = { 'developed': AddonUser.objects.filter(addon=obj.id, user=profile, role=amo.AUTHOR_ROLE_OWNER).exists(), 'installed': Installed.objects.filter(user=profile, addon_id=obj.id).exists(), 'purchased': obj.id in profile.purchase_ids(), } return data
def app_to_dict(app, currency=None, profile=None): """Return app data as dict for API.""" # Sad circular import issues. from mkt.api.resources import AppResource, PreviewResource 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)), 'content_ratings': dict([(cr.get_body().name, { 'name': cr.get_rating().name, '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, app.get_icon_url(icon_size)) for icon_size in (16, 48, 64, 128)]), 'is_packaged': app.is_packaged, 'listed_authors': [{ 'name': author.name } for author in app.listed_authors], 'manifest_url': app.get_manifest_url(), 'previews': PreviewResource().dehydrate_objects(app.previews.all()), 'premium_type': amo.ADDON_PREMIUM_API[app.premium_type], 'public_stats': app.public_stats, 'price': 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 []) } data['upsell'] = False if app.upsell: upsell = app.upsell.premium data['upsell'] = { 'id': upsell.id, 'app_slug': upsell.app_slug, 'icon_url': upsell.get_icon_url(128), 'name': unicode(upsell.name), 'resource_uri': AppResource().get_resource_uri(upsell), } if app.premium: q = AddonPaymentAccount.objects.filter(addon=app) if len(q) > 0 and q[0].payment_account: data['payment_account'] = AccountResource().get_resource_uri( q[0].payment_account) try: data['price'] = app.get_price(currency) data['price_locale'] = app.get_price_locale(currency) except AttributeError: # Until bug 864569 gets fixed. log.info('Missing price data for premium app: %s' % app.pk) with no_translation(): data['device_types'] = [n.api_name for n in app.device_types] if profile: data['user'] = { 'developed': app.has_author(profile, [amo.AUTHOR_ROLE_OWNER]), 'installed': app.has_installed(profile), 'purchased': app.pk in profile.purchase_ids(), } return data
def es_app_to_dict(obj, currency=None, profile=None): """ Return app data as dict for API where `app` is the elasticsearch result. """ # Circular import. from mkt.api.base import GenericObject from mkt.api.resources import AppResource, PrivacyPolicyResource from mkt.developers.api import AccountResource from mkt.developers.models import AddonPaymentAccount from mkt.webapps.models import Installed, Webapp src = obj._source # The following doesn't perform a database query, but gives us useful # methods like `get_detail_url`. If you use `obj` make sure the calls # don't query the database. is_packaged = src['app_type'] == amo.ADDON_WEBAPP_PACKAGED app = Webapp(app_slug=obj.app_slug, is_packaged=is_packaged) attrs = ('content_ratings', 'current_version', 'default_locale', 'homepage', 'manifest_url', 'previews', 'ratings', 'status', 'support_email', 'support_url') data = dict(zip(attrs, attrgetter(*attrs)(obj))) data.update({ 'absolute_url': absolutify(app.get_detail_url()), 'app_type': app.app_type, 'categories': [c for c in obj.category], 'description': get_attr_lang(src, 'description', obj.default_locale), 'device_types': [DEVICE_TYPES[d].api_name for d in src['device']], 'icons': dict((i['size'], i['url']) for i in src['icons']), 'id': str(obj._id), 'is_packaged': is_packaged, 'listed_authors': [{ 'name': name } for name in src['authors']], 'name': get_attr_lang(src, 'name', obj.default_locale), 'premium_type': amo.ADDON_PREMIUM_API[src['premium_type']], 'privacy_policy': PrivacyPolicyResource().get_resource_uri(GenericObject({'pk': obj._id})), 'public_stats': obj.has_public_stats, 'summary': get_attr_lang(src, 'summary', obj.default_locale), 'supported_locales': src.get('supported_locales', ''), 'slug': obj.app_slug, }) data['regions'] = RegionResource().dehydrate_objects( map(REGIONS_CHOICES_ID_DICT.get, app.get_region_ids(worldwide=True, excluded=obj.region_exclusions))) if src['premium_type'] in amo.ADDON_PREMIUMS: acct = list(AddonPaymentAccount.objects.filter(addon=app)) if acct and acct.payment_account: data['payment_account'] = AccountResource().get_resource_uri( acct.payment_account) else: data['payment_account'] = None data['price'] = data['price_locale'] = None try: if src['price_tier']: price = Price.objects.get(name=src['price_tier']) data['price'] = price.get_price(currency=currency) data['price_locale'] = price.get_price_locale(currency=currency) except Price.DoesNotExist: pass data['upsell'] = False if hasattr(obj, 'upsell'): data['upsell'] = obj.upsell data['upsell']['resource_uri'] = AppResource().get_resource_uri( Webapp(id=obj.upsell['id'])) # TODO: Let's get rid of these from the API to avoid db hits. if profile and isinstance(profile, UserProfile): data['user'] = { 'developed': AddonUser.objects.filter(user=profile, role=amo.AUTHOR_ROLE_OWNER).exists(), 'installed': Installed.objects.filter(user=profile, addon_id=obj.id).exists(), 'purchased': obj.id in profile.purchase_ids(), } return data