def test_personas_grid_sorting(self): """Ensure we hit a grid page if there is a sorting.""" category = Category( type=amo.ADDON_PERSONA, slug='abc', application=amo.FIREFOX.id) category.save() category_url = reverse('browse.personas', args=[category.slug]) response = self.client.get(category_url + '?sort=created') self.assertTemplateUsed(response, self.grid_template) # Whatever the `category.count` is. category.update(count=MIN_COUNT_FOR_LANDING + 1) response = self.client.get(category_url + '?sort=created') self.assertTemplateUsed(response, self.grid_template)
def add_static_theme_from_lwt(lwt): # Try to handle LWT with no authors author = (lwt.listed_authors or [_get_lwt_default_author()])[0] # Wrap zip in FileUpload for Addon/Version from_upload to consume. upload = FileUpload.objects.create( user=author, valid=True) destination = os.path.join( user_media_path('addons'), 'temp', uuid.uuid4().hex + '.xpi') build_static_theme_xpi_from_lwt(lwt, destination) upload.update(path=destination) # Create addon + version parsed_data = parse_addon(upload, user=author) addon = Addon.initialize_addon_from_upload( parsed_data, upload, amo.RELEASE_CHANNEL_LISTED, author) # Version.from_upload sorts out platforms for us. version = Version.from_upload( upload, addon, platforms=None, channel=amo.RELEASE_CHANNEL_LISTED, parsed_data=parsed_data) # Set category static_theme_categories = CATEGORIES.get(amo.FIREFOX.id, []).get( amo.ADDON_STATICTHEME, []) lwt_category = (lwt.categories.all() or [None])[0] # lwt only have 1 cat. lwt_category_slug = lwt_category.slug if lwt_category else 'other' static_category = static_theme_categories.get( lwt_category_slug, static_theme_categories.get('other')) AddonCategory.objects.create( addon=addon, category=Category.from_static_category(static_category, True)) # Set license lwt_license = PERSONA_LICENSES_IDS.get( lwt.persona.license, LICENSE_COPYRIGHT_AR) # default to full copyright static_license = License.objects.get(builtin=lwt_license.builtin) version.update(license=static_license) # Set tags for addon_tag in AddonTag.objects.filter(addon=lwt): AddonTag.objects.create(addon=addon, tag=addon_tag.tag) # Logging activity.log_create( amo.LOG.CREATE_STATICTHEME_FROM_PERSONA, addon, user=author) log.debug('New static theme %r created from %r' % (addon, lwt)) # And finally sign the files (actually just one) for file_ in version.all_files: sign_file(file_) file_.update( datestatuschanged=datetime.now(), reviewed=datetime.now(), status=amo.STATUS_PUBLIC) addon.update(status=amo.STATUS_PUBLIC) return addon
def test_personas_landing(self): """ Show landing page if there are greater than MIN_COUNT_FOR_LANDING popular Personas. """ self.create_personas(MIN_COUNT_FOR_LANDING, persona_extras={'popularity': 100}) base = Addon.objects.public().filter(type=amo.ADDON_PERSONA) assert base.count() == MIN_COUNT_FOR_LANDING + 2 response = self.client.get(self.landing_url) self.assertTemplateUsed(response, self.landing_template) # Whatever the `category.count` is. category = Category( type=amo.ADDON_PERSONA, slug='abc', count=MIN_COUNT_FOR_LANDING + 1, application=amo.FIREFOX.id) category.save() response = self.client.get(self.landing_url) self.assertTemplateUsed(response, self.landing_template)
def test_personas_landing(self): """ Show landing page if there are greater than MIN_COUNT_FOR_LANDING popular Personas. """ self.create_personas(MIN_COUNT_FOR_LANDING, persona_extras={'popularity': 100}) base = Addon.objects.public().filter(type=amo.ADDON_PERSONA) assert base.count() == MIN_COUNT_FOR_LANDING + 2 r = self.client.get(self.landing_url) self.assertTemplateUsed(r, self.landing_template) # Whatever the `category.count` is. category = Category( type=amo.ADDON_PERSONA, slug='abc', count=MIN_COUNT_FOR_LANDING + 1, application=amo.FIREFOX.id) category.save() response = self.client.get(self.landing_url) self.assertTemplateUsed(response, self.landing_template)
def test_themes_category(self): static_category = ( CATEGORIES[amo.FIREFOX.id][amo.ADDON_PERSONA]['fashion']) category = Category.from_static_category(static_category, True) self.theme = amo.tests.addon_factory( type=amo.ADDON_PERSONA, users=[self.user], category=category) res = self.client.get( self.user.get_themes_url_path(args=[category.slug])) self._test_good(res)
def setUp(self): super(TestCategoriesFeed, self).setUp() self.feed = feeds.CategoriesRss() self.u = u'Ελληνικά' self.wut = Translation(localized_string=self.u, locale='el') self.feed.request = mock.Mock() self.feed.request.APP.pretty = self.u self.category = Category(db_name=self.u) self.addon = Addon(name=self.u, id=2, type=1, slug='xx') self.addon._current_version = Version(version='v%s' % self.u)
def add_static_theme_from_lwt(lwt): # Try to handle LWT with no authors author = (lwt.listed_authors or [_get_lwt_default_author()])[0] # Wrap zip in FileUpload for Addon/Version from_upload to consume. upload = FileUpload.objects.create( user=author, valid=True) destination = os.path.join( user_media_path('addons'), 'temp', uuid.uuid4().hex + '.xpi') build_static_theme_xpi_from_lwt(lwt, destination) upload.update(path=destination) # Create addon + version parsed_data = parse_addon(upload, user=author) addon = Addon.initialize_addon_from_upload( parsed_data, upload, amo.RELEASE_CHANNEL_LISTED, author) # Version.from_upload sorts out platforms for us. version = Version.from_upload( upload, addon, platforms=None, channel=amo.RELEASE_CHANNEL_LISTED, parsed_data=parsed_data) # Set category static_theme_categories = CATEGORIES.get(amo.FIREFOX.id, []).get( amo.ADDON_STATICTHEME, []) lwt_category = (lwt.categories.all() or [None])[0] # lwt only have 1 cat. lwt_category_slug = lwt_category.slug if lwt_category else 'other' static_category = static_theme_categories.get( lwt_category_slug, static_theme_categories.get('other')) AddonCategory.objects.create( addon=addon, category=Category.from_static_category(static_category, True)) # Set license lwt_license = PERSONA_LICENSES_IDS.get( lwt.persona.license, LICENSE_COPYRIGHT_AR) # default to full copyright static_license = License.objects.get(builtin=lwt_license.builtin) version.update(license=static_license) # Set tags for addon_tag in AddonTag.objects.filter(addon=lwt): AddonTag.objects.create(addon=addon, tag=addon_tag.tag) # Logging activity.log_create( amo.LOG.CREATE_STATICTHEME_FROM_PERSONA, addon, user=author) log.debug('New static theme %r created from %r' % (addon, lwt)) # And finally update the statuses version.all_files[0].update(status=amo.STATUS_PUBLIC) addon.update(status=amo.STATUS_PUBLIC) return addon
def test_personas_grid_sorting(self): """Ensure we hit a grid page if there is a sorting.""" category = Category( type=amo.ADDON_PERSONA, slug='abc', application=amo.FIREFOX.id) category.save() category_url = reverse('browse.personas', args=[category.slug]) r = self.client.get(category_url + '?sort=created') self.assertTemplateUsed(r, self.grid_template) # Whatever the `category.count` is. category.update(count=MIN_COUNT_FOR_LANDING + 1) r = self.client.get(category_url + '?sort=created') self.assertTemplateUsed(r, self.grid_template)
def _handle_addon(self, addon_data): version = addon_data['current_version'] files = version['files'] or [] file_kw = {} try: file_kw = { 'hash': files[0]['hash'], 'status': amo.STATUS_CHOICES_API_LOOKUP[files[0]['status']], 'platform': amo.PLATFORM_DICT[files[0]['platform']].id, 'size': files[0]['size'], 'is_webextension': files[0]['is_webextension'], 'is_mozilla_signed_extension': ( files[0]['is_mozilla_signed_extension']), 'strict_compatibility': ( version['is_strict_compatibility_enabled']) } except (KeyError, IndexError): file_kw = {} # TODO: # * license # * ratings # * previews # * android compat & category data if Addon.objects.filter(slug=addon_data['slug']).exists(): print('Skipping %s (slug already exists)' % addon_data['slug']) return if addon_data['guid'] and Addon.objects.filter( guid=addon_data['guid']).exists(): print('Skipping %s (guid already exists)' % addon_data['guid']) return users = [] for user in addon_data['authors']: try: users.append(UserProfile.objects.get(username=user['name'])) except UserProfile.DoesNotExist: email = '*****@*****.**' % str(uuid.uuid4().hex) users.append(user_factory(username=user['name'], email=email)) addon_type = amo.ADDON_SEARCH_SLUGS[addon_data['type']] if 'firefox' in addon_data['categories']: category = addon_data['categories']['firefox'][0] else: category = None if category not in CATEGORIES[amo.FIREFOX.id][addon_type]: category = None print('Category %s' % category, 'not found') else: category = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][addon_type][category], True) print('Creating add-on %s' % addon_data['slug']) compatibility = version['compatibility'] if compatibility and 'firefox' in compatibility: version_kw = { 'min_app_version': version['compatibility']['firefox']['min'], 'max_app_version': version['compatibility']['firefox']['max'], } else: version_kw = {} with atomic(): addon_factory( users=users, average_daily_users=addon_data['average_daily_users'], category=category, type=addon_type, guid=addon_data['guid'], slug=addon_data['slug'], name=addon_data['name'], summary=addon_data['summary'], description=addon_data['description'], file_kw=file_kw, version_kw=version_kw, weekly_downloads=addon_data.get('weekly_downloads', 0), default_locale=addon_data['default_locale'], tags=addon_data['tags'], )
def addon_factory(status=amo.STATUS_PUBLIC, version_kw=None, file_kw=None, **kw): version_kw = version_kw or {} # Disconnect signals until the last save. post_save.disconnect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') type_ = kw.pop('type', amo.ADDON_EXTENSION) popularity = kw.pop('popularity', None) persona_id = kw.pop('persona_id', None) tags = kw.pop('tags', []) users = kw.pop('users', []) when = _get_created(kw.pop('created', None)) category = kw.pop('category', None) # Keep as much unique data as possible in the uuid: '-' aren't important. name = kw.pop('name', u'Addôn %s' % unicode(uuid.uuid4()).replace('-', '')) kwargs = { # Set artificially the status to STATUS_PUBLIC for now, the real # status will be set a few lines below, after the update_version() # call. This prevents issues when calling addon_factory with # STATUS_DELETED. 'status': amo.STATUS_PUBLIC, 'name': name, 'slug': name.replace(' ', '-').lower()[:30], 'average_daily_users': popularity or random.randint(200, 2000), 'weekly_downloads': popularity or random.randint(200, 2000), 'created': when, 'last_updated': when, } if type_ != amo.ADDON_PERSONA: # Personas don't have a summary. kwargs['summary'] = u'Summary for %s' % name kwargs.update(kw) # Save 1. if type_ == amo.ADDON_PERSONA: # Personas need to start life as an extension for versioning. addon = Addon.objects.create(type=amo.ADDON_EXTENSION, **kwargs) else: addon = Addon.objects.create(type=type_, **kwargs) # Save 2. version = version_factory(file_kw, addon=addon, **version_kw) addon.update_version() addon.status = status if type_ == amo.ADDON_PERSONA: addon.type = type_ persona_id = persona_id if persona_id is not None else addon.id # Save 3. Persona.objects.create(addon=addon, popularity=addon.weekly_downloads, persona_id=persona_id) for tag in tags: Tag(tag_text=tag).save_tag(addon) for user in users: addon.addonuser_set.create(user=user) application = version_kw.get('application', amo.FIREFOX.id) if not category: static_category = random.choice( CATEGORIES[application][type_].values()) category = Category.from_static_category(static_category, True) AddonCategory.objects.create(addon=addon, category=category) # Put signals back. post_save.connect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') # Save 4. addon.save() if 'nomination' in version_kw: # If a nomination date was set on the version, then it might have been # erased at post_save by addons.models.watch_status() version.save() return addon
def addon_factory(status=amo.STATUS_APPROVED, version_kw=None, file_kw=None, **kw): version_kw = version_kw or {} # Disconnect signals until the last save. post_save.disconnect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') type_ = kw.pop('type', amo.ADDON_EXTENSION) popularity = kw.pop('popularity', None) tags = kw.pop('tags', []) users = kw.pop('users', []) when = _get_created(kw.pop('created', None)) category = kw.pop('category', None) default_locale = kw.get('default_locale', settings.LANGUAGE_CODE) # Keep as much unique data as possible in the uuid: '-' aren't important. name = kw.pop('name', u'Addôn %s' % str(uuid.uuid4()).replace('-', '')) slug = kw.pop('slug', None) if slug is None: slug = name.replace(' ', '-').lower()[:30] should_be_recommended = kw.pop('recommended', False) kwargs = { # Set artificially the status to STATUS_APPROVED for now, the real # status will be set a few lines below, after the update_version() # call. This prevents issues when calling addon_factory with # STATUS_DELETED. 'status': amo.STATUS_APPROVED, 'default_locale': default_locale, 'name': name, 'slug': slug, 'average_daily_users': popularity or random.randint(200, 2000), 'weekly_downloads': popularity or random.randint(200, 2000), 'created': when, 'last_updated': when, } if 'summary' not in kw: # Assign a dummy summary if none was specified in keyword args. kwargs['summary'] = u'Summary for %s' % name if type_ not in [amo.ADDON_SEARCH]: # Search engines don't need guids kwargs['guid'] = kw.pop('guid', '{%s}' % str(uuid.uuid4())) kwargs.update(kw) # Save 1. with translation.override(default_locale): addon = Addon.objects.create(type=type_, **kwargs) # Save 2. if should_be_recommended: version_kw['recommendation_approved'] = True version = version_factory(file_kw, addon=addon, **version_kw) addon.update_version() addon.status = status for tag in tags: Tag(tag_text=tag).save_tag(addon) for user in users: addon.addonuser_set.create(user=user) application = version_kw.get('application', amo.FIREFOX.id) if not category: static_category = random.choice( list(CATEGORIES[application][addon.type].values())) category = Category.from_static_category(static_category, True) AddonCategory.objects.create(addon=addon, category=category) if should_be_recommended: DiscoveryItem.objects.create(addon=addon, recommendable=True) # Put signals back. post_save.connect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') # Save 4. addon.save() if addon.guid: AddonGUID.objects.create(addon=addon, guid=addon.guid) # Potentially update is_public on authors [user.update_is_public() for user in users] if 'nomination' in version_kw: # If a nomination date was set on the version, then it might have been # erased at post_save by addons.models.watch_status() version.save() return addon
def addon_factory(status=amo.STATUS_PUBLIC, version_kw=None, file_kw=None, **kw): version_kw = version_kw or {} # Disconnect signals until the last save. post_save.disconnect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') type_ = kw.pop('type', amo.ADDON_EXTENSION) popularity = kw.pop('popularity', None) persona_id = kw.pop('persona_id', None) tags = kw.pop('tags', []) users = kw.pop('users', []) when = _get_created(kw.pop('created', None)) category = kw.pop('category', None) default_locale = kw.get('default_locale', settings.LANGUAGE_CODE) # Keep as much unique data as possible in the uuid: '-' aren't important. name = kw.pop('name', u'Addôn %s' % six.text_type(uuid.uuid4()).replace('-', '')) slug = kw.pop('slug', None) if slug is None: slug = name.replace(' ', '-').lower()[:30] kwargs = { # Set artificially the status to STATUS_PUBLIC for now, the real # status will be set a few lines below, after the update_version() # call. This prevents issues when calling addon_factory with # STATUS_DELETED. 'status': amo.STATUS_PUBLIC, 'default_locale': default_locale, 'name': name, 'slug': slug, 'average_daily_users': popularity or random.randint(200, 2000), 'weekly_downloads': popularity or random.randint(200, 2000), 'created': when, 'last_updated': when, } if type_ != amo.ADDON_PERSONA and 'summary' not in kw: # Assign a dummy summary if none was specified in keyword args, unless # we're creating a Persona since they don't have summaries. kwargs['summary'] = u'Summary for %s' % name if type_ not in [amo.ADDON_PERSONA, amo.ADDON_SEARCH]: # Personas and search engines don't need guids kwargs['guid'] = kw.pop('guid', '{%s}' % six.text_type(uuid.uuid4())) kwargs.update(kw) # Save 1. with translation.override(default_locale): addon = Addon.objects.create(type=type_, **kwargs) # Save 2. version = version_factory(file_kw, addon=addon, **version_kw) if addon.type == amo.ADDON_PERSONA: addon._current_version = version persona_id = persona_id if persona_id is not None else addon.id # Save 3. Persona.objects.create(addon=addon, popularity=addon.average_daily_users, persona_id=persona_id) addon.update_version() addon.status = status for tag in tags: Tag(tag_text=tag).save_tag(addon) for user in users: addon.addonuser_set.create(user=user) application = version_kw.get('application', amo.FIREFOX.id) if not category: static_category = random.choice( list(CATEGORIES[application][addon.type].values())) category = Category.from_static_category(static_category, True) AddonCategory.objects.create(addon=addon, category=category) # Put signals back. post_save.connect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') # Save 4. addon.save() if addon.type == amo.ADDON_PERSONA: # Personas only have one version and signals.version_changed is never # fired for them - instead it gets updated through a cron (!). We do # need to get it right in some tests like the ui tests, so we call the # task ourselves. version_changed(addon.pk) # Potentially update is_public on authors [user.update_is_public() for user in users] if 'nomination' in version_kw: # If a nomination date was set on the version, then it might have been # erased at post_save by addons.models.watch_status() version.save() return addon
def addon_factory( status=amo.STATUS_PUBLIC, version_kw=None, file_kw=None, **kw): version_kw = version_kw or {} # Disconnect signals until the last save. post_save.disconnect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') type_ = kw.pop('type', amo.ADDON_EXTENSION) popularity = kw.pop('popularity', None) persona_id = kw.pop('persona_id', None) tags = kw.pop('tags', []) users = kw.pop('users', []) when = _get_created(kw.pop('created', None)) category = kw.pop('category', None) default_locale = kw.get('default_locale', settings.LANGUAGE_CODE) # Keep as much unique data as possible in the uuid: '-' aren't important. name = kw.pop('name', u'Addôn %s' % unicode(uuid.uuid4()).replace('-', '')) slug = kw.pop('slug', None) if slug is None: slug = name.replace(' ', '-').lower()[:30] kwargs = { # Set artificially the status to STATUS_PUBLIC for now, the real # status will be set a few lines below, after the update_version() # call. This prevents issues when calling addon_factory with # STATUS_DELETED. 'status': amo.STATUS_PUBLIC, 'default_locale': default_locale, 'name': name, 'slug': slug, 'average_daily_users': popularity or random.randint(200, 2000), 'weekly_downloads': popularity or random.randint(200, 2000), 'created': when, 'last_updated': when, } if type_ != amo.ADDON_PERSONA: # Personas don't have a summary. kwargs['summary'] = u'Summary for %s' % name if type_ not in [amo.ADDON_PERSONA, amo.ADDON_SEARCH]: # Personas and search engines don't need guids kwargs['guid'] = kw.pop('guid', '{%s}' % unicode(uuid.uuid4())) kwargs.update(kw) # Save 1. with translation.override(default_locale): addon = Addon.objects.create(type=type_, **kwargs) # Save 2. version = version_factory(file_kw, addon=addon, **version_kw) if addon.type == amo.ADDON_PERSONA: addon._current_version = version persona_id = persona_id if persona_id is not None else addon.id # Save 3. Persona.objects.create( addon=addon, popularity=addon.average_daily_users, persona_id=persona_id) addon.update_version() addon.status = status for tag in tags: Tag(tag_text=tag).save_tag(addon) for user in users: addon.addonuser_set.create(user=user) application = version_kw.get('application', amo.FIREFOX.id) if not category: static_category = random.choice( CATEGORIES[application][addon.type].values()) category = Category.from_static_category(static_category, True) AddonCategory.objects.create(addon=addon, category=category) # Put signals back. post_save.connect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') # Save 4. addon.save() if addon.type == amo.ADDON_PERSONA: # Personas only have one version and signals.version_changed is never # fired for them - instead it gets updated through a cron (!). We do # need to get it right in some tests like the ui tests, so we call the # task ourselves. version_changed(addon.pk) # Potentially update is_public on authors [user.update_is_public() for user in users] if 'nomination' in version_kw: # If a nomination date was set on the version, then it might have been # erased at post_save by addons.models.watch_status() version.save() return addon
def add_static_theme_from_lwt(lwt): from olympia.activity.models import AddonLog # Try to handle LWT with no authors author = (lwt.listed_authors or [_get_lwt_default_author()])[0] # Wrap zip in FileUpload for Addon/Version from_upload to consume. upload = FileUpload.objects.create(user=author, valid=True) destination = os.path.join(user_media_path('addons'), 'temp', uuid.uuid4().hex + '.xpi') build_static_theme_xpi_from_lwt(lwt, destination) upload.update(path=destination) # Create addon + version parsed_data = parse_addon(upload, user=author) addon = Addon.initialize_addon_from_upload(parsed_data, upload, amo.RELEASE_CHANNEL_LISTED, author) addon_updates = {} # Version.from_upload sorts out platforms for us. version = Version.from_upload(upload, addon, platforms=None, channel=amo.RELEASE_CHANNEL_LISTED, parsed_data=parsed_data) # Set category static_theme_categories = CATEGORIES.get(amo.FIREFOX.id, []).get(amo.ADDON_STATICTHEME, []) lwt_category = (lwt.categories.all() or [None])[0] # lwt only have 1 cat. lwt_category_slug = lwt_category.slug if lwt_category else 'other' static_category = static_theme_categories.get( lwt_category_slug, static_theme_categories.get('other')) AddonCategory.objects.create(addon=addon, category=Category.from_static_category( static_category, True)) # Set license lwt_license = PERSONA_LICENSES_IDS.get( lwt.persona.license, LICENSE_COPYRIGHT_AR) # default to full copyright static_license = License.objects.get(builtin=lwt_license.builtin) version.update(license=static_license) # Set tags for addon_tag in AddonTag.objects.filter(addon=lwt): AddonTag.objects.create(addon=addon, tag=addon_tag.tag) # Steal the ratings (even with soft delete they'll be deleted anyway) addon_updates.update(average_rating=lwt.average_rating, bayesian_rating=lwt.bayesian_rating, total_ratings=lwt.total_ratings, text_ratings_count=lwt.text_ratings_count) Rating.unfiltered.filter(addon=lwt).update(addon=addon, version=version) # Modify the activity log entry too. rating_activity_log_ids = [ l.id for l in amo.LOG if getattr(l, 'action_class', '') == 'review' ] addonlog_qs = AddonLog.objects.filter( addon=lwt, activity_log__action__in=rating_activity_log_ids) [alog.transfer(addon) for alog in addonlog_qs.iterator()] # Logging activity.log_create(amo.LOG.CREATE_STATICTHEME_FROM_PERSONA, addon, user=author) log.debug('New static theme %r created from %r' % (addon, lwt)) # And finally sign the files (actually just one) for file_ in version.all_files: sign_file(file_) file_.update(datestatuschanged=datetime.now(), reviewed=datetime.now(), status=amo.STATUS_PUBLIC) addon_updates['status'] = amo.STATUS_PUBLIC addon.update(**addon_updates) return addon
def test_basic(self): cat1 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['bookmarks']) cat1.save() license = License.objects.create( name={ 'en-US': u'My License', 'fr': u'Mä Licence', }, text={ 'en-US': u'Lorem ipsum dolor sit amet, has nemore patrioqué', }, url='http://license.example.com/' ) self.addon = addon_factory( average_daily_users=4242, average_rating=4.21, bayesian_rating=4.22, category=cat1, contributions=u'https://paypal.me/foobar/', description=u'My Addôn description', developer_comments=u'Dévelopers Addôn comments', file_kw={ 'hash': 'fakehash', 'is_restart_required': False, 'is_webextension': True, 'platform': amo.PLATFORM_WIN.id, 'size': 42, }, guid=generate_addon_guid(), homepage=u'https://www.example.org/', icon_type='image/png', name=u'My Addôn', public_stats=True, slug='my-addon', summary=u'My Addôn summary', support_email=u'*****@*****.**', support_url=u'https://support.example.org/support/my-addon/', tags=['some_tag', 'some_other_tag'], total_ratings=666, text_ratings_count=555, version_kw={ 'license': license, 'releasenotes': { 'en-US': u'Release notes in english', 'fr': u'Notes de version en français', }, }, weekly_downloads=2147483647, ) AddonUser.objects.create(user=user_factory(username='******'), addon=self.addon, listed=False) second_author = user_factory( username='******', display_name=u'Secönd Author') first_author = user_factory( username='******', display_name=u'First Authôr') AddonUser.objects.create( user=second_author, addon=self.addon, position=2) AddonUser.objects.create( user=first_author, addon=self.addon, position=1) second_preview = Preview.objects.create( addon=self.addon, position=2, caption={'en-US': u'My câption', 'fr': u'Mön tîtré'}, sizes={'thumbnail': [199, 99], 'image': [567, 780]}) first_preview = Preview.objects.create(addon=self.addon, position=1) av_min = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='2.0.99')[0] av_max = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='3.0.99')[0] ApplicationsVersions.objects.get_or_create( application=amo.THUNDERBIRD.id, version=self.addon.current_version, min=av_min, max=av_max) # Reset current_version.compatible_apps now that we've added an app. del self.addon.current_version._compatible_apps cat2 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['alerts-updates']) cat2.save() AddonCategory.objects.create(addon=self.addon, category=cat2) cat3 = Category.from_static_category( CATEGORIES[amo.THUNDERBIRD.id][amo.ADDON_EXTENSION]['calendar']) cat3.save() AddonCategory.objects.create(addon=self.addon, category=cat3) result = self.serialize() assert result['id'] == self.addon.pk assert result['average_daily_users'] == self.addon.average_daily_users assert result['categories'] == { 'firefox': ['alerts-updates', 'bookmarks'], 'thunderbird': ['calendar']} assert result['current_beta_version'] is None # In this serializer latest_unlisted_version is omitted. assert 'latest_unlisted_version' not in result assert result['current_version'] self._test_version( self.addon.current_version, result['current_version']) assert result['current_version']['url'] == absolutify( reverse('addons.versions', args=[self.addon.slug, self.addon.current_version.version]) ) self._test_version_license_and_release_notes( self.addon.current_version, result['current_version']) assert result['authors'] assert len(result['authors']) == 2 self._test_author(first_author, result['authors'][0]) self._test_author(second_author, result['authors'][1]) assert result['contributions_url'] == self.addon.contributions assert result['edit_url'] == absolutify(self.addon.get_dev_url()) assert result['default_locale'] == self.addon.default_locale assert result['description'] == {'en-US': self.addon.description} assert result['developer_comments'] == { 'en-US': self.addon.developer_comments} assert result['guid'] == self.addon.guid assert result['has_eula'] is False assert result['has_privacy_policy'] is False assert result['homepage'] == { 'en-US': get_outgoing_url(unicode(self.addon.homepage)) } assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['is_disabled'] == self.addon.is_disabled assert result['is_experimental'] == self.addon.is_experimental is False assert result['is_featured'] == self.addon.is_featured() is False assert result['is_source_public'] == self.addon.view_source assert result['last_updated'] == ( self.addon.last_updated.replace(microsecond=0).isoformat() + 'Z') assert result['name'] == {'en-US': self.addon.name} assert result['previews'] assert len(result['previews']) == 2 result_preview = result['previews'][0] assert result_preview['id'] == first_preview.pk assert result_preview['caption'] is None assert result_preview['image_url'] == absolutify( first_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( first_preview.thumbnail_url) assert result_preview['image_size'] == first_preview.image_size assert result_preview['thumbnail_size'] == first_preview.thumbnail_size result_preview = result['previews'][1] assert result_preview['id'] == second_preview.pk assert result_preview['caption'] == { 'en-US': u'My câption', 'fr': u'Mön tîtré' } assert result_preview['image_url'] == absolutify( second_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( second_preview.thumbnail_url) assert (result_preview['image_size'] == second_preview.image_size == [567, 780]) assert (result_preview['thumbnail_size'] == second_preview.thumbnail_size == [199, 99]) assert result['ratings'] == { 'average': self.addon.average_rating, 'bayesian_average': self.addon.bayesian_rating, 'count': self.addon.total_ratings, 'text_count': self.addon.text_ratings_count, } assert result['public_stats'] == self.addon.public_stats assert result['requires_payment'] == self.addon.requires_payment assert result['review_url'] == absolutify( reverse('reviewers.review', args=[self.addon.pk])) assert result['slug'] == self.addon.slug assert result['status'] == 'public' assert result['summary'] == {'en-US': self.addon.summary} assert result['support_email'] == {'en-US': self.addon.support_email} assert result['support_url'] == { 'en-US': get_outgoing_url(unicode(self.addon.support_url)) } assert 'theme_data' not in result assert set(result['tags']) == set(['some_tag', 'some_other_tag']) assert result['type'] == 'extension' assert result['url'] == absolutify(self.addon.get_url_path()) assert result['weekly_downloads'] == self.addon.weekly_downloads return result
def add_static_theme_from_lwt(lwt): from olympia.activity.models import AddonLog olympia.core.set_user(UserProfile.objects.get(pk=settings.TASK_USER_ID)) # Try to handle LWT with no authors author = (lwt.listed_authors or [_get_lwt_default_author()])[0] # Wrap zip in FileUpload for Addon/Version from_upload to consume. upload = FileUpload.objects.create(user=author, valid=True) destination = os.path.join(user_media_path('addons'), 'temp', uuid.uuid4().hex + '.xpi') build_static_theme_xpi_from_lwt(lwt, destination) upload.update(path=destination) # Create addon + version parsed_data = parse_addon(upload, user=author) addon = Addon.initialize_addon_from_upload(parsed_data, upload, amo.RELEASE_CHANNEL_LISTED, author) addon_updates = {} # static themes are only compatible with Firefox at the moment, # not Android version = Version.from_upload(upload, addon, selected_apps=[amo.FIREFOX.id], channel=amo.RELEASE_CHANNEL_LISTED, parsed_data=parsed_data) # Set category static_theme_categories = CATEGORIES.get(amo.FIREFOX.id, []).get(amo.ADDON_STATICTHEME, []) lwt_category = (lwt.categories.all() or [None])[0] # lwt only have 1 cat. lwt_category_slug = lwt_category.slug if lwt_category else 'other' static_category = static_theme_categories.get( lwt_category_slug, static_theme_categories.get('other')) AddonCategory.objects.create(addon=addon, category=Category.from_static_category( static_category, True)) # Set license lwt_license = PERSONA_LICENSES_IDS.get( lwt.persona.license, LICENSE_COPYRIGHT_AR) # default to full copyright static_license = License.objects.get(builtin=lwt_license.builtin) version.update(license=static_license) # Set tags for addon_tag in AddonTag.objects.filter(addon=lwt): AddonTag.objects.create(addon=addon, tag=addon_tag.tag) # Steal the ratings (even with soft delete they'll be deleted anyway) addon_updates.update(average_rating=lwt.average_rating, bayesian_rating=lwt.bayesian_rating, total_ratings=lwt.total_ratings, text_ratings_count=lwt.text_ratings_count) Rating.unfiltered.filter(addon=lwt).update(addon=addon, version=version) # Modify the activity log entry too. rating_activity_log_ids = [ l.id for l in amo.LOG if getattr(l, 'action_class', '') == 'review' ] addonlog_qs = AddonLog.objects.filter( addon=lwt, activity_log__action__in=rating_activity_log_ids) [alog.transfer(addon) for alog in addonlog_qs.iterator()] # Copy the ADU statistics - the raw(ish) daily UpdateCounts for stats # dashboard and future update counts, and copy the summary numbers for now. migrate_theme_update_count(lwt, addon) addon_updates.update(average_daily_users=lwt.persona.popularity or 0, hotness=lwt.persona.movers or 0) # Logging activity.log_create(amo.LOG.CREATE_STATICTHEME_FROM_PERSONA, addon, user=author) # And finally sign the files (actually just one) for file_ in version.all_files: sign_file(file_) file_.update(datestatuschanged=lwt.last_updated, reviewed=datetime.now(), status=amo.STATUS_PUBLIC) addon_updates['status'] = amo.STATUS_PUBLIC # set the modified and creation dates to match the original. addon_updates['created'] = lwt.created addon_updates['modified'] = lwt.modified addon_updates['last_updated'] = lwt.last_updated addon.update(**addon_updates) return addon
def test_basic(self): self.addon = addon_factory( average_daily_users=4242, average_rating=4.21, description=u'My Addôn description', file_kw={ 'hash': 'fakehash', 'platform': amo.PLATFORM_WIN.id, 'size': 42, }, guid=generate_addon_guid(), homepage=u'https://www.example.org/', icon_type='image/png', name=u'My Addôn', public_stats=True, slug='my-addon', summary=u'My Addôn summary', support_email=u'*****@*****.**', support_url=u'https://support.example.org/support/my-addon/', tags=['some_tag', 'some_other_tag'], total_reviews=666, weekly_downloads=2147483647, ) AddonUser.objects.create(user=user_factory(username='******'), addon=self.addon, listed=False) second_author = user_factory( username='******', display_name=u'Secönd Author') first_author = user_factory( username='******', display_name=u'First Authôr') AddonUser.objects.create( user=second_author, addon=self.addon, position=2) AddonUser.objects.create( user=first_author, addon=self.addon, position=1) second_preview = Preview.objects.create( addon=self.addon, position=2, caption={'en-US': u'My câption', 'fr': u'Mön tîtré'}) first_preview = Preview.objects.create(addon=self.addon, position=1) av_min = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='2.0.99')[0] av_max = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='3.0.99')[0] ApplicationsVersions.objects.get_or_create( application=amo.THUNDERBIRD.id, version=self.addon.current_version, min=av_min, max=av_max) # Reset current_version.compatible_apps now that we've added an app. del self.addon.current_version.compatible_apps cat1 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['bookmarks']) cat1.save() AddonCategory.objects.create(addon=self.addon, category=cat1) cat2 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['alerts-updates']) cat2.save() AddonCategory.objects.create(addon=self.addon, category=cat2) cat3 = Category.from_static_category( CATEGORIES[amo.THUNDERBIRD.id][amo.ADDON_EXTENSION]['calendar']) cat3.save() AddonCategory.objects.create(addon=self.addon, category=cat3) result = self.serialize() assert result['id'] == self.addon.pk assert result['average_daily_users'] == self.addon.average_daily_users assert result['categories'] == { 'firefox': ['alerts-updates', 'bookmarks'], 'thunderbird': ['calendar']} assert result['current_beta_version'] is None assert result['current_version'] self._test_version( self.addon.current_version, result['current_version']) assert result['authors'] assert len(result['authors']) == 2 assert result['authors'][0] == { 'name': first_author.name, 'url': absolutify(first_author.get_url_path())} assert result['authors'][1] == { 'name': second_author.name, 'url': absolutify(second_author.get_url_path())} assert result['edit_url'] == absolutify(self.addon.get_dev_url()) assert result['default_locale'] == self.addon.default_locale assert result['description'] == {'en-US': self.addon.description} assert result['guid'] == self.addon.guid assert result['has_eula'] is False assert result['has_privacy_policy'] is False assert result['homepage'] == {'en-US': self.addon.homepage} assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['is_disabled'] == self.addon.is_disabled assert result['is_experimental'] == self.addon.is_experimental is False assert result['is_listed'] == self.addon.is_listed assert result['is_source_public'] == self.addon.view_source assert result['name'] == {'en-US': self.addon.name} assert result['last_updated'] == self.addon.last_updated.isoformat() assert result['previews'] assert len(result['previews']) == 2 result_preview = result['previews'][0] assert result_preview['id'] == first_preview.pk assert result_preview['caption'] is None assert result_preview['image_url'] == absolutify( first_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( first_preview.thumbnail_url) result_preview = result['previews'][1] assert result_preview['id'] == second_preview.pk assert result_preview['caption'] == { 'en-US': u'My câption', 'fr': u'Mön tîtré' } assert result_preview['image_url'] == absolutify( second_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( second_preview.thumbnail_url) assert result['ratings'] == { 'average': self.addon.average_rating, 'count': self.addon.total_reviews, } assert result['public_stats'] == self.addon.public_stats assert result['review_url'] == absolutify( reverse('editors.review', args=[self.addon.pk])) assert result['slug'] == self.addon.slug assert result['status'] == 'public' assert result['summary'] == {'en-US': self.addon.summary} assert result['support_email'] == {'en-US': self.addon.support_email} assert result['support_url'] == {'en-US': self.addon.support_url} assert 'theme_data' not in result assert set(result['tags']) == set(['some_tag', 'some_other_tag']) assert result['type'] == 'extension' assert result['url'] == absolutify(self.addon.get_url_path()) assert result['weekly_downloads'] == self.addon.weekly_downloads return result
if addon.default_locale.lower() == lang.lower(): addon.target_locale = addon.default_locale addon.save() log.info( '[@None] Created new "{0}" language pack, version {1}'.format( xpi, data['version'])) # Set the category for app in version.compatible_apps: static_category = (CATEGORIES.get(app.id, []).get(amo.ADDON_LPAPP, []).get('general')) if static_category: category = Category.from_static_category(static_category, True) AddonCategory.objects.get_or_create(addon=addon, category=category) # Add a license if there isn't one already if not version.license: license = License.objects.builtins().get(builtin=1) version.update(license=license) file_ = version.files.get() if not is_beta: # Not `version.files.update`, because we need to trigger save # hooks. file_.update(status=amo.STATUS_PUBLIC) sign_file(file_)
def addon_factory(status=amo.STATUS_APPROVED, version_kw=None, file_kw=None, **kw): version_kw = version_kw or {} # Disconnect signals until the last save. post_save.disconnect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') post_save.disconnect(update_es_for_promoted, sender=PromotedAddon, dispatch_uid='addons.search.index') post_save.disconnect( update_es_for_promoted_approval, sender=PromotedApproval, dispatch_uid='addons.search.index', ) type_ = kw.pop('type', amo.ADDON_EXTENSION) popularity = kw.pop('popularity', None) tags = kw.pop('tags', []) users = kw.pop('users', []) when = _get_created(kw.pop('created', None)) category = kw.pop('category', None) default_locale = kw.get('default_locale', settings.LANGUAGE_CODE) # Keep as much unique data as possible in the uuid: '-' aren't important. name = kw.pop('name', 'Addôn %s' % str(uuid.uuid4()).replace('-', '')) slug = kw.pop('slug', None) if slug is None: slug = name.replace(' ', '-').lower()[:30] promoted_group = kw.pop('promoted', None) kwargs = { # Set artificially the status to STATUS_APPROVED for now, the real # status will be set a few lines below, after the update_version() # call. This prevents issues when calling addon_factory with # STATUS_DELETED. 'status': amo.STATUS_APPROVED, 'default_locale': default_locale, 'name': name, 'slug': slug, 'average_daily_users': popularity or random.randint(200, 2000), 'weekly_downloads': popularity or random.randint(200, 2000), 'created': when, 'last_updated': when, } if 'summary' not in kw: # Assign a dummy summary if none was specified in keyword args. kwargs['summary'] = 'Summary for %s' % name kwargs['guid'] = kw.pop('guid', '{%s}' % str(uuid.uuid4())) kwargs.update(kw) # Save 1. with translation.override(default_locale): addon = Addon.objects.create(type=type_, **kwargs) # Save 2. if promoted_group: PromotedAddon.objects.create(addon=addon, group_id=promoted_group.id) if 'promotion_approved' not in version_kw: version_kw['promotion_approved'] = True version = version_factory(file_kw, addon=addon, **version_kw) addon.update_version() # version_changed task will be triggered and will update last_updated in # database for this add-on depending on the state of the version / files. # We're calling the function it uses to compute the value ourselves and= # sticking that into the attribute ourselves so that we already have the # correct value in the instance we are going to return. # Note: the aim is to have the instance consistent with what will be in the # database because of the task, *not* to be consistent with the status of # the add-on. Because we force the add-on status without forcing the status # of the latest file, the value we end up with might not make sense in some # cases. addon.last_updated = compute_last_updated(addon) addon.status = status for tag in tags: Tag(tag_text=tag).save_tag(addon) for user in users: addon.addonuser_set.create(user=user) application = version_kw.get('application', amo.FIREFOX.id) if not category and addon.type in CATEGORIES[application]: static_category = random.choice( list(CATEGORIES[application][addon.type].values())) category = Category.from_static_category(static_category, True) if category: AddonCategory.objects.create(addon=addon, category=category) # Put signals back. post_save.connect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') post_save.connect(update_es_for_promoted, sender=PromotedAddon, dispatch_uid='addons.search.index') post_save.connect( update_es_for_promoted_approval, sender=PromotedApproval, dispatch_uid='addons.search.index', ) # Save 4. addon.save() if addon.guid: AddonGUID.objects.create(addon=addon, guid=addon.guid) # Potentially update is_public on authors [user.update_is_public() for user in users] if 'nomination' in version_kw: # If a nomination date was set on the version, then it might have been # erased at post_save by addons.models.watch_status() version.save() return addon
def test_basic(self): cat1 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['bookmarks']) cat1.save() self.addon = addon_factory( average_daily_users=4242, average_rating=4.21, bayesian_rating=4.22, category=cat1, description=u'My Addôn description', file_kw={ 'hash': 'fakehash', 'is_restart_required': False, 'is_webextension': True, 'platform': amo.PLATFORM_WIN.id, 'size': 42, }, guid=generate_addon_guid(), homepage=u'https://www.example.org/', icon_type='image/png', name=u'My Addôn', public_stats=True, slug='my-addon', summary=u'My Addôn summary', support_email=u'*****@*****.**', support_url=u'https://support.example.org/support/my-addon/', tags=['some_tag', 'some_other_tag'], total_reviews=666, weekly_downloads=2147483647, ) AddonUser.objects.create(user=user_factory(username='******'), addon=self.addon, listed=False) second_author = user_factory(username='******', display_name=u'Secönd Author') first_author = user_factory(username='******', display_name=u'First Authôr') AddonUser.objects.create(user=second_author, addon=self.addon, position=2) AddonUser.objects.create(user=first_author, addon=self.addon, position=1) second_preview = Preview.objects.create(addon=self.addon, position=2, caption={ 'en-US': u'My câption', 'fr': u'Mön tîtré' }) first_preview = Preview.objects.create(addon=self.addon, position=1) av_min = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='2.0.99')[0] av_max = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='3.0.99')[0] ApplicationsVersions.objects.get_or_create( application=amo.THUNDERBIRD.id, version=self.addon.current_version, min=av_min, max=av_max) # Reset current_version.compatible_apps now that we've added an app. del self.addon.current_version.compatible_apps cat2 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['alerts-updates']) cat2.save() AddonCategory.objects.create(addon=self.addon, category=cat2) cat3 = Category.from_static_category( CATEGORIES[amo.THUNDERBIRD.id][amo.ADDON_EXTENSION]['calendar']) cat3.save() AddonCategory.objects.create(addon=self.addon, category=cat3) result = self.serialize() assert result['id'] == self.addon.pk assert result['average_daily_users'] == self.addon.average_daily_users assert result['categories'] == { 'firefox': ['alerts-updates', 'bookmarks'], 'thunderbird': ['calendar'] } assert result['current_beta_version'] is None # In this serializer latest_unlisted_version is omitted. assert 'latest_unlisted_version' not in result assert result['current_version'] self._test_version(self.addon.current_version, result['current_version']) assert result['current_version']['url'] == absolutify( reverse('addons.versions', args=[self.addon.slug, self.addon.current_version.version])) assert result['authors'] assert len(result['authors']) == 2 self.check_author(first_author, result['authors'][0]) self.check_author(second_author, result['authors'][1]) assert result['edit_url'] == absolutify(self.addon.get_dev_url()) assert result['default_locale'] == self.addon.default_locale assert result['description'] == {'en-US': self.addon.description} assert result['guid'] == self.addon.guid assert result['has_eula'] is False assert result['has_privacy_policy'] is False assert result['homepage'] == { 'en-US': get_outgoing_url(unicode(self.addon.homepage)) } assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['is_disabled'] == self.addon.is_disabled assert result['is_experimental'] == self.addon.is_experimental is False assert result['is_featured'] == self.addon.is_featured() is False assert result['is_source_public'] == self.addon.view_source assert result['last_updated'] == ( self.addon.last_updated.replace(microsecond=0).isoformat() + 'Z') assert result['name'] == {'en-US': self.addon.name} assert result['previews'] assert len(result['previews']) == 2 result_preview = result['previews'][0] assert result_preview['id'] == first_preview.pk assert result_preview['caption'] is None assert result_preview['image_url'] == absolutify( first_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( first_preview.thumbnail_url) result_preview = result['previews'][1] assert result_preview['id'] == second_preview.pk assert result_preview['caption'] == { 'en-US': u'My câption', 'fr': u'Mön tîtré' } assert result_preview['image_url'] == absolutify( second_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( second_preview.thumbnail_url) assert result['ratings'] == { 'average': self.addon.average_rating, 'bayesian_average': self.addon.bayesian_rating, 'count': self.addon.total_reviews, } assert result['public_stats'] == self.addon.public_stats assert result['requires_payment'] == self.addon.requires_payment assert result['review_url'] == absolutify( reverse('editors.review', args=[self.addon.pk])) assert result['slug'] == self.addon.slug assert result['status'] == 'public' assert result['summary'] == {'en-US': self.addon.summary} assert result['support_email'] == {'en-US': self.addon.support_email} assert result['support_url'] == { 'en-US': get_outgoing_url(unicode(self.addon.support_url)) } assert 'theme_data' not in result assert set(result['tags']) == set(['some_tag', 'some_other_tag']) assert result['type'] == 'extension' assert result['url'] == absolutify(self.addon.get_url_path()) assert result['weekly_downloads'] == self.addon.weekly_downloads return result
def _handle_addon(self, addon_data): version = addon_data['current_version'] files = version['files'] or [] file_kw = {} try: file_kw = { 'hash': files[0]['hash'], 'status': amo.STATUS_CHOICES_API_LOOKUP[files[0]['status']], 'platform': amo.PLATFORM_DICT[files[0]['platform']].id, 'size': files[0]['size'], 'is_webextension': files[0]['is_webextension'], 'is_mozilla_signed_extension': (files[0]['is_mozilla_signed_extension']), 'strict_compatibility': (version['is_strict_compatibility_enabled']), } except (KeyError, IndexError): file_kw = {} # TODO: # * license # * ratings # * previews # * android compat & category data if Addon.objects.filter(slug=addon_data['slug']).exists(): print('Skipping %s (slug already exists)' % addon_data['slug']) return if (addon_data['guid'] and Addon.objects.filter(guid=addon_data['guid']).exists()): print('Skipping %s (guid already exists)' % addon_data['guid']) return users = [] for user in addon_data['authors']: try: users.append(UserProfile.objects.get(username=user['name'])) except UserProfile.DoesNotExist: email = '*****@*****.**' % str(uuid.uuid4().hex) users.append(user_factory(username=user['name'], email=email)) addon_type = amo.ADDON_SEARCH_SLUGS[addon_data['type']] if 'firefox' in addon_data['categories']: category = addon_data['categories']['firefox'][0] else: category = None if category not in CATEGORIES[amo.FIREFOX.id][addon_type]: category = None print('Category %s' % category, 'not found') else: category = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][addon_type][category], True) print('Creating add-on %s' % addon_data['slug']) compatibility = version['compatibility'] if compatibility and 'firefox' in compatibility: version_kw = { 'min_app_version': version['compatibility']['firefox']['min'], 'max_app_version': version['compatibility']['firefox']['max'], } else: version_kw = {} with atomic(): addon_factory( users=users, average_daily_users=addon_data['average_daily_users'], category=category, type=addon_type, guid=addon_data['guid'], slug=addon_data['slug'], name=addon_data['name'], summary=addon_data['summary'], description=addon_data['description'], file_kw=file_kw, version_kw=version_kw, weekly_downloads=addon_data.get('weekly_downloads', 0), default_locale=addon_data['default_locale'], tags=addon_data['tags'], )
def add_static_theme_from_lwt(lwt): from olympia.activity.models import AddonLog olympia.core.set_user(UserProfile.objects.get(pk=settings.TASK_USER_ID)) # Try to handle LWT with no authors author = (lwt.listed_authors or [_get_lwt_default_author()])[0] # Wrap zip in FileUpload for Addon/Version from_upload to consume. upload = FileUpload.objects.create( user=author, valid=True) destination = os.path.join( user_media_path('addons'), 'temp', uuid.uuid4().hex + '.xpi') build_static_theme_xpi_from_lwt(lwt, destination) upload.update(path=destination) # Create addon + version parsed_data = parse_addon(upload, user=author) addon = Addon.initialize_addon_from_upload( parsed_data, upload, amo.RELEASE_CHANNEL_LISTED, author) addon_updates = {} # static themes are only compatible with Firefox at the moment, # not Android version = Version.from_upload( upload, addon, selected_apps=[amo.FIREFOX.id], channel=amo.RELEASE_CHANNEL_LISTED, parsed_data=parsed_data) # Set category static_theme_categories = CATEGORIES.get(amo.FIREFOX.id, []).get( amo.ADDON_STATICTHEME, []) lwt_category = (lwt.categories.all() or [None])[0] # lwt only have 1 cat. lwt_category_slug = lwt_category.slug if lwt_category else 'other' static_category = static_theme_categories.get( lwt_category_slug, static_theme_categories.get('other')) AddonCategory.objects.create( addon=addon, category=Category.from_static_category(static_category, True)) # Set license lwt_license = PERSONA_LICENSES_IDS.get( lwt.persona.license, LICENSE_COPYRIGHT_AR) # default to full copyright static_license = License.objects.get(builtin=lwt_license.builtin) version.update(license=static_license) # Set tags for addon_tag in AddonTag.objects.filter(addon=lwt): AddonTag.objects.create(addon=addon, tag=addon_tag.tag) # Steal the ratings (even with soft delete they'll be deleted anyway) addon_updates.update( average_rating=lwt.average_rating, bayesian_rating=lwt.bayesian_rating, total_ratings=lwt.total_ratings, text_ratings_count=lwt.text_ratings_count) Rating.unfiltered.filter(addon=lwt).update(addon=addon, version=version) # Modify the activity log entry too. rating_activity_log_ids = [ l.id for l in amo.LOG if getattr(l, 'action_class', '') == 'review'] addonlog_qs = AddonLog.objects.filter( addon=lwt, activity_log__action__in=rating_activity_log_ids) [alog.transfer(addon) for alog in addonlog_qs.iterator()] # Copy the ADU statistics - the raw(ish) daily UpdateCounts for stats # dashboard and future update counts, and copy the summary numbers for now. migrate_theme_update_count(lwt, addon) addon_updates.update( average_daily_users=lwt.persona.popularity or 0, hotness=lwt.persona.movers or 0) # Logging activity.log_create( amo.LOG.CREATE_STATICTHEME_FROM_PERSONA, addon, user=author) # And finally sign the files (actually just one) for file_ in version.all_files: sign_file(file_) file_.update( datestatuschanged=lwt.last_updated, reviewed=datetime.now(), status=amo.STATUS_PUBLIC) addon_updates['status'] = amo.STATUS_PUBLIC # set the modified and creation dates to match the original. addon_updates['created'] = lwt.created addon_updates['modified'] = lwt.modified addon_updates['last_updated'] = lwt.last_updated addon.update(**addon_updates) return addon
if addon.default_locale.lower() == lang.lower(): addon.target_locale = addon.default_locale addon.save() log.info('[@None] Created new "{0}" language pack, version {1}' .format(xpi, data['version'])) # Set the category for app in version.compatible_apps: static_category = ( CATEGORIES.get(app.id, []).get(amo.ADDON_LPAPP, []) .get('general')) if static_category: category = Category.from_static_category(static_category, True) AddonCategory.objects.get_or_create( addon=addon, category=category) # Add a license if there isn't one already if not version.license: license = License.objects.builtins().get(builtin=1) version.update(license=license) file_ = version.files.get() if not is_beta: # Not `version.files.update`, because we need to trigger save # hooks. file_.update(status=amo.STATUS_PUBLIC) sign_file(file_, settings.SIGNING_SERVER)