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.developers.models import AddonPaymentAccount from mkt.webapps.models import Installed, Webapp translation_fields = ('banner_message', 'description', 'homepage', 'name', 'release_notes', 'support_email', 'support_url') lang = None if request and request.method == 'GET' and 'lang' in request.GET: lang = request.GET.get('lang', '').lower() 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 = ('created', 'current_version', 'default_locale', 'is_offline', 'manifest_url', 'previews', 'reviewed', 'ratings', 'status', 'weekly_downloads') data = dict((a, getattr(obj, a, None)) for a in attrs) # Flatten the localized fields from {'lang': ..., 'string': ...} # to {lang: string}. for field in translation_fields: src_field = '%s_translations' % field value_field = src.get(src_field) src[src_field] = dict((v.get('lang', ''), v.get('string', '')) for v in value_field) if value_field else {} data[field] = get_translations(src, src_field, obj.default_locale, lang) if getattr(obj, 'content_ratings', None): for region_key in obj.content_ratings: obj.content_ratings[region_key] = dehydrate_content_rating( obj.content_ratings[region_key], region_key) data.update({ 'absolute_url': absolutify(app.get_detail_url()), 'app_type': app.app_type, 'author': src.get('author', ''), 'banner_regions': src.get('banner_regions', []), 'categories': [c for c in obj.category], 'content_ratings': { 'ratings': getattr(obj, 'content_ratings', {}), 'descriptors': dehydrate_descriptors( getattr(obj, 'content_descriptors', {})), 'interactive_elements': dehydrate_interactives( getattr(obj, 'interactive_elements', [])), }, '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, 'payment_required': False, 'premium_type': amo.ADDON_PREMIUM_API[src.get('premium_type')], 'privacy_policy': reverse('app-privacy-policy-detail', kwargs={'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 def serialize_region(o): d = {} for field in ('name', 'slug', 'mcc', 'adolescent'): d[field] = getattr(o, field, None) return d data['regions'] = [serialize_region(REGIONS_CHOICES_ID_DICT.get(k)) for k in 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'] = reverse( 'payment-account-detail', kwargs={'pk': acct.payment_account.pk}) 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'] = reverse( 'app-detail', kwargs={'pk': 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) 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 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.developers.api import AccountResource from mkt.developers.models import AddonPaymentAccount from mkt.webapps.models import Installed, Webapp from stats.models import Contribution 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', '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'), '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'), 'premium_type': amo.ADDON_PREMIUM_API[src['premium_type']], 'public_stats': obj.has_public_stats, 'slug': obj.app_slug, }) 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 try: 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: data['price'] = data['price_locale'] = None # 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(), } try: contribution = Contribution.objects.get( user=profile, addon_id=obj.id) data['user']['purchased'] = ( contribution.type == amo.CONTRIB_PURCHASE) except Contribution.DoesNotExist: data['user']['purchased'] = False 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 es_app_to_dict(obj, profile=None, request=None): """ Return app data as dict for API where `app` is the elasticsearch result. """ # Circular import. from mkt.developers.models import AddonPaymentAccount from mkt.webapps.models import Installed, Webapp translation_fields = ('banner_message', 'description', 'homepage', 'name', 'release_notes', 'support_email', 'support_url') lang = None if request and request.method == 'GET' and 'lang' in request.GET: lang = request.GET.get('lang', '').lower() region_slug = None region_id = None if request and request.method == 'GET' and 'region' in request.GET: region_slug = request.GET.get('region', '').lower() if region_slug not in REGIONS_DICT: region_slug = get_region() region_id = REGIONS_DICT[region_slug].id src = obj._source is_packaged = src.get('app_type') != amo.ADDON_WEBAPP_HOSTED # The following doesn't perform a database query, but gives us useful # methods like `get_detail_url` and `get_icon_url`. If you use `app` make # sure the calls don't query the database. app = Webapp(id=obj._id, app_slug=obj.app_slug, is_packaged=is_packaged, type=amo.ADDON_WEBAPP, icon_type='image/png', modified=getattr(obj, 'modified', None)) attrs = ('created', 'current_version', 'default_locale', 'is_offline', 'manifest_url', 'reviewed', 'ratings', 'status', 'weekly_downloads') data = dict((a, getattr(obj, a, None)) for a in attrs) # Flatten the localized fields from {'lang': ..., 'string': ...} # to {lang: string}. for field in translation_fields: src_field = '%s_translations' % field value_field = src.get(src_field) src[src_field] = dict((v.get('lang', ''), v.get('string', '')) for v in value_field) if value_field else {} data[field] = get_translations(src, src_field, obj.default_locale, lang) # Generate urls for previews and icons before the data.update() call below # adds them to the result. previews = getattr(obj, 'previews', []) for preview in previews: if 'image_url' and 'thumbnail_url' in preview: # Old-style index, the full URL is already present, nothing to do. # TODO: remove this check once we have re-indexed everything. continue else: # New-style index, we need to build the URLs from the data we have. p = Preview(id=preview.pop('id'), modified=preview.pop('modified'), filetype=preview['filetype']) preview['image_url'] = p.image_url preview['thumbnail_url'] = p.thumbnail_url icons = getattr(obj, 'icons', []) for icon in icons: if 'url' in icon: # Old-style index, the full URL is already present, nothing to do. # TODO: remove this check once we have re-indexed everything. continue else: # New-style index, we need to build the URLs from the data we have. icon['url'] = app.get_icon_url(icon['size']) data.update({ 'absolute_url': absolutify(app.get_detail_url()), 'app_type': 'packaged' if is_packaged else 'hosted', 'author': src.get('author', ''), 'banner_regions': src.get('banner_regions', []), 'categories': [c for c in obj.category], 'content_ratings': filter_content_ratings_by_region({ 'ratings': dehydrate_content_ratings( getattr(obj, 'content_ratings', {})), 'descriptors': dehydrate_descriptors( getattr(obj, 'content_descriptors', {})), 'interactive_elements': dehydrate_interactives( getattr(obj, 'interactive_elements', [])), 'regions': mkt.regions.REGION_TO_RATINGS_BODY() }, region=region_slug), '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': long(obj._id), 'is_packaged': is_packaged, 'payment_required': False, 'premium_type': amo.ADDON_PREMIUM_API[src.get('premium_type')], 'previews': previews, 'privacy_policy': reverse('app-privacy-policy-detail', kwargs={'pk': obj._id}), 'public_stats': obj.has_public_stats, 'supported_locales': src.get('supported_locales', ''), 'slug': obj.app_slug, 'versions': dict((v.get('version'), v.get('resource_uri')) for v in src.get('versions')), }) if not data['public_stats']: data['weekly_downloads'] = None def serialize_region(o): d = {} for field in ('name', 'slug', 'mcc', 'adolescent'): d[field] = getattr(o, field, None) return d data['regions'] = [serialize_region(REGIONS_CHOICES_ID_DICT.get(k)) for k in app.get_region_ids( worldwide=True, excluded=obj.region_exclusions)] data['payment_account'] = None if src.get('premium_type') in amo.ADDON_PREMIUMS: try: acct = AddonPaymentAccount.objects.get(addon_id=src.get('id')) if acct.payment_account: data['payment_account'] = reverse( 'payment-account-detail', kwargs={'pk': acct.payment_account.pk}) except AddonPaymentAccount.DoesNotExist: pass # Developer hasn't set up a payment account yet. data['upsell'] = False if hasattr(obj, 'upsell'): exclusions = obj.upsell.get('region_exclusions') if exclusions is not None and region_slug not in exclusions: data['upsell'] = obj.upsell data['upsell']['resource_uri'] = reverse( 'app-detail', kwargs={'pk': 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) price_currency = price.get_price_currency(region=region_id) if price_currency and price_currency.paid: data['price'] = price.get_price(region=region_id) data['price_locale'] = price.get_price_locale( region=region_id) 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 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 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_PACKAGED 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["price"] = data["price_locale"] = None try: price_tier = src.get("price_tier") if price_tier: price = Price.objects.get(name=price_tier) if region in settings.PURCHASE_ENABLED_REGIONS or ( request and waffle.flag_is_active(request, "allow-paid-app-search") ): 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 data["upsell"] = False if hasattr(obj, "upsell") and region in settings.PURCHASE_ENABLED_REGIONS: 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(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 es_app_to_dict(obj, region=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(region=region) data['price_locale'] = price.get_price_locale(region=region) except (Price.DoesNotExist, KeyError): log.warning('Issue with price tier on app: {0}'.format(obj._id)) 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
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