def create_blocklisted_version(self): """ Creates a new version who's file is the blocklisted app found in /media and sets status to STATUS_BLOCKLISTED. """ blocklisted_path = os.path.join(settings.MEDIA_ROOT, 'packaged-apps', 'blocklisted.zip') last_version = self.current_version.version v = Version.objects.create(addon=self, version='blocklisted-%s' % last_version) f = File(version=v, status=amo.STATUS_BLOCKED, platform=Platform.objects.get(id=amo.PLATFORM_ALL.id)) f.filename = f.generate_filename() copy_stored_file(blocklisted_path, f.file_path) log.info(u'[Webapp:%s] Copied blocklisted app from %s to %s' % (self.id, blocklisted_path, f.file_path)) f.size = storage.size(f.file_path) f.hash = f.generate_hash(f.file_path) f.save() f.inject_ids() self.sign_if_packaged(v.pk) self.status = amo.STATUS_BLOCKED self._current_version = v self.save()
def manifest_updated(self, manifest, upload): """The manifest has updated, update the version and file. This is intended to be used for hosted apps only, which have only a single version and a single file. """ data = parse_addon(upload, self) version = self.versions.latest() version.update(version=data['version']) path = smart_path(nfd_str(upload.path)) file = version.files.latest() file.filename = file.generate_filename(extension='.webapp') file.size = int(max(1, round(storage.size(path) / 1024, 0))) file.hash = (file.generate_hash(path) if waffle.switch_is_active('file-hash-paranoia') else upload.hash) log.info('Updated file hash to %s' % file.hash) file.save() # Move the uploaded file from the temp location. copy_stored_file(path, os.path.join(version.path_prefix, nfd_str(file.filename))) log.info('[Webapp:%s] Copied updated manifest to %s' % ( self, version.path_prefix)) amo.log(amo.LOG.MANIFEST_UPDATED, self)
def approve_rereview(theme): """Replace original theme with pending theme on filesystem.""" # If reuploaded theme, replace old theme design. storage = LocalFileStorage() rereview = theme.rereviewqueuetheme_set.all() reupload = rereview[0] if reupload.header_path != reupload.theme.header_path: create_persona_preview_images( src=reupload.header_path, full_dst=[reupload.theme.thumb_path, reupload.theme.icon_path], set_modified_on=[reupload.theme.addon]) if not reupload.theme.is_new(): # Legacy themes also need a preview_large.jpg. # Modern themes use preview.png for both thumb and preview so there # is no problem there. copy_stored_file(reupload.theme.thumb_path, reupload.theme.preview_path, storage=storage) move_stored_file(reupload.header_path, reupload.theme.header_path, storage=storage) if reupload.footer_path != reupload.theme.footer_path: move_stored_file(reupload.footer_path, reupload.theme.footer_path, storage=storage) rereview.delete() theme.addon.increment_version()
def create_blocklisted_version(self): """ Creates a new version who's file is the blocklisted app found in /media and sets status to STATUS_BLOCKLISTED. """ blocklisted_path = os.path.join(settings.MEDIA_ROOT, 'packaged-apps', 'blocklisted.zip') last_version = self.current_version.version v = Version.objects.create( addon=self, version='blocklisted-%s' % last_version) f = File(version=v, status=amo.STATUS_BLOCKED, platform=Platform.objects.get(id=amo.PLATFORM_ALL.id)) f.filename = f.generate_filename() copy_stored_file(blocklisted_path, f.file_path) log.info(u'[Webapp:%s] Copied blocklisted app from %s to %s' % ( self.id, blocklisted_path, f.file_path)) f.size = storage.size(f.file_path) f.hash = f.generate_hash(f.file_path) f.save() f.inject_ids() self.sign_if_packaged(v.pk) self.status = amo.STATUS_BLOCKED self._current_version = v self.save()
def manifest_updated(self, manifest, upload): """The manifest has updated, update the version and file. This is intended to be used for hosted apps only, which have only a single version and a single file. """ data = parse_addon(upload, self) version = self.versions.latest() version.update(version=data['version']) path = smart_path(nfd_str(upload.path)) file = version.files.latest() file.filename = file.generate_filename(extension='.webapp') file.size = storage.size(path) file.hash = (file.generate_hash(path) if waffle.switch_is_active('file-hash-paranoia') else upload.hash) log.info('Updated file hash to %s' % file.hash) file.save() # Move the uploaded file from the temp location. copy_stored_file( path, os.path.join(version.path_prefix, nfd_str(file.filename))) log.info('[Webapp:%s] Copied updated manifest to %s' % (self, version.path_prefix)) amo.log(amo.LOG.MANIFEST_UPDATED, self)
def approve_rereview(theme): """Replace original theme with pending theme on filesystem.""" # If reuploaded theme, replace old theme design. storage = LocalFileStorage() rereview = theme.rereviewqueuetheme_set.all() reupload = rereview[0] if reupload.header_path != reupload.theme.header_path: create_persona_preview_images( src=reupload.header_path, full_dst=[ reupload.theme.thumb_path, reupload.theme.icon_path], set_modified_on=[reupload.theme.addon]) if not reupload.theme.is_new(): # Legacy themes also need a preview_large.jpg. # Modern themes use preview.png for both thumb and preview so there # is no problem there. copy_stored_file(reupload.theme.thumb_path, reupload.theme.preview_path, storage=storage) move_stored_file( reupload.header_path, reupload.theme.header_path, storage=storage) if reupload.footer_path != reupload.theme.footer_path: move_stored_file( reupload.footer_path, reupload.theme.footer_path, storage=storage) rereview.delete() theme.addon.increment_version()
def from_upload(cls, upload, version, platform, is_beta=False, parse_data={}): addon = version.addon file_ = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] if ext == '.jar': ext = '.xpi' file_.filename = file_.generate_filename(extension=ext or '.xpi') # Size in bytes. file_.size = storage.size(upload.path) data = cls.get_jetpack_metadata(upload.path) if 'sdkVersion' in data and data['sdkVersion']: file_.jetpack_version = data['sdkVersion'][:10] if file_.jetpack_version: Tag(tag_text='jetpack').save_tag(addon) file_.builder_version = data['builderVersion'] file_.no_restart = parse_data.get('no_restart', False) file_.strict_compatibility = parse_data.get('strict_compatibility', False) file_.is_multi_package = parse_data.get('is_multi_package', False) if is_beta and addon.status == amo.STATUS_PUBLIC: file_.status = amo.STATUS_BETA elif addon.trusted: # New files in trusted add-ons automatically receive the correct # approved status for their review class. if addon.status == amo.STATUS_PUBLIC: file_.status = amo.STATUS_PUBLIC elif addon.status in amo.LITE_STATUSES: file_.status = amo.STATUS_LITE file_.hash = file_.generate_hash(upload.path) if upload.validation: validation = json.loads(upload.validation) if validation['metadata'].get('requires_chrome'): file_.requires_chrome = True file_.save() log.debug('New file: %r from %r' % (file_, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if file_.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(file_.filename))) if upload.validation: # Import loop. from devhub.tasks import annotate_validation_results validation = annotate_validation_results(validation) FileValidation.from_json(file_, validation) return file_
def copy_to_mirror(self): if not self.filename: return try: if storage.exists(self.file_path): dst = self.mirror_file_path if not dst: return log.info("Moving file to mirror: %s => %s" % (self.file_path, dst)) copy_stored_file(self.file_path, dst) except UnicodeEncodeError: log.info("Copy Failure: %s %s %s" % (self.id, smart_str(self.filename), smart_str(self.file_path)))
def unhide_disabled_file(self): if not self.filename: return src, dst = self.guarded_file_path, self.file_path self.mv(src, dst, 'Moving undisabled file: %s => %s') # Put files back on the mirrors if necessary. if storage.exists(self.file_path): destinations = [self.version.path_prefix] if self.status in amo.MIRROR_STATUSES: destinations.append(self.version.mirror_path_prefix) for dest in destinations: dest = os.path.join(dest, nfd_str(self.filename)) log.info('Re-mirroring disabled/enabled file to %s' % dest) copy_stored_file(self.file_path, dest)
def copy_to_mirror(self): if not self.filename: return try: if storage.exists(self.file_path): dst = self.mirror_file_path if not dst: return log.info('Moving file to mirror: %s => %s' % (self.file_path, dst)) copy_stored_file(self.file_path, dst) except UnicodeEncodeError: log.info( 'Copy Failure: %s %s %s' % (self.id, smart_str(self.filename), smart_str(self.file_path)))
def from_upload(cls, upload, version, platform, is_beta=False, parse_data={}): f = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] if ext == '.jar': ext = '.xpi' f.filename = f.generate_filename(extension=ext or '.xpi') # Size in bytes. f.size = storage.size(upload.path) data = cls.get_jetpack_metadata(upload.path) if 'sdkVersion' in data and data['sdkVersion']: f.jetpack_version = data['sdkVersion'][:10] if f.jetpack_version: Tag(tag_text='jetpack').save_tag(version.addon) f.builder_version = data['builderVersion'] f.no_restart = parse_data.get('no_restart', False) f.strict_compatibility = parse_data.get('strict_compatibility', False) if version.addon.status == amo.STATUS_PUBLIC: if is_beta: f.status = amo.STATUS_BETA elif version.addon.trusted: f.status = amo.STATUS_PUBLIC elif (version.addon.status in amo.LITE_STATUSES and version.addon.trusted): f.status = version.addon.status f.hash = f.generate_hash(upload.path) if upload.validation: validation = json.loads(upload.validation) if validation['metadata'].get('requires_chrome'): f.requires_chrome = True f.save() log.debug('New file: %r from %r' % (f, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if f.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def from_upload(cls, upload, version, platform, parse_data={}): is_webapp = version.addon.is_webapp() f = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] if ext == '.jar': ext = '.xpi' f.filename = f.generate_filename(extension=ext or '.xpi') # Size in bytes. f.size = storage.size(upload.path) data = cls.get_jetpack_metadata(upload.path) if 'sdkVersion' in data and data['sdkVersion']: f.jetpack_version = data['sdkVersion'][:10] if f.jetpack_version: Tag(tag_text='jetpack').save_tag(version.addon) f.builder_version = data['builderVersion'] f.no_restart = parse_data.get('no_restart', False) f.strict_compatibility = parse_data.get('strict_compatibility', False) if is_webapp: f.status = amo.STATUS_PENDING elif version.addon.status == amo.STATUS_PUBLIC: if amo.VERSION_BETA.search(parse_data.get('version', '')): f.status = amo.STATUS_BETA elif version.addon.trusted: f.status = amo.STATUS_PUBLIC elif (version.addon.status in amo.LITE_STATUSES and version.addon.trusted): f.status = version.addon.status f.hash = f.generate_hash(upload.path) if upload.validation: validation = json.loads(upload.validation) if validation['metadata'].get('requires_chrome'): f.requires_chrome = True f.save() log.debug('New file: %r from %r' % (f, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if f.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def from_upload(cls, upload, version, platform, parse_data={}): upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] f = cls(version=version, platform=platform) f.filename = f.generate_filename(extension=ext or ".zip") f.size = storage.size(upload.path) # Size in bytes. f.status = amo.STATUS_PENDING f.hash = f.generate_hash(upload.path) f.save() log.debug("New file: %r from %r" % (f, upload)) # Move the uploaded file from the temp location. copy_stored_file(upload.path, os.path.join(version.path_prefix, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def from_upload(cls, upload, version, platform, parse_data={}): f = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] f.filename = f.generate_filename(extension=ext or '.xpi') # Size in kilobytes. f.size = int(max(1, round(storage.size(upload.path) / 1024, 0))) data = cls.get_jetpack_metadata(upload.path) f.jetpack_version = data['sdkVersion'] f.builder_version = data['builderVersion'] f.no_restart = parse_data.get('no_restart', False) f.strict_compatibility = parse_data.get('strict_compatibility', False) if version.addon.status == amo.STATUS_PUBLIC: if amo.VERSION_BETA.search(parse_data.get('version', '')): f.status = amo.STATUS_BETA elif version.addon.trusted: f.status = amo.STATUS_PUBLIC elif (version.addon.status in amo.LITE_STATUSES and version.addon.trusted): f.status = version.addon.status elif version.addon.is_webapp(): # Files don't really matter for webapps, just make them public. f.status = amo.STATUS_PUBLIC f.hash = (f.generate_hash(upload.path) if waffle.switch_is_active('file-hash-paranoia') else upload.hash) if upload.validation: validation = json.loads(upload.validation) if validation['metadata'].get('requires_chrome'): f.requires_chrome = True f.save() log.debug('New file: %r from %r' % (f, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if f.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def from_upload(cls, upload, version, platform, parse_data={}): f = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] f.filename = f.generate_filename(extension=ext or '.xpi') # Size in kilobytes. f.size = int(max(1, round(storage.size(upload.path) / 1024, 0))) data = cls.get_jetpack_metadata(upload.path) f.jetpack_version = data['sdkVersion'] f.builder_version = data['builderVersion'] f.no_restart = parse_data.get('no_restart', False) f.strict_compatibility = parse_data.get('strict_compatibility', False) if version.addon.is_webapp(): # Files don't really matter for webapps, just make them public. f.status = amo.STATUS_PUBLIC elif version.addon.status == amo.STATUS_PUBLIC: if amo.VERSION_BETA.search(parse_data.get('version', '')): f.status = amo.STATUS_BETA elif version.addon.trusted: f.status = amo.STATUS_PUBLIC elif (version.addon.status in amo.LITE_STATUSES and version.addon.trusted): f.status = version.addon.status f.hash = (f.generate_hash(upload.path) if waffle.switch_is_active('file-hash-paranoia') else upload.hash) if upload.validation: validation = json.loads(upload.validation) if validation['metadata'].get('requires_chrome'): f.requires_chrome = True f.save() log.debug('New file: %r from %r' % (f, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if f.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def from_upload(cls, upload, version, platform, parse_data={}): upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] f = cls(version=version, platform=platform) f.filename = f.generate_filename(extension=ext or '.zip') f.size = storage.size(upload.path) # Size in bytes. f.status = amo.STATUS_PENDING f.hash = f.generate_hash(upload.path) f.save() log.debug('New file: %r from %r' % (f, upload)) # Move the uploaded file from the temp location. copy_stored_file(upload.path, os.path.join(version.path_prefix, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def from_upload(cls, upload, version, platform, is_beta=False, parse_data={}): f = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] if ext == ".jar": ext = ".xpi" f.filename = f.generate_filename(extension=ext or ".xpi") # Size in bytes. f.size = storage.size(upload.path) data = cls.get_jetpack_metadata(upload.path) if "sdkVersion" in data and data["sdkVersion"]: f.jetpack_version = data["sdkVersion"][:10] if f.jetpack_version: Tag(tag_text="jetpack").save_tag(version.addon) f.builder_version = data["builderVersion"] f.no_restart = parse_data.get("no_restart", False) f.strict_compatibility = parse_data.get("strict_compatibility", False) f.is_multi_package = parse_data.get("is_multi_package", False) if version.addon.status == amo.STATUS_PUBLIC: if is_beta: f.status = amo.STATUS_BETA elif version.addon.trusted: f.status = amo.STATUS_PUBLIC elif version.addon.status in amo.LITE_STATUSES and version.addon.trusted: f.status = version.addon.status f.hash = f.generate_hash(upload.path) if upload.validation: validation = json.loads(upload.validation) if validation["metadata"].get("requires_chrome"): f.requires_chrome = True f.save() log.debug("New file: %r from %r" % (f, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if f.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(f.filename))) if upload.validation: FileValidation.from_json(f, upload.validation) return f
def manifest_updated(self, manifest, upload): """The manifest has updated, update the version and file. This is intended to be used for hosted apps only, which have only a single version and a single file. """ data = parse_addon(upload, self) version = self.versions.latest() version.update(version=data["version"]) path = smart_path(nfd_str(upload.path)) file = version.files.latest() file.filename = file.generate_filename(extension=".webapp") file.size = storage.size(path) file.hash = file.generate_hash(path) log.info("Updated file hash to %s" % file.hash) file.save() # Move the uploaded file from the temp location. copy_stored_file(path, os.path.join(version.path_prefix, nfd_str(file.filename))) log.info("[Webapp:%s] Copied updated manifest to %s" % (self, version.path_prefix)) amo.log(amo.LOG.MANIFEST_UPDATED, self)
def from_upload(cls, upload, version, platform, is_beta=False, parse_data={}): addon = version.addon file_ = cls(version=version, platform=platform) upload.path = amo.utils.smart_path(nfd_str(upload.path)) ext = os.path.splitext(upload.path)[1] if ext == '.jar': ext = '.xpi' file_.filename = file_.generate_filename(extension=ext or '.xpi') # Size in bytes. file_.size = storage.size(upload.path) data = cls.get_jetpack_metadata(upload.path) if 'sdkVersion' in data and data['sdkVersion']: file_.jetpack_version = data['sdkVersion'][:10] if file_.jetpack_version: Tag(tag_text='jetpack').save_tag(addon) file_.no_restart = parse_data.get('no_restart', False) file_.strict_compatibility = parse_data.get('strict_compatibility', False) file_.is_multi_package = parse_data.get('is_multi_package', False) if is_beta and addon.status == amo.STATUS_PUBLIC: file_.status = amo.STATUS_BETA elif addon.trusted: # New files in trusted add-ons automatically receive the correct # approved status for their review class. if addon.status == amo.STATUS_PUBLIC: file_.status = amo.STATUS_PUBLIC elif addon.status in amo.LITE_STATUSES: file_.status = amo.STATUS_LITE file_.hash = file_.generate_hash(upload.path) file_.original_hash = file_.hash if upload.validation: validation = json.loads(upload.validation) if validation['metadata'].get('requires_chrome'): file_.requires_chrome = True file_.save() log.debug('New file: %r from %r' % (file_, upload)) # Move the uploaded file from the temp location. destinations = [version.path_prefix] if file_.status in amo.MIRROR_STATUSES: destinations.append(version.mirror_path_prefix) for dest in destinations: copy_stored_file(upload.path, os.path.join(dest, nfd_str(file_.filename))) if upload.validation: # Import loop. from devhub.tasks import annotate_validation_results from devhub.utils import ValidationAnnotator validation = annotate_validation_results(validation) FileValidation.from_json(file_, validation) # Copy annotations from any previously approved file. ValidationAnnotator(file_).update_annotations() return file_
def test_copy(self): src = self.newfile('src.txt', '<contents>') dest = self.path('somedir/dest.txt') copy_stored_file(src, dest) eq_(self.contents(dest), '<contents>')
def test_non_ascii(self): src = self.newfile(u'kristi\u0107.txt', u'ivan kristi\u0107'.encode('utf8')) dest = self.path(u'somedir/kristi\u0107.txt') copy_stored_file(src, dest) eq_(self.contents(dest), 'ivan kristi\xc4\x87')
def test_copy_chunking(self): src = self.newfile('src.txt', '<contents>') dest = self.path('somedir/dest.txt') copy_stored_file(src, dest, chunk_size=1) eq_(self.contents(dest), '<contents>')
def test_self_copy(self): src = self.newfile('src.txt', '<contents>') dest = self.path('src.txt') copy_stored_file(src, dest) eq_(self.contents(dest), '<contents>')