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
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