def _search(request, category=None): ctx = {'browse': True} region = getattr(request, 'REGION', mkt.regions.WORLDWIDE) if category is not None: qs = Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0) ctx['category'] = get_object_or_404(qs, slug=category) ctx['featured'] = Webapp.featured(cat=ctx['category'], region=region, mobile=request.MOBILE) # Do a search filtered by this category and sort by Weekly Downloads. # TODO: Listen to andy and do not modify `request.GET` but at least # the traceback is fixed now. request.GET = request.GET.copy() request.GET.update({'cat': ctx['category'].id}) if not request.GET.get('sort'): request.GET['sort'] = 'downloads' else: ctx['featured'] = Webapp.featured(region=region, mobile=request.MOBILE) # Always show three (or zero) featured apps - nothing in between. ctx['featured'] = ctx['featured'][:0 if len(ctx['featured']) < 3 else 3] ctx.update(_app_search(request, category=ctx.get('category'), browse=True)) # If category is not listed as a facet, then remove redirect to search. if ctx.get('redirect'): return http.HttpResponseRedirect(ctx['redirect']) return jingo.render(request, 'search/results.html', ctx)
def featured_apps_admin(request): home_collection = Webapp.featured_collection('home') category_collection = Webapp.featured_collection('category') if request.POST: if 'home_submit' in request.POST: coll = home_collection rowid = 'home' elif 'category_submit' in request.POST: coll = category_collection rowid = 'category' existing = set(coll.addons.values_list('id', flat=True)) requested = set(int(request.POST[k]) for k in sorted(request.POST.keys()) if k.endswith(rowid + '-webapp')) CollectionAddon.objects.filter(collection=coll, addon__in=(existing - requested)).delete() for id in requested - existing: CollectionAddon.objects.create(collection=coll, addon_id=id) messages.success(request, 'Changes successfully saved.') return redirect(reverse('admin.featured_apps')) return jingo.render(request, 'zadmin/featuredapp.html', { 'home_featured': enumerate(home_collection.addons.all()), 'category_featured': enumerate(category_collection.addons.all()) })
def setUp(self): self.saved_cb = models._on_change_callbacks.copy() models._on_change_callbacks.clear() self.cb = Mock() self.cb.__name__ = 'testing_mock_callback' Webapp.on_change(self.cb) self.testapp = app_factory(public_stats=True)
def test_get_stats_url(self): webapp = Webapp(app_slug="woo") eq_(webapp.get_stats_url(), "/app/woo/statistics/") url = webapp.get_stats_url(action="installs_series", args=["day", "20120101", "20120201", "json"]) eq_(url, "/app/woo/statistics/installs-day-20120101-20120201.json")
def setUp(self): self.saved_cb = mkt.site.models._on_change_callbacks.copy() mkt.site.models._on_change_callbacks.clear() self.cb = Mock() self.cb.__name__ = 'testing_mock_callback' Webapp.on_change(self.cb) self.testapp = app_factory(public_stats=True)
def _search(request, category=None): ctx = {'browse': True} region = getattr(request, 'REGION', mkt.regions.WORLDWIDE) if category is not None: qs = Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0) ctx['category'] = get_object_or_404(qs, slug=category) ctx['featured'] = Webapp.featured(cat=ctx['category'], region=region) # Do a search filtered by this category and sort by Weekly Downloads. # TODO: Listen to andy and do not modify `request.GET` but at least # the traceback is fixed now. request.GET = request.GET.copy() request.GET.update({'cat': ctx['category'].id}) if not request.GET.get('sort'): request.GET['sort'] = 'downloads' else: ctx['featured'] = Webapp.featured(region=region) # Always show three (or zero) featured apps - nothing in between. ctx['featured'] = ctx['featured'][:0 if len(ctx['featured']) < 3 else 3] ctx.update(_app_search(request, category=ctx.get('category'), browse=True)) # If category is not listed as a facet, then remove redirect to search. if ctx.get('redirect'): return http.HttpResponseRedirect(ctx['redirect']) return jingo.render(request, 'search/results.html', ctx)
def test_multiple_ignored(self): cb = Mock() cb.__name__ = 'something' old = len(mkt.site.models._on_change_callbacks[Webapp]) Webapp.on_change(cb) eq_(len(mkt.site.models._on_change_callbacks[Webapp]), old + 1) Webapp.on_change(cb) eq_(len(mkt.site.models._on_change_callbacks[Webapp]), old + 1)
def test_has_premium(self): webapp = Webapp(premium_type=amo.ADDON_PREMIUM) webapp._premium = mock.Mock() webapp._premium.price = 1 eq_(webapp.has_premium(), True) webapp._premium.price = 0 eq_(webapp.has_premium(), True)
def test_get_price(self): # This test can be expensive to set up, lets just check it goes # down the stack. webapp = Webapp(premium_type=amo.ADDON_PREMIUM) webapp._premium = mock.Mock() webapp._premium.has_price.return_value = True webapp._premium.get_price.return_value = 1 eq_(webapp.get_price(currency='USD'), 1)
def test_multiple_ignored(self): cb = Mock() cb.__name__ = 'something' old = len(models._on_change_callbacks[Webapp]) Webapp.on_change(cb) eq_(len(models._on_change_callbacks[Webapp]), old + 1) Webapp.on_change(cb) eq_(len(models._on_change_callbacks[Webapp]), old + 1)
def test_get_stats_url(self): self.skip_if_disabled(settings.REGION_STORES) webapp = Webapp(app_slug="woo") eq_(webapp.get_stats_url(), "/app/woo/statistics/") url = webapp.get_stats_url(action="installs_series", args=["day", "20120101", "20120201", "json"]) eq_(url, "/app/woo/statistics/installs-day-20120101-20120201.json")
def test_get_stats_url(self): webapp = Webapp(app_slug='woo') eq_(webapp.get_stats_url(), '/app/woo/statistics/') url = webapp.get_stats_url(action='installs_series', args=['day', '20120101', '20120201', 'json']) eq_(url, '/app/woo/statistics/installs-day-20120101-20120201.json')
def test_has_price(self): webapp = Webapp(premium_type=amo.ADDON_PREMIUM) webapp._premium = mock.Mock() webapp._premium.price = None webapp._premium.has_price.return_value = True eq_(webapp.has_price(), True) webapp._premium.has_price.return_value = False eq_(webapp.has_price(), False)
def test_get_stats_url(self): self.skip_if_disabled(settings.REGION_STORES) webapp = Webapp(app_slug='woo') eq_(webapp.get_stats_url(), '/app/woo/statistics/') url = webapp.get_stats_url(action='installs_series', args=['day', '20120101', '20120201', 'json']) eq_(url, '/app/woo/statistics/installs-day-20120101-20120201.json')
def test_get_stats_url(self): webapp = Webapp(app_slug='woo') eq_(webapp.get_stats_url(), '/app/woo/statistics/') url = webapp.get_stats_url( action='installs_series', args=['day', '20120101', '20120201', 'json']) eq_(url, '/app/woo/statistics/installs-day-20120101-20120201.json')
def test_assign_uuid_max_tries(self, mock_uuid4): guid = 'abcdef12-abcd-abcd-abcd-abcdef123456' mock_uuid4.return_value = uuid.UUID(guid) # Create another webapp with and set the guid. Webapp.objects.create(guid=guid) # Now `assign_uuid()` should fail. app = Webapp() with self.assertRaises(ValueError): app.save()
def home(request): """The home page.""" if not getattr(request, 'can_view_consumer', True): return jingo.render(request, 'home/home_walled.html') featured = Webapp.featured('home')[:3] popular = Webapp.popular()[:6] return jingo.render(request, 'home/home.html', { 'featured': featured, 'popular': popular })
def tearDown(self): # Taken from MultiSearchView test. for w in Webapp.objects.all(): w.delete() for w in Website.objects.all(): w.delete() super(TestDailyGamesView, self).tearDown() Webapp.get_indexer().unindexer(_all=True) Website.get_indexer().unindexer(_all=True) self.refresh(('webapp', 'website'))
def home(request): """The home page.""" if not getattr(request, 'can_view_consumer', True): return jingo.render(request, 'home/home_walled.html') region = getattr(request, 'REGION', mkt.regions.WORLDWIDE) featured = Webapp.featured(region=region, cat=None)[:9] popular = _add_mobile_filter(request, Webapp.popular(region=region))[:10] latest = _add_mobile_filter(request, Webapp.latest(region=region))[:10] return jingo.render(request, 'home/home.html', { 'featured': featured, })
def _landing(request, category=None): if category: category = get_object_or_404(Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0), slug=category) featured = Webapp.featured(category) popular = Webapp.popular().filter(category=category.id) else: popular = Webapp.popular() featured = Webapp.featured(None) return jingo.render( request, "browse/landing.html", {"category": category, "featured": featured[:6], "popular": popular[:6]} )
def home(request): """The home page.""" if not getattr(request, 'can_view_consumer', True): return jingo.render(request, 'home/home_walled.html') featured = Webapp.featured('home')[:6] popular = Webapp.popular()[:10] latest = Webapp.latest()[:10] return jingo.render(request, 'home/home.html', { 'featured': featured, 'popular': popular, 'latest': latest })
def to_native(self, obj): # fake_app is a fake instance because we need to access a couple # properties and methods on Webapp. It should never hit the database. fake_app = Webapp(id=obj['id'], icon_type='image/png', modified=datetime.strptime(obj['modified'], '%Y-%m-%dT%H:%M:%S')) ESTranslationSerializerField.attach_translations(fake_app, obj, 'name') return { 'name': self.fields['name'].field_to_native(fake_app, 'name'), 'icon' : fake_app.get_icon_url(64), 'slug': obj['slug'], 'manifest_url': obj['manifest_url'], }
def home(request): """The home page.""" if not getattr(request, 'can_view_consumer', True): return jingo.render(request, 'home/home_walled.html') featured = Webapp.featured(cat=None) popular = Webapp.popular()[:10] latest = Webapp.latest()[:10] return jingo.render(request, 'home/home.html', { 'featured': featured, 'popular': popular, 'latest': latest })
def test_app_slug_collision(self): Webapp(app_slug='slug').save() w2 = Webapp(app_slug='slug') w2.save() eq_(w2.app_slug, 'slug-1') w3 = Webapp(app_slug='slug') w3.save() eq_(w3.app_slug, 'slug-2')
def test_initial(self): app = Webapp(status=amo.STATUS_PUBLIC) eq_(self.form(None, addon=app).fields['publish_type'].initial, amo.PUBLISH_IMMEDIATE) eq_(self.form(None, addon=app).fields['limited'].initial, False) app.status = amo.STATUS_UNLISTED eq_(self.form(None, addon=app).fields['publish_type'].initial, amo.PUBLISH_HIDDEN) eq_(self.form(None, addon=app).fields['limited'].initial, False) app.status = amo.STATUS_APPROVED eq_(self.form(None, addon=app).fields['publish_type'].initial, amo.PUBLISH_HIDDEN) eq_(self.form(None, addon=app).fields['limited'].initial, True)
def test_xss(self): nasty = '<script>' escaped = '<script>' author = self.webapp.authors.all()[0] author.display_name = nasty author.save() self.webapp.name = nasty self.webapp.save() Webapp.transformer([self.webapp]) # Transform `listed_authors`, etc. doc = pq(market_tile(self.context, self.webapp)) data = json.loads(doc('.mkt-tile').attr('data-product')) eq_(data['name'], escaped) eq_(data['author'], escaped)
def test_xss(self): nasty = "<script>" escaped = "<script>" author = self.webapp.authors.all()[0] author.display_name = nasty author.save() self.webapp.name = nasty self.webapp.save() Webapp.transformer([self.webapp]) # Transform `listed_authors`, etc. doc = pq(market_tile(self.context, self.webapp)) data = json.loads(doc(".mkt-tile").attr("data-product")) eq_(data["name"], escaped) eq_(data["author"], escaped)
def test_initial(self): app = Webapp(status=mkt.STATUS_PUBLIC) eq_(self.form(None, addon=app).fields['publish_type'].initial, mkt.PUBLISH_IMMEDIATE) eq_(self.form(None, addon=app).fields['limited'].initial, False) app.status = mkt.STATUS_UNLISTED eq_(self.form(None, addon=app).fields['publish_type'].initial, mkt.PUBLISH_HIDDEN) eq_(self.form(None, addon=app).fields['limited'].initial, False) app.status = mkt.STATUS_APPROVED eq_(self.form(None, addon=app).fields['publish_type'].initial, mkt.PUBLISH_HIDDEN) eq_(self.form(None, addon=app).fields['limited'].initial, True)
def to_native(self, obj): # fake_app is a fake instance because we need to access a couple # properties and methods on Webapp. It should never hit the database. fake_app = Webapp( id=obj['id'], icon_type='image/png', type=amo.ADDON_WEBAPP, default_locale=obj.get('default_locale', settings.LANGUAGE_CODE), icon_hash=obj.get('icon_hash'), modified=datetime.strptime(obj['modified'], '%Y-%m-%dT%H:%M:%S')) ESTranslationSerializerField.attach_translations(fake_app, obj, 'name') return { 'name': self.fields['name'].field_to_native(fake_app, 'name'), 'icon': fake_app.get_icon_url(64), 'slug': obj['slug'], 'manifest_url': obj['manifest_url'], }
def queue_apps(request): queues_helper = ReviewersQueuesHelper(request) qs = queues_helper.get_pending_queue() apps = queues_helper.sort(qs, date_sort='nomination') apps = [QueuedApp(app, app.all_versions[0].nomination) for app in Webapp.version_and_file_transformer(apps)] return _queue(request, apps, 'pending', date_sort='nomination')
def _landing(request, category=None): featured = Webapp.featured('category') popular = Webapp.popular() if category: category = get_object_or_404(Category.objects.filter( type=amo.ADDON_WEBAPP, weight__gte=0), slug=category) featured = featured.filter(category=category)[:6] popular = popular.filter(category=category.id) return jingo.render(request, 'browse/landing.html', { 'category': category, 'featured': featured[:6], 'popular': popular[:6] })
def verify_app_domain(manifest_url): if waffle.switch_is_active('webapps-unique-by-domain'): domain = Webapp.domain_from_url(manifest_url) if Addon.objects.filter(app_domain=domain).exists(): raise forms.ValidationError( _('An app already exists on this domain, ' 'only one app per domain is allowed.'))
def _landing(request, category=None): featured = Webapp.featured('category') popular = Webapp.popular() if category: category = get_object_or_404( Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0), slug=category) featured = featured.filter(category=category)[:6] popular = popular.filter(category=category.id) return jingo.render(request, 'browse/landing.html', { 'category': category, 'featured': featured[:6], 'popular': popular[:6] })
def alter_list_data_to_serialize(self, request, data): if waffle.switch_is_active("rocketfuel"): types = ( ("collections", COLLECTIONS_TYPE_BASIC), ("featured", COLLECTIONS_TYPE_FEATURED), ("operator", COLLECTIONS_TYPE_OPERATOR), ) for name, col_type in types: data[name] = self.collections(request, collection_type=col_type) else: form_data = self.get_search_data(request) region = getattr(request, "REGION", mkt.regions.WORLDWIDE) cat_slug = form_data.get("cat") if cat_slug: cat_slug = [cat_slug] # Filter by device feature profile. profile = self.get_feature_profile(request) qs = Webapp.featured(cat=cat_slug, region=region, profile=profile) bundles = (self.build_bundle(obj=obj, request=request) for obj in qs) data["featured"] = [AppResource().full_dehydrate(bundle) for bundle in bundles] # Alter the _view_name so that statsd logs seperately from search. request._view_name = "featured" return data
def queryset(self): res = SearchSuggestionsAjax.queryset(self) if self.category: res = res.filter(category__in=[self.category]) if (self.mobile or self.tablet) and not self.gaia: if isinstance(res, S): res = res.filter( ~F(premium_type__in=amo.ADDON_PREMIUMS, price__gt=0)) else: res.exclude(premium_type__in=amo.ADDON_PREMIUMS, price__gt=0) region = getattr(self.request, 'REGION', mkt.regions.WORLDWIDE) if region: excluded = Webapp.get_excluded_in(region) if excluded: if isinstance(res, S): # ES? Do fanciness. res = res.filter(~F(id__in=excluded)) else: # Django ORM? Do an `exclude`. res = res.exclude(id__in=excluded) if self.gaia: res = res.filter(device=amo.DEVICE_GAIA.id, uses_flash=False) elif self.mobile: res = res.filter(device=amo.DEVICE_MOBILE.id, uses_flash=False) return res
class RocketbarESAppSerializer(serializers.Serializer): """Used by Firefox OS's Rocketbar apps viewer.""" name = ESTranslationSerializerField() @property def data(self): if self._data is None: self._data = [self.to_native(o['payload']) for o in self.object] return self._data def to_native(self, obj): # fake_app is a fake instance because we need to access a couple # properties and methods on Webapp. It should never hit the database. self.fake_app = Webapp( id=obj['id'], icon_type='image/png', default_locale=obj.get('default_locale', settings.LANGUAGE_CODE), icon_hash=obj.get('icon_hash'), modified=es_to_datetime(obj['modified'])) ESTranslationSerializerField.attach_translations( self.fake_app, obj, 'name') return { 'name': self.fields['name'].field_to_native(self.fake_app, 'name'), 'icon': self.fake_app.get_icon_url(64), 'slug': obj['slug'], 'manifest_url': obj['manifest_url'], }
class RocketbarESAppSerializer(serializers.Serializer): """Used by Firefox OS's Rocketbar apps viewer.""" name = ESTranslationSerializerField() @property def data(self): if self._data is None: self._data = [self.to_native(o["payload"]) for o in self.object] return self._data def to_native(self, obj): # fake_app is a fake instance because we need to access a couple # properties and methods on Webapp. It should never hit the database. self.fake_app = Webapp( id=obj["id"], icon_type="image/png", type=amo.ADDON_WEBAPP, default_locale=obj.get("default_locale", settings.LANGUAGE_CODE), icon_hash=obj.get("icon_hash"), modified=es_to_datetime(obj["modified"]), ) ESTranslationSerializerField.attach_translations(self.fake_app, obj, "name") return { "name": self.fields["name"].field_to_native(self.fake_app, "name"), "icon": self.fake_app.get_icon_url(64), "slug": obj["slug"], "manifest_url": obj["manifest_url"], }
class RocketbarESAppSerializer(serializers.Serializer): """Used by Firefox OS's Rocketbar apps viewer.""" name = ESTranslationSerializerField() @property def data(self): if self._data is None: self._data = [self.to_native(o['payload']) for o in self.object] return self._data def to_native(self, obj): # fake_app is a fake instance because we need to access a couple # properties and methods on Webapp. It should never hit the database. self.fake_app = Webapp(id=obj['id'], icon_type='image/png', default_locale=obj.get('default_locale', settings.LANGUAGE_CODE), icon_hash=obj.get('icon_hash'), modified=es_to_datetime(obj['modified'])) ESTranslationSerializerField.attach_translations( self.fake_app, obj, 'name') return { 'name': self.fields['name'].field_to_native(self.fake_app, 'name'), 'icon': self.fake_app.get_icon_url(64), 'slug': obj['slug'], 'manifest_url': obj['manifest_url'], }
def test_field_null(self): field = self.field_class() self.app = Webapp() result = field.field_to_native(self.app, 'name') eq_(result, None) result = field.field_to_native(self.app, 'description') eq_(result, None)
def get_query(self, request, base_filters=None, region=None): return Webapp.from_search(request, region=region, gaia=request.GAIA, mobile=request.MOBILE, tablet=request.TABLET, filter_overrides=base_filters)
def field_to_native_es(self, obj, request): """ A version of field_to_native that uses ElasticSearch to fetch the apps belonging to the collection instead of SQL. Relies on a FeaturedSearchView instance in self.context['view'] to properly rehydrate results returned by ES. """ profile = get_feature_profile(request) region = self.context['view'].get_region_from_request(request) device = self._get_device(request) _rget = lambda d: getattr(request, d, False) qs = Webapp.from_search(request, region=region, gaia=_rget('GAIA'), mobile=_rget('MOBILE'), tablet=_rget('TABLET')) filters = {'collection.id': obj.pk} if device and device != amo.DEVICE_DESKTOP: filters['device'] = device.id if profile: filters.update(**profile.to_kwargs(prefix='features.has_')) qs = qs.filter(**filters).order_by({ 'collection.order': { 'order': 'asc', 'nested_filter': { 'term': {'collection.id': obj.pk} } } }) return self.to_native(qs, use_es=True)
def save_categories(self, obj, categories): before = set(obj.categories.values_list('id', flat=True)) # Add new categories. to_add = set(c.id for c in categories) - before for c in to_add: AddonCategory.objects.create(addon=obj, category_id=c) # Remove old categories. to_remove = before - set(categories) for c in to_remove: obj.addoncategory_set.filter(category=c).delete() # Disallow games in Brazil without a rating. games = Webapp.category('games') if not games: return for region in ALL_REGIONS_WITH_CONTENT_RATINGS(): if (self.product.listed_in(region) and not self.product.content_ratings_in(region)): if games.id in to_add: aer, created = AddonExcludedRegion.objects.get_or_create( addon=self.product, region=region.id) if created: log.info(u'[Webapp:%s] Game excluded from new region ' u'(%s).' % (self.product, region.slug)) elif games.id in to_remove: self.product.addonexcludedregion.filter( region=region.id).delete() log.info(u'[Webapp:%s] Game no longer excluded from region' u' (%s).' % (self.product, region.slug))
def alter_list_data_to_serialize(self, request, data): if waffle.switch_is_active('rocketfuel'): types = ( ('collections', COLLECTIONS_TYPE_BASIC), ('featured', COLLECTIONS_TYPE_FEATURED), ('operator', COLLECTIONS_TYPE_OPERATOR), ) self.filter_fallbacks = {} for name, col_type in types: data[name], fallback = self.collections(request, collection_type=col_type) if fallback: self.filter_fallbacks[name] = fallback else: form_data = self.get_search_data(request) region = getattr(request, 'REGION', mkt.regions.WORLDWIDE) cat_slug = form_data.get('cat') if cat_slug: cat_slug = [cat_slug] # Filter by device feature profile. profile = self.get_feature_profile(request) qs = Webapp.featured(cat=cat_slug, region=region, profile=profile) bundles = (self.build_bundle(obj=obj, request=request) for obj in qs) data['featured'] = [AppResource().full_dehydrate(bundle) for bundle in bundles] # Alter the _view_name so that statsd logs seperately from search. request._view_name = 'featured' return data
def run(): """Exclude Games in Brazil.""" games = Webapp.category('games') if games: apps = Webapp.objects.filter(categories=games.id) for app in apps: AER.objects.get_or_create(addon=app, region=mkt.regions.BR.id)
def field_to_native_es(self, obj, request): """ A version of field_to_native that uses ElasticSearch to fetch the apps belonging to the collection instead of SQL. Relies on a FeaturedSearchView instance in self.context['view'] to properly rehydrate results returned by ES. """ profile = get_feature_profile(request) region = self.context['view'].get_region(request) device = self._get_device(request) _rget = lambda d: getattr(request, d, False) qs = Webapp.from_search(request, region=region, gaia=_rget('GAIA'), mobile=_rget('MOBILE'), tablet=_rget('TABLET')) filters = {'collection.id': obj.pk} if device and device != amo.DEVICE_DESKTOP: filters['device'] = device.id if profile: filters.update(**profile.to_kwargs(prefix='features.has_')) qs = qs.filter(**filters).order_by({ 'collection.order': { 'order': 'asc', 'nested_filter': { 'term': { 'collection.id': obj.pk } } } }) return self.to_native_es(qs)
def field_to_native_es(self, obj, request): """ A version of field_to_native that uses ElasticSearch to fetch the apps belonging to the collection instead of SQL. Relies on a FeaturedSearchView instance in self.context['view'] to properly rehydrate results returned by ES. """ profile = get_feature_profile(request) region = self.context['view'].get_region(request) qs = Webapp.from_search(request, region=region) filters = {'collection.id': obj.pk} if profile: filters.update(**profile.to_kwargs(prefix='features.has_')) qs = qs.filter(**filters).order_by({ 'collection.order': { 'order': 'asc', 'nested_filter': { 'term': {'collection.id': obj.pk} } } }) return self.to_native_es(qs)
def save(self): after = list(self.cleaned_data['categories'] .values_list('id', flat=True)) before = self.cats_before # Add new categories. to_add = set(after) - set(before) for c in to_add: AddonCategory.objects.create(addon=self.product, category_id=c) # Remove old categories. to_remove = set(before) - set(after) for c in to_remove: self.product.addoncategory_set.filter(category=c).delete() # Disallow games in Brazil without a rating. games = Webapp.category('games') if (games and self.product.listed_in(mkt.regions.BR) and not self.product.content_ratings_in(mkt.regions.BR)): r = mkt.regions.BR.id if games.id in to_add: g, c = AddonExcludedRegion.objects.get_or_create( addon=self.product, region=r) if c: log.info(u'[Webapp:%s] Game excluded from new region ' '(%s).' % (self.product, r)) elif games.id in to_remove: self.product.addonexcludedregion.filter(region=r).delete() log.info(u'[Webapp:%s] Game no longer exluded from region ' '(%s).' % (self.product, r))
def test_field_null(self): field = TranslationSerializerField() app = Webapp() result = field.field_to_native(app, 'name') eq_(result, None) result = field.field_to_native(app, 'description') eq_(result, None)
def create(self, request, *args, **kwargs): uuid = request.DATA.get("upload", "") if uuid: is_packaged = True else: uuid = request.DATA.get("manifest", "") is_packaged = False if not uuid: raise serializers.ValidationError("No upload or manifest specified.") try: upload = FileUpload.objects.get(uuid=uuid) except FileUpload.DoesNotExist: raise exceptions.ParseError("No upload found.") if not upload.valid: raise exceptions.ParseError("Upload not valid.") if not request.user.read_dev_agreement: log.info(u"Attempt to use API without dev agreement: %s" % request.user.pk) raise exceptions.PermissionDenied("Terms of Service not accepted.") if not (upload.user and upload.user.pk == request.user.pk): raise exceptions.PermissionDenied("You do not own that app.") # Create app, user and fetch the icon. obj = Webapp.from_upload(upload, is_packaged=is_packaged) AddonUser(addon=obj, user=request.user).save() tasks.fetch_icon.delay(obj, obj.latest_version.all_files[0]) record_action("app-submitted", request, {"app-id": obj.pk}) log.info("App created: %s" % obj.pk) data = AppSerializer(context=self.get_serializer_context()).to_native(obj) return response.Response(data, status=201, headers={"Location": reverse("app-detail", kwargs={"pk": obj.pk})})
def home(request): """The home page.""" MOBILE = request.MOBILE and not request.TABLET region = getattr(request, 'REGION', mkt.regions.WORLDWIDE) featured = Webapp.featured(region=region, cat=None, mobile=False, limit=9 if MOBILE else 12) featured_cnt = len(featured) # Show featured apps in multiples of three. if MOBILE: if featured_cnt >= 9: featured = featured[:9] elif featured_cnt >= 6: featured = featured[:6] elif featured_cnt >= 3: featured = featured[:3] else: if featured_cnt >= 12: featured = featured[:12] elif featured_cnt >= 8: featured = featured[:8] elif featured_cnt >= 4: # Once we allow for the giant featured app we'll require at least # 5 featured apps on desktop. featured = featured[:4] return jingo.render(request, 'home/home.html', { 'featured': featured, })