Пример #1
0
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)
Пример #2
0
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())
    })
Пример #3
0
 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)
Пример #4
0
    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")
Пример #5
0
 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)
Пример #6
0
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)
Пример #7
0
 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)
Пример #8
0
    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)
Пример #9
0
 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)
Пример #10
0
 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)
Пример #11
0
    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)
Пример #12
0
    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")
Пример #13
0
    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')
Пример #14
0
    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)
Пример #15
0
    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')
Пример #16
0
    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')
Пример #17
0
    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)
Пример #18
0
 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()
Пример #19
0
 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()
Пример #20
0
    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')
Пример #21
0
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
    })
Пример #22
0
    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'))
Пример #23
0
    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'))
Пример #24
0
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,
    })
Пример #25
0
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,
    })
Пример #26
0
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]}
    )
Пример #27
0
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
    })
Пример #28
0
 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'],
     }
Пример #29
0
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
    })
Пример #30
0
    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')
Пример #31
0
    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)
Пример #32
0
    def test_xss(self):
        nasty = '<script>'
        escaped = '&lt;script&gt;'
        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)
Пример #33
0
    def test_xss(self):
        nasty = "<script>"
        escaped = "&lt;script&gt;"
        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)
Пример #34
0
    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)
Пример #35
0
 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'],
     }
Пример #36
0
    def test_xss(self):
        nasty = '<script>'
        escaped = '&lt;script&gt;'
        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)
Пример #37
0
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')
Пример #38
0
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]
    })
Пример #39
0
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.'))
Пример #40
0
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]
    })
Пример #41
0
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.'))
Пример #42
0
    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
Пример #43
0
    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
Пример #44
0
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'],
        }
Пример #45
0
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"],
        }
Пример #46
0
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'],
        }
Пример #47
0
 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)
Пример #48
0
 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)
Пример #49
0
    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)
Пример #50
0
    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))
Пример #51
0
    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
Пример #52
0
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)
Пример #53
0
    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)
Пример #54
0
    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)
Пример #55
0
    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))
Пример #56
0
    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))
Пример #57
0
 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)
Пример #58
0
    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})})
Пример #59
0
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,
    })