Ejemplo n.º 1
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'], is_listed=True)

        if data['current_version'] and data['current_version']['files']:
            data_version = data['current_version']
            obj._current_version = Version(
                id=data_version['id'],
                reviewed=self.handle_date(data_version['reviewed']),
                version=data_version['version'])
            obj._current_version.all_files = [
                File(
                    id=file_['id'], created=self.handle_date(file_['created']),
                    hash=file_['hash'], filename=file_['filename'],
                    size=file_['size'], status=file_['status'])
                for file_ in data_version['files']
            ]

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data,
            ('average_daily_users', 'bayesian_rating', 'created',
             'default_locale', 'guid', 'hotness', 'is_listed', 'last_updated',
             'public_stats', 'slug', 'status', 'type', 'weekly_downloads'))

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data['tags']
        obj.disabled_by_user = data['is_disabled']  # Not accurate, but enough.

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        return obj
Ejemplo n.º 2
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'], is_listed=True)

        if data['current_version'] and data['current_version']['files']:
            data_version = data['current_version']
            obj._current_version = Version(id=data_version['id'],
                                           reviewed=self.handle_date(
                                               data_version['reviewed']),
                                           version=data_version['version'])
            obj._current_version.all_files = [
                File(id=file_['id'],
                     created=self.handle_date(file_['created']),
                     hash=file_['hash'],
                     filename=file_['filename'],
                     size=file_['size'],
                     status=file_['status']) for file_ in data_version['files']
            ]

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data,
            ('average_daily_users', 'bayesian_rating', 'created',
             'default_locale', 'guid', 'hotness', 'is_listed', 'last_updated',
             'public_stats', 'slug', 'status', 'type', 'weekly_downloads'))

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data['tags']
        obj.disabled_by_user = data['is_disabled']  # Not accurate, but enough.

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        return obj
Ejemplo n.º 3
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'], is_listed=True)

        data_version = data.get('current_version')
        if data_version:
            obj._current_version = Version(addon=obj,
                                           id=data_version['id'],
                                           reviewed=self.handle_date(
                                               data_version['reviewed']),
                                           version=data_version['version'])
            data_files = data_version.get('files', [])
            obj._current_version.all_files = [
                File(id=file_['id'],
                     created=self.handle_date(file_['created']),
                     hash=file_['hash'],
                     filename=file_['filename'],
                     platform=file_['platform'],
                     size=file_['size'],
                     status=file_['status'],
                     version=obj._current_version) for file_ in data_files
            ]

            # In ES we store integers for the appversion info, we need to
            # convert it back to strings.
            compatible_apps = {}
            for app_id, compat_dict in data['appversion'].items():
                app_name = APPS_ALL[int(app_id)]
                compatible_apps[app_name] = ApplicationsVersions(
                    min=AppVersion(version=compat_dict.get('min_human', '')),
                    max=AppVersion(version=compat_dict.get('max_human', '')))

            obj._current_version.compatible_apps = compatible_apps

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data,
            ('average_daily_users', 'bayesian_rating', 'created',
             'default_locale', 'guid', 'hotness', 'is_listed', 'last_updated',
             'public_stats', 'slug', 'status', 'type', 'weekly_downloads'))

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data['tags']
        obj.disabled_by_user = data['is_disabled']  # Not accurate, but enough.

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        return obj
Ejemplo n.º 4
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'])

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data,
            ('average_daily_users', 'bayesian_rating', 'created',
             'default_locale', 'guid', 'has_eula', 'has_privacy_policy',
             'hotness', 'icon_type', 'is_experimental', 'last_updated',
             'modified', 'public_stats', 'slug', 'status', 'type',
             'view_source', 'weekly_downloads'))

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data['tags']
        obj.disabled_by_user = data['is_disabled']  # Not accurate, but enough.
        obj.all_categories = [
            CATEGORIES_BY_ID[cat_id] for cat_id in data.get('category', [])
        ]

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        # Attach related models (also faking them). `current_version` is a
        # property we can't write to, so we use the underlying field which
        # begins with an underscore. `current_beta_version` and
        # `latest_unlisted_version` are writeable cached_property so we can
        # directly write to them.
        obj.current_beta_version = self.fake_version_object(
            obj, data.get('current_beta_version'), amo.RELEASE_CHANNEL_LISTED)
        obj._current_version = self.fake_version_object(
            obj, data.get('current_version'), amo.RELEASE_CHANNEL_LISTED)
        obj.latest_unlisted_version = self.fake_version_object(
            obj, data.get('latest_unlisted_version'),
            amo.RELEASE_CHANNEL_UNLISTED)

        data_authors = data.get('listed_authors', [])
        obj.listed_authors = [
            UserProfile(id=data_author['id'],
                        display_name=data_author['name'],
                        username=data_author['username'])
            for data_author in data_authors
        ]

        # We set obj.all_previews to the raw preview data because
        # ESPreviewSerializer will handle creating the fake Preview object
        # for us when its to_representation() method is called.
        obj.all_previews = data.get('previews', [])

        obj.average_rating = data.get('ratings', {}).get('average')
        obj.total_reviews = data.get('ratings', {}).get('count')

        if data['type'] == amo.ADDON_PERSONA:
            persona_data = data.get('persona')
            if persona_data:
                obj.persona = Persona(
                    addon=obj,
                    accentcolor=persona_data['accentcolor'],
                    display_username=persona_data['author'],
                    header=persona_data['header'],
                    footer=persona_data['footer'],
                    # "New" Persona do not have a persona_id, it's a relic from
                    # old ones.
                    persona_id=0 if persona_data['is_new'] else 42,
                    textcolor=persona_data['textcolor'])
            else:
                # Sadly, https://code.djangoproject.com/ticket/14368 prevents
                # us from setting obj.persona = None. This is fixed in
                # Django 1.9, but in the meantime, work around it by creating
                # a Persona instance with a custom attribute indicating that
                # it should not be used.
                obj.persona = Persona()
                obj.persona._broken = True

        return obj
Ejemplo n.º 5
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data["id"], slug=data["slug"], is_listed=True)

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj,
            data,
            (
                "average_daily_users",
                "bayesian_rating",
                "created",
                "default_locale",
                "guid",
                "hotness",
                "icon_type",
                "is_listed",
                "last_updated",
                "modified",
                "public_stats",
                "slug",
                "status",
                "type",
                "weekly_downloads",
            ),
        )

        # Temporary hack to make sure all add-ons have a modified date when
        # serializing, to avoid errors when calling get_icon_url().
        # Remove once all add-ons have been reindexed at least once since the
        # addition of `modified` in the mapping.
        if obj.modified is None:
            obj.modified = obj.created

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data["tags"]
        obj.disabled_by_user = data["is_disabled"]  # Not accurate, but enough.

        # Categories are annoying, skip them for now. We probably need to start
        # declaring them in the code to properly handle translations etc if we
        # want to display them in search results.
        obj.all_categories = []

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        # Attach related models (also faking them).
        data_version = data.get("current_version")
        if data_version:
            obj._current_version = Version(
                addon=obj,
                id=data_version["id"],
                reviewed=self.handle_date(data_version["reviewed"]),
                version=data_version["version"],
            )
            data_files = data_version.get("files", [])
            obj._current_version.all_files = [
                File(
                    id=file_["id"],
                    created=self.handle_date(file_["created"]),
                    hash=file_["hash"],
                    filename=file_["filename"],
                    platform=file_["platform"],
                    size=file_["size"],
                    status=file_["status"],
                    version=obj._current_version,
                )
                for file_ in data_files
            ]

            # In ES we store integers for the appversion info, we need to
            # convert it back to strings.
            compatible_apps = {}
            for app_id, compat_dict in data["appversion"].items():
                app_name = APPS_ALL[int(app_id)]
                compatible_apps[app_name] = ApplicationsVersions(
                    min=AppVersion(version=compat_dict.get("min_human", "")),
                    max=AppVersion(version=compat_dict.get("max_human", "")),
                )

            obj._current_version.compatible_apps = compatible_apps

        if data["type"] == amo.ADDON_PERSONA:
            persona_data = data.get("persona")
            if persona_data:
                obj.persona = Persona(
                    addon=obj,
                    accentcolor=persona_data["accentcolor"],
                    display_username=persona_data["author"],
                    header=persona_data["header"],
                    footer=persona_data["footer"],
                    persona_id=1 if persona_data["is_new"] else None,
                    textcolor=persona_data["textcolor"],
                )
            else:
                # Sadly, https://code.djangoproject.com/ticket/14368 prevents
                # us from setting obj.persona = None. This is fixed in
                # Django 1.9, but in the meantime, work around it by creating
                # a Persona instance with a custom attribute indicating that
                # it should not be used.
                obj.persona = Persona()
                obj.persona._broken = True

        return obj
Ejemplo n.º 6
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'])

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data, (
                'average_daily_users',
                'bayesian_rating',
                'contributions',
                'created',
                'default_locale',
                'guid',
                'has_eula',
                'has_privacy_policy',
                'hotness',
                'icon_type',
                'is_experimental',
                'last_updated',
                'modified',
                'public_stats',
                'requires_payment',
                'slug',
                'status',
                'type',
                'view_source',
                'weekly_downloads'
            )
        )

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data.get('tags', [])
        obj.all_categories = [
            CATEGORIES_BY_ID[cat_id] for cat_id in data.get('category', [])]

        # Not entirely accurate, but enough in the context of the search API.
        obj.disabled_by_user = data.get('is_disabled', False)

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        # Attach related models (also faking them). `current_version` is a
        # property we can't write to, so we use the underlying field which
        # begins with an underscore. `current_beta_version` and
        # `latest_unlisted_version` are writeable cached_property so we can
        # directly write to them.
        obj.current_beta_version = self.fake_version_object(
            obj, data.get('current_beta_version'), amo.RELEASE_CHANNEL_LISTED)
        obj._current_version = self.fake_version_object(
            obj, data.get('current_version'), amo.RELEASE_CHANNEL_LISTED)
        obj.latest_unlisted_version = self.fake_version_object(
            obj, data.get('latest_unlisted_version'),
            amo.RELEASE_CHANNEL_UNLISTED)

        data_authors = data.get('listed_authors', [])
        obj.listed_authors = [
            UserProfile(
                id=data_author['id'], display_name=data_author['name'],
                username=data_author['username'],
                is_public=data_author.get('is_public', False))
            for data_author in data_authors
        ]

        # We set obj.all_previews to the raw preview data because
        # ESPreviewSerializer will handle creating the fake Preview object
        # for us when its to_representation() method is called.
        obj.all_previews = data.get('previews', [])

        ratings = data.get('ratings', {})
        obj.average_rating = ratings.get('average')
        obj.total_reviews = ratings.get('count')
        obj.text_reviews_count = ratings.get('text_count')

        obj._is_featured = data.get('is_featured', False)

        if data['type'] == amo.ADDON_PERSONA:
            persona_data = data.get('persona')
            if persona_data:
                obj.persona = Persona(
                    addon=obj,
                    accentcolor=persona_data['accentcolor'],
                    display_username=persona_data['author'],
                    header=persona_data['header'],
                    footer=persona_data['footer'],
                    # "New" Persona do not have a persona_id, it's a relic from
                    # old ones.
                    persona_id=0 if persona_data['is_new'] else 42,
                    textcolor=persona_data['textcolor'],
                    popularity=data.get('average_daily_users'),
                )
            else:
                # Sadly, https://code.djangoproject.com/ticket/14368 prevents
                # us from setting obj.persona = None. This is fixed in
                # Django 1.9, but in the meantime, work around it by creating
                # a Persona instance with a custom attribute indicating that
                # it should not be used.
                obj.persona = Persona()
                obj.persona._broken = True

        return obj
Ejemplo n.º 7
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'], is_listed=True)

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data,
            ('average_daily_users', 'bayesian_rating', 'created',
             'default_locale', 'guid', 'hotness', 'icon_type', 'is_listed',
             'last_updated', 'modified', 'public_stats', 'slug', 'status',
             'type', 'weekly_downloads'))

        # Temporary hack to make sure all add-ons have a modified date when
        # serializing, to avoid errors when calling get_icon_url().
        # Remove once all add-ons have been reindexed at least once since the
        # addition of `modified` in the mapping.
        if obj.modified is None:
            obj.modified = obj.created

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data['tags']
        obj.disabled_by_user = data['is_disabled']  # Not accurate, but enough.

        # Categories are annoying, skip them for now. We probably need to start
        # declaring them in the code to properly handle translations etc if we
        # want to display them in search results.
        obj.all_categories = []

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        # Attach related models (also faking them).
        data_version = data.get('current_version')
        if data_version:
            obj._current_version = Version(addon=obj,
                                           id=data_version['id'],
                                           reviewed=self.handle_date(
                                               data_version['reviewed']),
                                           version=data_version['version'])
            data_files = data_version.get('files', [])
            obj._current_version.all_files = [
                File(id=file_['id'],
                     created=self.handle_date(file_['created']),
                     hash=file_['hash'],
                     filename=file_['filename'],
                     platform=file_['platform'],
                     size=file_['size'],
                     status=file_['status'],
                     version=obj._current_version) for file_ in data_files
            ]

            # In ES we store integers for the appversion info, we need to
            # convert it back to strings.
            compatible_apps = {}
            for app_id, compat_dict in data['appversion'].items():
                app_name = APPS_ALL[int(app_id)]
                compatible_apps[app_name] = ApplicationsVersions(
                    min=AppVersion(version=compat_dict.get('min_human', '')),
                    max=AppVersion(version=compat_dict.get('max_human', '')))

            obj._current_version.compatible_apps = compatible_apps

        if data['type'] == amo.ADDON_PERSONA:
            persona_data = data.get('persona')
            if persona_data:
                obj.persona = Persona(
                    addon=obj,
                    accentcolor=persona_data['accentcolor'],
                    display_username=persona_data['author'],
                    header=persona_data['header'],
                    footer=persona_data['footer'],
                    persona_id=1 if persona_data['is_new'] else None,
                    textcolor=persona_data['textcolor'])
            else:
                # Sadly, https://code.djangoproject.com/ticket/14368 prevents
                # us from setting obj.persona = None. This is fixed in
                # Django 1.9, but in the meantime, work around it by creating
                # a Persona instance with a custom attribute indicating that
                # it should not be used.
                obj.persona = Persona()
                obj.persona._broken = True

        return obj
Ejemplo n.º 8
0
    def fake_object(self, data):
        """Create a fake instance of Addon and related models from ES data."""
        obj = Addon(id=data['id'], slug=data['slug'])

        # Attach base attributes that have the same name/format in ES and in
        # the model.
        self._attach_fields(
            obj, data,
            ('average_daily_users', 'bayesian_rating', 'created',
             'default_locale', 'guid', 'hotness', 'icon_type',
             'is_experimental', 'is_listed',
             'last_updated', 'modified', 'public_stats', 'slug', 'status',
             'type', 'view_source', 'weekly_downloads'))

        # Attach attributes that do not have the same name/format in ES.
        obj.tag_list = data['tags']
        obj.disabled_by_user = data['is_disabled']  # Not accurate, but enough.

        # Categories are annoying, skip them for now. We probably need to start
        # declaring them in the code to properly handle translations etc if we
        # want to display them in search results. See #2923.
        obj.all_categories = []

        # Attach translations (they require special treatment).
        self._attach_translations(obj, data, self.translated_fields)

        # Attach related models (also faking them).
        data_version = data.get('current_version')
        if data_version:
            obj._current_version = Version(
                addon=obj, id=data_version['id'],
                reviewed=self.handle_date(data_version['reviewed']),
                version=data_version['version'])
            data_files = data_version.get('files', [])
            obj._current_version.all_files = [
                File(
                    id=file_['id'], created=self.handle_date(file_['created']),
                    hash=file_['hash'], filename=file_['filename'],
                    platform=file_['platform'], size=file_['size'],
                    status=file_['status'], version=obj._current_version)
                for file_ in data_files
            ]

            # In ES we store integers for the appversion info, we need to
            # convert it back to strings.
            compatible_apps = {}
            for app_id, compat_dict in data['appversion'].items():
                app_name = APPS_ALL[int(app_id)]
                compatible_apps[app_name] = ApplicationsVersions(
                    min=AppVersion(version=compat_dict.get('min_human', '')),
                    max=AppVersion(version=compat_dict.get('max_human', '')))

            obj._current_version.compatible_apps = compatible_apps

        data_authors = data.get('listed_authors', [])
        obj.listed_authors = [
            UserProfile(
                id=data_author['id'], display_name=data_author['name'],
                username=data_author['username'])
            for data_author in data_authors
        ]

        # We set obj.all_previews to the raw preview data because
        # ESPreviewSerializer will handle creating the fake Preview object
        # for us when its to_representation() method is called.
        obj.all_previews = data.get('previews', [])

        obj.average_rating = data.get('ratings', {}).get('average')
        obj.total_reviews = data.get('ratings', {}).get('count')

        if data['type'] == amo.ADDON_PERSONA:
            persona_data = data.get('persona')
            if persona_data:
                obj.persona = Persona(
                    addon=obj,
                    accentcolor=persona_data['accentcolor'],
                    display_username=persona_data['author'],
                    header=persona_data['header'],
                    footer=persona_data['footer'],
                    persona_id=1 if persona_data['is_new'] else None,
                    textcolor=persona_data['textcolor']
                )
            else:
                # Sadly, https://code.djangoproject.com/ticket/14368 prevents
                # us from setting obj.persona = None. This is fixed in
                # Django 1.9, but in the meantime, work around it by creating
                # a Persona instance with a custom attribute indicating that
                # it should not be used.
                obj.persona = Persona()
                obj.persona._broken = True

        return obj