Esempio n. 1
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))
Esempio n. 2
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))
Esempio n. 3
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))
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)
Esempio n. 5
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))
Esempio n. 6
0
    def save(self):
        # Don't save regions if we are toggling.
        if self.is_toggling():
            return

        before = set(self.regions_before)
        after = set(map(int, self.cleaned_data['regions']))

        # If the app is paid, disable regions that do not use payments.
        if self._product_is_paid():
            after &= set(self.price_region_ids)

        # Add new region exclusions.
        to_add = before - after
        for r in to_add:
            g, c = AddonExcludedRegion.objects.get_or_create(
                addon=self.product, region=r)
            if c:
                log.info(u'[Webapp:%s] Excluded from new region (%s).'
                         % (self.product, r))

        # Remove old region exclusions.
        to_remove = after - before
        for r in to_remove:
            self.product.addonexcludedregion.filter(region=r).delete()
            log.info(u'[Webapp:%s] No longer exluded from region (%s).'
                     % (self.product, r))

        if self.cleaned_data['other_regions']:
            # Developer wants to be visible in future regions, then
            # delete excluded regions.
            self.future_exclusions.delete()
            log.info(u'[Webapp:%s] No longer excluded from future regions.'
                     % self.product)
        else:
            # Developer does not want future regions, then
            # exclude all future apps.
            g, c = AddonExcludedRegion.objects.get_or_create(
                addon=self.product, region=mkt.regions.WORLDWIDE.id)
            if c:
                log.info(u'[Webapp:%s] Excluded from future regions.'
                         % self.product)

        # Disallow games in Brazil without a rating.
        games = Webapp.category('games')
        if games:
            r = mkt.regions.BR

            if (self.product.categories.filter(id=games.id) and
                self.product.listed_in(r) and
                not self.product.content_ratings_in(r)):

                g, c = AddonExcludedRegion.objects.get_or_create(
                    addon=self.product, region=r.id)
                if c:
                    log.info(u'[Webapp:%s] Game excluded from new region '
                              '(%s).' % (self.product, r.id))
Esempio n. 7
0
def ban_game_in_brazil(app):
    # Disallow games in Brazil without a rating.
    games = Webapp.category("games")
    if games:
        r = mkt.regions.BR
        if app.categories.filter(id=games.id) and app.listed_in(r) and not app.content_ratings_in(r):

            g, c = AddonExcludedRegion.objects.get_or_create(addon=app, region=r.id)
            if c:
                log.info(u"[Webapp:%s] Game excluded from new region " u"(%s)." % (app, r.id))
Esempio n. 8
0
    def __init__(self, *args, **kw):
        self.product = kw.pop("product", None)
        self.request = kw.pop("request", None)
        self.price = kw.pop("price", None)
        self.region_ids = self.product.get_region_ids()
        super(RegionForm, self).__init__(*args, **kw)

        is_paid = self._product_is_paid()

        # If we have excluded regions, uncheck those.
        # Otherwise, default to everything checked.
        self.regions_before = self.product.get_region_ids()

        # If we have future excluded regions, uncheck box.
        self.future_exclusions = self.product.addonexcludedregion.filter(region=mkt.regions.WORLDWIDE.id)

        self.initial = {
            "regions": self.regions_before,
            "other_regions": (not self.future_exclusions.exists() and not is_paid),
        }

        # Games cannot be listed in Brazil without a content rating.
        self.disabled_regions = set()
        games = Webapp.category("games")
        if (
            games
            and self.product.categories.filter(id=games.id).exists()
            and not self.product.content_ratings_in(mkt.regions.BR)
        ):

            self.disabled_regions.add(mkt.regions.BR.id)

        # If the app is paid, disable regions that use payments.
        if is_paid:
            self.disabled_regions.add(mkt.regions.WORLDWIDE.id)
            self.fields["other_regions"].widget.attrs["disabled"] = "disabled"
            self.fields["other_regions"].label = _(u"Other regions")

            # Premium form was valid.
            if self.price and self.price != "free":
                self.price_region_ids = self.price.pricecurrency_set.values_list("region", flat=True)
            # Free app with in-app payments for this we just want to make
            # sure it's in a region that allows payments.
            elif self.price and self.price == "free":
                self.price_region_ids = ALL_PAID_REGION_IDS
            # Premium form wasn't valid and it is a POST. Since we can't
            # determine what price they wanted, just make sure it isn't a
            # disabled price.
            elif self.data:
                self.price_region_ids = []
            # Not a post, we can trust the price on the product.
            else:
                self.price_region_ids = self.product.get_possible_price_region_ids()

        self.disabled_regions = list(self.disabled_regions)
Esempio n. 9
0
    def _disabled_regions(self):
        disabled_regions = set()

        # Games cannot be listed in Brazil without a content rating.
        games = Webapp.category('games')
        if (games and
            self.product.categories.filter(id=games.id).exists() and
                not self.product.content_ratings_in(mkt.regions.BR)):
            disabled_regions.add(mkt.regions.BR.id)

        return disabled_regions
Esempio n. 10
0
    def _disabled_regions(self):
        disabled_regions = set()

        # Games cannot be listed in Brazil/Germany without a content rating.
        games = Webapp.category('games')

        if games and self.product.categories.filter(id=games.id).exists():
            for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS():
                if not self.product.content_ratings_in(region):
                    disabled_regions.add(region.id)

        return disabled_regions
Esempio n. 11
0
    def save(self):
        before = set(self.regions_before)
        after = set(map(int, self.cleaned_data['regions']))

        # If the app is paid, disable regions that use payments.
        if self._product_is_paid():
            after &= set(mkt.regions.ALL_PAID_REGION_IDS)

        # Add new region exclusions.
        to_add = before - after
        for r in to_add:
            g, c = AddonExcludedRegion.objects.get_or_create(
                addon=self.product, region=r)
            if c:
                log.info(u'[Webapp:%s] Excluded from new region (%s).' %
                         (self.product, r))

        # Remove old region exclusions.
        to_remove = after - before
        for r in to_remove:
            self.product.addonexcludedregion.filter(region=r).delete()
            log.info(u'[Webapp:%s] No longer exluded from region (%s).' %
                     (self.product, r))

        if self.cleaned_data['other_regions']:
            # Developer wants to be visible in future regions, then
            # delete excluded regions.
            self.future_exclusions.delete()
            log.info(u'[Webapp:%s] No longer excluded from future regions.' %
                     self.product)
        else:
            # Developer does not want future regions, then
            # exclude all future apps.
            g, c = AddonExcludedRegion.objects.get_or_create(
                addon=self.product, region=mkt.regions.WORLDWIDE.id)
            if c:
                log.info(u'[Webapp:%s] Excluded from future regions.' %
                         self.product)

        # Disallow games in Brazil without a rating.
        games = Webapp.category('games')
        if games:
            r = mkt.regions.BR

            if (self.product.categories.filter(id=games.id)
                    and self.product.listed_in(r)
                    and not self.product.content_ratings_in(r)):

                g, c = AddonExcludedRegion.objects.get_or_create(
                    addon=self.product, region=r.id)
                if c:
                    log.info(u'[Webapp:%s] Game excluded from new region '
                             '(%s).' % (self.product, r.id))
Esempio n. 12
0
    def _disabled_regions(self):
        disabled_regions = set()

        # Games cannot be listed in Brazil/Germany without a content rating.
        games = Webapp.category('games')

        if games and self.product.categories.filter(id=games.id).exists():
            for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS():
                if not self.product.content_ratings_in(region):
                    disabled_regions.add(region.id)

        return disabled_regions
Esempio n. 13
0
def unban_rated_game(app):
    """Allow games in Brazil/Germany with a rating."""
    if not Webapp.category('games'):
        return
    for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS:
        if (app.listed_in(category='games') and
            app.content_ratings_in(region)):
            aer = app.addonexcludedregion.filter(region=region.id)
            if aer.exists():
                aer.delete()
                log.info(u'[Webapp:%s] Game included for new region '
                         u'(%s).' % (app, region.id))
Esempio n. 14
0
    def __init__(self, *args, **kw):
        self.product = kw.pop('product', None)
        self.request = kw.pop('request', None)
        self.price = kw.pop('price', None)
        self.region_ids = self.product.get_region_ids()
        super(RegionForm, self).__init__(*args, **kw)

        is_paid = self._product_is_paid()

        # If we have excluded regions, uncheck those.
        # Otherwise, default to everything checked.
        self.regions_before = self.product.get_region_ids()

        # If we have future excluded regions, uncheck box.
        self.future_exclusions = self.product.addonexcludedregion.filter(
            region=mkt.regions.WORLDWIDE.id)

        self.initial = {
            'regions': self.regions_before,
            'other_regions': not self.future_exclusions.exists() and
                             not is_paid
        }

        # Games cannot be listed in Brazil without a content rating.
        self.disabled_regions = set()
        games = Webapp.category('games')
        if (games and
            self.product.categories.filter(id=games.id).exists() and
            not self.product.content_ratings_in(mkt.regions.BR)):

            self.disabled_regions.add(mkt.regions.BR.id)

        # If the app is paid, disable regions that use payments.
        if is_paid:
            self.disabled_regions.add(mkt.regions.WORLDWIDE.id)
            self.fields['other_regions'].widget.attrs['disabled'] = 'disabled'
            self.fields['other_regions'].label = _(u'Other regions')

            # Premium form was valid.
            if self.price:
                self.price_region_ids = (self.price.pricecurrency_set
                                         .values_list('region', flat=True))
            # Premium form wasn't valid and it is a POST. Since we can't
            # determine what price they wanted, just make sure it isn't a
            # disabled price.
            elif self.data:
                self.price_region_ids = []
            # Not a post, we can trust the price on the product.
            else:
                self.price_region_ids = (self.product
                                         .get_possible_price_region_ids())

        self.disabled_regions = list(self.disabled_regions)
Esempio n. 15
0
def ban_game_in_brazil(app):
    # Disallow games in Brazil without a rating.
    games = Webapp.category('games')
    if games:
        r = mkt.regions.BR
        if (app.categories.filter(id=games.id) and app.listed_in(r) and
            not app.content_ratings_in(r)):

            g, c = AddonExcludedRegion.objects.get_or_create(
                addon=app, region=r.id)
            if c:
                log.info(u'[Webapp:%s] Game excluded from new region '
                         u'(%s).' % (app, r.id))
Esempio n. 16
0
def ban_unrated_game(app):
    """Disallow games in Brazil/Germany without a rating."""
    if not Webapp.category('games'):
        return
    for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS:
        if (app.listed_in(category='games') and
            app.listed_in(region=region) and
            not app.content_ratings_in(region)):

            aer, created = AddonExcludedRegion.objects.get_or_create(
                addon=app, region=region.id)
            if created:
                log.info(u'[Webapp:%s] Game excluded from new region '
                         u'(%s).' % (app, region.id))
Esempio n. 17
0
    def _disabled_general_regions(self):
        """Regions that are disabled for general reasons."""
        disabled_general_regions = set()

        if self._product_is_paid():
            # Currently worldwide is disabled for paid apps.
            disabled_general_regions.add(mkt.regions.WORLDWIDE.id)

        # Games cannot be listed in Brazil without a content rating.
        games = Webapp.category('games')
        if (games and
            self.product.categories.filter(id=games.id).exists() and
                not self.product.content_ratings_in(mkt.regions.BR)):
            disabled_general_regions.add(mkt.regions.BR.id)

        return disabled_general_regions
Esempio n. 18
0
    def handle(self, *args, **options):
        from mkt.webapps.models import Webapp

        paid_types = amo.ADDON_PREMIUMS + (amo.ADDON_FREE_INAPP,)

        games_cat = Webapp.category('games')
        content_region_ids = [x.id for x in ALL_REGIONS_WITH_CONTENT_RATINGS()]

        apps = Webapp.objects.all()
        for app in apps:
            # If it's already restricted, don't bother.
            if app.geodata.restricted:
                continue

            geodata = {}

            # If this app was excluded in every region except one,
            # let's consider it regionally popular in that particular region.
            region_ids = app.get_region_ids()
            if len(region_ids) == 1:
                geodata['popular_region'] = (
                    REGIONS_CHOICES_ID_DICT[region_ids[0]].slug
                )

            if app.premium_type in paid_types:
                geodata['restricted'] = True
            else:
                exclusions = app.addonexcludedregion.exclude(
                    region__in=SPECIAL_REGION_IDS)
                for exclusion in exclusions:
                    # Do not delete region exclusions meant for unrated games.
                    region = REGIONS_CHOICES_ID_DICT[exclusion.region]
                    if (games_cat and region.id in content_region_ids and
                        app.listed_in(category='games') and
                        not app.content_ratings_in(region)):
                        continue

                    log.info('[App %s - %s] Removed exclusion: %s'
                             % (app.pk, app.slug, exclusion))

                    # Remove all other existing exclusions, since all apps
                    # are public in every region by default. If developers
                    # want to hard-restrict their apps they can now do that.
                    exclusion.delete()

            app.geodata.update(**geodata)
Esempio n. 19
0
    def _disabled_regions(self):
        disabled_regions = set()

        # Games cannot be listed in Brazil/Germany without a content rating.
        games = Webapp.category('games')

        if games and self.product.categories.filter(id=games.id).exists():
            for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS:
                if not self.product.content_ratings_in(region):
                    disabled_regions.add(region.id)

        # If it's been rejected for China, for example, don't ever allow
        # the developer to opt in again.
        for region in self.regions_before:
            status = self.product.geodata.get_status(region)
            if status == amo.STATUS_REJECTED:
                disabled_regions.add(region)

        return disabled_regions
Esempio n. 20
0
def toggle_game(app):
    """
    Exclude unrated games from regions requiring content ratings.
    Allow newly rated games in regions requiring content ratings.
    """
    if not Webapp.category('games'):
        return
    for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS():
        if app.listed_in(category='games'):
            if app.content_ratings_in(region):
                aer = app.addonexcludedregion.filter(region=region.id)
                if aer.exists():
                    aer.delete()
                    log.info(u'[Webapp:%s] Game included in new region '
                             u'(%s).' % (app, region.id))
            else:
                aer, created = app.addonexcludedregion.get_or_create(
                    region=region.id)
                if created:
                    log.info(u'[Webapp:%s] Game excluded from new region '
                             u'(%s).' % (app, region.id))
Esempio n. 21
0
def toggle_game(app):
    """
    Exclude unrated games from regions requiring content ratings.
    Allow newly rated games in regions requiring content ratings.
    """
    if not Webapp.category('games'):
        return
    for region in mkt.regions.ALL_REGIONS_WITH_CONTENT_RATINGS():
        if app.listed_in(category='games'):
            if app.content_ratings_in(region):
                aer = app.addonexcludedregion.filter(region=region.id)
                if aer.exists():
                    aer.delete()
                    log.info(u'[Webapp:%s] Game included in new region '
                             u'(%s).' % (app, region.id))
            else:
                aer, created = app.addonexcludedregion.get_or_create(
                    region=region.id)
                if created:
                    log.info(u'[Webapp:%s] Game excluded from new region '
                             u'(%s).' % (app, region.id))
Esempio n. 22
0
    def __init__(self, *args, **kw):
        self.product = kw.pop('product', None)
        super(RegionForm, self).__init__(*args, **kw)

        is_paid = self._product_is_paid()

        # If we have excluded regions, uncheck those.
        # Otherwise, default to everything checked.
        self.regions_before = self.product.get_region_ids()

        # If we have future excluded regions, uncheck box.
        self.future_exclusions = self.product.addonexcludedregion.filter(
            region=mkt.regions.WORLDWIDE.id)

        self.initial = {
            'regions': self.regions_before,
            'other_regions': not self.future_exclusions.exists() and
                             not is_paid
        }

        # Games cannot be listed in Brazil without a content rating.
        self.disabled_regions = set()
        games = Webapp.category('games')
        if (games and
            self.product.categories.filter(id=games.id).exists() and
            not self.product.content_ratings_in(mkt.regions.BR)):

            self.disabled_regions.add(mkt.regions.BR.id)

        # If the app is paid, disable regions that use payments.
        if is_paid:
            self.disabled_regions.add(mkt.regions.WORLDWIDE.id)
            self.fields['other_regions'].widget.attrs['disabled'] = 'disabled'
            self.fields['other_regions'].label = _(u'Other regions')
            for region in mkt.regions.ALL_REGIONS:
                if not region.has_payments:
                    self.disabled_regions.add(region.id)

        self.disabled_regions = list(self.disabled_regions)
Esempio n. 23
0
    def __init__(self, *args, **kw):
        self.product = kw.pop('product', None)
        super(RegionForm, self).__init__(*args, **kw)

        is_paid = self._product_is_paid()

        # If we have excluded regions, uncheck those.
        # Otherwise, default to everything checked.
        self.regions_before = self.product.get_region_ids()

        # If we have future excluded regions, uncheck box.
        self.future_exclusions = self.product.addonexcludedregion.filter(
            region=mkt.regions.WORLDWIDE.id)

        self.initial = {
            'regions': self.regions_before,
            'other_regions': not self.future_exclusions.exists()
            and not is_paid
        }

        # Games cannot be listed in Brazil without a content rating.
        self.disabled_regions = set()
        games = Webapp.category('games')
        if (games and self.product.categories.filter(id=games.id).exists()
                and not self.product.content_ratings_in(mkt.regions.BR)):

            self.disabled_regions.add(mkt.regions.BR.id)

        # If the app is paid, disable regions that use payments.
        if is_paid:
            self.disabled_regions.add(mkt.regions.WORLDWIDE.id)
            self.fields['other_regions'].widget.attrs['disabled'] = 'disabled'
            self.fields['other_regions'].label = _(u'Other regions')
            for region in mkt.regions.ALL_REGIONS:
                if not region.has_payments:
                    self.disabled_regions.add(region.id)

        self.disabled_regions = list(self.disabled_regions)
Esempio n. 24
0
    def __init__(self, *args, **kw):
        self.product = kw.pop('product', None)
        super(RegionForm, self).__init__(*args, **kw)

        # If we have excluded regions, uncheck those.
        # Otherwise, default to everything checked.
        self.regions_before = self.product.get_region_ids()

        # If we have future excluded regions, uncheck box.
        self.future_exclusions = self.product.addonexcludedregion.filter(
            region=mkt.regions.WORLDWIDE.id)

        self.initial = {
            'regions': self.regions_before,
            'other_regions': not self.future_exclusions.exists()
        }

        # Games cannot be listed in Brazil without a content rating.
        self.disabled_regions = []
        games = Webapp.category('games')
        if (games and self.product.categories.filter(id=games.id).exists()
                and not self.product.content_ratings_in(mkt.regions.BR)):
            self.disabled_regions.append(mkt.regions.BR.id)
Esempio n. 25
0
    def __init__(self, *args, **kw):
        self.product = kw.pop('product', None)
        super(RegionForm, self).__init__(*args, **kw)

        # If we have excluded regions, uncheck those.
        # Otherwise, default to everything checked.
        self.regions_before = self.product.get_region_ids()

        # If we have future excluded regions, uncheck box.
        self.future_exclusions = self.product.addonexcludedregion.filter(
            region=mkt.regions.WORLDWIDE.id)

        self.initial = {
            'regions': self.regions_before,
            'other_regions': not self.future_exclusions.exists()
        }

        # Games cannot be listed in Brazil without a content rating.
        self.disabled_regions = []
        games = Webapp.category('games')
        if (games and self.product.categories.filter(id=games.id).exists()
            and not self.product.content_ratings_in(mkt.regions.BR)):
            self.disabled_regions.append(mkt.regions.BR.id)
Esempio n. 26
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 not games:
            return

        for region in mkt.regions.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 exluded from region'
                             u' (%s).' % (self.product, region.slug))