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 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 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 handle_upload(self, request, addon, version_string, guid=None): if 'upload' in request.FILES: filedata = request.FILES['upload'] else: raise forms.ValidationError( ugettext(u'Missing "upload" key in multipart file data.'), status.HTTP_400_BAD_REQUEST) # # Parse the file to get and validate package data with the addon. pkg = parse_addon(filedata, addon, user=request.user) if addon is not None and addon.status == amo.STATUS_DISABLED: msg = ugettext( 'You cannot add versions to an addon that has status: %s.' % amo.STATUS_CHOICES_ADDON[amo.STATUS_DISABLED]) raise forms.ValidationError(msg, status.HTTP_400_BAD_REQUEST) version_string = version_string or pkg['version'] if version_string and pkg['version'] != version_string: raise forms.ValidationError( ugettext('Version does not match the manifest file.'), status.HTTP_400_BAD_REQUEST) if (addon is not None and addon.versions.filter(version=version_string).exists()): raise forms.ValidationError(ugettext('Version already exists.'), status.HTTP_409_CONFLICT) package_guid = pkg.get('guid', None) dont_allow_no_guid = (not addon and not package_guid and not pkg.get('is_webextension', False)) if dont_allow_no_guid: raise forms.ValidationError( ugettext('Only WebExtensions are allowed to omit the GUID'), status.HTTP_400_BAD_REQUEST) if guid is not None and not addon and not package_guid: # No guid was present in the package, but one was provided in the # URL, so we take it instead of generating one ourselves. But # first, validate it properly. if len(guid) > 64: raise forms.ValidationError( ugettext( 'Please specify your Add-on GUID in the manifest if it\'s ' 'longer than 64 characters.')) if not amo.ADDON_GUID_PATTERN.match(guid): raise forms.ValidationError(ugettext('Invalid GUID in URL'), status.HTTP_400_BAD_REQUEST) pkg['guid'] = guid # channel will be ignored for new addons. if addon is None: channel = amo.RELEASE_CHANNEL_UNLISTED # New is always unlisted. addon = Addon.initialize_addon_from_upload(data=pkg, upload=filedata, channel=channel, user=request.user) created = True else: created = False channel_param = request.POST.get('channel') channel = amo.CHANNEL_CHOICES_LOOKUP.get(channel_param) if not channel: last_version = (addon.find_latest_version(None, exclude=())) if last_version: channel = last_version.channel else: channel = amo.RELEASE_CHANNEL_UNLISTED # Treat as new. will_have_listed = channel == amo.RELEASE_CHANNEL_LISTED if not addon.has_complete_metadata( has_listed_versions=will_have_listed): raise forms.ValidationError( ugettext('You cannot add a listed version to this addon ' 'via the API due to missing metadata. ' 'Please submit via the website'), status.HTTP_400_BAD_REQUEST) file_upload = handle_upload(filedata=filedata, request=request, addon=addon, submit=True, channel=channel) return file_upload, created
def handle_upload(self, request, addon, version_string, guid=None): if 'upload' in request.FILES: filedata = request.FILES['upload'] else: raise forms.ValidationError( gettext('Missing "upload" key in multipart file data.'), status.HTTP_400_BAD_REQUEST, ) # Parse the file to get and validate package data with the addon. parsed_data = parse_addon(filedata, addon, user=request.user) if addon is not None and addon.status == amo.STATUS_DISABLED: msg = gettext( 'You cannot add versions to an addon that has status: %s.' % amo.STATUS_CHOICES_ADDON[amo.STATUS_DISABLED]) raise forms.ValidationError(msg, status.HTTP_400_BAD_REQUEST) version_string = version_string or parsed_data['version'] if version_string and parsed_data['version'] != version_string: raise forms.ValidationError( gettext('Version does not match the manifest file.'), status.HTTP_400_BAD_REQUEST, ) existing_version = addon and Version.unfiltered.filter( addon=addon, version=version_string) if existing_version: latest_version = addon.find_latest_version(None, exclude=()) msg = gettext('Version already exists. Latest version is: %s.' % latest_version.version) raise forms.ValidationError(msg, status.HTTP_409_CONFLICT) package_guid = parsed_data.get('guid', None) dont_allow_no_guid = (not addon and not package_guid and not parsed_data.get('is_webextension', False)) if dont_allow_no_guid: raise forms.ValidationError( gettext( 'Only WebExtensions are allowed to omit the Add-on ID'), status.HTTP_400_BAD_REQUEST, ) if guid is not None and not addon and not package_guid: # No guid was present in the package, but one was provided in the # URL, so we take it instead of generating one ourselves. There is # an extra validation check for those: guids passed in the URL are # not allowed to be longer than 64 chars. if len(guid) > 64: raise forms.ValidationError( gettext( "Please specify your Add-on ID in the manifest if it's " 'longer than 64 characters.')) parsed_data['guid'] = guid elif not guid and package_guid: guid = package_guid if guid: # If we did get a guid, regardless of its source, validate it now # before creating anything. if not amo.ADDON_GUID_PATTERN.match(guid): raise forms.ValidationError( gettext('Invalid Add-on ID in URL or package'), status.HTTP_400_BAD_REQUEST, ) block_qs = Block.objects.filter(guid=addon.guid if addon else guid) if block_qs and block_qs.first().is_version_blocked(version_string): msg = gettext( 'Version {version} matches {block_link} for this add-on. ' 'You can contact {amo_admins} for additional information.') raise forms.ValidationError( msg.format( version=version_string, block_link=absolutify( reverse('blocklist.block', args=[guid])), amo_admins='*****@*****.**', ), status.HTTP_400_BAD_REQUEST, ) # channel will be ignored for new addons. if addon is None: channel = amo.RELEASE_CHANNEL_UNLISTED # New is always unlisted. addon = Addon.initialize_addon_from_upload(data=parsed_data, upload=filedata, channel=channel, user=request.user) created = True else: created = False channel_param = request.POST.get('channel') channel = amo.CHANNEL_CHOICES_LOOKUP.get(channel_param) if not channel: last_version = addon.find_latest_version(None, exclude=()) if last_version: channel = last_version.channel else: channel = amo.RELEASE_CHANNEL_UNLISTED # Treat as new. if addon.disabled_by_user and channel == amo.RELEASE_CHANNEL_LISTED: msg = gettext( 'You cannot add listed versions to an addon set to ' '"Invisible" state.') raise forms.ValidationError(msg, status.HTTP_400_BAD_REQUEST) will_have_listed = channel == amo.RELEASE_CHANNEL_LISTED if not addon.has_complete_metadata( has_listed_versions=will_have_listed): raise forms.ValidationError( gettext('You cannot add a listed version to this addon ' 'via the API due to missing metadata. ' 'Please submit via the website'), status.HTTP_400_BAD_REQUEST, ) # Note: The following function call contains a log statement that is # used by foxsec-pipeline - if refactoring, keep in mind we need to # trigger the same log statement. file_upload = devhub_handle_upload( filedata=filedata, request=request, addon=addon, submit=True, channel=channel, source=amo.UPLOAD_SOURCE_API, ) return file_upload, created
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 handle_upload(self, request, addon, version_string, guid=None): if 'upload' in request.FILES: filedata = request.FILES['upload'] else: raise forms.ValidationError( ugettext(u'Missing "upload" key in multipart file data.'), status.HTTP_400_BAD_REQUEST) # # Parse the file to get and validate package data with the addon. pkg = parse_addon(filedata, addon, user=request.user) if addon is not None and addon.status == amo.STATUS_DISABLED: msg = ugettext( 'You cannot add versions to an addon that has status: %s.' % amo.STATUS_CHOICES_ADDON[amo.STATUS_DISABLED]) raise forms.ValidationError(msg, status.HTTP_400_BAD_REQUEST) version_string = version_string or pkg['version'] if version_string and pkg['version'] != version_string: raise forms.ValidationError( ugettext('Version does not match the manifest file.'), status.HTTP_400_BAD_REQUEST) if (addon is not None and addon.versions.filter(version=version_string).exists()): raise forms.ValidationError( ugettext('Version already exists.'), status.HTTP_409_CONFLICT) package_guid = pkg.get('guid', None) dont_allow_no_guid = ( not addon and not package_guid and not pkg.get('is_webextension', False)) if dont_allow_no_guid: raise forms.ValidationError( ugettext('Only WebExtensions are allowed to omit the GUID'), status.HTTP_400_BAD_REQUEST) if guid is not None and not addon and not package_guid: # No guid was present in the package, but one was provided in the # URL, so we take it instead of generating one ourselves. But # first, validate it properly. if len(guid) > 64: raise forms.ValidationError(ugettext( 'Please specify your Add-on GUID in the manifest if it\'s ' 'longer than 64 characters.' )) if not amo.ADDON_GUID_PATTERN.match(guid): raise forms.ValidationError( ugettext('Invalid GUID in URL'), status.HTTP_400_BAD_REQUEST) pkg['guid'] = guid # channel will be ignored for new addons. if addon is None: channel = amo.RELEASE_CHANNEL_UNLISTED # New is always unlisted. addon = Addon.initialize_addon_from_upload( data=pkg, upload=filedata, channel=channel, user=request.user) created = True else: created = False channel_param = request.POST.get('channel') channel = amo.CHANNEL_CHOICES_LOOKUP.get(channel_param) if not channel: last_version = ( addon.find_latest_version(None, exclude=())) if last_version: channel = last_version.channel else: channel = amo.RELEASE_CHANNEL_UNLISTED # Treat as new. will_have_listed = channel == amo.RELEASE_CHANNEL_LISTED if not addon.has_complete_metadata( has_listed_versions=will_have_listed): raise forms.ValidationError( ugettext('You cannot add a listed version to this addon ' 'via the API due to missing metadata. ' 'Please submit via the website'), status.HTTP_400_BAD_REQUEST) file_upload = handle_upload( filedata=filedata, request=request, addon=addon, submit=True, channel=channel) return file_upload, created
def create_version(self, addon=None): from olympia.addons.models import Addon from olympia.files.models import FileUpload from olympia.files.utils import parse_addon from olympia.versions.models import Version from olympia.versions.utils import get_next_version_number version_number = '1.0' # If passing an existing add-on, we need to bump the version number # to avoid clashes, and also perform a few checks. if addon is not None: # Obviously we want an add-on with the right type. if addon.type != amo.ADDON_SITE_PERMISSION: raise ImproperlyConfigured( 'SitePermissionVersionCreator was instantiated with non ' 'site-permission add-on' ) # If the user isn't an author, something is wrong. if not addon.authors.filter(pk=self.user.pk).exists(): raise ImproperlyConfigured( 'SitePermissionVersionCreator was instantiated with a ' 'bogus addon/user' ) # Changing the origins isn't supported at the moment. latest_version = addon.find_latest_version( exclude=(), channel=amo.RELEASE_CHANNEL_UNLISTED ) previous_origins = sorted( latest_version.installorigin_set.all().values_list('origin', flat=True) ) if previous_origins != self.install_origins: raise ImproperlyConfigured( 'SitePermissionVersionCreator was instantiated with an ' 'addon that has different origins' ) version_number = get_next_version_number(addon) # Create the manifest, with more user-friendly name & description built # from install_origins/site_permissions, and then the zipfile with that # manifest inside. manifest_data = self._create_manifest(version_number) file_obj = self._create_zipfile(manifest_data) # Parse the zip we just created. The user needs to be the Mozilla User # because regular submissions of this type of add-on is forbidden to # normal users. parsed_data = parse_addon( file_obj, addon=addon, user=get_task_user(), ) with core.override_remote_addr(self.remote_addr): if addon is None: # Create the Addon instance (without a Version/File at this point). addon = Addon.initialize_addon_from_upload( data=parsed_data, upload=file_obj, channel=amo.RELEASE_CHANNEL_UNLISTED, user=self.user, ) # Create the FileUpload that will become the File+Version. upload = FileUpload.from_post( file_obj, filename=file_obj.name, size=file_obj.size, addon=addon, version=version_number, channel=amo.RELEASE_CHANNEL_UNLISTED, user=self.user, source=amo.UPLOAD_SOURCE_GENERATED, ) # And finally create the Version instance from the FileUpload. return Version.from_upload( upload, addon, amo.RELEASE_CHANNEL_UNLISTED, selected_apps=[x[0] for x in amo.APPS_CHOICES], parsed_data=parsed_data, )
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