def shelf(apps, **kw): carrier = kw.get('carrier', random.choice(CARRIER_CHOICE_DICT.values())) region = REGIONS_DICT[kw.get('region', 'restofworld')].id sh = FeedShelf.objects.create( carrier=carrier.id, description=kw.get('description', 'shelf for ' + carrier.name), name=kw.get('name', '%s Op Shelf' % carrier.name), region=region) gen = pydenticon.Generator(8, 8, foreground=foreground) img = gen.generate(unicode(sh.name).encode('utf8'), 128, 128, output_format='png') with public_storage.open(sh.image_path(''), 'wb') as f: f.write(img) with public_storage.open(sh.image_path('_landing'), 'wb') as f: f.write(img) image_hash = hashlib.md5(img).hexdigest()[:8] sh.update(slug=kw.get('slug', 'shelf-%d' % sh.pk), image_hash=image_hash, image_landing_hash=image_hash) for a in apps: FeedShelfMembership.objects.create(obj=sh, app=a) FeedItem.objects.create(item_type='shelf', shelf=sh, region=region) return sh
def test_preview_rotated(self): addon = Webapp.objects.get(pk=337141) preview = Preview.objects.create(addon=addon) src = self.get_image('preview_landscape.jpg') tasks.resize_preview(src, preview.pk) preview = preview.reload() eq_(preview.image_size, [533, 400]) eq_(preview.thumbnail_size, [133, 100]) eq_(preview.is_landscape, True) with public_storage.open(preview.thumbnail_path) as fp: im = Image.open(fp) eq_(list(im.size), [133, 100]) with public_storage.open(preview.image_path) as fp: im = Image.open(fp) eq_(list(im.size), [533, 400])
def test_preview_rotated(self): addon = Webapp.objects.get(pk=337141) preview = Preview.objects.create(addon=addon) src = self.get_image('preview_landscape.jpg') tasks.resize_preview(src, preview.pk) preview = preview.reload() eq_(preview.image_size, [533, 400]) eq_(preview.thumbnail_size, [133, 100]) eq_(preview.is_landscape, True) with public_storage.open(preview.thumbnail_path) as fp: im = Image.open(fp) eq_(list(im.size), [133, 100]) with public_storage.open(preview.image_path) as fp: im = Image.open(fp) eq_(list(im.size), [533, 400])
def save_icon(obj, icon_content, sizes=mkt.CONTENT_ICON_SIZES): """ Saves the icon for `obj` to its final destination. `obj` can be an app or a website. """ tmp_dst = os.path.join(settings.TMP_PATH, 'icon', uuid.uuid4().hex) with public_storage.open(tmp_dst, 'wb') as fd: fd.write(icon_content) dirname = obj.get_icon_dir() destination = os.path.join(dirname, '%s' % obj.pk) remove_icons(destination) icon_hash = resize_icon(tmp_dst, destination, sizes, set_modified_on=[obj], src_storage=public_storage, dst_storage=public_storage) # Need to set icon type so .get_icon_url() works normally # submit step 4 does it through AppFormMedia, but we want to beat them to # the punch. resize_icon outputs pngs so we know it's 'image/png'. obj.icon_hash = icon_hash['icon_hash'] # In case, we're running not async. try: obj.icon_type = 'image/png' except AttributeError: # icon_type can be just a @property on models that only implement png. pass obj.save()
def test_saves_promo_img(self, requests_mock, crush_mock): img_path = os.path.join(settings.ROOT, 'mkt', 'site', 'tests', 'images', 'game_1050.jpg') # Mock the image fetch request. with open(img_path, 'r') as content: requests_mock.return_value = mock.Mock(content=content.read(), headers={'ok': 'ok'}, status_code=200) result = fetch_promo_imgs(self.website.pk, 'http://mocked_url.ly') ok_(result) website = Website.objects.all()[0] eq_(website.promo_img_hash, '215dd2a2') # Check the actual saved image on disk. img_dir = website.get_promo_img_dir() for size in mkt.PROMO_IMG_SIZES: img_path = os.path.join(img_dir, '%s-%s.png' % (str(website.id), size)) with public_storage.open(img_path, 'r') as img: checker = ImageCheck(img) assert checker.is_image() eq_(checker.img.size[0], size)
def create_export(self, name): with self.settings(DUMPED_APPS_PATH=self.export_directory): export_data(name=name) tarball_path = os.path.join(self.export_directory, "tarballs", name + ".tgz") self.tarfile_file = public_storage.open(tarball_path) self.tarfile = tarfile.open(fileobj=self.tarfile_file) return self.tarfile
def perform_create(self, serializer): """Download and validate image URL.""" imgs = [] for image_field, hash_field, suffix in self.image_fields: if serializer.validated_data.get(image_field): img_url = serializer.validated_data[image_field] img, hash_ = image_from_url(img_url) # Store img for `post_save` where we have access to the pk so # we can save img in appropriate directory. imgs.append((suffix, img, hash_)) serializer.validated_data[hash_field] = hash_ elif ( serializer.validated_data.get("type") or (serializer.instance and getattr(serializer.instance, "type", None)) ) == feed.COLLECTION_PROMO: # Remove background images for promo collections. serializer.validated_data[hash_field] = None if image_field in serializer.validated_data: del serializer.validated_data[image_field] obj = serializer.save() for suffix, image, hash_ in imgs: if image: i = Image.open(image) path = obj.image_path(suffix) with public_storage.open(path, "wb") as f: i.save(f, "png") pngcrush_image.delay(path, set_modified_on=[obj])
def test_upload_sign_error_existing(self, sign_app_mock): sign_app_mock.side_effect = SigningError langpack = self.create_langpack() eq_(LangPack.objects.count(), 1) original_uuid = langpack.uuid original_file_path = langpack.file_path original_file_version = langpack.file_version original_version = langpack.version # create_langpack() doesn't create a fake file, let's add one. with public_storage.open(langpack.file_path, 'w') as f: f.write('.') upload = self.upload('langpack') with self.assertRaises(SigningError): LangPack.from_upload(upload, instance=langpack) # Test that we didn't delete the upload file ok_(private_storage.exists(upload.path)) # Test that we didn't delete the existing filename or alter the # existing langpack in the database. eq_(LangPack.objects.count(), 1) langpack.reload() eq_(original_uuid, langpack.uuid) eq_(langpack.file_path, original_file_path) eq_(original_file_version, langpack.file_version) eq_(original_version, langpack.version) ok_(public_storage.exists(langpack.file_path)) # Cleanup public_storage.delete(langpack.file_path)
def test_pngcrush_image_is_called(self, mock_move): expected_suffix = '.opti.png' tmp_src = tempfile.NamedTemporaryFile(suffix='.png', delete=False) tmp_dest = os.path.splitext(tmp_src.name)[0] + expected_suffix copy_stored_file(self.img_path, tmp_dest, src_storage=public_storage, dst_storage=local_storage) with mock.patch('tempfile.NamedTemporaryFile', lambda *a, **k: tmp_src): rval = tasks.pngcrush_image(self.img_path) # pngcrush_image copies the stored file to a local tempfile. eq_(open(tmp_src.name).read(), public_storage.open(self.img_path).read()) expected_cmd = ['pngcrush', '-q', '-rem', 'alla', '-brute', '-reduce', '-e', expected_suffix, tmp_src.name] # pngcrush_image incokes pngcrush with the tempfile name and writes to # another tempfile. self.mock_popen.assert_called_once_with( expected_cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) # The output file is then copied back to storage. mock_move.assert_called_once_with(tmp_dest, self.img_path, dst_storage=public_storage, src_storage=local_storage) eq_(rval, {'image_hash': 'bb362450'})
def save_icon(obj, icon_content): """ Saves the icon for `obj` to its final destination. `obj` can be an app or a website. """ tmp_dst = os.path.join(settings.TMP_PATH, 'icon', uuid.uuid4().hex) with public_storage.open(tmp_dst, 'wb') as fd: fd.write(icon_content) dirname = obj.get_icon_dir() destination = os.path.join(dirname, '%s' % obj.pk) remove_icons(destination) icon_hash = resize_icon(tmp_dst, destination, mkt.CONTENT_ICON_SIZES, set_modified_on=[obj], src_storage=public_storage, dst_storage=public_storage) # Need to set icon type so .get_icon_url() works normally # submit step 4 does it through AppFormMedia, but we want to beat them to # the punch. resize_icon outputs pngs so we know it's 'image/png'. obj.icon_hash = icon_hash['icon_hash'] # In case, we're running not async. try: obj.icon_type = 'image/png' except AttributeError: # icon_type can be just a @property on models that only implement png. pass obj.save()
def collection(apps, slug, background_image=True, **kw): region = REGIONS_DICT[kw.get('region', 'restofworld')].id colorname = kw.get('color', random.choice(COLLECTION_COLORS.keys())) co = FeedCollection.objects.create( type=kw.get('type', 'listing'), color=colorname, background_color=COLLECTION_COLORS[colorname], slug=slug, description=kw.get('description', '')) name = kw.get('name', 'Collection %s' % co.pk) if background_image: gen = pydenticon.Generator(8, 8, foreground=foreground) img = gen.generate(name, 128, 128, output_format='png') with public_storage.open(co.image_path(''), 'wb') as f: f.write(img) image_hash = hashlib.md5(img).hexdigest()[:8] else: image_hash = None co.name = name co.image_hash = image_hash co.save() for a in apps: FeedCollectionMembership.objects.create(obj=co, app=a) FeedItem.objects.create(item_type='collection', collection=co, region=region) return co
def _no_sign(src, dst_path): # If this is a local development instance, just copy the file around # so that everything seems to work locally. log.info('Not signing the app, no signing server is active.') with public_storage.open(dst_path, 'w') as dst_f: shutil.copyfileobj(src, dst_f)
def perform_create(self, serializer): """Download and validate image URL.""" imgs = [] for image_field, hash_field, suffix in self.image_fields: if serializer.validated_data.get(image_field): img_url = serializer.validated_data[image_field] img, hash_ = image_from_url(img_url) # Store img for `post_save` where we have access to the pk so # we can save img in appropriate directory. imgs.append((suffix, img, hash_)) serializer.validated_data[hash_field] = hash_ elif ((serializer.validated_data.get('type') or (serializer.instance and getattr(serializer.instance, 'type', None))) == feed.COLLECTION_PROMO): # Remove background images for promo collections. serializer.validated_data[hash_field] = None if image_field in serializer.validated_data: del serializer.validated_data[image_field] obj = serializer.save() for suffix, image, hash_ in imgs: if image: i = Image.open(image) path = obj.image_path(suffix) with public_storage.open(path, 'wb') as f: i.save(f, 'png') pngcrush_image.delay(path, set_modified_on=[obj])
def test_saves_promo_img(self, requests_mock, crush_mock): img_path = os.path.join(settings.ROOT, 'mkt', 'site', 'tests', 'images', 'game_1050.jpg') # Mock the image fetch request. with open(img_path, 'r') as content: requests_mock.return_value = mock.Mock( content=content.read(), headers={'ok': 'ok'}, status_code=200) result = fetch_promo_imgs(self.website.pk, 'http://mocked_url.ly') ok_(result) website = Website.objects.all()[0] eq_(website.promo_img_hash, '215dd2a2') # Check the actual saved image on disk. img_dir = website.get_promo_img_dir() for size in mkt.PROMO_IMG_SIZES: img_path = os.path.join(img_dir, '%s-%s.png' % (str(website.id), size)) with public_storage.open(img_path, 'r') as img: checker = ImageCheck(img) assert checker.is_image() eq_(checker.img.size[0], size)
def collection(apps, slug, background_image=True, **kw): region = REGIONS_DICT[kw.get('region', 'restofworld')].id colorname = kw.get('color', random.choice(COLLECTION_COLORS.keys())) co = FeedCollection.objects.create( type=kw.get('type', 'listing'), color=colorname, background_color=COLLECTION_COLORS[colorname], slug=slug, description=kw.get('description', '')) name = kw.get('name', 'Collection %s' % co.pk) if background_image: gen = pydenticon.Generator(8, 8, foreground=foreground) img = gen.generate(name, 128, 128, output_format='png') with public_storage.open(co.image_path(''), 'wb') as f: f.write(img) image_hash = hashlib.md5(img).hexdigest()[:8] else: image_hash = None co.name = name co.image_hash = image_hash co.save() for a in apps: FeedCollectionMembership.objects.create(obj=co, app=a) FeedItem.objects.create(item_type='collection', collection=co, region=region) return co
def test_correct_new_icon(self): self.client.put(self.url, data=json.dumps(self.data)) icon_dir = self.app.get_icon_dir() icon_path = os.path.join(icon_dir, '%s-128.png' % str(self.app.id)) eq_( self.images_are_equal(self.mozball_image(), public_storage.open(icon_path)), True)
def test_upload_sign_error_existing(self, sign_app_mock): sign_app_mock.side_effect = SigningError langpack = self.create_langpack() eq_(LangPack.objects.count(), 1) original_uuid = langpack.uuid original_file_path = langpack.file_path original_file_version = langpack.file_version original_version = langpack.version # create_langpack() doesn't create a fake file, let's add one. with public_storage.open(langpack.file_path, 'w') as f: f.write('.') upload = self.upload('langpack') with self.assertRaises(SigningError): LangPack.from_upload(upload, instance=langpack) # Test that we didn't delete the upload file ok_(private_storage.exists(upload.path)) # Test that we didn't delete the existing filename or alter the # existing langpack in the database. eq_(LangPack.objects.count(), 1) langpack.reload() eq_(original_uuid, langpack.uuid) eq_(langpack.file_path, original_file_path) eq_(original_file_version, langpack.file_version) eq_(original_version, langpack.version) ok_(public_storage.exists(langpack.file_path)) # Cleanup public_storage.delete(langpack.file_path)
def setUp(self): self.export_directory = mkdtemp() self.existing_tarball = os.path.join(self.export_directory, "tarballs", "2004-08-15") with public_storage.open(self.existing_tarball, "w") as fd: fd.write(".") self.app_path = "apps/337/337141.json" self.tarfile_file = None self.tarfile = None
def test_inject_ids(self, post): post().status_code = 200 post().content = '{"zigbert.rsa": ""}' packaged.sign(self.version.pk) zf = zipfile.ZipFile(public_storage.open(self.file.signed_file_path), mode='r') ids_data = zf.read('META-INF/ids.json') eq_(sorted(json.loads(ids_data).keys()), ['id', 'version'])
def test_unhide_disabled_files(self): f = File.objects.get() f.status = mkt.STATUS_PUBLIC with private_storage.open(f.guarded_file_path, 'wb') as fp: fp.write('some data\n') f.unhide_disabled_file() assert public_storage.exists(f.file_path) assert public_storage.open(f.file_path).size
def test_inject_ids(self, post): post().status_code = 200 post().content = '{"zigbert.rsa": ""}' packaged.sign(self.version.pk) zf = zipfile.ZipFile(public_storage.open(self.file.signed_file_path), mode='r') ids_data = zf.read('META-INF/ids.json') eq_(sorted(json.loads(ids_data).keys()), ['id', 'version'])
def test_unhide_disabled_files(self): f = File.objects.get() f.status = mkt.STATUS_PUBLIC with private_storage.open(f.guarded_file_path, 'wb') as fp: fp.write('some data\n') f.unhide_disabled_file() assert public_storage.exists(f.file_path) assert public_storage.open(f.file_path).size
def create_export(self, name): with self.settings(DUMPED_APPS_PATH=self.export_directory): export_data(name=name) tarball_path = os.path.join(self.export_directory, 'tarballs', name + '.tgz') self.tarfile_file = public_storage.open(tarball_path) self.tarfile = tarfile.open(fileobj=self.tarfile_file) return self.tarfile
def setUp(self): self.export_directory = mkdtemp() self.existing_tarball = os.path.join(self.export_directory, 'tarballs', '2004-08-15') with public_storage.open(self.existing_tarball, 'w') as fd: fd.write('.') self.app_path = 'apps/337/337141.json' self.tarfile_file = None self.tarfile = None
def setUp(self): self.export_directory = mkdtemp() self.existing_tarball = os.path.join( self.export_directory, 'tarballs', '2004-08-15') with public_storage.open(self.existing_tarball, 'w') as fd: fd.write('.') self.app_path = 'apps/337/337141.json' self.tarfile_file = None self.tarfile = None
def check_delete(self, file_, filename): """Test that when the File object is deleted, it is removed from the filesystem.""" try: with public_storage.open(filename, 'w') as f: f.write('sample data\n') assert public_storage.exists(filename) file_.delete() assert not public_storage.exists(filename) finally: if public_storage.exists(filename): public_storage.delete(filename)
def setUp(self): super(TestExtensionNonAPIViews, self).setUp() self.fake_manifest = { 'name': u'Fake Extënsion', } self.extension = Extension.objects.create( version='0.1', status=STATUS_PUBLIC, manifest=self.fake_manifest) self.user = UserProfile.objects.get(pk=2519) self.extension.authors.add(self.user) with public_storage.open(self.extension.signed_file_path, 'w') as f: f.write('fake signed zip file\n')
def post_save(self, obj, created=True): """Store image that we attached to the obj in pre_save.""" for image_field, hash_field, suffix in self.image_fields: image = getattr(obj, '_%s' % image_field, None) if image: i = Image.open(image) path = obj.image_path(suffix) with public_storage.open(path, 'wb') as f: i.save(f, 'png') pngcrush_image.delay(path, set_modified_on=[obj]) return super(ImageURLUploadMixin, self).post_save(obj, created)
def post_save(self, obj, created=True): """Store image that we attached to the obj in pre_save.""" for image_field, hash_field, suffix in self.image_fields: image = getattr(obj, '_%s' % image_field, None) if image: i = Image.open(image) path = obj.image_path(suffix) with public_storage.open(path, 'wb') as f: i.save(f, 'png') pngcrush_image.delay(path, set_modified_on=[obj]) return super(ImageURLUploadMixin, self).post_save(obj, created)
def check_delete(self, file_, filename): """Test that when the File object is deleted, it is removed from the filesystem.""" try: with public_storage.open(filename, 'w') as f: f.write('sample data\n') assert public_storage.exists(filename) file_.delete() assert not public_storage.exists(filename) finally: if public_storage.exists(filename): public_storage.delete(filename)
def test_preview_dont_generate_image(self): addon = Webapp.objects.get(pk=337141) preview = Preview.objects.create(addon=addon) src = self.get_image('preview.jpg') tasks.resize_preview(src, preview.pk, generate_image=False) preview = preview.reload() eq_(preview.image_size, []) eq_(preview.thumbnail_size, [100, 133]) eq_(preview.sizes, {u'thumbnail': [100, 133]}) with public_storage.open(preview.thumbnail_path) as fp: im = Image.open(fp) eq_(list(im.size), [100, 133]) assert not os.path.exists(preview.image_path), preview.image_path
def test_preview_dont_generate_image(self): addon = Webapp.objects.get(pk=337141) preview = Preview.objects.create(addon=addon) src = self.get_image('preview.jpg') tasks.resize_preview(src, preview.pk, generate_image=False) preview = preview.reload() eq_(preview.image_size, []) eq_(preview.thumbnail_size, [100, 133]) eq_(preview.sizes, {u'thumbnail': [100, 133]}) with public_storage.open(preview.thumbnail_path) as fp: im = Image.open(fp) eq_(list(im.size), [100, 133]) assert not os.path.exists(preview.image_path), preview.image_path
def setUp(self): UserProfile.objects.get_or_create(id=settings.TASK_USER_ID) # Not using app factory since it creates translations with an invalid # locale of "en-us". self.addon = Webapp.objects.create() self.version = Version.objects.create(addon=self.addon, _developer_name='Mozilla') self.file = File.objects.create(version=self.version, hash=ohash, status=mkt.STATUS_PUBLIC, filename='%s-%s' % (self.addon.id, self.version.id)) self.addon.name = { 'en-US': 'MozillaBall', 'de': 'Mozilla Kugel', } self.addon.status = mkt.STATUS_PUBLIC self.addon.manifest_url = 'http://nowhere.allizom.org/manifest.webapp' self.addon.save() self.addon.update_version() self.addon.addonuser_set.create(user_id=999) with public_storage.open(self.file.file_path, 'w') as fh: fh.write(json.dumps(original)) # This is the hash to set the get_content_hash to, for showing # that the webapp has been updated. self._hash = nhash # Let's use deepcopy so nested dicts are copied as new objects. self.new = deepcopy(new) self.content_type = 'application/x-web-app-manifest+json' req_patcher = mock.patch('mkt.developers.tasks.requests.get') self.req_mock = req_patcher.start() self.addCleanup(req_patcher.stop) self.response_mock = mock.Mock(status_code=200) self.response_mock.iter_content.return_value = mock.Mock( next=self._data) self.response_mock.headers = {'content-type': self.content_type} self.req_mock.return_value = self.response_mock validator_patcher = mock.patch('mkt.webapps.tasks.validator') self.validator = validator_patcher.start() self.addCleanup(validator_patcher.stop) self.validator.return_value = {}
def test_delete_with_file(self): """Test that when a LangPack instance is deleted, the corresponding file on the filesystem is also deleted.""" langpack = LangPack.objects.create(version='0.1') file_path = langpack.file_path with public_storage.open(file_path, 'w') as f: f.write('sample data\n') assert public_storage.exists(file_path) try: langpack.delete() assert not public_storage.exists(file_path) finally: if public_storage.exists(file_path): public_storage.delete(file_path)
def check_icons(self, webapp, file_obj=None): manifest = webapp.get_manifest_json(file_obj) biggest = max([int(size) for size in manifest['icons']]) icon_dir = webapp.get_icon_dir() for size in mkt.CONTENT_ICON_SIZES: if not size <= biggest: continue icon_path = os.path.join(icon_dir, '%s-%s.png' % (str(webapp.id), size)) with public_storage.open(icon_path, 'r') as img: checker = ImageCheck(img) assert checker.is_image() eq_(checker.img.size, (size, size))
def check_icons(self, webapp, file_obj=None): manifest = webapp.get_manifest_json(file_obj) biggest = max([int(size) for size in manifest['icons']]) icon_dir = webapp.get_icon_dir() for size in mkt.CONTENT_ICON_SIZES: if not size <= biggest: continue icon_path = os.path.join(icon_dir, '%s-%s.png' % (str(webapp.id), size)) with public_storage.open(icon_path, 'r') as img: checker = ImageCheck(img) assert checker.is_image() eq_(checker.img.size, (size, size))
def setUp(self): super(TestLangPackNonAPIViews, self).setUp() self.fake_manifest = { 'name': u'Fake LangPäck', 'developer': { 'name': 'Mozilla' } } self.langpack = LangPack.objects.create( version='0.1', active=True, manifest=json.dumps(self.fake_manifest)) self.user = UserProfile.objects.get(pk=2519) with public_storage.open(self.langpack.file_path, 'w') as f: f.write('sample data\n')
def test_resize_transparency(): src = get_image_path('transparent.png') dest = tempfile.mkstemp(dir=settings.TMP_PATH)[1] expected = src.replace('.png', '-expected.png') if storage_is_remote(): copy_to_storage(src, src, src_storage=local_storage) try: resize_image(src, dest, (32, 32), remove_src=False) with public_storage.open(dest) as dfh: with open(expected) as efh: assert dfh.read() == efh.read() finally: if public_storage.exists(dest): public_storage.delete(dest)
def update(self, request, *args, **kwargs): obj = self.get_object() try: img, hash_ = image_from_data_url(request.read()) except ValidationError: return Response(status=status.HTTP_400_BAD_REQUEST) i = Image.open(img) with public_storage.open(obj.image_path(self.image_suffix), "wb") as f: i.save(f, "png") # Store the hash of the original image data sent. obj.update(**{self.hash_field: hash_}) pngcrush_image.delay(obj.image_path(self.image_suffix)) return Response(status=status.HTTP_204_NO_CONTENT)
def update(self, request, *args, **kwargs): obj = self.get_object() try: img, hash_ = image_from_data_url(request.read()) except ValidationError: return Response(status=status.HTTP_400_BAD_REQUEST) i = Image.open(img) with public_storage.open(obj.image_path(self.image_suffix), 'wb') as f: i.save(f, 'png') # Store the hash of the original image data sent. obj.update(**{self.hash_field: hash_}) pngcrush_image.delay(obj.image_path(self.image_suffix)) return Response(status=status.HTTP_204_NO_CONTENT)
def test_resize_transparency(): src = get_image_path('transparent.png') dest = tempfile.mkstemp(dir=settings.TMP_PATH)[1] expected = src.replace('.png', '-expected.png') if storage_is_remote(): copy_to_storage(src, src, src_storage=local_storage) try: resize_image(src, dest, (32, 32), remove_src=False) with public_storage.open(dest) as dfh: with open(expected) as efh: assert dfh.read() == efh.read() finally: if public_storage.exists(dest): public_storage.delete(dest)
def test_delete_with_file(self): """Test that when a LangPack instance is deleted, the corresponding file on the filesystem is also deleted.""" langpack = LangPack.objects.create(version='0.1') file_path = langpack.file_path with public_storage.open(file_path, 'w') as f: f.write('sample data\n') assert public_storage.exists(file_path) try: langpack.delete() assert not public_storage.exists(file_path) finally: if public_storage.exists(file_path): public_storage.delete(file_path)
def setUp(self): UserProfile.objects.get_or_create(id=settings.TASK_USER_ID) # Not using app factory since it creates translations with an invalid # locale of "en-us". self.webapp = Webapp.objects.create() self.version = Version.objects.create(webapp=self.webapp, _developer_name='Mozilla') self.file = File.objects.create( version=self.version, hash=ohash, status=mkt.STATUS_PUBLIC, filename='%s-%s' % (self.webapp.id, self.version.id)) self.webapp.name = { 'en-US': 'MozillaBall', 'de': 'Mozilla Kugel', } self.webapp.status = mkt.STATUS_PUBLIC self.webapp.manifest_url = 'http://nowhere.allizom.org/manifest.webapp' self.webapp.save() self.webapp.update_version() self.webapp.webappuser_set.create(user_id=999) with public_storage.open(self.file.file_path, 'w') as fh: fh.write(json.dumps(original)) # This is the hash to set the get_content_hash to, for showing # that the webapp has been updated. self._hash = nhash # Let's use deepcopy so nested dicts are copied as new objects. self.new = deepcopy(new) self.content_type = 'application/x-web-app-manifest+json' req_patcher = mock.patch('mkt.developers.tasks.requests.get') self.req_mock = req_patcher.start() self.addCleanup(req_patcher.stop) self.response_mock = mock.Mock(status_code=200) self.response_mock.iter_content.return_value = mock.Mock( next=self._data) self.response_mock.headers = {'content-type': self.content_type} self.req_mock.return_value = self.response_mock validator_patcher = mock.patch('mkt.webapps.tasks.validator') self.validator = validator_patcher.start() self.addCleanup(validator_patcher.stop) self.validator.return_value = {}
def shelf(apps, **kw): carrier = kw.get('carrier', random.choice(CARRIER_CHOICE_DICT.values())) region = REGIONS_DICT[kw.get('region', 'restofworld')].id sh = FeedShelf.objects.create( carrier=carrier.id, description=kw.get('description', 'shelf for ' + carrier.name), name=kw.get('name', '%s Op Shelf' % carrier.name), region=region) gen = pydenticon.Generator(8, 8, foreground=foreground) img = gen.generate(unicode(sh.name).encode('utf8'), 128, 128, output_format='png') with public_storage.open(sh.image_path(''), 'wb') as f: f.write(img) with public_storage.open(sh.image_path('_landing'), 'wb') as f: f.write(img) image_hash = hashlib.md5(img).hexdigest()[:8] sh.update(slug=kw.get('slug', 'shelf-%d' % sh.pk), image_hash=image_hash, image_landing_hash=image_hash) for a in apps: FeedShelfMembership.objects.create(obj=sh, app=a) FeedItem.objects.create(item_type='shelf', shelf=sh, region=region) return sh
def setUp(self): super(TestLangPackNonAPIViews, self).setUp() self.fake_manifest = { 'name': u'Fake LangPäck', 'developer': { 'name': 'Mozilla' } } self.langpack = LangPack.objects.create(version='0.1', active=True, manifest=json.dumps( self.fake_manifest)) self.user = UserProfile.objects.get(pk=2519) with public_storage.open(self.langpack.file_path, 'w') as f: f.write('sample data\n')
def resize_video(src, pk, user_pk=None, **kw): """Try and resize a video and cope if it fails.""" instance = Preview.objects.get(pk=pk) user = UserProfile.objects.get(pk=user_pk) if user_pk else None try: if not os.path.exists(src): # We're probably using S3 in this case. try: os.makedirs(os.path.dirname(src)) except OSError: # already exists pass copyfileobj(public_storage.open(src), open(src, 'w')) result = _resize_video(src, instance, **kw) except Exception, err: log.error('Error on processing video: %s' % err) _resize_error(src, instance, user) raise
def resize_video(src, pk, user_pk=None, **kw): """Try and resize a video and cope if it fails.""" instance = Preview.objects.get(pk=pk) user = UserProfile.objects.get(pk=user_pk) if user_pk else None try: if not os.path.exists(src): # We're probably using S3 in this case. try: os.makedirs(os.path.dirname(src)) except OSError: # already exists pass copyfileobj(public_storage.open(src), open(src, 'w')) result = _resize_video(src, instance, **kw) except Exception, err: log.error('Error on processing video: %s' % err) _resize_error(src, instance, user) raise
def pngcrush_image(src, hash_field='image_hash', **kw): """ Optimizes a PNG image by running it through Pngcrush. Returns hash. src -- filesystem image path hash_field -- field name to save the new hash on instance if passing instance through set_modified_on """ log.info('[1@None] Optimizing image: %s' % src) tmp_src = tempfile.NamedTemporaryFile(suffix='.png') with public_storage.open(src) as srcf: shutil.copyfileobj(srcf, tmp_src) tmp_src.seek(0) try: # pngcrush -ow has some issues, use a temporary file and do the final # renaming ourselves. suffix = '.opti.png' tmp_path = '%s%s' % (os.path.splitext(tmp_src.name)[0], suffix) cmd = [settings.PNGCRUSH_BIN, '-q', '-rem', 'alla', '-brute', '-reduce', '-e', suffix, tmp_src.name] sp = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = sp.communicate() if sp.returncode != 0: log.error('Error optimizing image: %s; %s' % (src, stderr.strip())) pngcrush_image.retry(args=[src], kwargs=kw, max_retries=3) return False # Return hash for set_modified_on. with open(tmp_path) as fd: image_hash = _hash_file(fd) copy_stored_file(tmp_path, src, src_storage=local_storage, dest_storage=public_storage) log.info('Image optimization completed for: %s' % src) os.remove(tmp_path) tmp_src.close() return { hash_field: image_hash } except Exception, e: log.error('Error optimizing image: %s; %s' % (src, e))
def app_item(a, type, **kw): region = REGIONS_DICT[kw.get('region', 'restofworld')].id colorname = kw.get('color', random.choice(COLLECTION_COLORS.keys())) gen = pydenticon.Generator(8, 8, foreground=foreground) img = gen.generate(a.app_slug, 128, 128, output_format='png') ap = FeedApp.objects.create( app=a, description=kw.get('description', rand_text(12)), type=type, color=colorname, preview=kw.get('preview', None), pullquote_attribution=kw.get('pullquote_attribution', None), pullquote_rating=kw.get('pullquote_rating', None), pullquote_text=kw.get('pullquote_text', None), background_color=COLLECTION_COLORS[colorname], slug=kw.get('slug', 'feed-app-%d' % a.pk)) with public_storage.open(ap.image_path(''), 'wb') as f: f.write(img) image_hash = hashlib.md5(img).hexdigest()[:8] ap.update(image_hash=image_hash) FeedItem.objects.create(item_type='app', app=ap, region=region) return ap
def _uploader(resize_size, final_size): img = get_image_path('mozilla.png') original_size = (339, 128) for rsize, fsize in zip(resize_size, final_size): dest_name = os.path.join(settings.ADDON_ICONS_PATH, '1234') src = tempfile.NamedTemporaryFile(mode='r+w+b', suffix='.png', delete=False) # resize_icon removes the original, copy it to a tempfile and use that. copy_stored_file(img, src.name, src_storage=local_storage, dest_storage=private_storage) # Sanity check. with private_storage.open(src.name) as fp: src_image = Image.open(fp) src_image.load() eq_(src_image.size, original_size) val = tasks.resize_icon(src.name, dest_name, resize_size) eq_(val, {'icon_hash': 'bb362450'}) dest_image_filename = '%s-%s.png' % (dest_name, rsize) with public_storage.open(dest_image_filename) as fp: dest_image = Image.open(fp) dest_image.load() # Assert that the width is always identical. eq_(dest_image.size[0], fsize[0]) # Assert that the height can be a wee bit fuzzy. assert -1 <= dest_image.size[1] - fsize[1] <= 1, ( 'Got width %d, expected %d' % (fsize[1], dest_image.size[1])) if public_storage.exists(dest_image_filename): public_storage.delete(dest_image_filename) assert not public_storage.exists(dest_image_filename) assert not private_storage.exists(src.name)
def app_item(a, type, **kw): region = REGIONS_DICT[kw.get('region', 'restofworld')].id colorname = kw.get('color', random.choice(COLLECTION_COLORS.keys())) gen = pydenticon.Generator(8, 8, foreground=foreground) img = gen.generate(a.app_slug, 128, 128, output_format='png') ap = FeedApp.objects.create( app=a, description=kw.get('description', rand_text(12)), type=type, color=colorname, preview=kw.get('preview', None), pullquote_attribution=kw.get('pullquote_attribution', None), pullquote_rating=kw.get('pullquote_rating', None), pullquote_text=kw.get('pullquote_text', None), background_color=COLLECTION_COLORS[colorname], slug=kw.get('slug', 'feed-app-%d' % a.pk)) with public_storage.open(ap.image_path(''), 'wb') as f: f.write(img) image_hash = hashlib.md5(img).hexdigest()[:8] ap.update(image_hash=image_hash) FeedItem.objects.create(item_type='app', app=ap, region=region) return ap
def _uploader(resize_size, final_size): img = get_image_path('mozilla.png') original_size = (339, 128) for rsize, fsize in zip(resize_size, final_size): dest_name = os.path.join(settings.ADDON_ICONS_PATH, '1234') src = tempfile.NamedTemporaryFile(mode='r+w+b', suffix='.png', delete=False) # resize_icon removes the original, copy it to a tempfile and use that. copy_stored_file(img, src.name, src_storage=local_storage, dest_storage=private_storage) # Sanity check. with private_storage.open(src.name) as fp: src_image = Image.open(fp) src_image.load() eq_(src_image.size, original_size) val = tasks.resize_icon(src.name, dest_name, resize_size) eq_(val, {'icon_hash': 'bb362450'}) dest_image_filename = '%s-%s.png' % (dest_name, rsize) with public_storage.open(dest_image_filename) as fp: dest_image = Image.open(fp) dest_image.load() # Assert that the width is always identical. eq_(dest_image.size[0], fsize[0]) # Assert that the height can be a wee bit fuzzy. assert -1 <= dest_image.size[1] - fsize[1] <= 1, ( 'Got width %d, expected %d' % ( fsize[1], dest_image.size[1])) if public_storage.exists(dest_image_filename): public_storage.delete(dest_image_filename) assert not public_storage.exists(dest_image_filename) assert not private_storage.exists(src.name)
def _promo_img_uploader(resize_size, final_size): img = get_image_path('game_1050.jpg') original_size = (1050, 591) for rsize, fsize in zip(resize_size, final_size): dst_name = os.path.join(settings.WEBAPP_PROMO_IMG_PATH, '1234') src = tempfile.NamedTemporaryFile(mode='r+w+b', suffix='.jpg', delete=False) # resize_icon removes the original, copy it to a tempfile and use that. copy_stored_file(img, src.name, src_storage=local_storage, dst_storage=private_storage) # Sanity check. with private_storage.open(src.name) as fp: src_image = Image.open(fp) src_image.load() eq_(src_image.size, original_size) val = tasks.resize_promo_imgs(src.name, dst_name, resize_size) eq_(val, {'promo_img_hash': '215dd2a2'}) dst_img_name = '%s-%s.png' % (dst_name, rsize) with public_storage.open(dst_img_name) as fp: dst_image = Image.open(fp) dst_image.load() # Assert that the width is always identical. eq_(dst_image.size[0], fsize[0]) # Assert that the height can be a wee bit fuzzy. assert -1 <= dst_image.size[1] - fsize[1] <= 1, ( 'Got width %d, expected %d' % ( fsize[1], dst_image.size[1])) if public_storage.exists(dst_img_name): public_storage.delete(dst_img_name) assert not public_storage.exists(dst_img_name) assert not private_storage.exists(src.name)
def test_already_exists(self, sign_app): with public_storage.open(self.file.signed_file_path, 'w') as f: f.write('.') assert packaged.sign(self.version.pk) assert not sign_app.called
def test_correct_new_icon(self): self.client.put(self.url, data=json.dumps(self.data)) icon_dir = self.app.get_icon_dir() icon_path = os.path.join(icon_dir, '%s-128.png' % str(self.app.id)) eq_(self.images_are_equal(self.mozball_image(), public_storage.open(icon_path)), True)
def clean_files(self, f): if not public_storage.exists(f.file_path): with public_storage.open(f.file_path, 'w') as fp: fp.write('sample data\n')